Prolog第一步:这段代码有什么问题?

时间:2016-09-15 09:16:39

标签: prolog

我刚开始学习Prolog并且找不到我的错误。当我想找jana sister(jana) true Prolog的姐妹(和父母)时,只需返回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).

ask(someActor, new SomeRequest(), timeout)
            .onSuccess(new OnSuccess<Object>() {
                @Override
                public void onSuccess(Object answer) throws Throwable {

                  // Modify actor state

                }
            }, getContext().system().dispatcher());

2 个答案:

答案 0 :(得分:2)

这些问题在初学者中很常见,并且通常可以通过使用更好的谓词名称轻松解决。

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

例如,如果您按如下方式编写代码,那么您的代码将变得很多更具可读性:

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).

请注意,我使用例如parent_child/2来明确哪个参数是父级,哪个参数是子级。

因此,很明显像sister/1这样的谓词只能说明单个人的某些内容,而你需要两个人之间的关系。因此,我称之为sister_person/2

所以它有效:

?- sister_person(jana, S).
S = jana ;
S = christine ;
false.

您可以使用 dif/2 ,表示术语的 disequality 来声明&#​​34;没有人是他们自己的妹妹&#34;:

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.

答案 1 :(得分:0)

这在语法上是正确的 - 当Person符合条件时返回true,例如有一个女性的兄弟,也就是一个妹妹

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

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

?- 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解释器的结果,并使用评论中的实际结果更新了答案。