1

这是一个我遇到问题的测试复习问题。您如何编写一个方法来计算带有运算符plusminus的代数表达式times。以下是一些测试查询:

simplify(Expression, Result, List)

?- simplify(plus(times(x,y),times(3 ,minus(x,y))),V,[x:4,y:2]).
          V = 14

?- simplify(times(2,plus(a,b)),Val,[a:1,b:5]).
          Val = 12

?- simplify(times(2,plus(a,b)),Val,[a:1,b:(-5)]).
          Val = -8 .

我得到的只是这些示例查询,没有其他解释。但我很确定该方法应该剖析第一个参数,它是代数表达式,用 x 和 y 代替它们在第三个参数(列表)中的值。第二个参数应该是计算表达式后的结果。

我认为其中一种方法应该是simplify(V, Val, L) :- member(V:Val, L). 理想情况下应该只再有 4 种方法......但我不知道该怎么做。

4

1 回答 1

2

从小处着手,写下你所知道的。

simplify(plus(times(x,y),times(3 ,minus(x,y))),V,[x:4,y:2]):- V = 14.

是一个非常好的开始:(+ (* 4 2) (* 3 (- 4 2))) = 8 + 3*2 = 14. 但是,当然,

simplify(times(x,y),V,[x:4,y:2]):- V is 4*2.

甚至更好。还,

simplify(minus(x,y),V,[x:4,y:2]):- V is 4-2.
simplify(plus(x,y),V,[x:4,y:2]):- V is 4+2.
simplify(x,V,[x:4,y:2]):- V is 4.

所有完美的 Prolog 代码。但当然,我们真正的意思是,很明显,是

simplify(A,V,L):- atom(A), getVal(A,L,V).
simplify(C,V,L):- compound(C), C =.. [F|T], 
  maplist( simp(L), T, VS),       % get the values of subterms
  calculate( F, VS, V).           % calculate the final result

simp(L,A,V):- simplify(A,V,L).    % just a different args order

getVal/3将需要以某种方式从L列表中检索值,并calculate/3在给定符号操作名称和计算值列表的情况下实际执行计算。

研究maplist/3=../2

(未完成,未测试)。


好吧,maplist这有点矫枉过正=..:你所有的条款都可能是op(A,B). 所以定义可以简化

simplify(plus(A,B),V,L):-
  simplify(A,V1,L),
  simplify(B,V2,L),
  V is V1 + V2.         % we add, for plus

simplify(minus(A,B),V,L):-
  % fill in the blanks
  .....
  V is V1 - V2.         % we subtract, for minus

simplify(times(A,B),V,L):-
  % fill in the blanks
  .....
  V is .... .           % for times we ...

simplify(A,V,L):-
  number(A),
  V = .... .            % if A is a number, then the answer is ...

最后一种可能性是,xy等等,满足atom/1

simplify(A,V,L):-
  atom(A),
  retrieve(A,V,L).

所以上面子句的最后一个调用可能看起来像retrieve(x,V,[x:4, y:3]),或者看起来像retrieve(y,V,[x:4, y:3])。实施起来应该是一件简单的事情。

于 2013-03-03T15:07:49.940 回答