35
   69
   70:- module(chr_runtime,
   71	  [ 'chr sbag_del_element'/3,
   72	    'chr merge_attributes'/3,
   73
   74	    'chr run_suspensions'/1,
   75	    'chr run_suspensions_loop'/1,
   76
   77	    'chr run_suspensions_d'/1,
   78	    'chr run_suspensions_loop_d'/1,
   79
   80	    'chr insert_constraint_internal'/5,
   81	    'chr remove_constraint_internal'/2,
   82	    'chr allocate_constraint'/4,
   83	    'chr activate_constraint'/3,
   84
   85	    'chr default_store'/1,
   86
   87	    'chr via_1'/2,
   88	    'chr via_2'/3,
   89	    'chr via'/2,
   90	    'chr newvia_1'/2,
   91	    'chr newvia_2'/3,
   92	    'chr newvia'/2,
   93
   94	    'chr lock'/1,
   95	    'chr unlock'/1,
   96	    'chr not_locked'/1,
   97	    'chr none_locked'/1,
   98
   99	    'chr error_lock'/1,
  100	    'chr unerror_lock'/1,
  101	    'chr not_error_locked'/1,
  102	    'chr none_error_locked'/1,
  103
  104	    'chr update_mutable'/2,
  105	    'chr get_mutable'/2,
  106	    'chr create_mutable'/2,
  107
  108	    'chr novel_production'/2,
  109	    'chr extend_history'/2,
  110	    'chr empty_history'/1,
  111
  112	    'chr gen_id'/1,
  113
  114	    'chr debugging'/0,
  115	    'chr debug_event'/1,
  116	    'chr debug command'/2,	  117
  118	    'chr chr_indexed_variables'/2,
  119
  120	    'chr all_suspensions'/3,
  121	    'chr new_merge_attributes'/3,
  122	    'chr normalize_attr'/2,
  123
  124	    'chr select'/3,
  125
  126	    'chr module'/1,		  127
  128	    chr_show_store/1,		  129	    find_chr_constraint/1,	  130	    current_chr_constraint/1,	  131
  132	    chr_trace/0,
  133	    chr_notrace/0,
  134	    chr_leash/1
  135	  ]).
  138:- set_prolog_flag(generate_debug_info, false).
  141:- meta_predicate
  142	current_chr_constraint(:).  143
  145
  146:- use_module(library(dialect/hprolog)).  147:- include(chr_op).
  156
  160:- dynamic user:exception/3.  161:- multifile user:exception/3.  162
  163user:exception(undefined_global_variable, Name, retry) :-
  164	chr_runtime_global_variable(Name),
  165	chr_init.
  166
  167chr_runtime_global_variable(chr_id).
  168chr_runtime_global_variable(chr_global).
  169chr_runtime_global_variable(chr_debug).
  170chr_runtime_global_variable(chr_debug_history).
  171
  172chr_init :-
  173	nb_setval(chr_id,0),
  174	nb_setval(chr_global,_),
  175	nb_setval(chr_debug,mutable(off)),            176	nb_setval(chr_debug_history,mutable([],0)). 
  184:- initialization chr_init.  185
  186
  194
  195chr_show_store(Mod) :-
  196	(
  197		Mod:'$enumerate_constraints'(Constraint),
  198		print(Constraint),nl,   199		fail
  200	;
  201		true
  202	).
  211find_chr_constraint(Constraint) :-
  212	'chr module'(Mod),
  213	Mod:'$enumerate_constraints'(Constraint).
  220current_chr_constraint(Mod:Constraint) :-
  221	'chr module'(Mod),
  222	Mod:'$enumerate_constraints'(Constraint).
  230'chr module'(Module) :-
  231	chr:'$chr_module'(Module).
  232:- if(current_prolog_flag(dialect, swi)).  233'chr module'(Module) :-
  234	module_property(Module, class(temporary)),
  235	current_predicate(Module:'$chr_initialization'/0),
  236	\+ predicate_property(Module:'$chr_initialization', imported_from(_)).
  237:- endif.  238
  247:- multifile user:goal_expansion/2.  248:- dynamic   user:goal_expansion/2.  249
  250user:goal_expansion('chr get_mutable'(Val,Var),    Var=mutable(Val)).
  251user:goal_expansion('chr update_mutable'(Val,Var), setarg(1,Var,Val)).
  252user:goal_expansion('chr create_mutable'(Val,Var), Var=mutable(Val)).
  253user:goal_expansion('chr default_store'(X),        nb_getval(chr_global,X)).
  281'chr run_suspensions'( Slots) :-
  282	    run_suspensions( Slots).
  283
  284'chr run_suspensions_loop'([]).
  285'chr run_suspensions_loop'([L|Ls]) :-
  286	run_suspensions(L),
  287	'chr run_suspensions_loop'(Ls).
  288
  289run_suspensions([]).
  290run_suspensions([S|Next] ) :-
  291	arg( 2, S, Mref),   292	'chr get_mutable'( Status, Mref),
  293	( Status==active ->
  294	    'chr update_mutable'( triggered, Mref),
  295	    arg( 4, S, Gref),   296	    'chr get_mutable'( Gen, Gref),
  297	    Generation is Gen+1,
  298	    'chr update_mutable'( Generation, Gref),
  299	    arg( 3, S, Goal),   300	    call( Goal),
  301	    'chr get_mutable'( Post, Mref),
  302	    ( Post==triggered ->
  303		'chr update_mutable'( active, Mref)	  304	    ;
  305		true
  306	    )
  307	;
  308	    true
  309	),
  310	run_suspensions( Next).
  311
  312'chr run_suspensions_d'( Slots) :-
  313	    run_suspensions_d( Slots).
  314
  315'chr run_suspensions_loop_d'([]).
  316'chr run_suspensions_loop_d'([L|Ls]) :-
  317	run_suspensions_d(L),
  318	'chr run_suspensions_loop_d'(Ls).
  319
  320run_suspensions_d([]).
  321run_suspensions_d([S|Next] ) :-
  322	arg( 2, S, Mref),   323	'chr get_mutable'( Status, Mref),
  324	( Status==active ->
  325	    'chr update_mutable'( triggered, Mref),
  326	    arg( 4, S, Gref),   327	    'chr get_mutable'( Gen, Gref),
  328	    Generation is Gen+1,
  329	    'chr update_mutable'( Generation, Gref),
  330	    arg( 3, S, Goal),   331	    (
  332		'chr debug_event'(wake(S)),
  333	        call( Goal)
  334	    ;
  335		'chr debug_event'(fail(S)), !,
  336		fail
  337	    ),
  338	    (
  339		'chr debug_event'(exit(S))
  340	    ;
  341		'chr debug_event'(redo(S)),
  342		fail
  343	    ),
  344	    'chr get_mutable'( Post, Mref),
  345	    ( Post==triggered ->
  346		'chr update_mutable'( active, Mref)     347	    ;
  348		true
  349	    )
  350	;
  351	    true
  352	),
  353	run_suspensions_d( Next).
  358
  360
  363
  364:- public locked:attr_unify_hook/2.  365locked:attr_unify_hook(_,_) :- fail.
  366
  368'chr lock'(T) :-
  369	( var(T)
  370	-> put_attr(T, locked, x)
  371        ;  term_variables(T,L),
  372           lockv(L)
  373	).
  374
  375lockv([]).
  376lockv([T|R]) :- put_attr( T, locked, x), lockv(R).
  377
  378'chr unlock'(T) :-
  379	( var(T)
  380	-> del_attr(T, locked)
  381	;  term_variables(T,L),
  382           unlockv(L)
  383	).
  384
  385unlockv([]).
  386unlockv([T|R]) :- del_attr( T, locked), unlockv(R).
  387
  389
  390'chr none_locked'( []).
  391'chr none_locked'( [V|Vs]) :-
  392	( get_attr(V, locked, _) ->
  393		fail
  394	;
  395		'chr none_locked'(Vs)
  396	).
  397
  398'chr not_locked'(V) :-
  399	( var( V) ->
  400		( get_attr( V, locked, _) ->
  401			fail
  402		;
  403			true
  404		)
  405	;
  406		true
  407	).
  408
  410
  412lock_error(Term) :-
  413	throw(error(instantation_error(Term),context(_,'CHR Runtime Error: unification in guard not allowed!'))).
  414
  417
  418error_locked:attr_unify_hook(_,Term) :- lock_error(Term).
  419
  421'chr error_lock'(T) :-
  422	( var(T)
  423	-> put_attr(T, error_locked, x)
  424        ;  term_variables(T,L),
  425           error_lockv(L)
  426	).
  427
  428error_lockv([]).
  429error_lockv([T|R]) :- put_attr( T, error_locked, x), error_lockv(R).
  430
  431'chr unerror_lock'(T) :-
  432	( var(T)
  433	-> del_attr(T, error_locked)
  434	;  term_variables(T,L),
  435           unerror_lockv(L)
  436	).
  437
  438unerror_lockv([]).
  439unerror_lockv([T|R]) :- del_attr( T, error_locked), unerror_lockv(R).
  440
  442
  443'chr none_error_locked'( []).
  444'chr none_error_locked'( [V|Vs]) :-
  445	( get_attr(V, error_locked, _) ->
  446		fail
  447	;
  448		'chr none_error_locked'(Vs)
  449	).
  450
  451'chr not_error_locked'(V) :-
  452	( var( V) ->
  453		( get_attr( V, error_locked, _) ->
  454			fail
  455		;
  456			true
  457		)
  458	;
  459		true
  460	).
  461
  466'chr remove_constraint_internal'( Susp, Agenda) :-
  467	arg( 2, Susp, Mref),   468	'chr get_mutable'( State, Mref),
  469	'chr update_mutable'( removed, Mref),		  470	( compound(State) ->			  471	    Agenda = []
  472	; State==removed ->
  473	    Agenda = []
  474	  475	  476	;
  477            Susp =.. [_,_,_,_,_,_,_|Args],
  478	    term_variables( Args, Vars),
  479	    'chr default_store'( Global),
  480	    Agenda = [Global|Vars]
  481	).
  482
  484'chr newvia_1'(X,V) :-
  485	( var(X) ->
  486		X = V
  487	;
  488		nonground(X,V)
  489	).
  490
  491'chr newvia_2'(X,Y,V) :-
  492	( var(X) ->
  493		X = V
  494	; var(Y) ->
  495		Y = V
  496	; compound(X), nonground(X,V) ->
  497		true
  498	;
  499		compound(Y), nonground(Y,V)
  500	).
  501
  508'chr newvia'(L,V) :- nonground(L,V).
  510
  511'chr via_1'(X,V) :-
  512	( var(X) ->
  513		X = V
  514	; atomic(X) ->
  515		'chr default_store'(V)
  516	; nonground(X,V) ->
  517		true
  518	;
  519		'chr default_store'(V)
  520	).
  521
  522'chr via_2'(X,Y,V) :-
  523	( var(X) ->
  524		X = V
  525	; var(Y) ->
  526		Y = V
  527	; compound(X), nonground(X,V) ->
  528		true
  529	; compound(Y), nonground(Y,V) ->
  530		true
  531	;
  532		'chr default_store'(V)
  533	).
  534
  541'chr via'(L,V) :-
  542	( nonground(L,V) ->
  543		true
  544	;
  545		'chr default_store'(V)
  546	).
  547
  548:- if(\+current_predicate(nonground/2)).  549nonground( Term, V) :-
  550	term_variables( Term, Vs),
  551	Vs = [V|_].
  552:- endif.  553
  555'chr novel_production'( Self, Tuple) :-
  556	arg( 5, Self, Ref),   557	'chr get_mutable'( History, Ref),
  558	( get_ds( Tuple, History, _) ->
  559	    fail
  560	;
  561	    true
  562	).
  563
  568'chr extend_history'( Self, Tuple) :-
  569	arg( 5, Self, Ref),   570	'chr get_mutable'( History, Ref),
  571	put_ds( Tuple, History, x, NewHistory),
  572	'chr update_mutable'( NewHistory, Ref).
  573
  575'chr allocate_constraint'( Closure, Self, F, Args) :-
  576	Self =.. [suspension,Id,Mref,Closure,Gref,Href,F|Args],   577	'chr create_mutable'(0, Gref),
  578	'chr empty_history'(History),
  579	'chr create_mutable'(History, Href),
  580	'chr create_mutable'(passive(Args), Mref),
  581	'chr gen_id'( Id).
  582
  588'chr activate_constraint'( Vars, Susp, Generation) :-
  589	arg( 2, Susp, Mref),   590	'chr get_mutable'( State, Mref),
  591	'chr update_mutable'( active, Mref),
  592	( nonvar(Generation) ->			  593	    true
  594	;
  595	    arg( 4, Susp, Gref),   596	    'chr get_mutable'( Gen, Gref),
  597	    Generation is Gen+1,
  598	    'chr update_mutable'( Generation, Gref)
  599	),
  600	( compound(State) ->			  601	    term_variables( State, Vs),
  602	    'chr none_locked'( Vs),
  603	    Vars = [Global|Vs],
  604	    'chr default_store'(Global)
  605	; State == removed ->			  606	    Susp =.. [_,_,_,_,_,_,_|Args],
  607	    term_variables( Args, Vs),
  608	    Vars = [Global|Vs],
  609	    'chr default_store'(Global)
  610	;
  611	    Vars = []
  612	).
  613
  614'chr insert_constraint_internal'([Global|Vars], Self, Closure, F, Args) :-
  615	'chr default_store'(Global),
  616	term_variables(Args,Vars),
  617	'chr none_locked'(Vars),
  618	Self =.. [suspension,Id,Mref,Closure,Gref,Href,F|Args],   619	'chr create_mutable'(active, Mref),
  620	'chr create_mutable'(0, Gref),
  621	'chr empty_history'(History),
  622	'chr create_mutable'(History, Href),
  623	'chr gen_id'(Id).
  624
  625insert_constraint_internal([Global|Vars], Self, Term, Closure, F, Args) :-
  626	'chr default_store'(Global),
  627	term_variables( Term, Vars),
  628	'chr none_locked'( Vars),
  629	'chr empty_history'( History),
  630	'chr create_mutable'( active, Mref),
  631	'chr create_mutable'( 0, Gref),
  632	'chr create_mutable'( History, Href),
  633	'chr gen_id'( Id),
  634	Self =.. [suspension,Id,Mref,Closure,Gref,Href,F|Args].   635
  637'chr empty_history'( E) :- empty_ds( E).
  638
  640'chr gen_id'( Id) :-
  641	nb_getval(chr_id,Id),
  642	NextId is Id + 1,
  643	nb_setval(chr_id,NextId).
  644
  648'chr create_mutable'(V,mutable(V)).
  649'chr get_mutable'(V,mutable(V)).
  650'chr update_mutable'(V,M) :- setarg(1,M,V).
  662'chr default_store'(X) :- nb_getval(chr_global,X).
  670
  671'chr sbag_del_element'( [],	  _,	[]).
  672'chr sbag_del_element'( [X|Xs], Elem, Set2) :-
  673	( X==Elem ->
  674	    Set2 = Xs
  675	;
  676	    Set2 = [X|Xss],
  677	    'chr sbag_del_element'( Xs, Elem, Xss)
  678	).
  679
  681'chr merge_attributes'([],Ys,Ys).
  682'chr merge_attributes'([X | Xs],YL,R) :-
  683  ( YL = [Y | Ys] ->
  684      arg(1,X,XId),   685      arg(1,Y,YId),	   686       ( XId < YId ->
  687           R = [X | T],
  688           'chr merge_attributes'(Xs,YL,T)
  689       ; XId > YId ->
  690           R = [Y | T],
  691           'chr merge_attributes'([X|Xs],Ys,T)
  692       ;
  693           R = [X | T],
  694           'chr merge_attributes'(Xs,Ys,T)
  695       )
  696  ;
  697       R = [X | Xs]
  698  ).
  699
  700'chr new_merge_attributes'([],A2,A) :-
  701	A = A2.
  702'chr new_merge_attributes'([E1|AT1],A2,A) :-
  703	( A2 = [E2|AT2] ->
  704		'chr new_merge_attributes'(E1,E2,AT1,AT2,A)
  705	;
  706		A = [E1|AT1]
  707	).
  708
  709'chr new_merge_attributes'(Pos1-L1,Pos2-L2,AT1,AT2,A) :-
  710	( Pos1 < Pos2 ->
  711		A = [Pos1-L1|AT],
  712		'chr new_merge_attributes'(AT1,[Pos2-L2|AT2],AT)
  713	; Pos1 > Pos2 ->
  714		A = [Pos2-L2|AT],
  715		'chr new_merge_attributes'([Pos1-L1|AT1],AT2,AT)
  716	;
  717		'chr merge_attributes'(L1,L2,L),
  718		A = [Pos1-L|AT],
  719		'chr new_merge_attributes'(AT1,AT2,AT)
  720	).
  721
  722'chr all_suspensions'([],_,_).
  723'chr all_suspensions'([Susps|SuspsList],Pos,Attr) :-
  724	all_suspensions(Attr,Susps,SuspsList,Pos).
  725
  726all_suspensions([],[],SuspsList,Pos) :-
  727	all_suspensions([],[],SuspsList,Pos).   728all_suspensions([APos-ASusps|RAttr],Susps,SuspsList,Pos) :-
  729	NPos is Pos + 1,
  730	( Pos == APos ->
  731		Susps = ASusps,
  732		'chr all_suspensions'(SuspsList,NPos,RAttr)
  733	;
  734		Susps = [],
  735		'chr all_suspensions'(SuspsList,NPos,[APos-ASusps|RAttr])
  736	).
  737
  738'chr normalize_attr'([],[]).
  739'chr normalize_attr'([Pos-L|R],[Pos-NL|NR]) :-
  740	sort(L,NL),
  741	'chr normalize_attr'(R,NR).
  742
  743'chr select'([E|T],F,R) :-
  744	( E = F ->
  745		R = T
  746	;
  747		R = [E|NR],
  748		'chr select'(T,F,NR)
  749	).
  750
  752
  753:- multifile
  754	chr:debug_event/2,		  755	chr:debug_interact/3.		  756
  757'chr debugging' :-
  758	nb_getval(chr_debug,mutable(trace)).
  759
  760'chr debug_event'(Event) :-
  761	(   nb_getval(chr_debug,mutable(State)),
  762	    State \== off
  763	->  (   chr:debug_event(State, Event)
  764	    ->  true
  765	    ;	debug_event(State,Event)
  766	    )
  767	;   true
  768	).
  769
  770chr_trace :-
  771	nb_setval(chr_debug,mutable(trace)).
  772chr_notrace :-
  773	nb_setval(chr_debug,mutable(off)).
  774
  778
  779chr_leash(Spec) :-
  780	leashed_ports(Spec, Ports),
  781	nb_setval(chr_leash,mutable(Ports)).
  782
  783leashed_ports(none, []).
  784leashed_ports(off,  []).
  785leashed_ports(all,  [call, exit, redo, fail, wake, try, apply, insert, remove]).
  786leashed_ports(default, [call,exit,fail,wake,apply]).
  787leashed_ports(One, Ports) :-
  788	atom(One), One \== [], !,
  789	leashed_ports([One], Ports).
  790leashed_ports(Set, Ports) :-
  791	sort(Set, Ports),		  792	leashed_ports(all, All),
  793	valid_ports(Ports, All).
  794
  795valid_ports([], _).
  796valid_ports([H|T], Valid) :-
  797	(   memberchk(H, Valid)
  798	->  true
  799	;   throw(error(domain_error(chr_port, H), _))
  800	),
  801	valid_ports(T, Valid).
  802
  803user:exception(undefined_global_variable, Name, retry) :-
  804	chr_runtime_debug_global_variable(Name),
  805	chr_debug_init.
  806
  807chr_runtime_debug_global_variable(chr_leash).
  808
  809chr_debug_init :-
  810   leashed_ports(default, Ports),
  811   nb_setval(chr_leash, mutable(Ports)).
  812
  813:- initialization chr_debug_init.  814
  816
  817
  821debug_event(trace,Event) :-
  822	Event = call(_), !,
  823	get_debug_history(History,Depth),
  824	NDepth is Depth + 1,
  825	chr_debug_interact(Event,NDepth),
  826	set_debug_history([Event|History],NDepth).
  827debug_event(trace,Event) :-
  828	Event = wake(_), !,
  829	get_debug_history(History,Depth),
  830	NDepth is Depth + 1,
  831	chr_debug_interact(Event,NDepth),
  832	set_debug_history([Event|History],NDepth).
  833debug_event(trace,Event) :-
  834	Event = redo(_), !,
  835	get_debug_history(_History, Depth),
  836	chr_debug_interact(Event, Depth).
  837debug_event(trace,Event) :-
  838	Event = exit(_),!,
  839	get_debug_history([_|History],Depth),
  840	chr_debug_interact(Event,Depth),
  841	NDepth is Depth - 1,
  842	set_debug_history(History,NDepth).
  843debug_event(trace,Event) :-
  844	Event = fail(_),!,
  845	get_debug_history(_,Depth),
  846	chr_debug_interact(Event,Depth).
  847debug_event(trace, Event) :-
  848	Event = remove(_), !,
  849	get_debug_history(_,Depth),
  850	chr_debug_interact(Event, Depth).
  851debug_event(trace, Event) :-
  852	Event = insert(_), !,
  853	get_debug_history(_,Depth),
  854	chr_debug_interact(Event, Depth).
  855debug_event(trace, Event) :-
  856	Event = try(_,_,_,_), !,
  857	get_debug_history(_,Depth),
  858	chr_debug_interact(Event, Depth).
  859debug_event(trace, Event) :-
  860	Event = apply(_,_,_,_), !,
  861	get_debug_history(_,Depth),
  862	chr_debug_interact(Event,Depth).
  863
  864debug_event(skip(_,_),Event) :-
  865	Event = call(_), !,
  866	get_debug_history(History,Depth),
  867	NDepth is Depth + 1,
  868	set_debug_history([Event|History],NDepth).
  869debug_event(skip(_,_),Event) :-
  870	Event = wake(_), !,
  871	get_debug_history(History,Depth),
  872	NDepth is Depth + 1,
  873	set_debug_history([Event|History],NDepth).
  874debug_event(skip(SkipSusp,SkipDepth),Event) :-
  875	Event = exit(Susp),!,
  876	get_debug_history([_|History],Depth),
  877	( SkipDepth == Depth,
  878	  SkipSusp == Susp ->
  879		set_chr_debug(trace),
  880		chr_debug_interact(Event,Depth)
  881	;
  882		true
  883	),
  884	NDepth is Depth - 1,
  885	set_debug_history(History,NDepth).
  886debug_event(skip(_,_),_) :- !,
  887	true.
  888
  894
  895chr_debug_interact(Event, Depth) :-
  896	chr:debug_interact(Event, Depth, Command), !,
  897	handle_debug_command(Command,Event,Depth).
  898chr_debug_interact(Event, Depth) :-
  899	print_event(Event, Depth),
  900	(   leashed(Event)
  901	->  ask_continue(Command)
  902	;   Command = creep
  903	),
  904	handle_debug_command(Command,Event,Depth).
  905
  906leashed(Event) :-
  907	functor(Event, Port, _),
  908	nb_getval(chr_leash, mutable(Ports)),
  909	memberchk(Port, Ports).
  910
  911:- multifile
  912	chr:debug_ask_continue/1.  913
  914ask_continue(Command) :-
  915	chr:debug_ask_continue(Command), !.
  916ask_continue(Command) :-
  917	print_message(trace, chr(prompt)),
  918	get_single_char(CharCode),
  919	(   CharCode == -1
  920	->  Char = end_of_file
  921	;   char_code(Char, CharCode)
  922	),
  923	(   debug_command(Char, Command)
  924	->  print_message(trace, chr(command(Command)))
  925	;   print_message(help, chr(invalid_command)),
  926	    ask_continue(Command)
  927	).
  928
  929
  930'chr debug command'(Char, Command) :-
  931	debug_command(Char, Command).
  932
  933debug_command(c, creep).
  934debug_command(' ', creep).
  935debug_command('\r', creep).
  936debug_command(s, skip).
  937debug_command(g, ancestors).
  938debug_command(n, nodebug).
  939debug_command(a, abort).
  940debug_command(f, fail).
  941debug_command(b, break).
  942debug_command(?, help).
  943debug_command(h, help).
  944debug_command(end_of_file, exit).
  945
  946
  947handle_debug_command(creep,_,_) :- !.
  948handle_debug_command(skip, Event, Depth) :- !,
  949	Event =.. [Type|Rest],
  950	( Type \== call,
  951	  Type \== wake ->
  952		handle_debug_command(creep,Event,Depth)
  953	;
  954		Rest = [Susp],
  955		set_chr_debug(skip(Susp,Depth))
  956	).
  957handle_debug_command(ancestors,Event,Depth) :- !,
  958	print_chr_debug_history,
  959	chr_debug_interact(Event,Depth).
  960handle_debug_command(nodebug,_,_) :- !,
  961	chr_notrace.
  962handle_debug_command(abort,_,_) :- !,
  963	abort.
  964handle_debug_command(exit,_,_) :- !,
  965	(   thread_self(main)		  966	->  halt			  967	;   permission_error(access, chr_debug, halt)
  968	).
  969handle_debug_command(fail,_,_) :- !,
  970	fail.
  971handle_debug_command(break,Event,Depth) :- !,
  972	break,
  973	chr_debug_interact(Event,Depth).
  974handle_debug_command(help,Event,Depth) :- !,
  975	print_message(help, chr(debug_options)),
  976	chr_debug_interact(Event,Depth).
  977handle_debug_command(Cmd, _, _) :-
  978	throw(error(domain_error(chr_debug_command, Cmd), _)).
  979
  980print_chr_debug_history :-
  981	get_debug_history(History,Depth),
  982	print_message(trace, chr(ancestors(History, Depth))).
  983
  984print_event(Event, Depth) :-
  985	print_message(trace, chr(event(Event, Depth))).
  986
  990
  991get_debug_history(History,Depth) :-
  992	nb_getval(chr_debug_history,mutable(History,Depth)).
  993
  994set_debug_history(History,Depth) :-
  995	nb_getval(chr_debug_history,Mutable),
  996	setarg(1,Mutable,History),
  997	setarg(2,Mutable,Depth).
  998
  999set_chr_debug(State) :-
 1000	nb_getval(chr_debug,Mutable),
 1001	setarg(1,Mutable,State).
 1002
 1003'chr chr_indexed_variables'(Susp,Vars) :-
 1004        Susp =.. [_,_,_,_,_,_,_|Args],
 1005	term_variables(Args,Vars).
 1006
 1007
 1008		  1011:- multifile
 1012	sandbox:safe_primitive/1. 1013
 1014sandbox:safe_primitive(chr_runtime:handle_debug_command(_,_,_)).
 1015sandbox:safe_primitive(chr_runtime:ask_continue(_))