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

发布于 2024-11-16 04:09:08 字数 1066 浏览 4 评论 0原文

我想出了以下代码来替换 Request 中所有出现的 FindReplace 。将答案放入 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).

这适用于 SWI-Prolog。有人对我如何改进它有任何意见吗?我正在学习如何使用 DCG's &差异列表。例如,我放入了剪切,以便在找到 Find 后,prolog 永远不会回溯 & 。将其解释为 [ C ] 情况下的普通字符。是否需要这样做,或者是否有更具声明性的方式来做到这一点?

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

提前致谢。

I came up w/ the following code to replace all occurences of Find w/ Replace in Request & put the answer in Result. This is using a DCG, so they are all lists of character codes. The predicate that client code would use is 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).

This works in SWI-Prolog. Does anyone have any comments on how I could improve it? I'm learning how to use DCG's & difference lists. E.g., I put in the cut so that, after finding Find, prolog doesn't ever backtrack & interpret that as an ordinary character in the [ C ] case. Is this needed, or is there a more declarative way of doing so?

Another question - is there a predicate already available to do the same thing that substitute does, maybe on atoms?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苍风燃霜 2024-11-23 04:09:08

考虑使用半上下文表示法来替换 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).

示例:

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

此外,下划线比 MixedCaseNamesAsYouSee 更可读。

Consider using semicontext notation to replace subsequences in DCGs:

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).

Example:

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

Also, underscores_are_much_more_readable thanMixedCaseNamesAsYouSee.

孤独陪着我 2024-11-23 04:09:08

关于第二个问题,即使用原子,我编写了这个实用程序 atomic_list_concat< /a>

%%  replace_word(+Old, +New, +Orig, -Replaced)
%%  is det.
%
%   string replacement
%   doesn't fail if not found
%
replace_word(Old, New, Orig, Replaced) :-
    atomic_list_concat(Split, Old, Orig),
    atomic_list_concat(Split, New, Replaced).

示例:

?- replace_word(a, b, atesta, X).
X = btestb.

About the second question, i.e. working with atoms, I wrote this utility perusing atomic_list_concat

%%  replace_word(+Old, +New, +Orig, -Replaced)
%%  is det.
%
%   string replacement
%   doesn't fail if not found
%
replace_word(Old, New, Orig, Replaced) :-
    atomic_list_concat(Split, Old, Orig),
    atomic_list_concat(Split, New, Replaced).

Example:

?- replace_word(a, b, atesta, X).
X = btestb.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文