git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@31 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
		
			
				
	
	
		
			593 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Prolog
		
	
	
	
	
	
			
		
		
	
	
			593 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Prolog
		
	
	
	
	
	
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| %  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(_,_)|_] ->
 | |
| 	    errput(0' ), errput(0'\\ ), errput(0' ),
 | |
| 	    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).
 |