| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
					
						
							|  |  |  | %  Constraint Handling Rules			      version 2.2 % | 
					
						
							|  |  |  | %								  % | 
					
						
							|  |  |  | %  (c) Copyright 1998						  % | 
					
						
							|  |  |  | %  LMU, Muenchen						  % | 
					
						
							|  |  |  | %								  % | 
					
						
							|  |  |  | %  File:   trace.pl						  % | 
					
						
							|  |  |  | %  Author: Christian Holzbaur		christian@ai.univie.ac.at % | 
					
						
							|  |  |  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    2 Mechanisms: trace+leash, debug+spy | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Debugger integration issue: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      We could use conditional spypoints of the Prolog debugger | 
					
						
							|  |  |  |      to get hooked, but then we depend a lot on it ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      :- spypoint_condition( debug_event(E), P, chr:de(P,E)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Todo: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      -) module_wrap/3 for all terms (M as arg to debug_event) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      -) guard-fail = rule-delay reason? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :- dynamic spy_rule/2. | 
					
						
							|  |  |  | :- dynamic spy_constraint/2. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :- initialization | 
					
						
							|  |  |  | 	getval( debug, _) -> true ; setval( debug, off). | 
					
						
							|  |  |  | :- initialization | 
					
						
							|  |  |  | 	retractall( spy_rule(_,_)). | 
					
						
							|  |  |  | :- initialization | 
					
						
							|  |  |  | 	retractall( spy_constraint(_,_)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | chr_trace :- | 
					
						
							|  |  |  | 	setval( debug, trace), | 
					
						
							|  |  |  | 	what_is_on( informational). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | chr_notrace :- | 
					
						
							|  |  |  | 	setval( debug, off), | 
					
						
							|  |  |  | 	what_is_on( informational). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | chr_debug :- | 
					
						
							|  |  |  | 	setval( debug, debug), | 
					
						
							|  |  |  | 	what_is_on( informational). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | chr_nodebug :- | 
					
						
							|  |  |  | 	chr_notrace. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | chr_spy( constraints(Cs)) :- | 
					
						
							|  |  |  | 	parse_spy_constraints( Cs, L, []), | 
					
						
							|  |  |  | 	member( N/A, L), | 
					
						
							|  |  |  | 	assert( spy_constraint(N,A)), | 
					
						
							|  |  |  | 	fail. | 
					
						
							|  |  |  | chr_spy( rules(Rs)) :- | 
					
						
							|  |  |  | 	parse_spy_rules( Rs, L, []), | 
					
						
							|  |  |  | 	member( Handler:Rule, L), | 
					
						
							|  |  |  | 	assert( spy_rule(Rule,Handler)), | 
					
						
							|  |  |  | 	fail. | 
					
						
							|  |  |  | chr_spy( _) :- getval( debug, trace), !. | 
					
						
							|  |  |  | chr_spy( _) :- chr_debug. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | chr_nospy( rules(Rs)) :- | 
					
						
							|  |  |  | 	parse_spy_rules( Rs, L1, []), | 
					
						
							|  |  |  | 	member( Handler:Rule, L1), | 
					
						
							|  |  |  | 	retract( spy_rule(Rule,Handler)), | 
					
						
							|  |  |  | 	fail. | 
					
						
							|  |  |  | chr_nospy( constraints(Cs)) :- | 
					
						
							|  |  |  | 	parse_spy_constraints( Cs, L, []), | 
					
						
							|  |  |  | 	member( N/A, L), | 
					
						
							|  |  |  | 	retract( spy_constraint(N,A)), | 
					
						
							|  |  |  | 	fail. | 
					
						
							|  |  |  | chr_nospy( _). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | parse_spy_constraints( C) --> {var(C)}, !, [ _ ]. | 
					
						
							|  |  |  | parse_spy_constraints( (C,Cs)) --> | 
					
						
							|  |  |  | 	parse_spy_constraints( C), | 
					
						
							|  |  |  | 	parse_spy_constraints( Cs). | 
					
						
							|  |  |  | parse_spy_constraints( N) --> {atom(N)}, [ N/_ ]. | 
					
						
							|  |  |  | parse_spy_constraints( N/A) --> {atom(N),integer(A),A>0}, [ N/A ]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | parse_spy_rules( R) --> {var(R)}, !, [ _ ]. | 
					
						
							|  |  |  | parse_spy_rules( (R,Rs)) --> !, | 
					
						
							|  |  |  | 	parse_spy_rules( R), | 
					
						
							|  |  |  | 	parse_spy_rules( Rs). | 
					
						
							|  |  |  | parse_spy_rules( H:R) --> !, [ H:R ]. | 
					
						
							|  |  |  | parse_spy_rules( R) --> [ _:R ].		% any handler | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | chr_leash( Spec) :- | 
					
						
							|  |  |  | 	nonvar( Spec), | 
					
						
							|  |  |  | 	chr_leash( Spec, I), | 
					
						
							|  |  |  | 	setval( leashing, I), | 
					
						
							|  |  |  | 	what_is_leashed( informational). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | chr_leash( none,    0) :- !. | 
					
						
							|  |  |  | chr_leash( off,     0) :- !. | 
					
						
							|  |  |  | chr_leash( all,    -1) :- !. | 
					
						
							|  |  |  | chr_leash( default, I) :- !, chr_leash( 0, I, [call,wake,apply,exit,fail], []). | 
					
						
							|  |  |  | chr_leash( L,	    I) :- chr_leash( 0, I, L, []), !. | 
					
						
							|  |  |  | chr_leash( X,	    I) :- chr_leash( 0, I, [X], []). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | chr_leash( I, K) --> [call],   {J is I\/2'100000000}, chr_leash( J, K). | 
					
						
							|  |  |  | chr_leash( I, K) --> [wake],   {J is I\/2'010000000}, chr_leash( J, K). | 
					
						
							|  |  |  | chr_leash( I, K) --> [try],    {J is I\/2'001000000}, chr_leash( J, K). | 
					
						
							|  |  |  | chr_leash( I, K) --> [apply],  {J is I\/2'000100000}, chr_leash( J, K). | 
					
						
							|  |  |  | chr_leash( I, K) --> [exit],   {J is I\/2'000010000}, chr_leash( J, K). | 
					
						
							|  |  |  | chr_leash( I, K) --> [redo],   {J is I\/2'000001000}, chr_leash( J, K). | 
					
						
							|  |  |  | chr_leash( I, K) --> [fail],   {J is I\/2'000000100}, chr_leash( J, K). | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | chr_leash( I, K) --> [insert], {J is I\/2'000000010}, chr_leash( J, K). | 
					
						
							|  |  |  | chr_leash( I, K) --> [remove], {J is I\/2'000000001}, chr_leash( J, K). | 
					
						
							|  |  |  | chr_leash( I, I) --> []. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :- initialization | 
					
						
							|  |  |  | 	chr_leash( default, I), setval( leashing, I). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debug_stop( call(S), L, Why) :- | 
					
						
							|  |  |  | 	( L/\2'100000000 > 0 -> true | 
					
						
							|  |  |  | 	; spypoint_susp( S, Why) | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | debug_stop( wake(S), L, Why) :- | 
					
						
							|  |  |  | 	( L/\2'010000000 > 0 -> true | 
					
						
							|  |  |  | 	; spypoint_susp( S, Why) | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | debug_stop( exit(S), L, Why) :- | 
					
						
							|  |  |  | 	( L/\2'000010000 > 0 -> true | 
					
						
							|  |  |  | 	; spypoint_susp( S, Why) | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | debug_stop( redo(S), L, Why) :- | 
					
						
							|  |  |  | 	( L/\2'000001000 > 0 -> true | 
					
						
							|  |  |  | 	; spypoint_susp( S, Why) | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | debug_stop( fail(S), L, Why) :- | 
					
						
							|  |  |  | 	( L/\2'000000100 > 0 -> true | 
					
						
							|  |  |  | 	; spypoint_susp( S, Why) | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | debug_stop( insert(S), L, Why) :- | 
					
						
							|  |  |  | 	( L/\2'000000010 > 0 -> true | 
					
						
							|  |  |  | 	; spypoint_susp( S, Why) | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | debug_stop( remove(S), L, Why) :- | 
					
						
							|  |  |  | 	( L/\2'000000001 > 0 -> true | 
					
						
							|  |  |  | 	; spypoint_susp( S, Why) | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | debug_stop( try(H,R,_,Hs,_,_), L, Why)	 :- | 
					
						
							|  |  |  | 	( L/\2'001000000 > 0 -> true | 
					
						
							|  |  |  | 	; spy_rule(R,H) -> Why = r | 
					
						
							|  |  |  | 	; spypoint_head( Hs, Why) | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | debug_stop( apply(H,R,_,Hs,_,_), L, Why) :- | 
					
						
							|  |  |  | 	( L/\2'000100000 > 0 -> true | 
					
						
							|  |  |  | 	; spy_rule(R,H) -> Why = r | 
					
						
							|  |  |  | 	; spypoint_head( Hs, Why) | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | spypoint_susp( S, c) :- | 
					
						
							|  |  |  | 	S =.. [suspension,_,_,_,_,_,N|Args], | 
					
						
							|  |  |  | 	length( Args, A), | 
					
						
							|  |  |  | 	spy_constraint( N, A). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | spypoint_head( Hs, c) :- | 
					
						
							|  |  |  | 	member( H, Hs), | 
					
						
							|  |  |  | 	arg( 1, H, Term), | 
					
						
							|  |  |  | 	functor( Term, N, A), | 
					
						
							|  |  |  | 	spy_constraint( N, A). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debug_stop_reason( Why, _) :- nonvar( Why). | 
					
						
							|  |  |  | debug_stop_reason( Why, Event) :- var( Why), | 
					
						
							|  |  |  | 	( debug_stop( Event, 0, Why) -> | 
					
						
							|  |  |  | 	    true | 
					
						
							|  |  |  | 	; | 
					
						
							|  |  |  | 	    Why = ' ' | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | chr_debugging :- | 
					
						
							|  |  |  | 	what_is_on( help), | 
					
						
							|  |  |  | 	what_is_leashed( help), | 
					
						
							|  |  |  | 	what_spypoints( help). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | what_is_on( Type) :- | 
					
						
							|  |  |  | 	getval( debug, Mode), | 
					
						
							|  |  |  | 	print_message( Type, debug(Mode)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | what_is_leashed( Type) :- | 
					
						
							|  |  |  | 	getval( leashing, Leash), | 
					
						
							|  |  |  | 	findall( P, (chr_leash(0,K,[P],[]),K/\Leash>0), L), | 
					
						
							|  |  |  | 	print_message( Type, leash(L)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | what_spypoints( Type) :- | 
					
						
							|  |  |  | 	findall( rules(E), (spy_rule(R,H),(var(H)->E=R;E=H:R)), L0, L1), | 
					
						
							|  |  |  | 	findall( constraints(E), (spy_constraint(N,A),(var(A)->E=N;E=N/A)), L1, []), | 
					
						
							|  |  |  | 	sort( L0, Ls), | 
					
						
							|  |  |  | 	print_message( Type, spypoints(Ls)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % ----------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debug_event( Event) :- | 
					
						
							|  |  |  | 	getval( debug, State), | 
					
						
							|  |  |  | 	( State == off -> | 
					
						
							|  |  |  | 	    true | 
					
						
							|  |  |  | 	; | 
					
						
							|  |  |  | 	    debug_event( State, Event), | 
					
						
							|  |  |  | 	    debug_stack( Event) | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debug_event( trace, Event) :- | 
					
						
							|  |  |  | 	getval( leashing, L), | 
					
						
							|  |  |  | 	( debug_stop( Event, L, SpyInd) -> | 
					
						
							|  |  |  | 	    debug_stop_reason( SpyInd, Event), | 
					
						
							|  |  |  | 	    debug_show( SpyInd, Event), | 
					
						
							|  |  |  | 	    get_command( Cmd), | 
					
						
							|  |  |  | 	    debug_do( Cmd, Event, trace) | 
					
						
							|  |  |  | 	; | 
					
						
							|  |  |  | 	    debug_stop_reason( SpyInd, Event), | 
					
						
							|  |  |  | 	    debug_show( SpyInd, Event), | 
					
						
							|  |  |  | 	    errnl | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | debug_event( debug, Event) :- | 
					
						
							|  |  |  | 	( debug_stop( Event, 0, SpyInd) -> | 
					
						
							|  |  |  | 	    debug_show( SpyInd, Event), | 
					
						
							|  |  |  | 	    get_command( Cmd), | 
					
						
							|  |  |  | 	    debug_do( Cmd, Event, debug) | 
					
						
							|  |  |  | 	; | 
					
						
							|  |  |  | 	    true | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | debug_event( skip(N,S), Event) :- | 
					
						
							|  |  |  | 	stack_depth( M), | 
					
						
							|  |  |  | 	( M =< N, member( Event, [exit(_),fail(_)]) -> | 
					
						
							|  |  |  | 	    setval( debug, S), | 
					
						
							|  |  |  | 	    debug_event( S, Event) | 
					
						
							|  |  |  | 	; | 
					
						
							|  |  |  | 	    true | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | debug_event( off, _). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debug_stack( Event) :- Event = call(_), !, stack_push( Event). | 
					
						
							|  |  |  | debug_stack( Event) :- Event = wake(_), !, stack_push( Event). | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | debug_stack( Event) :- Event = apply(_,_,_,_,_,_), !, | 
					
						
							|  |  |  | 	stack_pop, | 
					
						
							|  |  |  | 	stack_push( Event). | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | debug_stack( exit(_)) :- !, stack_pop. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | debug_stack( _). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | stack_push( S) :- | 
					
						
							|  |  |  | 	get_dbg_state( Ref), | 
					
						
							|  |  |  | 	get_mutable( Stack, Ref), | 
					
						
							|  |  |  | 	update_mutable( [S|Stack], Ref). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | stack_pop :- | 
					
						
							|  |  |  | 	get_dbg_state( Ref), | 
					
						
							|  |  |  | 	get_mutable( [_|Stack], Ref), | 
					
						
							|  |  |  | 	update_mutable( Stack, Ref). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | stack_depth( Depth) :- | 
					
						
							|  |  |  | 	get_dbg_state( Ref), | 
					
						
							|  |  |  | 	get_mutable( Stack, Ref), | 
					
						
							|  |  |  | 	length( Stack, Depth). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | show_stack :- | 
					
						
							|  |  |  | 	get_dbg_state( Ref), | 
					
						
							|  |  |  | 	get_mutable( Stack, Ref), | 
					
						
							|  |  |  | 	length( Stack, N), | 
					
						
							|  |  |  | 	errwrite('Ancestors:'), errnl, | 
					
						
							|  |  |  | 	show_stack( Stack, N), errnl. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | show_stack( [],     _). | 
					
						
							|  |  |  | show_stack( [S|Ss], N) :- | 
					
						
							|  |  |  | 	M is N-1, | 
					
						
							|  |  |  | 	show_stack( Ss, M), | 
					
						
							|  |  |  | 	Spy = ' ', | 
					
						
							|  |  |  | 	( arg( 3, S, Hp) -> true ; Hp = '-' ), | 
					
						
							|  |  |  | 	functor( S, Port, _), | 
					
						
							|  |  |  | 	errformat( ' ~w ~|~t~d~4+ ~|~t~w~3+ ~|~p~t~7+', [Spy,N,Hp,Port]), | 
					
						
							|  |  |  | 	debug_show_event( S), | 
					
						
							|  |  |  | 	errnl. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debug_show( Spy, Event) :- | 
					
						
							|  |  |  | 	functor( Event, Port, _), | 
					
						
							|  |  |  | 	( arg( 3, Event, Hp) -> true ; Hp = '-' ), | 
					
						
							|  |  |  | 	stack_depth( Depth), | 
					
						
							|  |  |  | 	errformat( ' ~w ~|~t~d~4+ ~|~t~w~3+ ~|~p~t~7+', [Spy,Depth,Hp,Port]), | 
					
						
							|  |  |  | 	debug_show_event( Event). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debug_show_event( call(S)) :- | 
					
						
							|  |  |  | 	debug_susp_term( S, Term), errtab( 1), errprint( Term). | 
					
						
							|  |  |  | debug_show_event( wake(S)) :- | 
					
						
							|  |  |  | 	debug_susp_term( S, Term), errtab( 1), errprint( Term). | 
					
						
							|  |  |  | debug_show_event( exit(S)) :- | 
					
						
							|  |  |  | 	debug_susp_term( S, Term), errtab( 1), errprint( Term). | 
					
						
							|  |  |  | debug_show_event( redo(S)) :- | 
					
						
							|  |  |  | 	debug_susp_term( S, Term), errtab( 1), errprint( Term). | 
					
						
							|  |  |  | debug_show_event( fail(S)) :- | 
					
						
							|  |  |  | 	debug_susp_term( S, Term), errtab( 1), errprint( Term). | 
					
						
							|  |  |  | debug_show_event( remove(S)) :- | 
					
						
							|  |  |  | 	debug_susp_term( S, Term), errtab( 1), errprint( Term). | 
					
						
							|  |  |  | debug_show_event( insert(C)) :- | 
					
						
							|  |  |  | 	errtab( 1), errprint( C). | 
					
						
							|  |  |  | debug_show_event( try(Handler,Rule,_,Heads,_,_)) :- | 
					
						
							|  |  |  | 	errformat( ' ~p:~p @ ', [Handler,Rule]), | 
					
						
							|  |  |  | 	show_heads( Heads, 0, 0, _). | 
					
						
							|  |  |  | debug_show_event( apply(Handler,Rule,_,Heads,_,_)) :- | 
					
						
							|  |  |  | 	errformat( ' ~p:~p @ ', [Handler,Rule]), | 
					
						
							|  |  |  | 	show_heads( Heads, 0, 0, _). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debug_susp_term( S, Term#S) :- | 
					
						
							|  |  |  | 	S =.. [suspension,_,_,_,_,_,F|Args], | 
					
						
							|  |  |  | 	Term =.. [F|Args]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debug_do( 0'a, _, _) :- !, abort. | 
					
						
							|  |  |  | debug_do( 0'n, _, _) :- !, chr_notrace. | 
					
						
							|  |  |  | debug_do( 0'&, E, S) :- !, show_store( 0), debug_event( S, E). | 
					
						
							|  |  |  | debug_do( [0'&|_], E, S) :- !, show_store( 1), debug_event( S, E). | 
					
						
							|  |  |  | debug_do( 0'g, E, S) :- !, show_stack, debug_event( S, E). | 
					
						
							|  |  |  | debug_do( 0'., E, S) :- | 
					
						
							|  |  |  | 	dbg_at_rule( E, _, _), | 
					
						
							|  |  |  | 	!, | 
					
						
							|  |  |  | 	show_rule( E), | 
					
						
							|  |  |  | 	debug_event( S, E). | 
					
						
							|  |  |  | debug_do( 0'+, E, S) :- !, | 
					
						
							|  |  |  | 	( dbg_at_rule( E, Handler, Rule) -> | 
					
						
							|  |  |  | 	    chr_spy( rules( Handler:Rule)) | 
					
						
							|  |  |  | 	; dbg_at_constraint( E, N, A) -> | 
					
						
							|  |  |  | 	    chr_spy( constraints( N/A)) | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	debug_event( S, E). | 
					
						
							|  |  |  | debug_do( 0'-, E, S) :- !, | 
					
						
							|  |  |  | 	( dbg_at_rule( E, Handler, Rule) -> | 
					
						
							|  |  |  | 	    chr_nospy( rules( Handler:Rule)) | 
					
						
							|  |  |  | 	; dbg_at_constraint( E, N, A) -> | 
					
						
							|  |  |  | 	    chr_nospy( constraints( N/A)) | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	debug_event( S, E). | 
					
						
							|  |  |  | debug_do( 0'b, E, S) :- !, | 
					
						
							|  |  |  | 	setval( debug, off), | 
					
						
							|  |  |  | 	break, | 
					
						
							|  |  |  | 	setval( debug, S), | 
					
						
							|  |  |  | 	debug_event( S, E). | 
					
						
							|  |  |  | debug_do( 0' | 
					
						
							|  |  |  | 	     , _, _) :- !, setval( debug, trace). % CR = creep | 
					
						
							|  |  |  | debug_do( 0'c, _, _) :- !, setval( debug, trace). % creep | 
					
						
							|  |  |  | debug_do( 0'l, _, _) :- !, setval( debug, debug). % leap | 
					
						
							|  |  |  | debug_do( 0's, E, S) :- chr_skip( E, S, _), !.	% skip | 
					
						
							|  |  |  | debug_do( [0's,N], E, S) :- chr_skip( E, S, N), !. % skip | 
					
						
							|  |  |  | debug_do( 0'<, E, S) :- !, set_pd(10), debug_event( S, E). | 
					
						
							|  |  |  | debug_do( [0'<,N], E, S) :- !, set_pd(N), debug_event( S, E). | 
					
						
							|  |  |  | debug_do( 0'=, E, S) :- !, chr_debugging, debug_event( S, E). | 
					
						
							|  |  |  | debug_do( 0'?, E, S) :- !, dbg_help, debug_event( S, E). | 
					
						
							|  |  |  | debug_do( 0'h, E, S) :- !, dbg_help, debug_event( S, E). | 
					
						
							|  |  |  | debug_do( _,   E, S) :- | 
					
						
							|  |  |  | 	print_message( informational, wrong_option), | 
					
						
							|  |  |  | 	debug_event( S, E). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | chr_skip( E, S, K) :- E = exit(_), stack_depth( K), !, debug_event( S, E). | 
					
						
							|  |  |  | chr_skip( E, S, K) :- E = fail(_), stack_depth( K), !, debug_event( S, E). | 
					
						
							|  |  |  | chr_skip( _, S, K) :- | 
					
						
							|  |  |  | 	stack_depth( Depth), | 
					
						
							|  |  |  | 	( var(K) -> | 
					
						
							|  |  |  | 	    N is Depth+1 | 
					
						
							|  |  |  | 	; | 
					
						
							|  |  |  | 	    1 =< K, K =< Depth, | 
					
						
							|  |  |  | 	    N = K | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	setval( debug, skip(N,S)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | dbg_at_rule( try(Handler,Rule,_,_,_,_),   Handler, Rule). | 
					
						
							|  |  |  | dbg_at_rule( apply(Handler,Rule,_,_,_,_), Handler, Rule). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | dbg_at_constraint( E, N, A) :- | 
					
						
							|  |  |  | 	dbg_at_constraint( E, S), | 
					
						
							|  |  |  | 	S =.. [suspension,_,_,_,_,_,N|Args], | 
					
						
							|  |  |  | 	length( Args, A). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | dbg_at_constraint( call(S), S). | 
					
						
							|  |  |  | dbg_at_constraint( wake(S), S). | 
					
						
							|  |  |  | dbg_at_constraint( exit(S), S). | 
					
						
							|  |  |  | dbg_at_constraint( redo(S), S). | 
					
						
							|  |  |  | dbg_at_constraint( fail(S), S). | 
					
						
							|  |  |  | dbg_at_constraint( insert(S), S). | 
					
						
							|  |  |  | dbg_at_constraint( remove(S), S). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % numbervars binds variables ... | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | show_rule( Event) :- | 
					
						
							|  |  |  | 	Event =.. [Which,Handler,Rule,_,Heads,Guard,Body], | 
					
						
							|  |  |  | 	member( Which, [try,apply]), | 
					
						
							|  |  |  | 	current_handler( Handler, _), | 
					
						
							|  |  |  | 	!, | 
					
						
							|  |  |  | 	show_rule( Rule, Heads, Guard, Body). | 
					
						
							|  |  |  | show_rule( _). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | show_rule :- | 
					
						
							|  |  |  | 	chrcmp:rule( _, _, Name, Heads, Guard, Body, _), | 
					
						
							|  |  |  | 	numbervars( Heads/Name/Guard/Body, 0, _), | 
					
						
							|  |  |  | 	show_rule( Name, Heads, Guard, Body), | 
					
						
							|  |  |  | 	fail. | 
					
						
							|  |  |  | show_rule. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | show_rule( Name, Heads, Guard, Body) :- | 
					
						
							|  |  |  | 	errformat( '~n ~p @', [Name]), | 
					
						
							|  |  |  | 	show_heads( Heads, 2, 2, Ident), | 
					
						
							|  |  |  | 	( member( k(_,_), Heads) -> | 
					
						
							|  |  |  | 	    errformat( ' <=>~n~n', []) | 
					
						
							|  |  |  | 	; | 
					
						
							|  |  |  | 	    errformat( ' ==>~n~n', []) | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	( Guard==true -> | 
					
						
							|  |  |  | 	    show_body( Body, Ident) | 
					
						
							|  |  |  | 	; | 
					
						
							|  |  |  | 	    show_body( Guard, Ident), errnl, | 
					
						
							|  |  |  | 	    errtab( Ident), errwrite( '|'), errnl, | 
					
						
							|  |  |  | 	    show_body( Body, Ident) | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	errput( 0'.), errnl, errnl. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | show_body( (A,B), Tab) :- !, | 
					
						
							|  |  |  | 	show_body( A, Tab), | 
					
						
							|  |  |  | 	errwrite( ','), errnl, | 
					
						
							|  |  |  | 	show_body( B, Tab). | 
					
						
							|  |  |  | show_body( (A->B;C), Tab) :- !, | 
					
						
							|  |  |  | 	errtab( Tab), errwrite( '('), errnl, | 
					
						
							|  |  |  | 	NTab1 is Tab+2, | 
					
						
							|  |  |  | 	NTab2 is Tab+5, | 
					
						
							|  |  |  | 	show_body( A, NTab1), | 
					
						
							|  |  |  | 	errwrite( '  ->'), errnl, | 
					
						
							|  |  |  | 	show_body( B, NTab2), errnl, | 
					
						
							|  |  |  | 	errtab( Tab), errwrite( ';'), errnl, | 
					
						
							|  |  |  | 	show_body( C, NTab2), errnl, | 
					
						
							|  |  |  | 	errtab( Tab), errwrite( ')'). | 
					
						
							|  |  |  | show_body( (A->B), Tab) :- !, | 
					
						
							|  |  |  | 	errtab( Tab), errwrite( '('), errnl, | 
					
						
							|  |  |  | 	NTab1 is Tab+2, | 
					
						
							|  |  |  | 	NTab2 is Tab+5, | 
					
						
							|  |  |  | 	show_body( A, NTab1), | 
					
						
							|  |  |  | 	errwrite( '  ->'), errnl, | 
					
						
							|  |  |  | 	show_body( B, NTab2), errnl, | 
					
						
							|  |  |  | 	errtab( Tab), errwrite( ')'). | 
					
						
							|  |  |  | show_body( (A;B), Tab) :- !, | 
					
						
							|  |  |  | 	errtab( Tab), errwrite( '('), errnl, | 
					
						
							|  |  |  | 	NTab is Tab+5, | 
					
						
							|  |  |  | 	show_body( A, NTab), errnl, | 
					
						
							|  |  |  | 	errtab( Tab), errwrite( ';'), errnl, | 
					
						
							|  |  |  | 	show_body( B, NTab), errnl, | 
					
						
							|  |  |  | 	errtab( Tab), errwrite( ')'). | 
					
						
							|  |  |  | show_body( A, Tab) :- | 
					
						
							|  |  |  | 	errtab( Tab), | 
					
						
							|  |  |  | 	errwriteq( A). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | show_heads( [],     I, _, I). | 
					
						
							|  |  |  | show_heads( [H|Hs], I, D, If) :- | 
					
						
							|  |  |  | 	arg( 1, H, C), | 
					
						
							|  |  |  | 	arg( 2, H, T), | 
					
						
							|  |  |  | 	( I>0 -> errnl ; true ), | 
					
						
							|  |  |  | 	errtab( I), errprint( C#T), | 
					
						
							|  |  |  | 	( Hs=[] -> | 
					
						
							|  |  |  | 	    If = I | 
					
						
							|  |  |  | 	; H=r(_,_), Hs=[k(_,_)|_] -> | 
					
						
							| 
									
										
										
										
											2001-05-08 20:39:01 +00:00
										 |  |  | 	    errput(0' ), errput(0'\\ ), errput(0' ), | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	    J is I+D, | 
					
						
							|  |  |  | 	    show_heads( Hs, J, D, If) | 
					
						
							|  |  |  | 	; | 
					
						
							|  |  |  | 	    errput(0',), errput(0' ), | 
					
						
							|  |  |  | 	    J is I+D, | 
					
						
							|  |  |  | 	    show_heads( Hs, J, D, If) | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | show_store( 0) :- | 
					
						
							|  |  |  | 	errnl, | 
					
						
							|  |  |  | 	global_term_ref_1( Global), | 
					
						
							|  |  |  | 	find_constraint_internal( Global, Term, S, active, Module), | 
					
						
							|  |  |  | 	module_wrap( Term, Module, Wrapped), | 
					
						
							|  |  |  | 	errprint( Wrapped#S), errnl, | 
					
						
							|  |  |  | 	fail. | 
					
						
							|  |  |  | show_store( 1) :- | 
					
						
							|  |  |  | 	prolog_flag( debugger_print_options, Options), | 
					
						
							|  |  |  | 	errnl, | 
					
						
							|  |  |  | 	global_term_ref_1( Global), | 
					
						
							|  |  |  | 	find_constraint_internal( Global, Term, S, State, Module), | 
					
						
							|  |  |  | 	S =.. [suspension,Id,_,_Closure,Gref,Href|_], | 
					
						
							|  |  |  | 	get_mutable( Generation, Gref), | 
					
						
							|  |  |  | 	get_mutable( Hist, Href), | 
					
						
							|  |  |  | 	assoc_to_list( Hist, History), | 
					
						
							|  |  |  | 	module_wrap( Term, Module, Wrapped), | 
					
						
							|  |  |  | 	errformat( '~|~t~p~5+ ~|~t~d~3+ ~|~p~t~10+ ~|~@~t~50+ ', | 
					
						
							|  |  |  | 	  [Id,Generation,State,write_term(Wrapped,Options)]), | 
					
						
							|  |  |  | 	show_history( History), | 
					
						
							|  |  |  | 	errnl, | 
					
						
							|  |  |  | 	fail. | 
					
						
							|  |  |  | show_store( _) :- errnl. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | show_history( []). | 
					
						
							|  |  |  | show_history( [K-_|Hs]) :- | 
					
						
							|  |  |  | 	errprint( K), | 
					
						
							|  |  |  | 	( Hs==[] -> true ; errput(0',) ), | 
					
						
							|  |  |  | 	show_history( Hs). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | set_pd( N) :- | 
					
						
							|  |  |  | 	prolog_flag( debugger_print_options, Old), | 
					
						
							|  |  |  | 	( select( max_depth(_), Old, Rest) -> | 
					
						
							|  |  |  | 	    true | 
					
						
							|  |  |  | 	; | 
					
						
							|  |  |  | 	    Rest = Old | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	( N < 0 -> D = 0 ; D = N ), | 
					
						
							|  |  |  | 	prolog_flag( debugger_print_options, _, [max_depth(D)|Rest]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | dbg_help :- | 
					
						
							|  |  |  | 	errnl, | 
					
						
							|  |  |  | 	errwrite('CHR debugging options:'), errnl, | 
					
						
							|  |  |  | 	errwrite('   <cr>   creep            c      creep'), errnl, | 
					
						
							|  |  |  | 	errwrite('    l     leap			 '), errnl, | 
					
						
							|  |  |  | 	errwrite('    s     skip             s <i>  skip i'), errnl, | 
					
						
							|  |  |  | 	errwrite('    g     ancestors			'), errnl, | 
					
						
							|  |  |  | 	errwrite('    &     constraints      & <i>  constraints (details)'), errnl, | 
					
						
							|  |  |  | 	errwrite('    n     nodebug          =      debugging'), errnl, | 
					
						
							|  |  |  | 	errwrite('    +     spy this			'), errnl, | 
					
						
							|  |  |  | 	errwrite('    -     nospy this       .      show rule'), errnl, | 
					
						
							|  |  |  | 	errwrite('    <     reset printdepth < <n>  set printdepth'), errnl, | 
					
						
							|  |  |  | 	errwrite('    a     abort            b      break'), errnl, | 
					
						
							|  |  |  | 	errwrite('    ?     help             h      help'), errnl, | 
					
						
							|  |  |  | 	errnl. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | errnl :- nl( user_error). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | errput( X) :- put( user_error, X). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | errtab( X) :- tab( user_error, X). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | errwrite( X) :- write( user_error, X). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | errwriteq( X) :- writeq( user_error, X). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | errprint( X) :- | 
					
						
							|  |  |  | 	prolog_flag( debugger_print_options, Options), | 
					
						
							|  |  |  | 	write_term( user_error, X, Options). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | errformat( F, A) :- format( user_error, F, A). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % ---------------------------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % code from the Bips/trace.pl | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | get_command(Command) :- | 
					
						
							|  |  |  | 	errwrite(' ? '), | 
					
						
							|  |  |  | 	ttyflush, | 
					
						
							|  |  |  | 	ttyget0(C1), | 
					
						
							|  |  |  | 	get_command(C1, Command). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | get_command(0' | 
					
						
							|  |  |  | 	, 0' | 
					
						
							|  |  |  | 	   ) :- !. | 
					
						
							|  |  |  | get_command(C1, Command) :- | 
					
						
							|  |  |  | 	ttyget0(C2), | 
					
						
							|  |  |  | 	get_args(C2, Args), | 
					
						
							|  |  |  | 	(   Args = [] -> Command = C1 | 
					
						
							|  |  |  | 	;   Command = [C1|Args] | 
					
						
							|  |  |  | 	). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | get_args(0' | 
					
						
							|  |  |  | 	 , []) :- !. | 
					
						
							|  |  |  | get_args(C1, [Arg|Args]) :- | 
					
						
							|  |  |  | 	C1 >= 0'0, C1 =< 0'9, !, | 
					
						
							|  |  |  | 	get_arg(C1, 0, Arg, C2), | 
					
						
							|  |  |  | 	get_args(C2, Args). | 
					
						
							|  |  |  | get_args(0'-, [Arg|Args]) :- !, | 
					
						
							|  |  |  | 	ttyget0(C2), | 
					
						
							|  |  |  | 	get_arg(C2, 0, Arg1, C3), | 
					
						
							|  |  |  | 	Arg is -Arg1, | 
					
						
							|  |  |  | 	get_args(C3, Args). | 
					
						
							|  |  |  | get_args(_, Args) :- | 
					
						
							|  |  |  | 	ttyget0(C2), | 
					
						
							|  |  |  | 	get_args(C2, Args). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | get_arg(C1, Arg0, Arg, C) :- | 
					
						
							|  |  |  | 	C1 >= 0'0, C1 =< 0'9, !, | 
					
						
							|  |  |  | 	Arg1 is Arg0*10 + C1 - 0'0, | 
					
						
							|  |  |  | 	ttyget0(C2), | 
					
						
							|  |  |  | 	get_arg(C2, Arg1, Arg, C). | 
					
						
							|  |  |  | get_arg(C1, Arg, Arg, C1). | 
					
						
							| 
									
										
										
										
											2004-12-05 05:01:45 +00:00
										 |  |  | 
 |