使用prolog DCG查找和替换 - 代码审查

Ash*_*ley 4 prolog dcg

我想出了瓦特/下面的代码来替换出现的所有Find瓦特/ ReplaceRequest和放在答案Result.这是使用DCG,因此它们都是字符代码列表.客户端代码将使用的谓词是substitute.

findReplace(_, _, [], []) -->
    [].  % The end.
findReplace(Find, Replace, Result, ResultRest) -->
    Find,  % Found Find.
    { append(Replace, Intermediate, Result) },  % Put in Replace in Find's place.
    !,  % Make sure we don't backtrack & interpret Find as the next case.
    findReplace(Find, Replace, Intermediate, ResultRest).
findReplace(Find, Replace, [ C | Intermediate ], ResultRest) -->
    [ C ],  % Any other character.
    findReplace(Find, Replace, Intermediate, ResultRest).

substitute(Find, Replace, Request, Result):-
    phrase(findReplace(Find, Replace, Result, []), Request).
Run Code Online (Sandbox Code Playgroud)

这适用于SWI-Prolog.有没有人对我如何改进它有任何意见?我正在学习如何使用DCG和差异列表.例如,我放入剪辑,以便在发现后Find,prolog不会回溯并将其解释为[ C ]案件中的普通角色.这需要,还是有更多的声明方式?

另一个问题 - 是否有一个谓词已经可以用替代品做同样的事情,也许是在原子上?

提前致谢.

mat*_*mat 10

考虑使用semicontext表示法替换DCG中的子序列:

eos([], []).

replace(_, _) --> call(eos), !.
replace(Find, Replace), Replace -->
        Find,
        !,
        replace(Find, Replace).
replace(Find, Replace), [C] -->
        [C],
        replace(Find, Replace).

substitute(Find, Replace, Request, Result):-
        phrase(replace(Find, Replace), Request, Result).
Run Code Online (Sandbox Code Playgroud)

例:

?- substitute("a", "b", "atesta", R), atom_codes(A, R).
R = [98, 116, 101, 115, 116, 98],
A = btestb.
Run Code Online (Sandbox Code Playgroud)

另外,underscores_are_much_more_readable thanMixedCaseNamesAsYouSee.