Prolog - 评估代数表达式

时间:2013-03-02 02:39:54

标签: prolog

这是我遇到问题的测试复习问题。你如何编写一个方法来用运算符'plus','minus'和'times'来评估代数表达式。以下是一些测试查询:

简化(表达,结果,列表)

?- 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

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

我认为其中一种方法应该是简化(V,Val,L): - 成员(V:Val,L)。理想情况下,应该只有4种方法......但我不确定如何解决这个问题。

到目前为止,我不知道身体应该是什么:

simplify(Var, Value, Lst) :- member(Var:Value, Lst).
simplify(plus(Var), Value, Lst) :- 
simplify(minus(Var), Value, Lst) :-
simplify(times(Var), Value, Lst) :-

我不确定第五种方法应该是什么。

1 个答案:

答案 0 :(得分:2)

我怀疑你是否允许自己因复杂的例子而下雪。你只是缺少一个基本案例,所有归纳案例都非常简单。你只需要一些简单的例子。首先,应该返回什么?

?- simplify(3, Val, []).

是的,Val = 3。所以让我们添加缺少的基本情况:

simplify(Num, Num, _) :- number(Num).

归纳案例的关键见解是plusminustimes都具有相同的递归二进制结构。您可以递归地将simplify应用于双方以实现对事物的评估。让我们尝试另一个简单的例子:

?- simplify(times(3, 3), Val, []).

我们想要Val = 9。我们需要做的就是弄清楚左边和右边的值是什么,然后将它们相乘。所以最终会看起来像这样:

simplify(times(Left, Right), Value, Lst) :-
  simplify(Left, LeftVal, Lst),
  simplify(Right, RightVal, Lst),
  Value is LeftVal * RightVal.

您希望将Lst传递给递归调用,以便它们也可以查找变量。从这里开始,您应该可以推断出plusminus个案会是什么样子。你真的不应该需要看起来像plus(X)的情况,因为它只有一个参数。

Prolog的神奇之处在于,这就是你所要做的一切。只要你有简单的工作,递归就会处理你的复杂例子。试试吧。 :)

希望这有帮助!