This utility shows constraint propagation at work. Goal should be a constraint involving domain variables. The Goal is first called, i.e. the constraint is being set up. Then (if it does not fail), some of its variables are reduced in their domains, which may lead to the Goal waking up and propagating the domain changes. This process is repeated until either the Goal fails, or all variables are instantiated and the goal succeeds.
Throughout the process, a protocol is printed to the Out stream. Output lines are marked with C (initial call), P (propagation result) or L (imposed domain reduction, or labeling), and display the corresponding state of the constraint with its variable domains.
Domain reductions are chosen randomly: in each step, 1 to 3 variables are selected randomly, and each receives a random domain reduction (upper and/or lower bound). To create a reproducible sequence, it is recommended to invoke seed/1 beforehand.
?- [X,Y]::1..3, random_bound_reduction_test(output, alldifferent([X,Y])). C alldifferent([_{1 .. 3}, _{1 .. 3}]) P alldifferent([_{1 .. 3}, _{1 .. 3}]) L alldifferent([_{1 .. 3}, _{[1, 2]}]) L alldifferent([_{[1, 2]}, 1]) P alldifferent([2, 1]) yes.