0

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

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.
4

1 回答 1

1

第一点:谓词函子以小写字母开头,而不是大写字母:大写字母用于变量

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

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

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

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

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

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

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

或者,您可以使用 Prolog 的if-then-else 结构并使用显式统一:

if_then_else(X,Y,Z) :-
    (  father(X,Y)
    -> Z = male
    ;  Z = female
    ).
于 2017-03-06T14:28:37.380 回答