Prolog中的分布检查

用户名

假设我有一个等价关系eq,并且有多个二元运算符o_1, o_2, ... o_n我想找出哪些操作分布在其他操作上。假设我有一个可以确定两个表达式是否相等的知识库,一个简单的解决方案是只输入所有可能的查询:

(用于左分布)

?- 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))). 

但是必须有更好的方法来做到这一点。对于初学者,我想定义一个谓词left_dist,以便left_dist(o_m,o_k)为我生成相应的查询。我最初以为可以使用来完成此操作call,如

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))).

但是由于此问题中概述的原因,嵌套调用不起作用,我想这也不是进行Prolog编程的好方法。

所以问题是:如何left_dist在Prolog中定义或简化上面的查询?

左分配性意味着x,y,zx*(y+z)=(x*y)+(x*z)

现在您不提及具体领域,因此我假设所有关系都已经知道它们。这假定Add_3Mult_3始终终止。

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) ).

这使用iwhen/2

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章