【问题标题】:Prolog - Cleaner way to define a ruleProlog - 定义规则的更简洁方式
【发布时间】:2021-09-15 09:17:24
【问题描述】:

刚开始在 Prolog 中进行一些编程,但我觉得我要么误解了一些概念,要么你必须有更多的规则。

我希望它检查儿子是男性并且至少有一个父母(父亲/母亲)

% Son
son(X, Y):- male(X), father(Y, X).
son(X, Y):- male(X), mother(Y, X).

有什么方法可以轻松组合,所以我不需要两行相似的行?可能是这样的:检查X 是否是男性,然后检查他是否有父亲,如果没有则检查他是否有母亲。仅当 X 是男性并且有父亲和/或母亲时才返回。

【问题讨论】:

  • 请不要在问题中添加答案。如果有答案,您可以接受。如果没有,那么写下你自己的答案。问题是为了问题,答案是为了答案。

标签: prolog


【解决方案1】:

如果你想要一个显式的析取,你可以改为:

son(X, Y) :- male(X), (father(Y, X); mother(Y, X)).

这里我使用了;/2 运算符。 A ; B 首先尝试目标A,如果不成功则尝试B

通过下面的数据,我们可以看到唯一的好处是male(X)被查询了两次:

male(a).
father(b, a).
mother(c, a).

追踪您的原始代码:

      1    1  Call: son(a,c) ? 
      2    2  Call: male(a) ? 
      2    2  Exit: male(a) ? 
      3    2  Call: father(c,a) ? 
      3    2  Fail: father(c,a) ? 
      2    2  Call: male(a) ?              ; <--- just this is not queried
      2    2  Exit: male(a) ? 
      3    2  Call: mother(c,a) ? 
      3    2  Exit: mother(c,a) ? 
      1    1  Exit: son(a,c) ? 

使用;/2析取来跟踪新代码。

      1    1  Call: son(a,c) ? 
      2    2  Call: male(a) ? 
      2    2  Exit: male(a) ? 
      3    2  Call: father(c,a) ? 
      3    2  Fail: father(c,a) ? 
      3    2  Call: mother(c,a) ? 
      3    2  Exit: mother(c,a) ? 
      1    1  Exit: son(a,c) ? 

【讨论】:

    【解决方案2】:

    另一种选择是使用辅助谓词parent/2 来包含father/2mother/2

    parent(A, B) :- father(A, B).
    parent(A, B) :- mother(A, B).
    
    son(A, B) :- male(A), parent(B, A).
    

    【讨论】:

      【解决方案3】:

      回答你的措辞,而不是你写的代码,它是

      son(S):- male(S), setof( Y, (mother(Y,S) ; father(Y,S)), _).
      

      就像你说的,儿子是指一个是男性,并且有至少一个父母(或两者都有)。

      与其他答案的不同之处在于,如果同一个人既有父亲又有母亲,则不会被报告两次:

      2 ?- [user].
      son(S):- male(S), setof( Y, (mother(Y,S) ; father(Y,S)), _).
      |: male(a).
      |: father(b,a).
      |: mother(c,a).
      |: 
      true.
      
      3 ?- son(X).
      X = a.
      

      【讨论】:

      • 你确定吗?以male(a). father(b,ax). mother(c,ax). ...
      • @false 这是一个错字。 :) 谢谢你抓住它!
      • setof(t, Y^ ( mother(Y,S) ; father(Y,S) ), _) 似乎更合适。
      • @false 有什么区别吗?
      • 在高度工业化的案例中? setof/3 的良好实现可能会利用在这种情况下不需要排序这一事实。
      【解决方案4】:

      我可能会这样做,因为它更好地表达了意图:

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

      【讨论】:

      • 将儿子与父母联系起来无法正常工作。它只返回男性和父母,但不保证他们实际上是父母和儿子。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-15
      • 2015-06-05
      • 1970-01-01
      • 2022-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多