【问题标题】:Error when defining length in SWI Prolog在 SWI Prolog 中定义长度时出错
【发布时间】:2018-12-05 16:41:13
【问题描述】:

我在一个名为test.pl的文件中定义了一个名为length的过程:

% Finds the length of a list.
length([], 0).
length([_ | Tail], N) :-
    length(Tail, N1),
    N is 1 + N1.

使用SWI-Prolog(prolog test.pl)运行程序时,出现如下错误:

ERROR: /home/user/test.pl:2:
    No permission to modify static procedure `length/2'
    Defined at /usr/lib/swi-prolog/boot/init.pl:3496
ERROR: /home/user/test.pl:3:
    No permission to modify static procedure `length/2'
    Defined at /usr/lib/swi-prolog/boot/init.pl:3496

我尝试将程序名称从length 更改为mylength,错误消失了。这个错误是什么意思?我可以定义一个名为length 的过程吗?如果没有,为什么不能完成?

【问题讨论】:

    标签: prolog swi-prolog


    【解决方案1】:

    没错。 length/2built-in predicate:如果 Int 表示 List 中的元素数量,则 length(?List, ?Int) 为 True。所以这个名字已经被使用了。

    【讨论】:

    • 还有其他由 SWI Prolog 定义的谓词(例如 memberappend 等)在我尝试“覆盖”它们时不会导致类似的错误。为什么这只发生在 length 上?
    • @Flux 我不知道。最可能负责的区别是memberappendpart of the lists library,并且您的代码优先于自动加载。另一个可能是您定义了,例如member/3,它与现有的member/2 没有冲突。
    【解决方案2】:

    length/2 没有在 Prolog 中定义,但它是原生(高效)列表实现的浅接口的一部分。你应该使用指令redefine_system_predicate

    例如,保存在文件 redef_length.pl

    :- redefine_system_predicate(length(?,?)).
    
    % Finds the length of a list.
    length([], 0).
    length([_ | Tail], N) :-
        length(Tail, N1),
        N is 1 + N1.
    

    那就咨询吧

    ?- [test/prolog/redef_length].
    true.
    
    ?- trace.
    true.
    
    [trace]  ?- length(A,B).
       Call: (8) length(_1476, _1478) ? creep
       Exit: (8) length([], 0) ? creep
    A = [],
    B = 0 ;
       Redo: (8) length(_1476, _1478) ? creep
       Call: (9) length(_1718, _1738) ? creep
       Exit: (9) length([], 0) ? creep
       Call: (9) _1478 is 1+0 ? creep
       Exit: (9) 1 is 1+0 ? creep
       Exit: (8) length([_1716], 1) ? creep
    A = [_1716],
    B = 1 
    

    【讨论】:

      猜你喜欢
      • 2011-04-26
      • 2011-11-11
      • 2015-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多