Distributivity check in Prolog -
suppose have equivalence relation eq
, , multiple binary operators o_1, o_2, ... o_n
. want find out operations distribute on others. assuming have knowledge base can determine whether 2 expressions equivalent, simple solution enter possible queries :
(for left-distributivity)
?- eq(o_1(z,o_1(x,y)),o_1(o_1(z,x),o_1(z,y))). ?- eq(o_1(z,o_2(x,y)),o_2(o_1(z,x),o_1(z,y))). ?- eq(o_1(z,o_3(x,y)),o_3(o_1(z,x),o_1(z,y))). ... ?- eq(o_2(z,o_2(x,y)),o_2(o_2(z,x),o_2(z,y))). ?- eq(o_2(z,o_3(x,y)),o_3(o_2(z,x),o_2(z,y))). ... ?- eq(o_n(z,o_n(x,y)),o_n(o_n(z,x),o_n(z,y))).
but there must better ways this. starters, i'd define predicate left_dist
such left_dist(o_m,o_k)
generate corresponding query me. thought i'd using call
, in
left_dist(o_m,o_k) :- eq(call(o_m,z,call(o_k,x,y)),call(o_k,call(o_m,z,x),call(o_m,z,y))).
but nested calls not work reasons outlined in this question, , guess it's not way approach prolog programming either.
so question : how can define left_dist
, or otherwise simplify queries above, in prolog?
left distributivity means x,y,z
: x*(y+z)=(x*y)+(x*z)
now not mention concrete domains, assume relations know them already. assumes add_3
, mult_3
terminate.
not_left_dist(mult_3, add_3) :- call(add_3, y, z, yz), call(mult_3, x, yz, lhs), call(mult_3, x, y, xy), call(mult_3, x, z, xz), call(add_3, xy, xz, rhs), neq(lhs, rhs). left_dist(mult_3, add_3) :- iwhen(ground(mult_3+add_3), \+ not_left_dist(mult_3, add_3) ).
this uses iwhen/2
.
Comments
Post a Comment