10.15.4.5 Showing Selected Constraints (advanced version)

Suppose that you want to give the constraints that you are interested in as an argument to the visualizer, instead of defining them in a table. The following visualizer implements this.

%% filter_events(+CtrSpecs, +Constraint, +Actions):  This predicate will
%%   only show constraint events if they match an element in the list CtrSpecs,
%%   or if CtrSpecs is wrapped in -/1, all the non-matching events will
%%   be shown.
%%   CtrSpecs can contain the following types of elements:
%%     ctr_name             - matches all constraints of the given name
%%     ctr_name/arity       - matches constraints with the given name and arity
%%     ctr_name(…args…) - matches constraints unifyable with the given term
%%
%%   For the selected events fdbg_show(Constraint, Actions) is called.
%%   This visualizer can be specified when turning fdbg on, e.g.:
%%     fdbg_on([constraint_hook(filter_events([count/4]))]), or
%%     fdbg_on([constraint_hook(filter_events(-[in_set]))]).
filter_events(CtrSpecs, Constraint, Actions) :-
        filter_events(CtrSpecs, fdbg_show, Constraint, Actions).

%% filter_events(+CtrSpecs, +Visualizer, +Constraint, +Actions):  Same as
%%   the above predicate, but the extra argument Visualizer specifies the
%%   predicate to be called for the selected events (in the same form as
%%   in the constraint_hook option, i.e. without the last two arguments). E.g.
%%     fdbg_on([constraint_hook(filter_events([count/4],my_show))]).
filter_events(-CtrSpecs, Visualizer, Constraint, Actions) :- !,
        \+ show_constraint(CtrSpecs, Constraint),
        call(Visualizer, Constraint, Actions).
filter_events(CtrSpecs, Visualizer, Constraint, Actions) :-
        show_constraint(CtrSpecs, Constraint),
        call(Visualizer, Constraint, Actions).

show_constraint([C|_], Constraint) :-
        matches(C, Constraint), !.
show_constraint([_|Cs], Constraint) :-
        show_constraint(Cs, Constraint).

matches(Name/Arity, Constraint) :- !,
        functor(Constraint, Name, Arity).
matches(Name, Constraint) :-
        atom(Name), !,
        functor(Constraint, Name, _).
matches(C, Constraint) :-
        C = Constraint.

Here is a session using the visualizer, filtering out everything but all_distinct/2 constraints:

| ?- [library('clpfd/examples/suudoku')].
[…]
| ?- fdbg_on([constraint_hook(filter_events([all_distinct/2]))]).
% The clp(fd) debugger is switched on
% advice
| ?- suudoku([], 1, domain).
all_distinct([1,<fdvar_1>,<fdvar_2>,8,<fdvar_3>,
               4,<fdvar_4>,<fdvar_5>,<fdvar_6>],[consistency(domain)])
    fdvar_1 = 1..9 -> (2..3)\/(5..7)\/{9}
    fdvar_2 = 1..9 -> (2..3)\/(5..7)\/{9}
    fdvar_3 = 1..9 -> (2..3)\/(5..7)\/{9}
    fdvar_4 = 1..9 -> (2..3)\/(5..7)\/{9}
    fdvar_5 = 1..9 -> (2..3)\/(5..7)\/{9}
    fdvar_6 = 1..9 -> (2..3)\/(5..7)\/{9}

[…]

all_distinct([7,6,2,5,8,4,1,3,9],[consistency(domain)])
    Constraint exited.
1 5 6 8 9 4 3 2 7 
9 2 8 7 3 1 4 5 6 
4 7 3 2 6 5 9 1 8 
3 6 2 4 1 7 8 9 5 
7 8 9 3 5 2 6 4 1 
5 1 4 9 8 6 2 7 3 
8 3 1 5 4 9 7 6 2 
6 9 7 1 2 3 5 8 4 
2 4 5 6 7 8 1 3 9 
yes
% advice
| ?- fdbg_off.
% The clp(fd) debugger is switched off

In the next session, all constraints named all_distinct are ignored, irrespective of arity. Also, we explicitly specified the visualizer to be called for the events that are kept (here, we have written the default, fdbg_show, so the actual behavior is not changed).

| ?- [library('clpfd/examples/suudoku')].
[…]
| ?- fdbg_on([constraint_hook(filter_events(-[all_distinct],fdbg_show))]).
% The clp(fd) debugger is switched on
% advice
| ?- suudoku([], 1, domain).
domain([1,<fdvar_1>,<fdvar_2>,8,<fdvar_3>, …, 
        <fdvar_50>,<fdvar_51>,9],1,9)
    fdvar_1 = inf..sup -> 1..9
    fdvar_2 = inf..sup -> 1..9
    …
    fdvar_50 = inf..sup -> 1..9
    fdvar_51 = inf..sup -> 1..9
    Constraint exited.

[…]
1 5 6 8 9 4 3 2 7 
9 2 8 7 3 1 4 5 6 
4 7 3 2 6 5 9 1 8 
3 6 2 4 1 7 8 9 5 
7 8 9 3 5 2 6 4 1 
5 1 4 9 8 6 2 7 3 
8 3 1 5 4 9 7 6 2 
6 9 7 1 2 3 5 8 4 
2 4 5 6 7 8 1 3 9 
yes
% advice
| ?- fdbg_off.
% The clp(fd) debugger is switched off

In the last session, we specify a list of constraints to ignore, using a pattern to select the appropriate constraints. Since all constraints in the example match one of the items in the given list, no events are printed.

| ?- [library('clpfd/examples/suudoku')].
[…]
| ?- fdbg_on([constraint_hook(filter_events(-[domain(_,1,9),all_distinct]))]).
% The clp(fd) debugger is switched on
% advice
| ?- suudoku([], 1, domain).
1 5 6 8 9 4 3 2 7 
9 2 8 7 3 1 4 5 6 
4 7 3 2 6 5 9 1 8 
3 6 2 4 1 7 8 9 5 
7 8 9 3 5 2 6 4 1 
5 1 4 9 8 6 2 7 3 
8 3 1 5 4 9 7 6 2 
6 9 7 1 2 3 5 8 4 
2 4 5 6 7 8 1 3 9 
yes
% advice
| ?- fdbg_off.
% The clp(fd) debugger is switched off


Send feedback on this subject.