私は一日中これについて考えてきました。最後に認めますが、私は Prolog を思ったほどよく理解していません。
一日の初めに、2 つの s-Number を乗算する後継演算の実装に問題がありました。その構造は次のとおりです。
nat(0).
nat(s(X)):-nat(X).
私の最初の試みはこれでした:
mul(0,_,0).
mul(s(F1),F2,P):-mul(F1,F2,Tmp),add(F2,Tmp,P)
これは機能しましたが、クエリmul(X,Y,s(0))
は無限ループで終了しました。なんで?次の投稿を読みました: Prolog successor notation yields incomplete result and infinite loop
そこからわかったこと: add を呼び出す前に mul を呼び出し、両方の mul/3 呼び出しで使用されていない変数が mul/3 述語にある場合、Prolog はバインドされなかった変数の新しい可能性を見つけようとします。したがって、無限ループに陥ります。
この問題を解決するために、最初に add を呼び出しました。
mul(0,_,0).
mul(s(F1),F2,P):-add(F2,Tmp,P),mul(F2,F1,Tmp).
それでできました。それからべき乗関数を実装しようとしましたが、「まあ、今は簡単です。最初に試すのは次のようになります。
pow(_,0,s(0)).
pow(B,s(E),R):-pow(B,E,Tmp), mul(Tmp,B,R).
しかし、R と Tmp の左再帰を防ぐために、最初に mul を配置する必要があります。
簡単!」 男の子、私はとても間違っていました. mul を前に置いたとしても、無限ループに陥らずに実装する方法がわかりません.
どんなアドバイスでも大歓迎です。あなたは私の土曜日の仕事の労力を節約し、私の自尊心を高めることができます! 前もって感謝します。
編集:不足している合計述語を追加しました:
add(0, Y, Y).
add(s(S1), S2, s(Sum)):- add(S1,S2,Sum).