用Prolog中的列表替换原子和相应的值

时间:2018-01-08 19:25:34

标签: list prolog

我有以下代码。我传入一个原子作为第一个参数,一个等式列表作为第二个参数,我想根据等式列表返回原子的值。

evaluator(Id,VariablesIn,Answer):-
     exp_symbols(Id,VariablesIn,Answer).

exp_symbols(Id, VariablesIn, VariablesOut) :-
     VariablesIn =.. [F|Args],   
     ( member(F=V, Id) -> G = V ; G = F ), 
     maplist(exp_symbols(Id), Args, ArgsSWithSym),
     VariablesOut =.. [G|ArgsSWithSym]. 

当我打电话

evaluator(a,[a=2,b=3],Answer).

我希望此返回

Answer = 2

因为我的列表物种a = 2

相反,我得到

Answer = [a=2, b=3].

1 个答案:

答案 0 :(得分:2)

在最简单的情况下,如果您只是在映射中查找一个变量:

lookup(Variable, Mapping, Value) :- member(Variable=Value, Mapping).

这为您提供了一个简单的查找:

| ?- lookup(a, [a=1,b=2], Value).

Value = 1

yes
| ?-

如果你想做一个表达,你需要做一些更精细的事情,这就是=../2发挥作用的地方。例如,如果您有a+3,则相当于'+'(a, 3)。您需要提取参数并将映射应用于非数字的映射。由于表达式可以嵌入(例如a*(b + (4*c))),这意味着它必须是递归的。 =../2会将一个术语与一个列表相关联,其中头部是仿函数,列表的其余部分(尾部)是参数。例如,foo(a, b) =.. [F | Args]会产生F = fooArgs = [a, b]。因此,'+'(a, 3) =.. [F | Args]会产生F = '+'Args = [a, 3]

您发布的代码实际上使用我刚才描述的方法工作,您只是错误地调用它。您致电evaluator(a, [a=2,b=3], Answer),但您应该致电evaluator([a=2,b=3], a, Answer)

| ?- evaluator([a=2,b=3], a, Answer).

Answer = 2

yes
| ?-

对于更复杂的表达方式:

| ?- evaluator([a=2,b=3], (a+3)*(b+7), Answer).

Answer = (2+3)*(3+7)

yes
| ?-

同样,这些结果直接来自您在问题中发布的代码。