:- use_module(library(clpfd)).

:- use_module(library(random)).

:- compile(proptest_common).


setup_and_solve(inc, AB, N, Vars, OrderedPairs) :-
	setup_bounds(Vars, N),
	setup_ordered(OrderedPairs, AB).
setup_and_solve(batch, _AB, _N, _Vars, _OrderedPairs) :-
	write('Batch not supported'), nl,
	abort.


setup_bounds([], _N).
setup_bounds([X|Xs], N) :-
	X in 0..N,
	setup_bounds(Xs, N).

setup_ordered([], _AB).
setup_ordered([Y1-Y2|Is], AB) :-
	Y2 #>= Y1+AB,
	setup_ordered(Is, AB).


%----------------------------------------------------------------------
% Test harness auxiliaries which are not built-in in SICStus
%----------------------------------------------------------------------

% SICStus timing: need to add back garbage collection time.
%                 stack shifting times are not added as ECLiPSe does not
%                 stack shift

cputime(T) :- 
	statistics(runtime,[T0,_]), 
	statistics(garbage_collection, [_,_,GC]), 
	T is (T0+GC)/1000.

% Missing lists predicates. Taken from ECLiPSe

splice([], Rs, LRs) :- !, LRs=Rs.
splice(Ls, [], LRs) :- !, LRs=Ls.
splice([L|Ls], [R|Rs], [L,R|LRs]) :-
	splice(Ls, Rs, LRs).

% Shuffle a list
% This neat method seems to be from Lee Naish
shuffle(L, R) :-
	write('WARNING: this uses a different random function from ECLiPSe'),
	nl,
        add_random_keys(L, KL),
        keysort(KL, KR),
        rm_keys(KR, R).

        % add random key to each list element
add_random_keys([], []).
add_random_keys([A|L], [K-A|KL]) :-
        sics_random(K),
        add_random_keys(L, KL).

        % remove keys from association list
rm_keys([], []).
rm_keys([_K-A|KL], [A|L]) :-
        rm_keys(KL, L).


sics_random(N) :-
	write('WARNING: this uses a different random function from ECLiPSe'),
	nl,
	random(0, 4294967295/*2^32-1*/, N).

seed(X) :-
	setrand(rand(X,X,X)).


