%   File   : BETWEEN.PL
%   Author : R.A.O'Keefe
%   Updated: 4 October 1984, 11-8-87
%   Purpose: Generate integers.

between(L, U, N) :-
	nonvar(N),
	!,
	integer(L),
	integer(U),
	integer(N),
	L =< N,
	N =< U.

between(L, U, N) :-
	integer(L),
	integer(U),
	L =< U,
	between1(L, U, N).

between1(L, _, L).

between1(L, U, N) :-
	L < U,
	M is L+1,
	between1(M, U, N).

%   gen_arg(N, Term, Arg)
%   is exactly like arg(N, Term, Arg), except that it will generate
%   solutions for N by backtracking (will work when N is a variable).

gen_arg(N, Term, Arg) :-
	functor(Term, _, Arity),
	between(1, Arity, N),
	arg(N, Term, Arg).

% Original by R O'Keefe
%
% gen_nat(+X)	 True if X is a natural number, false otherwise
% gen_nat(-X)	 Instantiates X to 0, then 1, 2, 3, 4...
%
% gen_nat(+L,-N) Instantiates N to L, then L+1, L+2...
% gen_nat(+L,+N) True if N >= L
% gen_nat(-L,+N) ** Succeeds with L = N , then LOOPS **
%
% gen_int(-X)	 Instantiates X to 0, then 1, -1, 2, -2, 3, -3...

gen_nat(N) :-			% gen-erate nat-ural
	nonvar(N),		% if we aren't to generate it
	!,			% demand that it
	integer(N),		% be an integer
	N >= 0.			% and non-negative.

gen_nat(N) :-			% otherwise, generate an
	gen_nat(0, N).		% integer >= 0
 
 
gen_nat(L, L).

gen_nat(L,N) :-			% Bug fix  Ken Johnson 6-5-87
	nonvar(L),		% Where both args are instantiated
	nonvar(N),		% just test N >= L.
	integer(L),		% Avoids an infinite loop
	integer(N),		% where N < L
	!,
	N >= L.

gen_nat(L, N) :-		% generate natural > L
	succ(L,M),
	gen_nat(M, N).		% generate natural >= M
 
 

gen_int(I) :-			% gen-erate int-eger
	nonvar(I),		% if we aren't to generate it
	!,			% demand that it is an integer.
	integer(I).
gen_int(0).			% generate 0
gen_int(I) :-			% generate +/- N for N > 0
	gen_nat(1, N),
	(   I = N
	;   I is -N
	).