Booleans as a data type
Propositional logic as universal facts, then improved with rules.
A recap example: modelling propositional logic
File booleans-facts.pl. The modelling idea is that this is a simple data type:
- we have two booleans, modelled as atomic terms
b_trueandb_false(functors with arity 0); - a unary function is modelled as a binary predicate
p(I, O); - a binary function is modelled as a ternary predicate
p(I1, I2, O); - use universal facts to somewhat address DRY (don't repeat yourself).
Can we derive a general approach for data types?
b_not(b_true, b_false).
b_not(b_false, b_true).
b_and(B, b_true, B).
b_and(_, b_false, b_false).
b_or(B, b_false, B).
b_or(_, b_true, b_true).?- b_not(b_false, B)?- b_and(b_false, b_true, B)?- b_or(b_false, b_true, B)?- b_or(b_true, B2, B)?- b_or(B1, B2, B)The last two goals are the interesting ones. b_or(b_true, B2, B) has two answers: whatever B2 is, the result is b_true, because the first argument is true. And b_or(B1, B2, B) is the whole truth table of or in two clauses: either B2 is false and the result is just B1, or B2 is true and the result is true.
Improving booleans with rules
File booleans-rules.pl. The same booleans, with b_or and b_implies as rules, defined by composing the other functions:
b_not(b_true, b_false).
b_not(b_false, b_true).
b_and(B, b_true, B).
b_and(_, b_false, b_false).
b_or(B1, B2, B) :- % (a or b) = !(!a and !b)
b_not(B1, NB1), b_not(B2, NB2),
b_and(NB1, NB2, NB), b_not(NB, B).
b_implies(B1, B2, B) :- % a --> b = !a or b
b_not(B1, NB1), b_or(NB1, B2, B).?- b_implies(b_true, b_false, O)?- b_implies(b_false, b_false, O)The resolution of b_implies(b_true, b_false, O), one resolvent per line:
b_implies(b_true, b_false, O)
b_not(b_true, NB1'), b_or(NB1', b_false, O)
b_or(b_false, b_false, O)
b_not(b_false, NB1'), b_not(b_false, NB2'), b_and(NB1', NB2', NB'), b_not(NB', O)
b_not(b_false, NB2'), b_and(b_true, NB2', NB'), b_not(NB', O)
b_and(b_true, b_true, NB'), b_not(NB', O)
b_not(b_true, O)
{O/b_false}
This is the procedural interpretation at work: each goal of a body is replaced, in turn, by the body of a matching clause, until the resolvent is empty, and the substitution is the result.
Exercise: Exclusive or
The booleans of the rule-based file are loaded (b_not/2, b_and/3, b_or/3). Write b_xor(B1, B2, B): exclusive or, defined by composing the other functions as (a or b) and not (a and b).