如何在Prolog中传递谓词作为另一个谓词的参数? [英] How can I pass a predicate as parameter for another predicate in Prolog?
问题描述
我有这3个谓词:
times(X, Y):-
Result is X * Y.
minus(X, Y):-
Result is X - Y.
plus(X, Y):-
Result is X + Y.
,我想通过例如 times(2,2)
在加(X,Y)
像这样加(times(2,2),minus(X,Y))
。
and I want to pass for example times(2,2)
in the plus(X, Y)
like this plus(times(2,2), minus(X, Y))
.
推荐答案
您的问题标题与您的问题的文字之间的关系对我来说不清楚,我认为@false可能是正确的,这里有一个更基本的误解Prolog。我不知道这是否真的满足了你的需要,但这里的替代方法就是编写自己的评估者。
The relationship between the title of your question and the text of your question is unclear to me, and I think @false is probably right that there is a more fundamental misunderstanding about Prolog here. I don't know if this really addresses your need or not, but the alternative here is writing your own evaluator.
eval(times(X,Y), Result) :-
eval(X, XResult),
eval(Y, YResult),
Result is XResult * YResult.
eval(minus(X,Y), Result) :-
eval(X, XResult),
eval(Y, YResult),
Result is XResult - YResult.
eval(plus(X,Y), Result) :-
eval(X, XResult),
eval(Y, YResult),
Result is XResult + YResult.
递归调用 eval / 2
需要这些规则中的每一个的身体来处理例如 plus(times(2,2),minus(X,Y))
的情况。那么你需要一个数字规则:
The recursive calls to eval/2
inside the bodies of each of these rules are needed to handle cases like plus(times(2,2), minus(X, Y))
. Then you need a rule for numbers:
eval(Num, Num) :- number(Num).
这对于像这样的情况非常好:
This works great for cases like this:
?- eval(plus(times(2,2), minus(7,1)), Result).
Result = 10.
对于这样的情况,你不会有任何好处:
It doesn't do you any good for cases like this:
?- eval(plus(times(2,2), minus(X,Y)), Result).
ERROR: Out of local stack
当然,如果我们建立绑定X和Y在到达之前,但如果您希望它为X和Y生成可能的解决方案,那么您将不幸运,您需要使用 clpfd
。这个奇怪的错误的原因,如果你追踪,是因为 number(X)
当 X
未绑定是false ,所以它实际上生成了涉及时间,减号和加号结构的新条款,并尝试它们,这不是您在评估者中所需要的。
Of course, it would work if we established bindings for X and Y before getting there, but if you want it to generate possible solutions for X and Y you're out of luck, you'll need to use clpfd
. The reason for this curious error, if you trace in, is because number(X)
when X
is unbound is false, so it is actually generating new clauses involving the times, minus and plus structures and trying them, which isn't what you want in an evaluator.
编辑 c
eval / 2
谓词显示如何执行递归树步行。校长与制作漂亮的打印机相同。我非常懒惰,所以我只会草绘,你必须自己填写细节。
The eval/2
predicate shows you how to perform a recursive tree walk. The principal is the same with making a pretty printer. I am very lazy so I will only sketch it, you'll have to fill in the details yourself.
printterm(T) :- format_term(T, Formatted), write(Formatted), nl.
format_term(plus(X,Y), Formatted) :-
format_term(X, XFormatted),
format_term(Y, YFormatted),
format(atom(Formatted), '(~a + ~a)', [XFormatted, YFormatted]).
% other format_term clauses here for other arithmetic expressions
format_term(X, X) :- number(X).
希望这有帮助!
这篇关于如何在Prolog中传递谓词作为另一个谓词的参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!