在SWI Prolog中定义长度时出错

在SWI Prolog中定义长度时出错,prolog,swi-prolog,Prolog,Swi Prolog,我在一个名为test.pl的文件中定义了一个名为length的过程: 使用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

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

使用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的过程吗?如果没有,为什么不能这样做

没错。长度/2是一个:长度?列表,如果Int表示列表中的元素数,则Int为真。所以这个名字已经被使用了。

没错。长度/2是一个:长度?列表,如果Int表示列表中的元素数,则Int为真。因此,这个名称已经被使用。

length/2没有在Prolog中定义,而是本机高效列表实现上的浅层接口的一部分。你应该使用指令

例如,保存在文件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 

length/2没有在Prolog中定义,但它是本机高效列表实现上的浅层接口的一部分。你应该使用指令

例如,保存在文件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 

还有SWI Prolog定义的其他谓词,例如成员、附加等,在我尝试“覆盖”它们时不会导致类似错误。为什么这只发生在长度上?@Flux我不知道。最有可能造成这种差异的原因是成员和附加是,并且您的代码优先于自动加载。另一种可能是,您定义的成员/3与现有成员/2没有冲突。SWI Prolog还定义了其他谓词,例如成员、附加等,在我尝试“覆盖”它们时不会导致类似错误。为什么这只发生在长度上?@Flux我不知道。最有可能造成这种差异的原因是成员和附加是,并且您的代码优先于自动加载。另一种可能是,您定义的成员/3与现有成员/2没有冲突。