问题描述
我需要简化序言中的身份(例如 x+0 = x
、x-x=0
等).为此,我需要用 x
替换部分表达式(比如 x+0
).
I need to simplify identities in prolog (e.g. x+0 = x
, x-x=0
, etc.). For this I need to replace parts of the expression (say x+0
by x
).
你能帮我更换吗?
推荐答案
Prolog 的一个巧妙之处在于您可以非常轻松地解构算术表达式.您的基本模板将如下所示:
A neat thing about Prolog is that you can deconstruct an arithmetic expression pretty easily. Your basic template is going to look like this:
simplify(X, X) :- number(X) ; atom(X) ; var(X).
simplify(X+Y, X1+Y1) :- simplify(X, X1), simplify(Y, Y1).
simplify(X-Y, X1-Y1) :- simplify(X, X1), simplify(Y, Y1).
simplify(X*Y, X1*Y1) :- simplify(X, X1), simplify(Y, Y1).
simplify(X/Y, X1/Y1) :- simplify(X, X1), simplify(Y, Y1).
除了递归地遍历表达式之外,这并没有真正做任何事情.我们在运算符的两边递归调用simple,以便简化模式匹配,而不管它们出现在表达式中的什么地方.但现在它似乎什么都不做:
This doesn't really do anything except recursively walk the expression. We're recursively calling simplify on both sides of the operator so that the simplification patterns are matched regardless of where they occur in the expression. But for now it appears to do nothing:
?- simplify(3+X*y, Q).
Q = 3+X*y
把它想象成你的空循环.有了这个,你就可以开始处理你的身份了,把特殊情况"放在上面这个遍历.身份是您可以通过这种方式处理的一件事:
Think of it as your empty loop. With this in hand, you can start dealing with your identities by putting "special cases" above this traversal. The identities are one thing you can handle this way:
simplify(1*X, X1) :- simplify(X, X1).
simplify(X*1, X1) :- simplify(X, X1).
simplify(0+X, X1) :- simplify(X, X1).
simplify(X+0, X1) :- simplify(X, X1).
尝试一下:
?- simplify(x*1+0, Q).
Q = x
你可以在这里看到我们为什么使用递归例程:
And you can see why we're using a recursive routine here:
?- simplify(x+(y+(z*43)+0)*1, Q).
Q = x+(y+z*43)
即使 +0 深入嵌套在结构中,它也被删除了.我们也可以做一些更彻底的简化:
Even though the +0 is deeply nested within the structure, it is removed. We could do some more drastic simplifications too:
simplify(_*0, 0).
simplify(0*_, 0).
这里不用递归了,整个子表达式基本删除了:
No need for recursion here, the whole subexpression is basically deleted:
?- simplify(x+(y+(z*43)+1)*0, Q).
Q = x+0 ;
你也可以做一些更有趣的事情:
You can do some more interesting things as well:
simplify(X*Y+Z*Y, Y1*(X1+Z1)) :-
simplify(X, X1), simplify(Y, Y1), simplify(Z, Z1).
尝试一下:
?- simplify(34*z+17*z, X).
X = z* (34+17)
?- simplify(34*z+z*17, X).
X = 34*z+z*17
此处的第二个示例表明此类处理存在限制.您不想提供模板的每一个排列.如果你想让它们更智能,你可能不得不采用更智能的中间表示,或者比简单的统一更智能的应用模板方法.统一是伟大的,但它不理解交换或结合的性质.
This second example here reveals that there is a limitation to this type of processing. You don't want to have to give every permutation of your templates. If you want to make them more intelligent you're probably going to have to either adopt a more intelligent intermediate representation, or a more intelligent means of applying templates than simple unification. Unification is great, but it doesn't understand the commutative or associative properties.
为了更进一步,您可能想要更深入地了解 Prolog.大多数 Prolog 书籍都研究了此类问题;我偏爱Programming Prolog 和Prolog 的艺术,但我听说 Bratko 的书很棒.我建议您尝试其中之一并开始深入研究.不过,请不要犹豫,提出更多问题!
To go further, you're probably going to want to dig a little deeper into Prolog. This type of problem is studied in most Prolog books; I'm partial to Programming Prolog and Art of Prolog but I hear Bratko's book is amazing. I'd recommend you get your hands on one of these and start digging through it. Don't hesitate to ask more questions though!
这篇关于替换序言中的表达部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!