evaluation - Controlling Prolog variable value selection -


inspired an earlier question tried implement enumerate possibilities boolean expression. however, i'm having trouble variable choice. here's intended outcome:

?- eval(x^y, r). r = 0^0; r = 0^1; r = 1^0; r = 1^1; no. 

here's 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 doesn't want 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, can see problem here, on way through split(y, yp) prolog has exhausted first 2 clauses, winds in split(x^y, ...) again, unifying y x'^y', essentially. not sure need close off path except @ outset have structure ^/2.

i'd work nested structures, can't eliminate recursive processing of branches.

edit: without operators

if op/3 bothering you, consider formulation:

eval(and(x,y), r). r = and(0,0); r = and(0,1); r = and(1,0); r = and(1,1); no. 

this code in 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 work recursive formulations and(and(x,y),and(y,z)) etc.

main problem: defaulty representation

the core problem in case defaulty representation using represent boolean expressions.

by "defaulty" mean cannot distinguish cases pattern matching: in case, variable v may denote either

  • one of propositional constants 0 and 1, or
  • a compound expression of form a^b.

due shortcoming, cannot cleanly express constraint of form "the variable x stands 1 of 2 propositional constants" within program.


a way out: clean representation

a declarative way out use clean representation instead.

for example, suppose arbitrarily use v/1 distinguish variables denote propositional constants, have:

  • v(x) denote propositional variable x
  • a^b denote compound expression.

clearly, since principal functors , arities different (v/1 vs. (^)/2), can distinguish cases pattern matching alone.

with new representation, snippet becomes:

 split(v(v), v) :- v = 0. split(v(v), v) :- v = 1. split(x^y, xp ^ yp) :-         split(x, xp),         split(y, yp). 

example query:

 ?- split(v(x)^v(y), r). x = y, y = 0, r = 0^0 ; x = 0, y = 1, r = 0^1 ; x = 1, y = 0, r = 1^0 ; x = y, y = 1, r = 1^1. 

note still works in all directions, in most general case:

 ?- split(expr, r). expr = v(0), r = 0 ; expr = v(1), r = 1 ; expr = v(0)^v(0), r = 0^0 ; expr = v(0)^v(1), r = 0^1 ; etc. 

as rule of thumb, once have use extra-logical predicate var/1 in code, there little hope retain logical purity , monotonicity. aim clean representations preserve these properties.

sometimes, unavoidable use defaulty representations, example, because want make input easier for users. in such cases, aim convert them clean ones before starting actual reasoning.


Comments

Popular posts from this blog

python - How to insert QWidgets in the middle of a Layout? -

python - serve multiple gunicorn django instances under nginx ubuntu -

module - Prestashop displayPaymentReturn hook url -