Prolog 序言:使用事实替换列表项

Prolog 序言:使用事实替换列表项,prolog,Prolog,我试图创建一个函数,在列表中循环,如果元素与事实匹配,则替换它 我能够实现一个简单的替换,替换列表中的每个元素 replace([X|T], Y, [Y|T2]) :- replace(T,Y,T2). replace([],X,[X]). 所以这只是用Y替换X中的每个列表项 现在我想用如下事实替换X中的每个列表项: replace([1,2,3], [ rule(1, [one]), rule(2, [two]) ], Result) 因此,如果列表是[1,2,3],结果将是[1,2,3]

我试图创建一个函数,在列表中循环,如果元素与事实匹配,则替换它

我能够实现一个简单的替换,替换列表中的每个元素

replace([X|T], Y, [Y|T2]) :- replace(T,Y,T2).
replace([],X,[X]).
所以这只是用Y替换X中的每个列表项

现在我想用如下事实替换X中的每个列表项:

replace([1,2,3], [ rule(1, [one]), rule(2, [two]) ], Result)
因此,如果列表是
[1,2,3]
,结果将是
[1,2,3]


如何执行此操作?

您可以通过添加第二条规则来执行此操作,该规则遍历替换列表,然后选择第一条匹配的规则,或者保持项目不变,如下所示:

replace([],_,[]).
replace([H|T], L, [RH|RT]) :- replace(T,L,RT), replace_one(H, L, RH).

replace_one(H, [], H).
replace_one(H, [rule(H,B)|_], B).
replace_one(H, [rule(A,_)|T], R) :- H \= A, replace_one(H, T, R).

我更喜欢使用高阶库支持

replace(In, Replacements, Out) :-
  maplist(replace_one(Replacements), In, Out).

replace_one(RepList, Rep, Val) :-
  memberchk(rule(Rep, [Val]), RepList) -> true ; Rep = Val.

我认为可以简单地说:

replace([], _, []).
replace([H|T], Rules, [R|TR]) :-
        (   memberchk(rule(H, [R]), Rules)
        ->  true
        ;   H = R
        ),
        replace(T, Rules, TR).