【问题标题】:Prolog - family treeProlog - 家谱
【发布时间】:2016-03-17 02:53:05
【问题描述】:

我正致力于在 prolog 中创建一个家谱。当我拜访姐妹或兄弟时,我遇到了麻烦。我得到的结果是正确的,其中 julie 是 mike 的妹妹,julie 是 amanda 的妹妹,amanda 是 mike 的妹妹,amanda 是 julie 的妹妹。但是会发生什么而不是在那里结束,如果我继续按“n”键,它将再次循环返回结果。为什么会这样?

parent(pete,mike).
parent(pete,julie).
parent(pete,amanda).
parent(mary,mike).
parent(mary,julie).
parent(mary,amanda).
female(mary).
female(julie).
female(amanda).
male(mike).
male(pete).



mother(X,Y):-
    parent(X,Y),
    female(X).

father(X,Y):-
    parent(X,Y),
    male(X).

sibling(X,Y):-
    parent(Z,X),
    parent(Z,Y),
    X\=Y.

sister(X,Y):-
    sibling(X,Y),
    female(X).

brother(X,Y):-
    sibling(X,Y),
    male(X).

【问题讨论】:

    标签: prolog family-tree


    【解决方案1】:

    每对兄弟姐妹都有相同的父亲相同的母亲(至少在更保守的社会中,至少在您的计划中)。这是你得到双重答案的地方。您也许可以说兄弟姐妹总是共享双方父母?

    【讨论】:

    • 怎么说?
    • @OmonoiatisUSa 正如你现在所做的那样,只需在sibling 的定义中再添加两个parent 子目标(别忘了说Parent1Parent2 不是一样)。
    • 是的,我知道这听起来很愚蠢,但我仍然不确定如何:/你介意给我看吗?
    • @OmonoiatisUSa 查看其他答案。
    【解决方案2】:

    如前所述,您会得到双重答案,因为您正在检查他们是否有相同的父母,并且他们有两个。此外,您将获得更多解决方案,因为例如mike 是 amanda 的兄弟姐妹,但 amanda 也是 mike 的兄弟姐妹,您没有采取任何措施来阻止这两种解决方案的出现。 所以而不是:

    sibling(X, Y):-
        parent(Z, X),
        parent(Z, Y),
        X\=Y.
    

    要解决两个父母的问题,你可以说他们总是共享父母:

    sibling(X, Y):-
        mother(Z, X),
        mother(Z, Y),
        father(W, X),
        father(W, Y),
        X\=Y.
    

    你可以通过引入@来解决第二个问题(X=mike, Y=amanda; X=amanda, Y=mike)<:>

    sibling(X, Y):-
        mother(Z, X),
        mother(Z, Y),
        father(W, X),
        father(W, Y),
        X@<Y.
    

    这样,只会出现一组解决方案,但您必须小心,因为它可能无法达到您想要的效果,具体取决于您想要实现的目标(X=julie,Y=amanda 不会在这种情况下是正确的)。

    根据需要,也许更优雅和通用的解决方案(不要求父母双方相同)将 setof (http://www.swi-prolog.org/pldoc/doc_for?object=setof/3) 与您原来的兄弟条款一起使用,但您会修改您的兄弟/姐妹条款,例如:

    sibling(X, Y):-
        parent(Z, X),
        parent(Z, Y),
        X\=Y.
    
    sister(X,Y,L):-
        female(X),
        setof([X, Y], (sibling(X, Y)), L).
    
    brother(X,Y,L):-
        male(X),
        setof([X, Y], (sibling(X, Y)), L).
    

    这将为您提供列表 L 中唯一对的列表,例如对于姐姐(X,Y,L),你得到:

    X = julie
    L = [[julie, amanda], [julie, mike]]
    
    X = amanda
    L = [[amanda, julie], [amanda, mike]]
    

    稍微玩一下就可以得到你需要的东西。

    【讨论】:

    • 好的和彻底的 (+1),只是一个小细节:X @&lt; Y 暗示 X \= Y,所以你可以省略它。
    • 是的,很好的答案。但另一个小提示:使用 dif/2 代替 X\=Y 因为它是一个纯谓词;)
    猜你喜欢
    • 1970-01-01
    • 2017-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多