【问题标题】:Arguments are not sufficiently instantiated SWI-Prolog参数没有充分实例化 SWI-Prolog
【发布时间】:2012-07-26 14:09:03
【问题描述】:

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

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

【问题讨论】:

    标签: prolog swi-prolog instantiation-error


    【解决方案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.
    

    【讨论】:

    • 问题是我需要每一个 X可以导致'gleve',这包括'gleve','glave','gleva'和'glava'
    • @Diego Sevilla:除非您使用 nonvar(Orig) 替代,否则剪裁是必要的。但使用 if-then-else 可能会更好。
    【解决方案2】:

    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),可以使用一对 Old-New....

    测试:

    ?- replace_word('a','e',X,'gleve').
    X = glava ;
    X = glave ;
    X = gleva ;
    X = gleve ;
    false.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多