2

我有以下条款:

num_parent(adam, X) :- !, X = 0.  
num_parent(eve, X) :- !, X = 0.  
num_parent(X, 2).  

当我输入查询时:

num_parent(eve,X).

它只返回:

X = 0.  

这就是我想要的。

但是当我输入这个查询时:

num_parent(X,0).  

它只返回:

X = adam.

那么如何修改子句使其返回:

X = adam;
X = eve.

谢谢

4

2 回答 2

4

首先,试着用简单的英语表达你想要的东西。你可能想说:

每个人都有两个父母,除了没有父母的亚当和夏娃。

莉莉丝呢?没关系,让我们坚持你的阅读。

num_parent(Person, 2) :-
   dif(Person, adam),
   dif(Person, eve).
num_parent(adam, 0).
num_parent(eve, 0).

如您所见,定义这个有点麻烦:您必须两次提及每个杰出的人。容易出错。

使用if_/3 适用于library(reif) SICStus SWI 内容, 您可以更简洁地编写:

num_parent(Person, Num) :-
   if_( ( Person = adam ; Person = eve ), Num = 0, Num = 2 ).

现在有一些用途:

?- num_parent(eve, Num).
   Num = 0.

?- num_parent(X, 0).
   X = adam
;  X = eve
;  false.

?- num_parent(X, 2).
   dif(X, eve),
   dif(X, adam).

?- num_parent(lilith, 2).
   true.
于 2017-11-23T16:08:16.960 回答
0

程序仅X = adam因为您插入了剪辑而返回!。当您找到正确的规则并且您不需要做进一步的评估时使用切割,但它会切割所有其他解决方案。

在你的情况下

num_parent(adam, X) :- !, X = 0.  
num_parent(eve, X) :- !, X = 0.  
num_parent(_, 2). %replaced num_parent(X, 2) with num_parent(_, 2) to avoid singleton variable

num_parent(X, 0)只返回X = adam

如果你写

num_parent(adam, X) :- X = 0.  
num_parent(eve, X) :- !, X = 0.  
num_parent(_, 2). 

解决方案是X = adamand X = eve,在这种情况下:

num_parent(adam, X) :- X = 0.  
num_parent(eve, X) :- X = 0.  
num_parent(_, 2). 

解决方案将是X = adamX = eve并且false因为查询num_parent(X, 0)不与num_parent(_, 2).

您可以使用跟踪器更好地查看此行为。

于 2017-11-23T12:50:48.427 回答