:- module(_,_).
:- use_package(clpr).
% You can also try: :- use_package(clpq).

% -------------------------------------------------------------------
%% * CLP and search space reduction
%%   Generate and test vs. constrain and generate

%% ** Problem: find three consecutive numbers, e.g., in: 

p(11).   p(3).   p(7).   p(16).   p(15).   p(14).


% ** Simple generate and test in standard Prolog
solution_gen_test_prolog_1(X, Y, Z) :-
    p(X),
    p(Y),
    p(Z),
    prolog_test(X, Y, Z).

prolog_test(X, Y, Z) :-  Y is X + 1, Z is Y + 1.

% ?- time(solution_gen_test_prolog_1(X, Y, Z)).
% -> Seems to work well

% ** But, what if we have a larger search space?
%    We consider q/1 below. 

% ** Simple generate and test in standard Prolog
solution_gen_test_prolog(X, Y, Z) :-
    q(X),
    q(Y),
    q(Z),
    prolog_test(X, Y, Z).

% ?- time(solution_gen_test_prolog(X, Y, Z)).
% -> Now takes much longer!

% ** Simple generate and test in CLP
solution_gen_test_clp(X, Y, Z) :-
    q(X),
    q(Y),
    q(Z),
    clp_test(X, Y, Z).

clp_test(X, Y, Z) :-  Y .=. X + 1, Z .=. Y + 1.

% ?- time(solution_gen_test_clp(X, Y, Z)).
% -> Actually, takes longer than generate and test
%    in standard Prolog (constraint solving does
%    have overhead)

% ** Constrain and generate in CLP
solution_cons_gen_clp(X, Y, Z) :-
    clp_test(X, Y, Z), 
    q(X),
    q(Y),
    q(Z).

% ?- time(solution_cons_gen_clp(X, Y, Z)).
% -> Much better!

% ** Constrain and generate in standard Prolog?
solution_cons_gen_prolog(X, Y, Z) :-
    prolog_test(X, Y, Z),
    q(X),
    q(Y),
    q(Z).

% ?- time(solution_cons_gen_prolog(X, Y, Z)).
% -> Does not work!

% ** Alternative: pushing tests as close as possible
%    to generation.
solution_gen_and_early_test_prolog(X, Y, Z) :-
    q(X),
    Y is X + 1,
    q(Y),
    Z is Y + 1,
    q(Z).

% ?- time(solution_gen_and_early_test_prolog(X, Y, Z)).
% -> Works quite well! But can be harder / more work
%    than constrain and generate in realistic cases.


%% q/1: making the search space a little larger:
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).

q(11). q(3). q(7). q(16). q(15). q(14).

q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0). q(0).
