Implementing a `range` predicate

Directory: C:/Users/Groot
File: example.pl

:- module(example,
    [
        range/3
    ]).

range(From,Length,List) :-
    is_of_type(nonneg,From),
    is_of_type(nonneg,Length),
    var(List),
    !,
    range_(From,Length,List).

range(From,Length,List) :-
    var(From),
    var(Length),
    ground(List),
    !,
    List = [From|_],
    length(List,Length).

range_(_,0,[]) :- !.
range_(Current,Length0,[Current|T]) :-
    !,
    Length is Length0 - 1,
    Next is Current + 1,
    range_(Next,Length,T).

Example run

Welcome to SWI-Prolog (threaded, 64 bits, version 8.5.5)

?- working_directory(_,'C:/Users/Groot').
true.

?- [example].
true.

?- range(From,Length,[3,4,5,6]).
From = 3,
Length = 4.

?- range(3,4,L).
L = [3, 4, 5, 6].
1 Like