我有以下代码。我传入一个原子作为第一个参数,一个等式列表作为第二个参数,我想根据等式列表返回原子的值。
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].
答案 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 = foo
和Args = [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
| ?-
同样,这些结果直接来自您在问题中发布的代码。