Prolog中的分布检查 [英] Distributivity check in Prolog
问题描述
假设我有一个等价关系 eq
和多个二元运算符 o_1, o_2, ... o_n
.我想找出哪些操作分布在其他操作上.假设我有一个可以确定两个表达式是否等价的知识库,一个简单的解决方案是输入所有可能的查询:
Suppose I have an equivalence relation eq
, and multiple binary operators o_1, o_2, ... o_n
. I want to find out which operations distribute over others. Assuming that I have a knowledge base that can determine whether two expressions are equivalent, a simple solution is to just enter all possible queries :
(用于左分配)
?- 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
来做到这一点,如
but there must be better ways to do this. For starters, I'd like to define a predicate left_dist
such that left_dist(o_m,o_k)
would generate the corresponding query for me. I initially thought I'd do this by using call
, as 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))).
但是由于这个问题,我想这也不是进行 Prolog 编程的好方法.
but the nested calls do not work for reasons outlined in this question, and I guess it's not a good way to approach Prolog programming either.
所以问题是:如何在 Prolog 中定义 left_dist
,或以其他方式简化上述查询?
So the question is : how can I define left_dist
, or otherwise simplify the queries above, in Prolog?
推荐答案
左分配意味着对于所有 x,y,z
: x*(y+z)=(x*y)+(x*z)
Left distributivity means that for all x,y,z
: x*(y+z)=(x*y)+(x*z)
现在你没有提到具体的领域,所以我假设所有的关系都已经知道它们.这假设 Add_3
和 Mult_3
总是终止.
Now you do not mention concrete domains, so I assume that all relations know them already. This assumes that Add_3
and Mult_3
always 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) ).
这里使用 iwhen/2
.
这篇关于Prolog中的分布检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!