1

簡単な手順の後に特定の文字列になる文字列のリストを作成できる Prolog スクリプトを作成しようとしています。Prolog に関する私の知識は非常に限られており、これを実行できるかどうかもわかりません。不可能な場合は教えてください。

私はこれまでにこれを手に入れました

replace_word(Old, New, Orig, Replaced) :-
    atomic_list_concat(Split, Old, Orig),
    atomic_list_concat(Split, New, Replaced).

この操作を実行できます

10 ?- replace_word('a','e','glava',X).
X = gleve.

しかし、それを後戻りすることはできません

11 ?- replace_word('a','e',X,'gleve').
ERROR: atomic_list_concat/3: Arguments are not sufficiently instantiated

問題の原因は想像できますが、それを回避する方法はありますか?

4

2 に答える 2

1

replace_word / 4は、SWI-Prologのファーストクラスのアトム処理により、効率を上げるためにそのように記述されています。そのセマンティクスを「逆にする」ために、ヘルパー述語を使用するよりも良い方法を見つけることはできません。

replace_word(Old, New, Orig, Replaced) :-
    (   var(Orig)
    ->  atomic_list_concat(L, New, Replaced),
        insert_alt(L, [Old, New], L1),
        atomic_list_concat(L1, Orig)
    ;   atomic_list_concat(L, Old, Orig),
        atomic_list_concat(L, New, Replaced)
    ).
insert_alt([A,B|R], Ks, [A,K|T]) :-
    member(K, Ks),
    insert_alt([B|R], Ks, T).
insert_alt([A], _Ks, [A]).

insert_alt / 3これは、リスト(Ks)の代わりに、古いものと新しいもののペアを使用できる、必要なものよりも少し一般的です。

テスト:

?- replace_word('a','e',X,'gleve').
X = glava ;
X = glave ;
X = gleva ;
X = gleve ;
false.
于 2012-07-31T09:14:54.203 に答える
1

確かに、これを実装するには他のオプションがあるはずです。私はPrologの専門家ではありませんがatomic_list_concat/3、引数として2つの変数を受け入れないようです(この述語が何をするかを考えると、トリッキーになりますよね?)ので、バイパスできます句の順序を変更して、以前に知っている変数を「修正」することによって変数が与えられるという問題。例えば:

replace_word(Old, New, Orig, Replaced) :-
    (var(Orig), !, atomic_list_concat(Split, New, Replaced),
     atomic_list_concat(Split, Old, Orig)) ;
    (atomic_list_concat(Split, Old, Orig),
     atomic_list_concat(Split, New, Replaced)).

カットは必要ないことに注意してください。

?- replace_word('a','e',X,'gleve').
X = glava.

?- replace_word('a','e','glava',Y).
Y = gleve.
于 2012-07-27T23:18:52.803 に答える