参数没有充分实例化SWI-Prolog

时间:2012-07-27 20:57:34

标签: prolog swi-prolog instantiation-error

我尝试编写一个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

我可以想象是什么导致了这个问题,但它有办法吗?

2 个答案:

答案 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)

由于SWI-Prolog对原子的一流处理,

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.