1
votes

I have defined a procedure named length in a file named test.pl:

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

When the program is run using SWI-Prolog (prolog test.pl), the following error appears:

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

I tried changing the name of the procedure from length to mylength, and the error disappears. What does this error mean? Can I define a procedure named length? If not, why can't it be done?

2

2 Answers

2
votes

That's right. length/2 is a built-in predicate: length(?List, ?Int) is True if Int represents the number of elements in List. So the name is already used.

2
votes

length/2 isn't defined in Prolog, but it's instead part of the shallow interface over native (high efficient) lists implementation. You should use the directive redefine_system_predicate.

For instance, save in a file 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.

then consult it

?- [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