I have created a clause table
for creating a truth table given 2 premises and 3 predicates and a conclusion:
bool(true).
bool(false).
% Function for printing out the table
table(P,Q,R,E1,E2,Conclusion):-
write('P\tQ\tR\t'),
write(E1), write('\t'),
write(E2), write('\t'),
write(Conclusion),
write('\tCheck'), nl,
printValues(P,Q,R,E1,E2,Conclusion).
% Function prints out the truth tables.
printValues(P,Q,R,E1,E2,Conclusion):-
bool(P), bool(Q), bool(R), % Get the permutations of all the possible combinations of true and false.
write(P), format(P), write('\t'), % Print each true/false.
write(Q), format(Q), write('\t'),
write(R), format(R), write('\t'),
writePremise(E1), write('\t'), % Evaluate the premises and write out the result.
writePremise(E2), write('\t\t'),
writePremise(Conclusion), write('\t\t'), % Evaluate the conclusion and write out the result.
writeCheck(E1, E2, Conclusion). % perform check to see if valid.
% Evalutes a given premise and writes out true or false.
writePremise(E):-
(E -> write('true'); write('false')).
writeCheck(E1, E2, Conclusion):-
((E1,E2 -> (Conclusion -> write('okay'); write('invalid')));
write('okay')), nl, fail.
Which given a query such creates a truth table:
| ?- table(P,Q,R,and(P,Q),P,my_not(Q)).
P Q R and(_26,_27) _26 my_not(_27) Check
true true true true true false invalid
true true false true true false invalid
true false true false true true okay
true false false false true true okay
false true true false false false okay
false true false false false false okay
false false true false false true okay
false false false false false true okay
no
Now I want to change create a new clause that can take in two lists - one for predicates and one for premises.
It currently looks like so:
tableMoreDynamic(Predicates,Premises, Conclusion):-
writePredicates(Predicates),
writePremises(Premises),
writePremise(Conclusion), write('\t\t'),
writeDynamicCheck(Premises, Conclusion),
nl, fail.
writePredicates([]):- true.
writePredicates([HEAD|TAIL]):-
bool(HEAD),
write(HEAD) , write('\t'),
writePredicates(TAIL).
writePremises([]):- true.
writePremises([HEAD|TAIL]):-
writePremise(HEAD), write('\t'),
writePremises(TAIL).
writeDynamicCheck(Premises, Conclusion):-
(checkList(Premises) -> (Conclusion -> write('okay'); write('invalid'));
write('okay')).
checkList([]):- true.
checkList([HEAD|TAIL]):-
HEAD,
checkList(TAIL).
It currently works in that it prints out the correct values for the premises, conclusion and the valid check. However due to backtracking in the writePredicates clause it doesn't print out all the different predicates on each line:
| ?- tableMoreDynamic([P,Q],[P],my_not(P)).
true true true false invalid
false true false invalid
false true false true okay
false false true okay
As such I was wondering if there was a way to know if you have backtracked within this function (so that we can reprint earlier values on that line). Or perhaps a way to map the bool clause to a list so we can just print out that list. Apologies for the wall of code. Thanks
As such I was wondering if there was a way to know if you have backtracked within this function (so that we can reprint earlier values on that line).
There is probably some ingenious hack to do this, but it would be a very confusing solution to a confusing interpretation of the problem. The problem itself is simple:
Or perhaps a way to map the bool clause to a list so we can just print out that list.
Yes. And you already know how to do it, since this is what you are doing inside writePredicates
anyway! The only thing you're missing is that you should do this "labeling" of a complete list of bools before starting printing, rather than interleaving the labeling and printing of individual elements.
So all you need is this:
bools([]).
bools([Bool | Bools]) :-
bool(Bool),
bools(Bools).
tableMoreDynamic(Predicates,Premises, Conclusion):-
bools(Predicates),
writePredicates(Predicates),
...
leaving the rest of your code unchanged. (You can remove the bool
call inside writePredicates
, it no longer does anything.)
And this prints the complete table:
?- tableMoreDynamic([P,Q],[P],my_not(P)).
true true true false invalid
true false true false invalid
false true false true okay
false false false true okay
false.
If you don't want to write out the entire recursion for bools
yourself, there might be an even shorter solution, if your Prolog provides some higher-order predicates. For example, in SWI-Prolog you can just call:
maplist(bool, Predicates)
without needing to define a bools
predicate at all.