/* prolog tutorial 2.13 Truth table maker */ :- op(1000,xfy,'and'). :- op(1000,xfy,'or'). /* :- op(900,fy,'not'). */ find_vars(N,V,V) :- member(N,[0,1]),!. /* Boolean constants in expression */ find_vars(X,Vin,Vout) :- atom(X), (member(X,Vin) -> Vout = Vin ; /* already have */ Vout = [X|Vin]). /* include */ find_vars(X and Y,Vin,Vout) :- find_vars(X,Vin,Vtemp), find_vars(Y,Vtemp,Vout). find_vars(X or Y,Vin,Vout) :- find_vars(X,Vin,Vtemp), find_vars(Y,Vtemp,Vout). find_vars(not X,Vin,Vout) :- find_vars(X,Vin,Vout). initial_assign([],[]). initial_assign([X|R],[0|S]) :- initial_assign(R,S). successor(A,S) :- reverse(A,R), next(R,N), reverse(N,S). next([0|R],[1|R]). next([1|R],[0|S]) :- next(R,S). truth_value(N,_,_,N) :- member(N,[0,1]). truth_value(X,Vars,A,Val) :- atom(X), lookup(X,Vars,A,Val). truth_value(X and Y,Vars,A,Val) :- truth_value(X,Vars,A,VX), truth_value(Y,Vars,A,VY), boole_and(VX,VY,Val). truth_value(X or Y,Vars,A,Val) :- truth_value(X,Vars,A,VX), truth_value(Y,Vars,A,VY), boole_or(VX,VY,Val). truth_value(not X,Vars,A,Val) :- truth_value(X,Vars,A,VX), boole_not(VX,Val). lookup(X,[X|_],[V|_],V). lookup(X,[_|Vars],[_|A],V) :- lookup(X,Vars,A,V). tt(E) :- find_vars(E,[],V), reverse(V,Vars), initial_assign(Vars,A), write(' '), write(Vars), write(' '), write(E), nl, write('-----------------------------------------'), nl, write_row(E,Vars,A), write('-----------------------------------------'), nl. write_row(E,Vars,A) :- write(' '), write(A), write(' '), truth_value(E,Vars,A,V), write(V), nl, (successor(A,N) -> write_row(E,Vars,N) ; true). boole_and(0,0,0). boole_or(0,0,0). boole_not(0,1). boole_and(0,1,0). boole_or(0,1,1). boole_not(1,0). boole_and(1,0,0). boole_or(1,0,1). boole_and(1,1,1). boole_or(1,1,1).