:- module(fd_prop_test_util).
:- export random_bound_reduction_test / 2.
:- tool(random_bound_reduction_test / 2, random_bound_reduction_test_ / 3).
:- export random_bound_reduction_test / 3.
:- tool(random_bound_reduction_test / 3, random_bound_reduction_test_ / 4).
:- export random_reduce_until_ground / 3.
:- export make_n_random_variables / 4.
:- export random_int_between / 3.
:- export make_n_random_seeds / 2.
:- comment(categories, ["Development Tools"]).
:- comment(summary, "Tools for testing global constraints").
:- comment(author, "Joachim Schimpf, Coninfer Ltd").
:- comment(copyright, "Joachim Schimpf, Coninfer Ltd").
:- comment(date, "$Date: 2013/01/27 23:24:26 $").
:- comment(make_n_random_seeds / 2, [summary : "Create random seeds for seed/1", amode : (make_n_random_seeds(+, -) is det), args : ["NSeeds" : "Number of seeds (integer)", "Seeds" : "List of seeds (output)"]]).
:- comment(make_n_random_variables / 4, [summary : "Create random domain variables", amode : (make_n_random_variables(+, +, +, -) is det), args : ["NVars" : "Number of variables to create (integer)", "Min" : "Minimum lower domain bound (integer)", "Max" : "Maximum upper domain bound (integer)", "Vars" : "List of variables (output)"]]).
:- comment(random_bound_reduction_test / 2, [summary : "Run and keep waking a constraint until ground", amode : (random_bound_reduction_test(+, +) is det), args : ["Out" : "An output stream for printing the execution protocol", "Goal" : "A goal, usually a constraint with domain variables"], see_also : [random_bound_reduction_test / 3], desc : html("<P>\n    This utility shows constraint propagation at work.  Goal should be\n    a constraint involving domain variables.  The Goal is first called,\n    i.e. the constraint is being set up.  Then (if it does not fail),\n    some of its variables are reduced in their domains, which may lead\n    to the Goal waking up and propagating the domain changes.  This\n    process is repeated until either the Goal fails, or all variables\n    are instantiated and the goal succeeds.\n</P><P>\n    Throughout the process, a protocol is printed to the Out stream.\n    Output lines are marked with C (initial call), P (propagation result)\n    or L (imposed domain reduction, or labeling), and display the\n    corresponding state of the constraint with its variable domains.\n</P><P>\n    Domain reductions are chosen randomly: in each step, 1 to 3 variables\n    are selected randomly, and each receives a random domain reduction\n    (upper and/or lower bound).  To create a reproducible sequence, it\n    is recommended to invoke seed/1 beforehand.\n</P>"), eg : "\n    ?- [X,Y]::1..3, random_bound_reduction_test(output, alldifferent([X,Y])).\n    C alldifferent([_{1 .. 3}, _{1 .. 3}])\n    P alldifferent([_{1 .. 3}, _{1 .. 3}])\n    L alldifferent([_{1 .. 3}, _{[1, 2]}])\n    L alldifferent([_{[1, 2]}, 1])\n    P alldifferent([2, 1])\n    yes."]).
:- comment(random_bound_reduction_test / 3, [summary : "Run and keep waking a constraint until ground", amode : (random_bound_reduction_test(+, +, +) is det), args : ["Out" : "An output stream for printing the execution protocol", "Goal" : "A goal, usually a constraint with domain variables", "Vars" : "Subset of Goal's variables to be domain-reduced"], see_also : [random_bound_reduction_test / 2]]).
:- comment(random_int_between / 3, [summary : "Create random integer", amode : (random_int_between(+, +, -) is det), args : ["Min" : "Minimum value (integer)", "Max" : "Maximum value (integer)", "X" : "Random value (output integer)"]]).
