2017-05-12 19 views
1

問題のあるプログラムで作業しています。この短い例では、エラーは同じです。無限ループで失われました

EDITコードが間違っていた

does_something(A, [Num], Sol) :- 
    sort([Num|A], Sol). 

correct(Solution) :- 
    Solution = [1,2,3,4,5]. 

pred1(_, Solution, Solution) :- correct(Solution), !. 
pred1(A, B, Solution) :- 
    member(Num, A), 
    does_something(B, [Num], B_aux), 
    pred1(A, B_aux, Solution). 

最終編集:私は何をしたいことは述語がdoes_somethingし、正しいとは何の関係もありません。これらは例のためのものですが、問題とは何の関係もありません。私が望むのは、述語numを使ってdoes_somethingを呼び出すのが正しい解を与えるかどうかを知ることです。それが解決しない場合、Aの別のメンバーを試すように訴えられます。それが決して失敗しなければ、問題はありません。私の問題は、私はA.

?- pred1([1,2,3], [], S). 

Call: (9) [user] does_something([1], [1], _G6045) ? creep 
Call: (10) [system] sort([1, 1], _G6047) ? creep 
Exit: (10) [system] sort([1, 1], [1]) ? creep 
Exit: (9) [user] does_something([1], [1], [1]) ? creep 
Call: (9) [user] pred1([1, 2, 3], [1], _G5943) ? creep 
Call: (10) [user] correct([1]) ? creep 
Call: (11) [system] [1]=[1, 2, 3, 4, 5] ? creep 
Fail: (11) [system] [1]=[1, 2, 3, 4, 5] ? creep 
Fail: (10) [user] correct([1]) ? creep 
Redo: (9) [user] pred1([1, 2, 3], [1], _G5943) ? creep 
Call: (10) [lists] lists:member(_G6052, [1, 2, 3]) ? creep 
Exit: (10) [lists] lists:member(1, [1, 2, 3]) ? creep 
Call: (10) [user] does_something([1], [1], _G6057) ? creep 

そのトレース部分の最初と最後の行が等しいに最初よりも別のテンキーと呼ばれるようにdoes_something作ることができないということです。

+0

トレースを表示できますか?プログラムの完全なソースも役に立ちます。しかし、理想的には、エラーを再現する最小限の完全な例を見つけることを試みるべきです。 [MCVE](https://stackoverflow.com/help/mcve)を参照してください –

+0

例を試してみましょう –

+0

**プログラム全体を表示してください!そうでなければ、それはすべての2番目の推測です。 – false

答えて

3

明らかな問題は、Aが変更されないことです。つまり、再帰の各ステップで、member(_GXXX, [1, 2, 3])を呼び出し続けることになります。これは常に最初の要素1を選択します。リストとソートに追加すると、1とソートだけが追加されるので、B[1]にとどまります。

これはあなたのコードが行うことです。あなたが達成することを目的とすることは別の問題である、と私は本当にこのコード:-(

を見てから、あなたの意図を推測することはできませんところで、この:

append(A, [X], A1), sort(A1, B) 

と同じ効果を持つべきです
sort([X|A], B) 

append/3を使用すると、リストを横断する必要がないという小さな違いがあります(append/3は実際には別のものと呼ばれるはずです)。通常、リストを追加するために使用するので、分割すると便利です。 ..)

PS:リストから1つの要素を引き続き使用したい場合は、最初の要素を選択するのが最も簡単です。そのような述語は次のようになります。

foo([], Result, ...). 
foo([X|Xs], R, ...) :- 
    foo(Xs, [X|R], ...). 

したがって、要素を1つ選択して他のリストに入れるだけです。これにはmember/2は必要ありません。また、select/3を使用すると、要素を取得するだけでなく、残りの項目のリストも表示できます。ただし、これは:

​​

上記のfooと同じです。

+0

swiターミナルにmember(Num、[1,2,3])、writeln(Num)、failを入力すると、3つの数字とfalseが書き込まれます。なぜこの場合、述語メンバーはそれぞれの失敗時に番号を変更していますが、私の場合はそうではありませんか? –

+0

@DavidNunesあなたの述語定義に 'fail'がないので、あなたですか? –

+0

@DavidNunesプログラムが何をしているかを観察するのは一つのことです。理由を知る別の事;他のことをする他のプログラムを書く方法を理解するもう一つのことです。 –

関連する問題