2

私は宿題のためにPrologで家系図プログラムを書こうとしています。これはコードの一部です。

/** a sample fact **/
parents(someone, someoneelse, child).

/** are M and F parents of the children in the given list? **/
parents(M,F,[]) :- parents(M,F,_).
parents(M,F,[First|Rest]) :- parents(M,F,First), parents(M,F,Rest).

/** are M and F parents? **/
parents(M,F) :- parents(M,F,_).

事実に一致するクエリを使用すると、上記のコードが機能します。

   [trace] 25 ?- parents(someone,someoneelse).
       Call: (6) parents(someone, someoneelse) ? creep
       Call: (7) parents(someone, someoneelse, _G586) ? creep
       Exit: (7) parents(someone, someoneelse, child) ? creep
       Exit: (6) parents(someone, someoneelse) ? creep
    true 
    .

しかし、私がこれを試してみると:

[trace] 26 ?- parents(aa, bb).
   Call: (6) parents(aa, bb) ? creep
   Call: (7) parents(aa, bb, _G541) ? creep
   Call: (8) parents(aa, bb, _G541) ? creep
   Call: (9) parents(aa, bb, _G541) ? creep
   Call: (10) parents(aa, bb, _G541) ? 
...

それは機能せず、無限ループに入ります。私がここで間違っているのは何ですか?

編集:私はそのようにコードを変更しました:

/** a sample fact **/
parents(someone, someoneelse, child).

/** are M and F parents of the children in the given list? **/
parents(M,F,[]).
parents(M,F,[First|Rest]) :- parents(M,F,First), parents(M,F,Rest).

/** are M and F parents? **/
parents(M,F) :- parents(M,F,A), not(A=[]).

今私が得るものはこれです:

[trace] 3 ?- parents(a,b).
   Call: (6) parents(a, b) ? creep
   Call: (7) parents(a, b, _G514) ? creep
   Exit: (7) parents(a, b, []) ? creep
^  Call: (7) not([]=[]) ? creep
^  Fail: (7) not(user: ([]=[])) ? creep
   Redo: (7) parents(a, b, _G514) ? creep
   Call: (8) parents(a, b, _G508) ? creep
   Exit: (8) parents(a, b, []) ? creep
   Call: (8) parents(a, b, _G509) ? creep
   Exit: (8) parents(a, b, []) ? creep
   Exit: (7) parents(a, b, [[]]) ? creep
^  Call: (7) not([[]]=[]) ? creep
^  Exit: (7) not(user: ([[]]=[])) ? creep
   Exit: (6) parents(a, b) ? creep
true 
.

失敗してやり直しになる理由がわかりません。何か案は?

4

2 に答える 2

0

2 つの異なる述語を 1 つに混同しているように感じます。

/** a sample fact **/
parents(someone, someoneelse, child).

/** are M and F parents of any child? **/
parents(M,F) :- parents(M,F,_).

/** are M and F parents of the children in the given list? **/
parents_of_all_children(M,F,[]).
parents_of_all_children(M,F,[First|Rest]) :-
    parents(M,F,First), parents_of_all_children(M,F,Rest).

次に、クエリは理にかなっています。

?- parents(someone, someoneelse, C).
C = child.
%-- someone & someoneelse have child "child"

?- parents(A, B).
A = someone,
B = someoneelse.
%-- all possible parent pairs out there

?- parents(aa, bb).
false.
%-- do "aa" & "bb" form a parents pair?
于 2012-05-21T17:56:26.547 に答える
0

検索を停止する必要があります。Prolog はすべてのルールを調べて、一致するものを見つけます。一致する場合は、展開を経てプロセスを繰り返します。

don't care (最後のルールから) が [] にマップされているため、2 行目は inf ループの原因です。

ペアが子の親であるかどうかを調べたい場合は、中間の 2 つのルールを削除するだけです。

parents(M,F,[]) :- parents(M,F,_).
parents(M,F,[First|Rest]) :- parents(M,F,First), parents(M,F,Rest).
于 2012-05-21T16:41:31.017 に答える