Prolog“切换”语句

问题描述

如何实现与嵌套的 if_ 集等效的 switch 语句?

理想情况下是这样的(不要介意语法):

compatible(X,Y) :-
    switch X
    a1 -> dif(Y,b2),a2 -> dif(Y,c2),dif(Y,c3),_  -> true 

工作方式与此相同:

compatible(X,Y) :-
    if_(X = a1,if_(X = a2,(dif(Y,c3)),true
        )
    ).  

解决方法

:- module(switch_,[]).

:- use_module(library(reif)).

:- multifile goal_expansion/2.

user:goal_expansion(switch_(X,;(->(H,C),T)),if_(X = H,C,switch_(X,T))).
user:goal_expansion(switch_(X,->(H,C)),fail)).
user:goal_expansion(switch_(_,true),true).
user:goal_expansion(switch_(_,false),false).
:- use_module(switch_).

likes(A,B) :-
   switch_(A,(
      john -> B = mary ;
      mary -> dif(B,john) ;
      true
   )).

示例

?- likes(A,B).
A = john,B = mary ;
A = mary,dif(B,john) ;
dif(A,mary),dif(A,john).

?- likes(mary,B).
dif(B,john).

?- likes(john,B).
B = mary.