Prolog 中的 DRY 算术表达式求值 [英] DRY arithmetic expression evaluation in Prolog

查看:23
本文介绍了Prolog 中的 DRY 算术表达式求值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 Prolog 中为算术编写评估谓词,我发现 这个:

I wanted to write evaluating predicate in Prolog for arithmetics and I found this:

eval(A+B,CV):-eval(A,AV),eval(B,BV),CV is AV+BV.
eval(A-B,CV):-eval(A,AV),eval(B,BV),CV is AV-BV.
eval(A*B,CV):-eval(A,AV),eval(B,BV),CV is AV*BV.
eval(Num,Num):-number(Num).

这很棒,但不是很干.

我还发现了 这个:

:- op(100,fy,neg), op(200,yfx,and), op(300,yfx,or).

positive(Formula) :-
    atom(Formula).

positive(Formula) :-
    Formula =.. [_,Left,Right],
    positive(Left),
    positive(Right).

?- positive((p or q) and (q or r)).
Yes
?- positive(p and (neg q or r)).
No

这里操作符与_匹配,参数与Left和Right匹配.

Operator is here matched with _ and arguments are matched with Left and Right.

所以我想出了这个:

eval(Formula, Value) :-
    Formula =.. [Op, L, R], Value is Op(L,R).

如果它只工作但它会给出 Syntax error: Operator expected ,那将是地狱般的干燥.

It would be DRY as hell if only it worked but it gives Syntax error: Operator expected instead.

在这种情况下,Prolog 中有没有办法将运算符应用于参数?

Is there a way in Prolog to apply operator to arguments in such a case?

推荐答案

您的几乎 DRY 解决方案无法正常工作,原因如下:

Your almost DRY solution does not work for several reasons:

  • Formula =.. [Op, L, R] 仅指二元运算符.你当然也想引用数字.

  • Formula =.. [Op, L, R] refers to binary operators only. You certainly want to refer to numbers too.

根本不考虑参数LR.

Op(L,R) 不是有效的 Prolog 语法.

Op(L,R) is not valid Prolog syntax.

从好的方面来说,您的尝试会为变量产生一个干净的实例化错误,而 positive/1 会失败并且 eval/2 循环至少比失败.

on the plus side, your attempt produces a clean instantiation error for a variable, whereas positive/1 would fail and eval/2 loops which is at least better than failing.

由于您的操作符实际上与 (is)/2 使用的操作符相同,因此您可能需要先检查,然后才能重用 (is)/2.p>

Since your operators are practically identical to those used by (is)/2 you might want to check first and only then reuse (is)/2.

eval2(E, R) :-
   isexpr(E),
   R is E.

isexpr(BinOp) :-
   BinOp =.. [F,L,R],
   admissibleop(F),
   isexpr(L),
   isexpr(R).
isexpr(N) :-
   number(N).

admissibleop(*).
admissibleop(+).
% admissibleop(/).
admissibleop(-).

请注意,number/1 因变量而失败 - 这会导致许多错误的程序.一个安全的选择是

Note that number/1 fails for a variable - which leads to many erroneous programs. A safe alternative would be

t_number(N) :-
   functor(N,_,0),
   number(N).

这篇关于Prolog 中的 DRY 算术表达式求值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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