我正在尝试在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
.
我不明白为什么现在失败后会重做。有什么想法吗?
答案 0 :(得分:0)
您必须停止搜索。 Prolog将完成所有规则并找到匹配项。如果匹配,则它将进行扩展并重复该过程。
第二行是inf循环的原因,因为不关心(从最后一条规则)映射到[]。
如果你想知道一对是否是任何孩子的父母,你只需删除2条中间规则:
parents(M,F,[]) :- parents(M,F,_).
parents(M,F,[First|Rest]) :- parents(M,F,First), parents(M,F,Rest).
答案 1 :(得分:0)
我感觉你将两个不同的谓词混淆为一个:
/** 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?