Prolog,关于如何形成更好的条款

Prolog, about how to form better clauses

我有以下条款:

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

当我键入查询时:

num_parent(eve,X).

它只有 return 秒:

X = 0.  

这就是我想要的。

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

num_parent(X,0).  

它只有 returns:

X = adam.

那么如何修改子句使其成为return:

X = adam;
X = eve.

谢谢

程序 returns 仅 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) returns 仅 X = adam.

如果你写

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

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

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

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

统一

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

首先,尝试用通俗易懂的英语表达您想要的内容。你可能想说:

Everyone has two parents except Adam and Eve who have none.

莉莉丝呢?没关系,还是坚持看书吧。

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

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

if_/3 可用 library(reif) 为了 SICStusSWI 你可以写得更简洁:

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.