第一点:谓词和函子以小写字母开头,而不是大写字母:大写字母用于变量。
您似乎错过了 Prolog 中的谓词不返回值这一点。他们只能成功或失败(在这个意义上他们“返回”一个布尔值)。提供(非布尔)输出的方法是使用unification。
在这里,您可以通过将文字放在头部来做到这一点:
if_then_else(X,Y,male) :- father(X,Y).
if_then_else(X,Y,female).
但是现在还有另一个问题:Prolog回溯。所以这意味着即使第一个子句成功,它也会尝试第二个子句。和pedro-i
都将如此。您可以通过在第二个子句上设置一个守卫来解决这个问题,如果 Prolog 无法证明存在关系,则该子句成功。就像是:male
female
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 需要检查所有分支)。这样做甚至可能导致无限循环。在这种情况下,您可以使用剪切( !
)。如果你达到一个切分,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
).