如何将谓词作为参数传递给 Prolog 中的另一个谓词? [英] How can I pass a predicate as parameter for another predicate in Prolog?

查看:12
本文介绍了如何将谓词作为参数传递给 Prolog 中的另一个谓词?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这 3 个谓词:

times(X, Y):-
    Result is X * Y.
minus(X, Y):-
    Result is X - Y.
plus(X, Y):-
    Result is X + Y.

我想在 plus(X, Y) 中传递例如 times(2,2) 像这样 plus(times(2,2), 减(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 未绑定时是假的,所以它实际上是在生成涉及时间的新子句,减号和加号结构并尝试它们,这不是您想要的评估器.

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.

编辑:实现printterm/1.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆