prolog - Prolog 中的 DRY 算术表达式求值

标签 prolog refactoring dry arithmetic-expressions

我想在 Prolog 中编写算术评估谓词,我发现 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).

这很棒,但不是很干。

我还发现了this :

:- 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 匹配。

所以我想出了这个:

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

如果它能工作,那就太干了,但它却给出了语法错误:需要运算符

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

最佳答案

您的几乎 DRY 解决方案因以下几个原因而不起作用:

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

  • 参数 LR根本不考虑。

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

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

因为您的运算符实际上与 (is)/2 使用的运算符相同您可能想先检查然后再重用 (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变量失败 - 这会导致许多错误的程序。一个安全的替代方案是

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

关于prolog - Prolog 中的 DRY 算术表达式求值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23854857/

相关文章:

prolog - 写入文件(Prolog)

list - 多个列表的组合 - Prolog

java - 如何在 Java 中的 Eclipse 中自动创建抽象类的子类?

javascript - 如何将内部 setState 函数重构为静态类方法?

python - Django:优化违反 DRY 的测试

sql - 如何跨 UNION 重复 SQL 查询的部分? (SQL 中的 DRY)

prolog - Clojure core.logic 的简单序言

io - 在 prolog 中的文件中搜索

optimization - 您如何管理 PhoneGap 和 webapp 代码?

ruby - 在 ruby​​ 中扩展/修补库的 DRYest 方法是什么?