问题
I have the following code. I pass in an atom as the first argument a list of equalities as the second argument, and I want to return the value of the atom according to the list of equalities.
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].
When I call
evaluator(a,[a=2,b=3],Answer).
I want this to return
Answer = 2
Because my list species that a=2
Instead I get
Answer = [a=2, b=3].
回答1:
In the simplest case, if you're just looking up one variable in your mapping:
lookup(Variable, Mapping, Value) :- member(Variable=Value, Mapping).
This gives you a trivial lookup:
| ?- lookup(a, [a=1,b=2], Value).
Value = 1
yes
| ?-
If you want to do an expression, you'll need to do something more elaborate, which is where =../2
comes into play. For example, if you have a+3
, that is equivalent to '+'(a, 3)
. You need to pull out the arguments and apply the mapping to the ones that are not numbers. Since expressions can be embedded (e.g., a*(b + (4*c))
), that means it must be recursive. =../2
will associate a term with a list where the head is the functor and the rest of the list (the tail) are the arguments. For example, foo(a, b) =.. [F | Args]
results in F = foo
and Args = [a, b]
. So, '+'(a, 3) =.. [F | Args]
results in F = '+'
and Args = [a, 3]
.
The code you posted actually does work using the method I just described, you just called it incorrectly. You called, evaluator(a, [a=2,b=3], Answer)
but you should have called evaluator([a=2,b=3], a, Answer)
:
| ?- evaluator([a=2,b=3], a, Answer).
Answer = 2
yes
| ?-
And for more complex expressions:
| ?- evaluator([a=2,b=3], (a+3)*(b+7), Answer).
Answer = (2+3)*(3+7)
yes
| ?-
Again, these results are directly from the code that you posted in your question.
来源:https://stackoverflow.com/questions/48156852/replacing-atom-with-corresponding-value-from-a-list-in-prolog