Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog:程序中的统一或回溯错误_Prolog_Backtracking_Unification_Family Tree - Fatal编程技术网

Prolog:程序中的统一或回溯错误

Prolog:程序中的统一或回溯错误,prolog,backtracking,unification,family-tree,Prolog,Backtracking,Unification,Family Tree,我有一个简单的知识库,可以对家谱进行编码。此表述中的一些重要规则如下: % fathers father(michael,cathy). father(michael,sharon). father(charles_gordon,michael). father(charles_gordon,julie). father(charles,charles_gordon). father(jim,melody). father(jim,crystal). father(elmo,jim). fath

我有一个简单的知识库,可以对家谱进行编码。此表述中的一些重要规则如下:

% fathers
father(michael,cathy).
father(michael,sharon).
father(charles_gordon,michael).
father(charles_gordon,julie).
father(charles,charles_gordon).
father(jim,melody).
father(jim,crystal).
father(elmo,jim).
father(greg,stephanie).
father(greg,danielle).
% mothers
mother(melody,cathy).
mother(melody,sharon).
mother(hazel,michael).
mother(hazel,julie).
mother(eleanor,melody).
mother(eleanor,crystal).
mother(crystal,stephanie).
mother(crystal,danielle).
% parents
parent(X,Y) :- father(X,Y).
parent(X,Y) :- mother(X,Y).
% men
male(michael).
male(charles_gordon).
male(charles).
male(jim).
male(elmo).
male(greg).
% women
female(cathy).
female(sharon).
female(julie).
female(hazel).
female(eleanor).
female(melody).
female(crystal).
female(stephanie).
female(danielle). 

person(X) :- male(X) ; female(X).
parent(X,Y) :- father(X,Y) ; mother(X,Y).          % X is parent of Y
child(X,Y) :- parent(Y,X).
elder(X,Y) :-   parent(X,Y).                       % X is an elder of Y, meaning X is a parent or an ancestor of Y
elder(X,Y) :-   parent(X,Z), elder(Z,Y).
junior(X,Y) :-  child(X,Y).                        % X is a junior of Y, meaning X is a child or some descendant of Y
junior(X,Y) :-  child(X,Z), junior(Z,Y).
我试图在两个人之间找到最近的长者(谓词
ne(X,Y,Z)
)。这个人
Z
X
Y
中的长者,而
Z
中的下级也不是
X
Y
中的长者

我的尝试如下所示:

ne(X,Y,Z) :-    person(X),
            person(Y),
            X \= Y,
            elder(Z,X),
            elder(Z,Y),
            junior(A,Z),
            not(elder(A,X)),
            not(elder(A,Y)).
但这在某种程度上是不正确的,因为每当我运行
?-ne(stephanie,cathy,Z)。

Z = jim ;
Z = jim ;
Z = jim ;
Z = jim ;
Z = elmo ;
Z = elmo ;
Z = elmo ;
Z = elmo ;
Z = eleanor ;
Z = eleanor ;
Z = eleanor ;
Z = eleanor ;
但我只能得到一个答案,我不知道怎么回事。谢谢

从这个图中

看来这个答案是正确的

?- ne(stephanie,cathy,A).
A = eleanor ;
A = jim.
这是我尝试的ne/3

ne(X,Y,Z) :-
    setof(A, (
        elder(A, X),
        elder(A, Y),
        X \= Y,
        \+ (elder(A, T), elder(T, X) , elder(T, Y) ))
    , As), member(Z, As).
不确定这是不是更好的方式

Setof/3(与member/2连接)用于消除重复答案,因为

?- aggregate(count,A^ne(stephanie,cathy,A),N).
N = 32.
有了这个核心逻辑

ne(X,Y,A) :-
        elder(A, X),
        elder(A, Y),
        X \= Y,
        \+ (elder(A, T), elder(T, X) , elder(T, Y)).
注:变量A局部替换原始Z

编辑


我没有考虑@Boris的精明评论,但在删除重复的parent/2定义后,
setof/3+member/2
技巧变得毫无用处。

您的程序中有相当多的冗余。您已经定义了两次
parent/2
。同样,“人”是“男性”或“女性”,但为什么你有
父亲/2
母亲/2
,而不仅仅是
父母/2
?或者同一个“人”可以是“男性”和“母亲”?无论哪种方式,跟踪你的程序,你都可能“发现”出了什么问题。不要忽略编译时警告。谢谢你的评论。我想我应该研究一下单例变量警告以及类似的答案。我的尝试是错误的,因为它打印了埃莉诺、吉姆和埃尔莫,他们都是他们(斯蒂芬妮和凯西)的共同长者(埃莉诺、吉姆和埃尔莫)。它应该做的就是打印埃莉诺和吉姆。我尝试了您的实现,但它似乎没有绑定任何变量?(它无限打印“true”)。