我是序言中的第一名。
有一些家谱。因此,我想抽象一个阿姨的名单,但是,如果我使用if,则不会抽象出一个阿姨。而且,如果我不使用条件,那么妈妈也将从谓词中抽象出来。
如果没有,我如何继续?
useEffect
答案 0 :(得分:1)
我认为您可以通过在aunt/2
谓词中编写所有逻辑来使其变得更加复杂。与其试图用单个谓词解决整个问题,不如编写几个小的 reuseable 谓词通常是有益的。它使谓词更易于理解,此外,您可以在其他谓词中重用这些组件。
例如,我们可以实现一个slibing/2
谓词:
sibling(S1, S2) :-
parent(P, S1),
male(P),
parent(P, S2),
dif(S1, S2).
在这里,dif/2
将防止S1
和S2
是同一个人。因此,这意味着我们无需在slibing/2
谓词的所有用例中都担心这种情况。我们在这里使用male/1
来防止两个兄弟姐妹产生两次:一次是母亲关系,一次是父亲关系。
也许您以后想对上述谓词进行细化,因为如果S1
和S2
是同父异母的兄弟,则该谓词将会成功。 / 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].