在 Prolog 中构建表达式树

发布于 2024-12-11 01:22:01 字数 432 浏览 3 评论 0原文

我正在寻找一种在 Prolog 中构建表达式树的方法。我已经做了一些实验并提出了以下工作代码(仅处理常量和加号表达式):

const(_).
plus(_, _).

eval(const(R), R).

eval(plus(A, B), R) :- number(A), number(B), R is A+B.
eval(plus(A, B), R) :- number(A), eval(B, B_R), R is A+B_R.
eval(plus(A, B), R) :- eval(A, A_R), number(B), R is A_R+B.
eval(plus(A, B), R) :- eval(A, A_R), eval(B, B_R), R is A_R+B_R.

这种方法有没有更简单的替代方法?我是否必须为计划添加到程序中的每一个运算符定义这 4 种情况?

I'm looking for a way to build an Expression Tree in Prolog. I already did some experiments and came up with the following working code (that will only handle constants and the plus expression):

const(_).
plus(_, _).

eval(const(R), R).

eval(plus(A, B), R) :- number(A), number(B), R is A+B.
eval(plus(A, B), R) :- number(A), eval(B, B_R), R is A+B_R.
eval(plus(A, B), R) :- eval(A, A_R), number(B), R is A_R+B.
eval(plus(A, B), R) :- eval(A, A_R), eval(B, B_R), R is A_R+B_R.

Is there any simpler alternative to this approach? Will I have to define these 4 cases for each one of the operators I plan on adding to my program?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如若梦似彩虹 2024-12-18 01:22:01

请参阅此处的另一个模式,利用 DCG 和(一种)惰性求值:

/*
File:    dcg_calculator.pl
Author:  Carlo,,,
Created: Aug 16 2011
Purpose: associativity and precedences in calculator
*/

:- module(dcg_calculator, [dcg_calculator/2, expr//1]).
%- [library(http/dcg_basics)]. obsolete
:- [library(dcg/basics)].

/* usage

?- dcg_calculator("1+(-2-2)",S),V is S.
S = 1+ (-2-2),
V = -3 ;
false.

*/
dcg_calculator(Formula, IsEvaluable) :-
    phrase(expr(IsEvaluable), Formula, []).

expr(Evaluable) -->
    sum(Evaluable).

sum(S) -->
    product(P), sum_1(P, S).
sum_1(L, S) -->
    "+", product(P), sum_1(L + P, S);
    "-", product(P), sum_1(L - P, S);
    {L = S}.

product(P) -->
    value(V), product_1(V, P).
product_1(V, P) -->
    "*", value(U), product_1(V * U, P);
    "/", value(U), product_1(V / U, P);
    {V = P}.

% value(V) -->
%   {var(V)} -> {V=0 /* between(0, 9, V)*/ }, "0".

value(V) -->
    "(", expr(V), ")" ;
    number(V).

使用语法对数据结构进行建模,这是 Prolog 中非常有用的技术。使用的语法是 PEG 的实现。 SWI-Prolog 的依赖性非常有限,只有 number//1。

See here another schema, exploiting DCG and (a kind of) lazy evaluation:

/*
File:    dcg_calculator.pl
Author:  Carlo,,,
Created: Aug 16 2011
Purpose: associativity and precedences in calculator
*/

:- module(dcg_calculator, [dcg_calculator/2, expr//1]).
%- [library(http/dcg_basics)]. obsolete
:- [library(dcg/basics)].

/* usage

?- dcg_calculator("1+(-2-2)",S),V is S.
S = 1+ (-2-2),
V = -3 ;
false.

*/
dcg_calculator(Formula, IsEvaluable) :-
    phrase(expr(IsEvaluable), Formula, []).

expr(Evaluable) -->
    sum(Evaluable).

sum(S) -->
    product(P), sum_1(P, S).
sum_1(L, S) -->
    "+", product(P), sum_1(L + P, S);
    "-", product(P), sum_1(L - P, S);
    {L = S}.

product(P) -->
    value(V), product_1(V, P).
product_1(V, P) -->
    "*", value(U), product_1(V * U, P);
    "/", value(U), product_1(V / U, P);
    {V = P}.

% value(V) -->
%   {var(V)} -> {V=0 /* between(0, 9, V)*/ }, "0".

value(V) -->
    "(", expr(V), ")" ;
    number(V).

Using grammars to model data structures it's a very useful technique in Prolog. The grammar used it's an implementation of PEGs. Dependency from SWI-Prolog it's very limited, just number//1.

花之痕靓丽 2024-12-18 01:22:01

我认为这应该可以做到,尽管我不熟悉构造 pred1(pred2(...)...) :- ... (我的 Prolog 非常生锈)。

eval(A, A) :- number(A).
eval(plus(A, B), R) :- eval(A, A_R), eval(B, B_R), R is A_R+B_R.

I think this should do it, though I'm not familiar with the construct pred1(pred2(...)...) :- ... (my Prolog is very rusty).

eval(A, A) :- number(A).
eval(plus(A, B), R) :- eval(A, A_R), eval(B, B_R), R is A_R+B_R.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文