这是我的问题:
我有一个与此相似的键VAL对字典(实际代码中的更多对(:
args = [(score, 0), (multiplier, 1), (reward, 0), (prior_prob, 1)].
我定义了两个函数以使用字典:
% look up the Val of a Key in a Dict
lookup(Key,Dict,Val):-
member((Key,Val), Dict).
和
% update(Key, NewVal, Dict, NewDict) updates the value of a key in the dict
update(Key,Val,[],[(Key,Val)]). % Add new pair to current dict
update(Key,Val,[(Key,_)|Rest], [(Key,Val)|Rest]):- !. % Found the key and update the value
update(Key,Val,[KV|Rest],[KV|Result]) :- % recursively look for the key
update(Key,Val,Rest,Result).
我需要字典的原因是我有许多需要这些参数的函数(例如"得分","乘数"等(。这些功能互相调用并传递参数。并非每个功能都需要所有的参数,但是其中许多参数比其他函数都比其他函数更新。因此,该字典基本上是包裹着作为包装的参数列表,需要经常通过并经常覆盖。例如,没有字典,我可能具有此(化妆(功能:
calculate('cond1', 'cond2', S0, S1, Multiplier, Reward, Prior):-
getscore('cond1', 'cond2', S0, S1, Multiplier, Reward, Prior).
getscore('cond1', 'cond2', S0, S1, Multiplier, Reward, Prior):-
reward('cond1', 'cond2', Reward), % look up rewards based on conditions
MultNew is Multiplier*Prior, % calculate the new multiplier
S1 is (S0+Rewards*MultNew). % update score
但是有一个字典,我可以:
calculate2('cond1', 'cond2', Args, NewArgs):-
getscore2('cond1', 'cond2', Args, NewArgs).
getscore2('cond1', 'cond2', Args, NewArgs):-
reward('cond1', 'cond2', Reward),
lookup(prior, Args, Prior),
lookup(multiplier, Args, Mult),
update(reward, Reward, Args),
MultNew is Multiplier*Prior,
update(multiplier, MultNew, Args, NewArgs),
update(score, S0+Reward*MultNew, Args, NewArgs).
(第二种方式看起来比第一个方式更长,更慢,但是由于实际上,并非所有的ARG都需要一次更新或一次查找,并且由于以后添加更多参数更加灵活,所以我认为最好是有字典。请让我知道是否有更好的设计选择(,当我运行时,我会得到:
No permission to modify static procedure `(=)/2'
在我定义字典args的行号上。
我尝试了:-dynamic(arg/0, update/4, lookup/3).
,这是没有用的。
(=(/2在这里意味着什么?如何允许在Prolog中覆盖词典?预先感谢您!
这是您问题的(可能(解决方案(在 swi-prolog 中(。字典使用 swi-prolog 嵌入数据库(非persistent(
这是一组术语链。术语与用户提供的键
关联%key `small int` or `atom`-
lookup(Key, Value) :-
current_key( Key ),
recorded( Key, Value, _ ) ->
true
;
recordz(Key, Value).
update( Key, OldValue, NewValue ) :-
same_term( OldValue, NewValue ) ->
true
;
(current_key( Key ),
recorded( Key, OldValue, Ref ase( Ref )
;
true,
recordz( Key, NewValue, _ )).
编辑您还可以使用全局var,可回溯且不可折叠。例如 nb_setval/2, nb_getval/2
因此您的第一个语句看起来如下
:- nb_setval(score, 0),
nb_setval(multiplier, 1),
nb_setval(reward, 0),
nb_setval(prior_prob, 1),
nb_setval(args, [score, multiplier, reward, prior_prob]).
edit2
=/2
是谓词调用序言的统一过程unify/2
。如果您的意思是在字典覆盖下 可变组的重新分配,则可以使用任何一种解决方案来完成:
edit3
%我认为应该这样:
update_dict(Dict):-
update(args, Dict).
update(Key, Val):-
(nb_getval(Key, OldVal),
exists(Val, OldVal)) -> true;
nb_setval(Key, Val).
update(Key, Val, Dict):-
update_dict( Dict ),
update( Key, Val ).
exists(Val, OldVal) :-
nonvar(OldVal),
same_term(Val, OldVal).
%======================================
lookup_dict( Dict):-
lookup(args, Dict).
lookup(Key, Val):-
nb_getval(Key, OldVal),
exists( Val, OldVal ) ->
true
;
nb_setval(Key, Val).
lookup( Key, Val, Dict ):-
lookup_dict( Dict ),
lookup( Key, Val ).