我曾经改编过关于真值表制造商的JRFischer 教程页面,它解释了与您需要的任务非常相似的任务。我使用了不同的运算符,除了含义之外,它们非常适合 (->)/2。
formula(N,_,_,N) :-
member(N,[0,1]).
formula(X,Vars,A,Val) :-
atom(X),
lookup(X,Vars,A,Val).
formula(X + Y,Vars,A,Val) :-
formula(X,Vars,A,VX),
formula(Y,Vars,A,VY),
and(VX,VY,Val).
formula(X * Y,Vars,A,Val) :-
formula(X,Vars,A,VX),
formula(Y,Vars,A,VY),
or(VX,VY,Val).
formula(X -> Y,Vars,A,Val) :-
formula(X,Vars,A,VX),
formula(Y,Vars,A,VY),
imply(VX,VY,Val).
formula(- X,Vars,A,Val) :-
formula(X,Vars,A,VX),
not(VX,Val).
lookup(X,[X|_],[V|_],V).
lookup(X,[_|Vars],[_|A],V) :- lookup(X,Vars,A,V).
and(0,0,0).
and(1,1,1).
and(0,1,0).
and(1,0,0).
or(0,0,0).
or(0,1,1).
or(1,0,1).
or(1,1,1).
not(0,1).
not(1,0).
imply(0,0,1).
imply(0,1,1).
imply(1,0,0).
imply(1,1,1).
这段代码比要求的更通用,要获得所需的分配,我们必须限制调用:
?- lenght(A,3),formula(q + (r -> p), [p,q,r], A, 1).
Correct to: "length(A,3)"? yes
A = [0, 1, 0] ;
A = [1, 1, 0] ;
A = [1, 1, 1] ;
false.