1%   Package: visualize_tree
    2%   Author : Helmut Simonis, Mats Carlsson
    3%   Updated: 18 March 2010
    4%   Purpose: labeling with support for visualization for SICStus Prolog
    5%   Development version, in flux!
    6
    7:- module(visualize_tree, [
    8	root/1,
    9	solution/1,
   10	try/4, % questionable
   11	number_variables/3,
   12	number_variables/4,
   13	name_variables/4,
   14	name_variables/5,
   15	extract_array/4,
   16	extract_array/5,
   17	create_visualization/2,
   18	add_visualizer/3,
   19	draw_visualization/1,
   20	draw_visualization/2,
   21	close_visualization/1,
   22	label_visualization/3
   23	]).

Utility LOGICMOO_CPVIZ

This module includes utilities for visualizing prolog data.

   32:- use_module(library(types)).   33:- use_module(library(timeout)).   34:- use_module(library(lists)).   35:- use_module(library(clpfd)).   36:- use_module(structures).   37:- use_module(visualization).   38
   39root(Handle) :-
   40	get_struct(visualization(tree_stream:Stream), Handle),
   41        set_node_cnt(0), % we are in tree search
   42        format(Stream,'<root id=\"~d\"/>\n',[0]),
   43        draw_visualization(Handle).
   44
   45solution(Handle) :-
   46        draw_visualization(Handle),
   47	get_struct(visualization(tree_stream:Stream), Handle),
   48        current_node_cnt(Id),
   49        format(Stream,'<succ id=\"~d\"/>\n',[Id]).
   50
   51try(Handle,Name,Size,Value) :-
   52        new_node_cnt(Handle,Id,Parent,Stream),
   53        format(Stream,'<try id=\"~d\" parent=\"~d\" name=\"~w\" size=\"~d\" value=\"~d\" />\n',
   54               [Id,Parent,Name,Size,Value]).
   55
   56failure(Handle,Name,Size,Value) :-
   57        new_node_cnt(Handle,Id,Parent,Stream),
   58        format(Stream,'<fail id=\"~d\" parent=\"~d\" name=\"~w\" size=\"~d\" value=\"~d\" />\n',
   59               [Id,Parent,Name,Size,Value]).
   60
   61number_variables(Handle,L,Pairs) :-
   62	get_struct(visualization(var_arg:1,name_arg:2,focus_arg:2), Handle),
   63        (   foreach(X,L),
   64	    foreach(t(X,J),Pairs),
   65	    count(J,1,_)
   66	do  true
   67        ).
   68
   69number_variables(Handle,L,Group,Pairs) :-
   70	get_struct(visualization(var_arg:1,name_arg:2,focus_arg:3), Handle),
   71        (   foreach(X,L),
   72	    foreach(t(X,J,group(Group,J)),Pairs),
   73	    count(J,1,_),
   74	    param(Group)
   75	do  true
   76        ).
   77
   78name_variables(Handle,L,K,P) :-
   79	get_struct(visualization(var_arg:1,name_arg:2,focus_arg:3), Handle),
   80        (   foreach(X,L),
   81	    foreach(Y,K),
   82	    count(J,1,_),
   83	    foreach(t(X,Y,J),P)
   84	do  true
   85        ).
   86
   87name_variables(Handle,L,K,Group,P) :-
   88	get_struct(visualization(var_arg:1,name_arg:2,focus_arg:3), Handle),
   89        (   foreach(X,L),
   90	    foreach(Y,K),
   91	    count(J,1,_),
   92	    foreach(t(X,Y,group(Group,J)),P),
   93	    param(Group)
   94	do  true
   95        ).
   96
   97extract_array(Handle,col,Matrix,List) :- !,
   98	get_struct(visualization(var_arg:1,name_arg:2,focus_arg:3), Handle),
   99	transpose(Matrix, Transpose),
  100	(   foreach(Col,Transpose),
  101	    count(J,1,_),
  102	    fromto(1,K1,K3,_),
  103	    fromto(List,L1,L3,[])
  104	do  (   foreach(V,Col),
  105		count(I,1,_),
  106		count(K2,K1,K3),
  107		fromto(L1,[t(V,K2,I-J)|L2],L2,L3),
  108		param(J)
  109	    do  true
  110	    )
  111	).
  112extract_array(Handle,row,Matrix,List) :- !,
  113	get_struct(visualization(var_arg:1,name_arg:2,focus_arg:3), Handle),
  114	(   foreach(Row,Matrix),
  115	    count(I,1,_),
  116	    fromto(1,K1,K3,_),
  117	    fromto(List,L1,L3,[])
  118	do  (   foreach(V,Row),
  119		count(J,1,_),
  120		count(K2,K1,K3),
  121		fromto(L1,[t(V,K2,I-J)|L2],L2,L3),
  122		param(I)
  123	    do  true
  124	    )
  125	).
  126
  127extract_array(Handle,col,Group,Matrix,List) :- !,
  128	get_struct(visualization(var_arg:1,name_arg:2,focus_arg:3), Handle),
  129	transpose(Matrix, Transpose),
  130	(   foreach(Col,Transpose),
  131	    count(J,1,_),
  132	    fromto(1,K1,K3,_),
  133	    fromto(List,L1,L3,[]),
  134	    param(Group)
  135	do  (   foreach(V,Col),
  136		count(I,1,_),
  137		count(K2,K1,K3),
  138		fromto(L1,[t(V,K2,group(Group,I-J))|L2],L2,L3),
  139		param(J,Group)
  140	    do  true
  141	    )
  142	).
  143extract_array(Handle,row,Group,Matrix,List) :- !,
  144	get_struct(visualization(var_arg:1,name_arg:2,focus_arg:3), Handle),
  145	(   foreach(Row,Matrix),
  146	    count(I,1,_),
  147	    fromto(1,K1,K3,_),
  148	    fromto(List,L1,L3,[]),
  149	    param(Group)
  150	do  (   foreach(V,Row),
  151		count(J,1,_),
  152		count(K2,K1,K3),
  153		fromto(L1,[t(V,K2,group(Group,I-J))|L2],L2,L3),
  154		param(I,Group)
  155	    do  true
  156	    )
  157	).
  158
  159% NOTE: Terms are compound terms containing variables as well as annotations
  160% for visualization
  161label_visualization(Options, Terms, Handle) :-
  162	Goal = label_visualization(Options,Terms,Handle),
  163	prolog:get_module(Options, Options2, _),
  164	must_be(Options2, proper_list(callable), Goal, 1),
  165	clpfd:labeling_options(Options2, opt(leftmost,all,step(up,Handle),_,33554431,any),
  166			       opt(Sel,Sol,Enum,K,DU,TimeOut),
  167			       Terms, Goal),
  168	labeling(Sol, Terms, Sel, Enum, K, DU, TimeOut, Handle).
  169
  170labeling(all, Terms, Sel, Enum, K, DU, TO, Handle) :-
  171	nobb_labeling_top(TO, Terms, param(Sel,Enum), 0, K, nobb(DU), Handle).
  172labeling(minimize(Value,Goal), Terms, Sel, Enum, K, DU, TO, Handle) :-
  173	(   foreach(_,Terms),
  174	    foreach(0,Zeros)
  175	do  true
  176	),
  177	clpfd:'$fd_minint_maxint'(_Minint, Maxint),
  178	asserta(clpfd:incumbent(Maxint,Zeros), Ref),
  179	call_cleanup(bb_labeling_top(TO, Terms, Sel, Enum, 0, K,
  180				     bb(minimize(Value),Ref,Goal,DU), Handle),
  181	             erase(Ref)).
  182labeling(maximize(Value,Goal), Terms, Sel, Enum, K, DU, TO, Handle) :-
  183	(   foreach(_,Terms),
  184	    foreach(0,Zeros)
  185	do  true
  186	),
  187	clpfd:'$fd_minint_maxint'(Minint, _Maxint),
  188	asserta(clfpd:incumbent(Minint,Zeros), Ref),
  189	call_cleanup(bb_labeling_top(TO, Terms, Sel, Enum, 0, K,
  190				     bb(maximize(Value),Ref,Goal,DU), Handle),
  191	             erase(Ref)).
  192
  193bb_labeling_top(any, Terms, Sel, Enum, I, K, BB, Handle) :-
  194	BB = bb(MinMax,Ref,_,_), 
  195	bb_labeling(Terms, Sel, Enum, I, K, BB, Handle),
  196	bb_labeling_2(MinMax, Ref, Terms, Handle).
  197bb_labeling_top(time_out(Time,Flag), Terms, Sel, Enum, I, K, BB, Handle) :-
  198	BB = bb(MinMax,Ref,_,_), 
  199	time_out(clpfd:bb_labeling(Terms, Sel, Enum, I, K, BB, Handle), Time, Flag),
  200	bb_labeling_2(MinMax, Ref, Terms, Handle).
  201
  202bb_labeling(Terms, Sel, Enum, I, K, BB, Handle) :-
  203	BB = bb(MinMax,Ref,Goal,_),
  204	nobb_labeling(Terms, param(Sel,Enum), I, K, BB, Handle),
  205	arg(1, MinMax, Value),
  206	get_struct(visualization(var_arg:VarArg), Handle),
  207	(   foreach(Term,Terms),
  208	    foreach(Var,Variables),
  209	    param(VarArg)
  210	do  arg(VarArg, Term, Var)
  211	),
  212	(   var(Value) -> illarg(var, Goal, 1)
  213        ;   clpfd:'$fd_update_incumbent'(Ref, Value, Variables)
  214        ),
  215	fail.
  216bb_labeling(_, _, _, _, _, _, _).
  217
  218bb_labeling_2(minimize(ValueV), Ref, Terms, Handle) :-
  219	clause(clpfd:incumbent(Value,Tuple), true, Ref),
  220	clpfd:'$fd_minint_maxint'(_Minint, Maxint),
  221	Value < Maxint,
  222	get_struct(visualization(var_arg:VarArg), Handle),
  223	(   foreach(Term,Terms),
  224	    foreach(Var,Variables),
  225	    param(VarArg)
  226	do  arg(VarArg, Term, Var)
  227	),
  228	clpfd:fd_unify([ValueV|Variables], [Value|Tuple]).
  229bb_labeling_2(maximize(ValueV), Ref, Terms, Handle) :-
  230	clause(clpfd:incumbent(Value,Tuple), true, Ref),
  231	clpfd:'$fd_minint_maxint'(Minint, _Maxint),
  232	Value > Minint,
  233	get_struct(visualization(var_arg:VarArg), Handle),
  234	(   foreach(Term,Terms),
  235	    foreach(Var,Variables),
  236	    param(VarArg)
  237	do  arg(VarArg, Term, Var)
  238	),
  239	clpfd:fd_unify([ValueV|Variables], [Value|Tuple]).
  240
  241nobb_labeling_top(any, L, Param, I, K, BB, Handle) :-
  242	nobb_labeling(L, Param, I, K, BB, Handle).
  243nobb_labeling_top(time_out(Time,Flag), L, Param, I, K, BB, Handle) :-
  244	time_out(clpfd:nobb_labeling(L, Param, I, K, BB, Handle), Time, Flag).
  245
  246nobb_labeling([], _, K, K, _, _).
  247nobb_labeling(LL, Param, I, K, BB, Handle) :-
  248	LL = [T|_],
  249	get_struct(visualization(var_arg:VarArg), Handle),
  250	arg(VarArg, T, X),
  251	var(X), !,
  252	Param = param(Selector,Enum),
  253	delete(Selector, LL, T1, L1, VarArg),
  254	labeling_cont(Enum, T1, L1, LL, R, BB, BB1, Handle),
  255	J is I+1,
  256	nobb_labeling(R, Param, J, K, BB1, Handle).
  257nobb_labeling([_|L], Param, I, K, BB, Handle) :-
  258	nobb_labeling(L, Param, I, K, BB, Handle).
  259
  260labeling_cont(value(Enum), T, L, LL, LL, BB, BB1, Handle) :-
  261	get_struct(visualization(var_arg:VarArg), Handle),
  262	arg(VarArg, T, X),
  263	call(Enum, X, L, BB, BB1, V), % API change !!!
  264	try_or_fail(T, V, Handle).
  265labeling_cont(enum(Arg), T, L, _LL, L, BB, BB1, Handle) :-
  266	get_struct(visualization(var_arg:VarArg), Handle),
  267	arg(VarArg, T, X),
  268	clpfd:get_fd_domain(X, Dom),
  269	Dom = dom(Set,_Min,_Max,_Size),
  270	clpfd:indomain(Arg, V, Set, BB, BB1),
  271	try_or_fail(T, V, Handle).
  272labeling_cont(step(Arg), T, L, LL, R, BB, BB1, Handle) :-
  273	labeling_cont(enum(Arg), T, L, LL, R, BB, BB1, Handle).
  274labeling_cont(bisect(Arg), T, L, LL, R, BB, BB1, Handle) :-
  275	labeling_cont(enum(Arg), T, L, LL, R, BB, BB1, Handle).
  276% NOT IMPLEMENTED: step-search, dichotomic search
  277% labeling_cont(step(Arg), X, L, LL, R, BB, BB1, Handle) :-
  278% 	clpfd:get_fd_domain(X, Dom),
  279% 	Dom = dom(_Set,Min,Max,_Size),
  280% 	clfpd:labeling_step(Arg, Min, Max, V, L, LL, R, BB, BB1),
  281% 	try_or_fail(X, V, Handle).
  282% labeling_cont(bisect(Arg), X, _L, LL, LL, BB, BB1, Handle) :-
  283% 	clpfd:get_fd_domain(X, Dom),
  284% 	Dom = dom(_Set,Min,Max,_Size),
  285% 	clpfd:labeling_bisect(Arg, Min, Max, V, BB, BB1),
  286% 	try_or_fail(X, V, Handle).
  287
  288try_or_fail(Term, V, Handle) :-
  289	get_struct(visualization(var_arg:VarArg,
  290				 name_arg:NameArg,
  291				 focus_arg:FocusArg), Handle),
  292        arg(VarArg, Term, X),
  293	arg(NameArg, Term, Name),
  294	arg(FocusArg, Term, Focus),
  295	fd_size(X, Size),
  296        (   X = V
  297	->  try(Handle, Name, Size, V),
  298	    focus_option(Focus, FocusOption),
  299	    draw_visualization(Handle, FocusOption)
  300	;   failure(Handle, Name, Size, V),
  301	    fail_option(Focus, V, FailOption),
  302	    draw_visualization(Handle, FailOption),
  303	    fail
  304	).
  305
  306focus_option(group(Group,V),[focus(Group,V)]) :- !.
  307focus_option(V,[focus(1,V)]).
  308
  309fail_option(group(Group,V),Value,[failed(Group,V,Value)]) :- !.
  310fail_option(V,Value,[failed(1,V,Value)]).
  311
  312delete(leftmost, [X|L], X, L, _VarArg).
  313delete(min, LL, T1, LL, VarArg) :-
  314	LL = [T|L],
  315	arg(VarArg, T, X),
  316	fd_min(X, Rank),
  317	deletemin(L, Rank, T, T1, VarArg).
  318delete(max, LL, T1, LL, VarArg) :-
  319	LL = [T|L],
  320	arg(VarArg, T, X),
  321	fd_max(X, Rank),
  322	deletemax(L, Rank, T, T1, VarArg).
  323delete(ff, LL, T1, LL, VarArg) :-
  324	LL = [T|L],
  325	arg(VarArg, T, X),
  326	clpfd:fd_rank(X, Rank),
  327	deleteff(L, Rank, T, T1, VarArg).
  328delete(ffc, LL, T1, LL, VarArg) :-
  329	LL = [T|L],
  330	arg(VarArg, T, X),
  331	clpfd:fd_rankc(X, Rank),
  332	deleteffc(L, Rank, T, T1, VarArg).
  333delete(variable(Sel), LL, T1, L1, VarArg) :-
  334	call(Sel, LL, T1, L1, VarArg). % API change !!!
  335
  336% deletexx(+Vars, +Rank, +Best, -Var, +VarArg).
  337
  338deletemin([], _, T, T, _VarArg).
  339deletemin([T0|L0], Rank1, T1, T, VarArg) :-
  340	arg(VarArg, T0, X),
  341	(   integer(X)
  342	->  deletemin(L0, Rank1, T1, T, VarArg)
  343	;   fd_min(X, Rank0),
  344	    (   Rank0 < Rank1
  345	    ->  deletemin(L0, Rank0, T0, T, VarArg)
  346	    ;   deletemin(L0, Rank1, T1, T, VarArg)
  347	    )
  348	).
  349
  350deletemax([], _, T, T, _VarArg).
  351deletemax([T0|L0], Rank1, T1, T, VarArg) :-
  352	arg(VarArg, T0, X),
  353	(   integer(X)
  354	->  deletemax(L0, Rank1, T1, T, VarArg)
  355	;   fd_max(X, Rank0),
  356	    (   Rank0 > Rank1
  357	    ->  deletemax(L0, Rank0, T0, T, VarArg)
  358	    ;   deletemax(L0, Rank1, T1, T, VarArg)
  359	    )
  360	).
  361
  362deleteff(_ , 2, T, T, _VarArg) :- !.
  363deleteff([], _, T, T, _VarArg).
  364deleteff([T0|L0], Rank1, T1, T, VarArg) :-
  365	arg(VarArg, T0, X),
  366	(   integer(X)
  367	->  deleteff(L0, Rank1, T1, T, VarArg)
  368	;   clpfd:fd_rank(X, Rank0),
  369	    (   Rank0 @< Rank1
  370	    ->  deleteff(L0, Rank0, T0, T, VarArg)
  371	    ;   deleteff(L0, Rank1, T1, T, VarArg)
  372	    )
  373	).
  374
  375deleteffc([], _, T, T, _).
  376deleteffc([T0|L0], Rank1, T1, T, _VarArg) :-
  377	arg(VarArg, T0, X),
  378	(   integer(X)
  379	->  deleteffc(L0, Rank1, T1, T, VarArg)
  380	;   clpfd:fd_rankc(X, Rank0),
  381	    (   Rank0 @< Rank1
  382	    ->  deleteffc(L0, Rank0, T0, T, VarArg)
  383	    ;   deleteffc(L0, Rank1, T1, T, VarArg)
  384	    )
  385	)