Inspired by an earlier question I tried to implement something that would enumerate the possibilities for a boolean expression. However, I'm having trouble with variable choice. Here's my intended outcome:
?- eval(X^Y, R).
R = 0^0;
R = 0^1;
R = 1^0;
R = 1^1;
no.
Here's my code:
:- op(200, yfx, ^).
split(V, R) :- var(V), R = 0.
split(V, R) :- var(V), R = 1.
split(X ^ Y, XP ^ YP) :- split(X, XP), split(Y, YP).
This already doesn't do what I want even for this simple case:
?- split(Y, R).
R = 0 ;
R = 1 ;
Y = _G269^_G270,
R = 0^0 ;
Y = _G269^_G270,
R = 0^1 ;
Y = _G269^ (_G275^_G276),
R = 0^ (0^0) ;
Y = _G269^ (_G275^_G276),
R = 0^ (0^1) ;
Y = _G269^ (_G275^ (_G281^_G282)),
R = 0^ (0^ (0^0)) .
So, I can see what the problem is here, which is that on the way through split(Y, YP)
Prolog has exhausted the first two clauses, so it winds up in split(X^Y, ...)
again, unifying my Y
with X'^Y'
, essentially. I am just not sure what I need to do to close off that path except at the outset where I have the structure ^/2
.
I'd also like this to work with nested structures, so I can't just eliminate the recursive processing of the branches.
Edit: without operators
If the op/3
is bothering you, consider this formulation:
eval(and(X,Y), R).
R = and(0,0);
R = and(0,1);
R = and(1,0);
R = and(1,1);
no.
This would be the code in that case:
split(V, R) :- var(V), R = 0.
split(V, R) :- var(V), R = 1.
split(and(X,Y), and(XP,YP)) :- split(X, XP), split(Y, YP).
Bear in mind I'd still like it to work with recursive formulations like and(and(X,Y),and(Y,Z))
etc.