Prolog,性别与if_then_else

时间:2017-03-06 14:11:50

标签: if-statement prolog family-tree

我想说的是,如果他是父亲,他就是男性,也就是女性

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.

1 个答案:

答案 0 :(得分:1)

第一句话:谓词仿函数以小写字母开头,而不是大写字母:大写字母用于变量

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

在这里,您可以将文字放在头部,如:

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

但现在有另一个问题:Prolog 回溯。所以这意味着即使第一个子句成功,它也会尝试第二个子句。因此pedro-imalefemale。您可以通过在第二个子句上放置 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并使用显式统一:

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