私はswi Prologを学んでおり、各要素に+2を追加する述語を作成したいと考えていました。
だから私はこのようなものを書きました:
addUp([],_).
addUp([H|T],R):-addUp(T,R),is_list(R)->append([H+2],R,R);R=[H+2|[]].
addUp([1,2],X).
しかし、それは常に false を返します。なんで?
最初のアドバイス: maplist /3 の使い方を学ぶ: それを使って書く
addUp(Xs, Ys) :- maplist(addUp2, Xs, Ys).
addUp2(X, Y) :- Y is X + 2.
またはより良い、より再利用可能なスニペット...
addUp(Xs, Ys) :- maplist(addUp(2), Xs, Ys).
addUp(N, X, Y) :- Y is X + N.
とにかく、Prolog の算術演算は「明示的に」評価する必要があり、動作させるにはコードを大幅に単純化する必要があります
addUp([], []).
addUp([H|T], [H1|T1]) :- H1 is H+2, addUp(T, T1).
しかし、それは常に false を返します。なんで?
あなたの定義は常に失敗するとは限りません:
?- addUp([1],X)。 X = [1+2]。
それで成功することもあります。そして、このケースは多かれ少なかれあなたが望んでいたものであるようです. 他にどこで成功しますか?他のプログラミング言語では、プログラムを推測するか、天国では禁じられていることを読む必要があります。Prolog では、これは必要ありません。適切なクエリを見つけるだけです。良い候補は、最も一般的なクエリです:
?- addUp(Xs,Ys)。 Xs = [] ...
Xs
したがって、あなたの定義はequal to []
、およびYs
equal to ... まあ、 equal to anythingに対して成功します。したがって、この答えは一般的すぎます。
別の目標が私の目を引きます: is_list(R)->append([H+2],R,R)
. これがいつ実現するか想像してみましょう。R = []
ないため、またはR = [_]
. 実際、これが当てはまる長さはありません。
これで、プログラムの修正を開始できます。chac/CapelliC の提案を参照してください。