0

这是一个我遇到问题的测试复习问题。您如何编写一种方法来使用运算符“加号”、“减号”和“次”来评估代数表达式。以下是一些测试查询:

简化(表达式、结果、列表)

?- 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 代替它们在第三个参数(列表)中的值。第二个参数应该是计算表达式后的结果。

我认为其中一种方法应该是简化(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) :-

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

4

1 回答 1

2

我怀疑你已经让自己被复杂的例子蒙蔽了。您只是缺少一个基本案例,所有归纳案例都非常简单。你只需要一些更简单的例子。首先,这应该返回什么?

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

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

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

归纳案例的关键见解是plus,minus并且times都具有相同的递归二进制结构。您可以递归地应用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 的神奇之处在于,这实际上就是你所要做的。只要你有简单的例子,递归就会处理你的复杂例子。试试看。:)

希望这可以帮助!

于 2013-03-02T04:55:35.297 回答