我尝试编写一个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
我可以想象是什么导致了这个问题,但它有办法吗?
答案 0 :(得分:1)
当然应该有其他选择来实现这一点,而且我不是Prolog专家,但似乎atomic_list_concat/3
不会接受两个变量作为参数(考虑到这个谓词的作用)会不会很棘手,对吧?),所以你可以通过改变子句的顺序来解决问题,并修改"修复"你以前知道的变量。例如:
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.
答案 1 :(得分:1)
replace_word / 4被编写为效率的方式。为了“反转”它的语义,我看不到比使用辅助谓词更好的方法:
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)可以使用Old-New对....
试验:
?- replace_word('a','e',X,'gleve').
X = glava ;
X = glave ;
X = gleva ;
X = gleve ;
false.