如何在序言中使用if else提取所有数据

时间:2019-05-12 05:53:24

标签: prolog

我是序言中的第一名。

有一些家谱。因此,我想抽象一个阿姨的名单,但是,如果我使用if,则不会抽象出一个阿姨。而且,如果我不使用条件,那么妈妈也将从谓词中抽象出来。

如果没有,我如何继续?

useEffect

2 个答案:

答案 0 :(得分:1)

我认为您可以通过在aunt/2谓词中编写所有逻辑来使其变得更加复杂。与其试图用单个谓词解决整个问题,不如编写几个小的 reuseable 谓词通常是有益的。它使谓词更易于理解,此外,您可以在其他谓词中重用这些组件。

例如,我们可以实现一个slibing/2谓词:

sibling(S1, S2) :-
    parent(P, S1),
    male(P),
    parent(P, S2),
    dif(S1, S2).

在这里,dif/2将防止S1S2是同一个人。因此,这意味着我们无需在slibing/2谓词的所有用例中都担心这种情况。我们在这里使用male/1来防止两个兄弟姐妹产生两次:一次是母亲关系,一次是父亲关系。

也许您以后想对上述谓词进行细化,因为如果S1S2是同父异母的兄弟,则该谓词将会成功。 / p>

接下来,我们可以实现一个sister/2谓词,例如:

sister(S, C) :-
    sibling(S, C),
    female(S).

现在我们的aunt/2仅仅是一个人的父母的姐姐,所以:

aunt(A, C):-
    parent(P, C),
    sister(A, P).

不仅使谓词更简单,我们现在还有两个额外的谓词。此外,如果sibling/2的逻辑确实有问题,我们可以在特定级别进行修复,并且sibling/2的所有调用方也将得到修复。

答案 1 :(得分:1)

您可能指的是“提取”,而不是“抽象”。

您为什么要使用repeat?有人告诉您使用它还是您认为必须使用它?与->相同:您在这里当然不需要它。

这是定义所需内容的一种方法:

aunt(Aunt, Child) :-
    parent(Parent, Child),
    siblings(Parent, Aunt),
    female(Aunt).

siblings(C1, C2) :-
    dif(C1, C2),
    parent(P, C1),
    parent(P, C2).

dif/2的定义中,您唯一拥有的是siblings/2,这样一个人就不会成为自己的兄弟姐妹。

您将获得有关回溯的答案(您无需使用repeat!)

?- aunt(Aunt, Child).
Aunt = aunt1,
Child = sis ;
Aunt = aunt2,
Child = sis ;
Aunt = aunt1,
Child = sis ;
Aunt = aunt2,
Child = sis ;
Aunt = aunt1,
Child = bro ;
Aunt = aunt2,
Child = bro ;
Aunt = aunt1,
Child = bro ;
Aunt = aunt2,
Child = bro ;
false.

显示所有解决方案并避免重复的简单方法是setof/3

?- setof(Aunt-Child, aunt(Aunt, Child), Results).
Results = [aunt1-bro, aunt1-sis, aunt2-bro, aunt2-sis].