% CS 415, Fall 2005 % % This code from % http://www.csupomona.edu/~jrfisher/www/prolog_tutorial/2_13.html % % This code will print a truth table for a given Boolean expression % Defines an operator. 'xfy' means it's infix, 'fy' means it's unary :- op(1000,xfy,'and'). :- op(1000,xfy,'or'). :- op(900,fy,'not'). % Extract the variables from the boolean expression. 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). % Find the initial assignments for the variables (all 0's) initial_assign([],[]). initial_assign([_X|R],[0|S]) :- initial_assign(R,S). % Changes the truth assignments by doing a binary addition with 1 (but % the binary number is _reversed_ next([0|R],[1|R]). next([1|R],[0|S]) :- next(R,S). % Reverse a list reverse([],[]). reverse([H],[H]). reverse(A,B) :- reverse(A,[],B). reverse([],R,R). reverse([H|T],S,L) :- reverse(T,[H|S],L). % Find the next set of truth table values successor(A,S) :- reverse(A,R), next(R,N), reverse(N,S). % The Boolean definitions for and, or, and not; for use in truth_value boole_and(0,0,0). boole_and(0,1,0). boole_and(1,0,0). boole_and(1,1,1). boole_or(0,0,0). boole_or(0,1,1). boole_or(1,0,1). boole_or(1,1,1). boole_not(0,1). boole_not(1,0). % Returns the truth value for the passed expression 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). % Given a key and two lists (one which is the list of keys, the other % which is the list of values), will return the appropriate value. % The last parameter is the output parameter. lookup(X,[X|_],[V|_],V). lookup(X,[_|Vars],[_|A],V) :- lookup(X,Vars,A,V). % Generates the truth table % Profile: find_vars(+The_Expression,+Previously_Found_Variables,-Answer) 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. % Prints out the given row, and the recursively prints out all the % remaining rows 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). % Usage: % tt(x or (not y and z)).