2016-05-14 2 views
1

いくつかのエラーを解決できますか?私はこのエラーを理解していません。アキュムレータと反対側のプロローグエラー

reverse(L, R) :- reverse(L, [], R). 
reverse([], R, R). 
reverse([Head|Tail], Acc, R) :- NewAcc is [Head|Acc], reverse(Tail, NewAcc, R). 

? - reverse [1,2,3]、X)。

Type error: `[]' expected, found `[2|1]' (a compound) ("x" must hold one character) 
+1

'されます/ 2'を用いて算術式を評価する。 '[Head | Acc]'は算術式ではありません。 reverse([Head | Tail]、Acc、R): - reverse(Tail、[Head | Acc])を逆順に呼び出すことで、 'NewAcc = [Head | Acc] 、R)。 – lurker

+0

* 'is/2'は算術式を評価するために使用されます*正確にはどういう意味ですか? –

+1

'Xが 'のときは、' 'は評価可能な算術式でなければならず、' 'のすべての変数がバインドされていなければならないことを意味します(値があります)。たとえば、 'Xが(Y + 7)/(2 * log(Z))'のように使用し、その場合は 'Y'と' Z'は値を持たなければならず、Prologはその式を評価します。 'X'も既に値を持っていれば、式は真ならば成功し、偽なら失敗します。多くの初めのPrologプログラマーは、一般的な代入演算子として間違って 'is/2'を使います。 Prologには "代入"演算子*がありません。 – lurker

答えて

4

あなたの述語は、原則的に動作しますが、あなたはおそらく代わりに、算術評価の/ 2は、あなたの再帰的な目標で/ 2である統一(=)を使用したい:あなたの述語の作品、この小さな変更で

reverse(L, R) :- 
    reverse(L, [], R). 

reverse([], R, R). 
reverse([Head|Tail], Acc, R) :- 
    NewAcc = [Head|Acc],    % <- here 
    reverse(Tail, NewAcc, R). 

コメントで@lurkerで指摘したように
?- reverse([1,2,3],R). 
R = [3,2,1] 

、あなたはその再帰的に[Head|Acc]を組み込むことにより、よりコンパクトに再帰ルールを表現することができますそのような目標:

reverse([Head|Tail], Acc, R) :- 
    reverse(Tail, [Head|Acc], R). 

しかし、あなたは彼らがより簡単に読み取り可能なコードを生成するように、このタスクのDCGsを使用して検討したいと思うかもしれません:

reverse(L,R) :- 
    phrase(invlist(L),R). 

invlist([]) --> 
    []. 
invlist([H|T]) --> 
    invlist(T), 
    [H]. 

それぞれのクエリでは:

?- reverse([1,2,3],R). 
R = [3,2,1] 
+1

'reverse(tail、[Head | Acc]、R)'で 'NewAcc = [Head | Acc]'を取り除くことができます。 :) – lurker

+1

@lurker:私はその細部を完全に無視しました。ヒントのおかげで、私は私の答えにそれを組み込んだ:-) – tas

関連する問題