5

Findw/ Replacein Request& put the answer inのすべての出現を置き換えるために、次のコードを思いつきました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 の & 差分リストの使い方を学んでいます。Findたとえば、 を見つけた後、プロローグがバックトラックしてそれを通常の文字として解釈しないように、カットを入れました[ C ]。これは必要ですか、それとももっと宣言的な方法がありますか?

もう 1 つの質問 - 代用と同じことを行うための述語がすでに利用可能ですか? おそらくアトム上で?

前もって感謝します。

4

2 に答える 2

11

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 よりも underscores_are_much_more_readable です。

于 2011-06-18T10:56:02.337 に答える
2

2 番目の質問、つまりアトムの操作については、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).

例:

?- replace_word(a, b, atesta, X).
X = btestb.
于 2012-10-07T12:17:29.463 に答える