【问题标题】:Prolog, gender with if_then_else序言,带有 if_then_else 的性别
【发布时间】:2017-03-06 14:11:49
【问题描述】:

我想说,如果他是父亲,他就是男性,否则就是女性

father(pedro-i,beatriz(1347)).
father(pedro-i,joão(1349)).
father(pedro-i,dinis(1354)).
father(pedro-i,joão_grão_mestre_da_ordem_de_avis).
mother(constança(1320),luis).
mother(constança(1320),maria(1342)).


% I want to say that if is the father then is male else is a female

IF_then_else(X,Y,Z) :- father(X,Y),male.
IF_then_else(X,Y,Z) :- female.

【问题讨论】:

    标签: if-statement prolog family-tree


    【解决方案1】:

    第一句话:谓词函子以小写字母开头,而不是大写字母:变量使用大写字母。

    您似乎错过了 Prolog 中的谓词不返回值这一点。他们只能成功失败(在这个意义上他们“返回”一个布尔值)。提供(非布尔)输出的方式是使用unification

    在这里,您可以通过将文字放在头部来做到这一点:

    if_then_else(X,Y,male) :- father(X,Y).
    if_then_else(X,Y,female).

    但现在有另一个问题:Prolog 回溯。所以这意味着即使第一个子句成功,它也会尝试第二个子句。所以pedro-i 将是malefemale。您可以通过在第二个子句上放置一个 guard 来解决此问题,如果 Prolog 无法证明存在 father(X,Y) 关系,则该子句成功。比如:

    if_then_else(X,Y,male) :- father(X,Y).
    if_then_else(X,Y,female) :- \+ father(X,Y).

    但这可能会导致计算量大的问题:证明存在father(X,Y). 关系可能需要很长时间,如果不存在这种关系,则无法证明这一点将花费更多时间(因为 Prolog 需要检查所有分支)。这样做甚至可能导致无限循环。在这种情况下,您可以使用 cut (!)。如果你达到一个切分,Prolog 将不会尝试在谓词的以下子句中查找结果。所以你可以写:

    if_then_else(X,Y,male) :- father(X,Y), !.
    if_then_else(X,Y,female).

    或者,您可以使用 Prolog 的 if-then-else structure 并使用 explicit 统一:

    if_then_else(X,Y,Z) :-
        (  father(X,Y)
        -> Z = male
        ;  Z = female
        ).

    【讨论】:

      猜你喜欢
      • 2019-06-24
      • 1970-01-01
      • 1970-01-01
      • 2015-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多