This is a famous logic puzzle: There is a barber who shaves a person if and only if he does not shave himself. Then does the barber shaves himself?
I “solved” this puzzle by enumerating models using my private ZDD library.
First, enumerate all models for a barber who shaves
a person if and only if he does not shave himself with a fixed small domain D={a, b, c}, too small. The experiment returns 512 as the number of such models.
Next, I count the number M of the given model, i.e., in which the barber shaves himself. It returns M = 0 (no model found) as we all might expected.
The idea behind this model finder is simple. As the domain is small enough, FOL formula is expanded a quantifier-free ground formula (i.e. a proposition). Then convert it a DNF (disjunctive normal form like ab + cd*e + … ), the point is here that the required number is calculated from the DNF easily. I think everything is clear, aside my presentation. ZDD contribution here is only its capacity to keep a big DNF and efficient form for counting models from the DNF.
I believe this is one of the most naive model finders. There may be many smart ones, but unfortunately they might be too advanced and difficult for me to catch up.
% ?- time((dnf_model([a,b,c], (all(x, barbar(x) =:= all(y, -shave(y,y) =:= shave(x, y)))), Z, S), ltr_card(Z, C, S), get_key(atomnum, Count, S))).
%@ [-barbar(a),-shave(c,c),-shave(a,c),-barbar(b),-shave(b,c),-barbar(c)]
%@ [-barbar(a),shave(c,c),shave(a,c),-barbar(b),shave(b,c),-barbar(c)]
%@ [-barbar(a),-shave(b,b),-shave(c,c),-shave(a,c),-barbar(b),-barbar(c)]
<snip>
% ?- time((dnf_model([a,b,c], (all(x, barbar(x) =:= all(y, -shave(y,y) =:= shave(x, y))), some(z, (shave(z, z), barbar(z)))), Z, S), ltr_card(Z, C, S), get_key(atomnum, Count, S))).
%@ atomnum(12)
%@ % 114,915 inferences, 0.008 CPU in 0.008 seconds (98% CPU, 14958995 Lips)
%@ Z = C, C = 0,
%@ S = ..,
%@ Count = 12.