Prolog 序言第一步:这段代码有什么错?

Prolog 序言第一步:这段代码有什么错?,prolog,Prolog,我刚开始学习Prolog,没有发现我的错误。当我想用sister(jana)Prolog查找jana的姐妹(和父母)时,只需返回true child(hanna,sabine). child(hanna,peter). child(robert,sabine). child(robert,peter). child(peter,jana). child(peter,christine). child(claudia,jana). child(claudia,christine). child(c

我刚开始学习Prolog,没有发现我的错误。当我想用
sister(jana)
Prolog查找
jana的姐妹(和父母)时,只需返回
true

child(hanna,sabine). child(hanna,peter). child(robert,sabine).
child(robert,peter). child(peter,jana). child(peter,christine).
child(claudia,jana). child(claudia,christine). child(claudia,jutta).
child(jana,jakob). female(claudia). female(jana).
female(christine). female(jutta). female(sabine).
female(hanna). male(peter). male(robert).
male(jakob).

sister(Person) :-
   female(Sister),
   male(Father),
   child(Father,Person),
   child(Father,Sister),
   female(Mother),
   child(Mother, Person),
   child(Mother, Sister).

这在语法上是正确的-当
Person
满足标准时返回true,例如有一个女性兄弟姐妹

你可以通过这样做来让所有有姐妹的人:

?- sister(X). 
X = jana ; 
X = christine ; 
X = jana ; 
X = christine ; 
X = sabine ; 
X = peter ; 
false.
正如你所看到的,一个人可以有不止一个姐妹,事实上,谓词并不检查一个人的姐妹是否相同——每个女孩都被认为是她自己的姐妹(参见@mat的答案来解决这个问题)。而且,我没有想到,男人也可以有姐妹

结果由@Lester提供,因此这是实际输出

要获得您想要的,您需要这样定义:

sisterOf(Person, Sister) :-
   female(Sister),
   male(Father),
   child(Father,Person),
   child(Father,Sister),
   female(Mother),
   child(Mother, Person),
   child(Mother, Sister).
然后像这样运行它:

?- sisterOf(jana,X).
X = jana ;
X = christine.
这看起来很奇怪,不是吗?但同样,由于我们没有检查姐妹和人是否相同,每个女性都被谓词视为自己的姐妹


免责声明:我在10年前学会了prolog,从未使用过,所以我肯定不是最新的。此外,我在任何地方都没有Prolog引擎,因此最初的结果是由我大脑中托管的Prolog解释器得出的,并用评论的真实结果更新了答案。

这些问题在初学者中很常见,通常通过使用更好的谓词名称来解决

重要的是,注意谓词定义了事物之间的关系。在哪些事情之间?理想情况下,这反映在谓词的名称中,表示每个参数代表什么

例如,如果您按照以下方式编写代码,则代码的可读性将大大提高:

sister_person(Sister, Person) :- female(Sister), male(Father), parent_child(Father, Person), parent_child(Father, Sister), female(Mother), parent_child(Mother, Person), parent_child(Mother, Sister). 您可以使用dif/2来表示术语的质量,表示“没有人是自己的姐妹”:

姐妹人(姐妹,人):- dif(姐妹、个人), 女(姐妹),, 男性(父亲), 父母子女(父亲、个人), 父母和子女(父亲、姐妹), 女性(母亲), 父母子女(母亲、个人), 父母和孩子(母亲、姐妹)。 现在您可以得到一个单一的解决方案:

?- sister_person(jana, P). P = christine ; false. -修女(jana,P)。 P=克里斯汀; 错。
谢谢你的回答。第一个版本返回
?-sister(X)。X=jana;X=克里斯汀;X=jana;X=克里斯汀;X=萨宾;X=彼得;false。
第二个版本返回您对第一个版本的期望值。我还是不明白这是怎么回事…啊,是的。。。男人也可以有姐妹。。。主要要知道的是,Prolog找到了所有的解决方案。但是您编写的谓词没有“无界变量”可搜索-它只是一个简单的问题:“实体‘jana’是否满足‘姐妹’关系?”结果是真的。同样地,
sisterOf(jana,christine)
可以表述为“实体‘jana’和‘christine’实现了‘sisterOf’的关系吗?”并且结果将再次为真。当与无界变量(例如X)一起使用时,问题变成:“嘿,伙计,给我所有的X值,其中'sisterOf'对'jana'和X都是真的。”只有第二个参数的存在。。。但总的来说,@mat的解决方案要好得多-他实际上知道Prolog-我只是这个领域的业余爱好者。。。 ?- sister_person(jana, S). S = jana ; S = christine ; false. sister_person(Sister, Person) :- dif(Sister, Person), female(Sister), male(Father), parent_child(Father, Person), parent_child(Father, Sister), female(Mother), parent_child(Mother, Person), parent_child(Mother, Sister). ?- sister_person(jana, P). P = christine ; false.