0

最初に、これは宿題として与えられたクラスの演習の一部であることを述べさせてください. ただし、課題全体は、この質問の主題よりもはるかに複雑です。そう..

述語に与えられた 2 つのリストを検索しています。私の目標は、このリスト内の対応する要素を比較し、最初の要素が大きいかどうかを判断することです。そうであれば、最終的にはそれらすべての項の合計を返す必要があります。これが私がこれまでに持っているものです:

isumrow([], [], Iresult) :- 
    Iresult is 0.
isumrow([Hi1row | Ti1row], [Hi2row | Ti2row], Iresult) :-   
    if((Hi1row - Hi2row), IsumDiff, Hi1row),
    NewIresult is IsumDiff + Iresult,
    isumrow(Ti1row, Ti2row, NewIresult),
    Iresult is NewIresult.

if(Diff, Iresult, Entry) :-
    Diff > 0,                       

    Iresult is Entry.

if(_, Iresult, _) :-
    Iresult is 0.

何らかの理由で、割り当てのどこかを台無しにしていて、どこにあるのかわかりません。ヒントをいただければ幸いです。繰り返しますが、これは私が取り組んでいるより大きな課題の一部ですが、これを取得できません。ありがとう

4

2 に答える 2

1
isumrow([], [], Iresult) :-
    Iresult is 0.

isumrow([Hi1row | Ti1row], [Hi2row | Ti2row], Iresult) :-
    if((Hi1row - Hi2row), IsumDiff, Hi1row),              
    NewIresult is IsumDiff + Iresult, 
    isumrow(Ti1row, Ti2row, NewIresult), 
    Iresult is NewIresult. 

if(Diff, Iresult, Entry) :- 
    Diff > 0,                                            
    Iresult is Entry. 

if(_, Iresult, _) :- 
    Iresult is 0. 
于 2009-12-28T08:03:28.027 に答える
0

あなたのコードにできる限り小さな変更を加えようとします。

絶対に間違っていることの 1 つは、差を計算しようとする場所です。isProlog は、演算子を使用する場合にのみ算術計算を行います。あなたのコード:

if((Hi1row - Hi2row), IsumDiff, Hi1row),

形式 (XY) の式をif述語に渡すだけで、それを計算していません。後でif、差を計算しませんが、式をゼロと比較しようとします...これは失敗します。これは、数値を式ではなく数値としか比較できず、Diff式に割り当てられるためです。

if の最初の節を次のように書き直すとうまくいきます (ただし、isここでは削除する必要があります)。

if((X-Y), Iresult, Entry) :-
    X > Y,
    Iresult is Entry.

このようにして、if述語は式から X と Y を取得し、それらを比較できるようになります。

ifまた、 2 つの可能な答えを得るには述語を避ける必要があります。ifバックトラックの過程で X>Y: の場合でも、2 番目の句が呼び出されます。!最も簡単な方法は、最初の節の最後に置くことです。「これまでのところ、私はこのプログラムの最初の解決策を受け入れており、ここから戻って他の解決策を見つけたくありません」という意味です。条項は次のように変更されます。

if((X-Y), Iresult, Entry) :-
    X > Y,
    Iresult is Entry,
    !.

しかし...これは小さなプログラムでは良いことであり、プログラムの他の部分で実際にバックトラックが必要な場合、これはそれを壊す可能性があります. よりクリーンな方法は、両方の句で適切な状態をチェックすることです。それらを次のように書き換えます。

if((X-Y), Iresult, Entry) :-
    X > Y,                                           
    Iresult is Entry.

if((X-Y), Iresult, _) :-
    X =< Y,
    Iresult is 0.

次に、X>Y の場合、2 番目の句は失敗します。

これらの変更の後、コードは機能するはずです...機能しない場合は報告してください。それでもプロローグ風にはなりません。少し冗長すぎます。


編集:

わかりました、私はそれを簡単な方法で書きます:

sum_if_bigger([], [], 0).
sum_if_bigger([A|L1], [B|L2], Result) :-
        sum_if_bigger(L1, L2, Partial),
        Result is Partial + max(0, A-B).

...または末尾再帰的な方法で:

sum_if_bigger_tr(L1, L2, R) :-
        sum_if_bigger_tr(L1, L2, 0, R).
sum_if_bigger_tr([], [], R, R).
sum_if_bigger_tr([A|L1], [B|L2], Partial, Result) :-
        NewPartial is Partial + max(0, A-B),
        sum_if_bigger_tr(L1, L2, NewPartial, Result).
于 2009-11-20T01:52:55.037 に答える