在SWI Prolog中定义长度时出错

时间:2018-06-26 21:37:26

标签: prolog swi-prolog

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

% 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的过程吗?如果没有,为什么不能完成?

2 个答案:

答案 0 :(得分:2)

是的。 length/2built-in predicate:如果 Int 表示 List <中的元素数,则 length(?List,?Int)为True。 / em>。因此,该名称已被使用。

答案 1 :(得分: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