【问题标题】:DRY arithmetic expression evaluation in PrologProlog 中的 DRY 算术表达式求值
【发布时间】:2014-07-14 07:49:39
【问题描述】:

我想在 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).

如果它只工作但它会提供Syntax error: Operator expected,那将是地狱般的干燥。

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

【问题讨论】:

    标签: prolog refactoring dry arithmetic-expressions


    【解决方案1】:

    您的几乎 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).
    

    【讨论】:

    • 谢谢!使用 (is)/2 完成所有工作的好主意。我还需要对其进行一些扩展以处理变量,但这应该不是问题:)
    猜你喜欢
    • 1970-01-01
    • 2013-09-12
    • 2014-05-23
    • 2015-12-20
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    • 2011-01-25
    • 2012-03-01
    相关资源
    最近更新 更多