我想在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是否有办法将运算符应用于参数?
答案 0 :(得分:3)
由于以下几个原因,您几乎干的解决方案无效:
Formula =.. [Op, L, R]
仅指二元运算符。你当然也想引用数字。
根本不考虑参数L
和R
。
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).