在Prolog中表达"交换"的替代方案?

Mat*_*att 8 prolog commutativity

作为Prolog的初学者,我发现Prolog中的交换表达非常不直观.

例如,如果我想表达X和Y在一个家庭中,如:

family(X,Y) :-
      married(X,Y);
      relative(X,Y);
      father_son(X,Y).
Run Code Online (Sandbox Code Playgroud)

我还应该在定义中添加以下内容,以使其"可交换":

      married(Y,X);
      relative(Y,X);
      father_son(Y,X).
Run Code Online (Sandbox Code Playgroud)

但是我们使用Prolog,因为我们想要编写优雅的代码......所以,我希望只在原始代码中添加一行(而不是上面的三行):

      family(Y,X).
Run Code Online (Sandbox Code Playgroud)

这是POINT.它会导致不确定!为什么序言不那么"合乎逻辑"?是否有一个替代这个整洁的单行表达式,不会导致不确定?

周末愉快!瓦

das*_*ght 11

family(X,Y) :- family(Y,X).部分规则的问题在于它在每个级别上无条件地与自身统一,并且不断递归; 此递归没有退出条件.

您应该在上面的级别进行参数交换:

family(X,Y) :-
    is_family(X,Y);
    is_family(Y,X).

is_family(X,Y) :-
    married(X,Y);
    relative(X,Y);
    father_son(X,Y).
Run Code Online (Sandbox Code Playgroud)

或者,您可以在有意义的地方使基础规则低于对称:

is_married(X,Y) :-
    married(X,Y);
    married(Y,X).

is_relative(X,Y) :-
    relative(X,Y);
    relative(Y,X).
Run Code Online (Sandbox Code Playgroud)

您现在可以family按如下方式重写规则:

family(X,Y) :-
    is_married(X,Y);
    is_relative(X,Y);
    father_son(X,Y);
    father_son(Y,X).
Run Code Online (Sandbox Code Playgroud)