Get length of list in prolog in non-recursive way
Here's an iterative solution that uses a predicate repeat/0
:
getlength(L,N) :-
retractall(getlength_res(_)),
assert(getlength_res(0)),
retractall(getlength_list(_)),
assert(getlength_list(L)),
repeat,
(
getlength_list([]), !, getlength_res(N)
;
retract(getlength_res(V)), W is V + 1, assert(getlength_res(W)),
retract(getlength_list([_|T])), assert(getlength_list(T)), fail
).
This solution creates and removes facts getlength_res/1
and getlength_list/1
, as it scans through the list, replacing the old list with the shorter one and the old number with the number that is larger in each iteration repeat/0
. In a sense, two dynamically asserted / retracted facts behave very much like assignable variables of imperative languages.
In general, iterative solutions in Prolog are harder to read than their recursive counterparts. This shouldn't come as a surprise, given that anything that influences the assignment wording of an imperative programming language runs counter to Prolog's design philosophy.
source to share
You are asking the wrong question :)
But seriously: the only sane way to find the length of a list is to use the inline length/2
. How this is implemented does not matter - its semantics are more important:
?- length([a,b], 2). true. ?- length([a,b], 4). false. ?- length([a,b,c], Len). Len = 3. ?- length(List, 3). List = [_G937, _G940, _G943]. ?- length(List, Len). List = [], Len = 0 ; List = [_G949], Len = 1 ; List = [_G949, _G952], Len = 2 . % and so on
In any case, this is not simplified. Any other way of finding the length of a list, or checking the length of a list, or creating a list of a specific length, or enumerating lists of increasing length would be less "easy" than using length/2
.
And then: learning in Prolog means learning length/2
, as well as other beautifully declarative builtins.
Splitting a list into segments of some length
I'm sure you can think of many other uses length/2
.