* Deleted copy_term_nat/2 definition
[chr.git] / chr_runtime.pl
blob318cc5acfc2ffe853943899d7167a293ba7dd3db
1 /* $Id$
3 Part of CHR (Constraint Handling Rules)
5 Author: Christian Holzbaur and Tom Schrijvers
6 E-mail: christian@ai.univie.ac.at
7 Tom.Schrijvers@cs.kuleuven.ac.be
8 WWW: http://www.swi-prolog.org
9 Copyright (C): 2003-2004, K.U. Leuven
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 as published by the Free Software Foundation; either version 2
14 of the License, or (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU Lesser General Public
22 License along with this library; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 As a special exception, if you link this library with other files,
26 compiled with a Free Software compiler, to produce an executable, this
27 library does not by itself cause the resulting executable to be covered
28 by the GNU General Public License. This exception does not however
29 invalidate any other reasons why the executable file might be covered by
30 the GNU General Public License.
32 Distributed with SWI-Prolog under the above conditions with
33 permission from the authors.
37 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 %% _ _ _
39 %% ___| |__ _ __ _ __ _ _ _ __ | |_(_)_ __ ___ ___
40 %% / __| '_ \| '__| | '__| | | | '_ \| __| | '_ ` _ \ / _ \
41 %% | (__| | | | | | | | |_| | | | | |_| | | | | | | __/
42 %% \___|_| |_|_| |_| \__,_|_| |_|\__|_|_| |_| |_|\___|
44 %% hProlog CHR runtime:
46 %% * based on the SICStus CHR runtime by Christian Holzbaur
47 %%
48 %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
49 %% % Constraint Handling Rules version 2.2 %
50 %% % %
51 %% % (c) Copyright 1996-98 %
52 %% % LMU, Muenchen %
53 %% % %
54 %% % File: chr.pl %
55 %% % Author: Christian Holzbaur christian@ai.univie.ac.at %
56 %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57 %%
58 %%
59 %% * modified by Tom Schrijvers, K.U.Leuven, Tom.Schrijvers@cs.kuleuven.ac.be
60 %% - ported to hProlog
61 %% - modified for eager suspension removal
63 %% * First working version: 6 June 2003
65 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66 %% SWI-Prolog changes
67 %%
68 %% * Added initialization directives for saved-states
69 %% * Renamed merge/3 --> sbag_merge/3 (name conflict)
70 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72 :- module(chr_runtime,
73 [ 'chr sbag_del_element'/3,
74 'chr sbag_member'/2,
75 'chr merge_attributes'/3,
77 'chr run_suspensions'/1,
78 'chr run_suspensions_loop'/1,
80 'chr run_suspensions_d'/1,
81 'chr run_suspensions_loop_d'/1,
83 'chr insert_constraint_internal'/5,
84 'chr remove_constraint_internal'/2,
85 'chr allocate_constraint'/4,
86 'chr activate_constraint'/3,
88 'chr global_term_ref_1'/1,
90 'chr via_1'/2,
91 'chr via_2'/3,
92 'chr via'/2,
94 'chr lock'/1,
95 'chr unlock'/1,
96 'chr not_locked'/1,
97 'chr none_locked'/1,
99 'chr update_mutable'/2,
100 'chr get_mutable'/2,
102 'chr novel_production'/2,
103 'chr extend_history'/2,
104 'chr empty_history'/1,
106 'chr gen_id'/1,
108 'chr debug_event'/1,
109 'chr debug command'/2, % Char, Command
111 'chr chr_indexed_variables'/2,
113 chr_trace/0,
114 chr_notrace/0,
115 chr_leash/1
117 :- set_prolog_flag(generate_debug_info, false).
119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121 :- use_module(library(assoc)).
122 :- use_module(hprolog).
123 :- use_module(library(lists)).
124 :- include(chr_op).
126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
128 % I N I T I A L I S A T I O N
130 ?- initialization % SWI
131 nb_setval(id,0).
133 ?- initialization % SWI
134 nb_setval(chr_global,_).
136 ?- initialization
137 nb_setval(chr_debug,mutable(off)).
139 ?- initialization
140 nb_setval(chr_debug_history,mutable([],0)).
142 show_store(Mod) :-
144 Mod:'$enumerate_suspensions'(Susp),
145 arg(6,Susp,C),
146 writeln(C),
147 fail
149 true
152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
153 'chr merge_attributes'( As, Bs, Cs) :-
154 sbag_union(As,Bs,Cs).
156 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
157 'chr run_suspensions'( Slots) :-
158 run_suspensions( Slots).
160 'chr run_suspensions_loop'([]).
161 'chr run_suspensions_loop'([L|Ls]) :-
162 run_suspensions(L),
163 'chr run_suspensions_loop'(Ls).
165 run_suspensions([]).
166 run_suspensions([S|Next] ) :-
167 arg( 2, S, Mref),
168 Mref = mutable(Status), % get_mutable( Status, Mref), % XXX Inlined
169 ( Status==active ->
170 update_mutable( triggered, Mref),
171 arg( 4, S, Gref),
172 Gref = mutable(Gen), % get_mutable( Gen, Gref), % XXX Inlined
173 Generation is Gen+1,
174 update_mutable( Generation, Gref),
175 arg( 3, S, Goal),
176 call( Goal),
177 % get_mutable( Post, Mref), % XXX Inlined
178 ( Mref = mutable(triggered) -> % Post==triggered ->
179 update_mutable( removed, Mref)
181 true
184 true
186 run_suspensions( Next).
188 'chr run_suspensions_d'( Slots) :-
189 run_suspensions_d( Slots).
191 'chr run_suspensions_loop_d'([]).
192 'chr run_suspensions_loop_d'([L|Ls]) :-
193 run_suspensions_d(L),
194 'chr run_suspensions_loop_d'(Ls).
196 run_suspensions_d([]).
197 run_suspensions_d([S|Next] ) :-
198 arg( 2, S, Mref),
199 Mref = mutable(Status), % get_mutable( Status, Mref), % XXX Inlined
200 ( Status==active ->
201 update_mutable( triggered, Mref),
202 arg( 4, S, Gref),
203 Gref = mutable(Gen), % get_mutable( Gen, Gref), % XXX Inlined
204 Generation is Gen+1,
205 update_mutable( Generation, Gref),
206 arg( 3, S, Goal),
208 'chr debug_event'(wake(S)),
209 call( Goal)
211 'chr debug_event'(fail(S)), !,
212 fail
215 'chr debug_event'(exit(S))
217 'chr debug_event'(redo(S)),
218 fail
220 % get_mutable( Post, Mref), % XXX Inlined
221 ( Mref = mutable(triggered) -> % Post==triggered ->
222 update_mutable( removed, Mref)
224 true
227 true
229 run_suspensions_d( Next).
230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
231 locked:attr_unify_hook(_,_) :- fail.
233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
234 'chr lock'(T) :-
235 lock(T).
237 'chr unlock'(T) :-
238 unlock(T).
240 'chr not_locked'(T) :-
241 not_locked(T).
243 lock(T) :-
244 ( var(T)
245 -> put_attr(T, locked, x)
246 ; term_variables(T,L),
247 lockv(L)
250 lockv([]).
251 lockv([T|R]) :- put_attr( T, locked, x), lockv(R).
253 unlock(T) :-
254 ( var(T)
255 -> del_attr(T, locked)
256 ; term_variables(T,L),
257 unlockv(L)
260 unlockv([]).
261 unlockv([T|R]) :- del_attr( T, locked), unlockv(R).
263 'chr none_locked'( []).
264 'chr none_locked'( [V|Vs]) :-
265 not_locked( V),
266 'chr none_locked'( Vs).
268 not_locked( V) :-
269 ( var( V) ->
270 ( get_attr( V, locked, _) ->
271 fail
273 true
276 true
279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
281 % Eager removal from all chains.
283 'chr remove_constraint_internal'( Susp, Agenda) :-
284 arg( 2, Susp, Mref),
285 Mref = mutable(State), % get_mutable( State, Mref), % XXX Inlined
286 update_mutable( removed, Mref), % mark in any case
287 ( compound(State) -> % passive/1
288 Agenda = []
289 ; State==removed ->
290 Agenda = []
291 %; State==triggered ->
292 % Agenda = []
294 Susp =.. [_,_,_,_,_,_,_|Args],
295 term_variables( Args, Vars),
296 global_term_ref_1( Global),
297 Agenda = [Global|Vars]
300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
301 'chr via_1'(X,V) :-
302 ( var(X) ->
303 X = V
304 ; atomic(X) ->
305 global_term_ref_1(V)
306 ; nonground(X,V) ->
307 true
309 global_term_ref_1(V)
311 % 'chr via_1'( X, V) :- var(X), !, X=V.
312 % 'chr via_1'( T, V) :- compound(T), nonground( T, V), ! .
313 % 'chr via_1'( _, V) :- global_term_ref_1( V).
315 'chr via_2'(X,Y,V) :-
316 ( var(X) ->
317 X = V
318 ; var(Y) ->
319 Y = V
320 ; compound(X), nonground(X,V) ->
321 true
322 ; compound(Y), nonground(Y,V) ->
323 true
325 global_term_ref_1(V)
327 % 'chr via_2'( X, _, V) :- var(X), !, X=V.
328 % 'chr via_2'( _, Y, V) :- var(Y), !, Y=V.
329 % 'chr via_2'( T, _, V) :- compound(T), nonground( T, V), ! .
330 % 'chr via_2'( _, T, V) :- compound(T), nonground( T, V), ! .
331 % 'chr via_2'( _, _, V) :- global_term_ref_1( V).
334 % The second arg is a witness.
335 % The formulation with term_variables/2 is
336 % cycle safe, but it finds a list of all vars.
337 % We need only one, and no list in particular.
339 'chr via'(L,V) :-
340 ( nonground(L,V) ->
341 true
343 global_term_ref_1(V)
346 nonground( Term, V) :-
347 term_variables( Term, Vs),
348 Vs = [V|_].
350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
351 'chr novel_production'( Self, Tuple) :-
352 arg( 5, Self, Ref),
353 Ref = mutable(History), % get_mutable( History, Ref), % XXX Inlined
354 ( get_assoc( Tuple, History, _) ->
355 fail
357 true
361 % Not folded with novel_production/2 because guard checking
362 % goes in between the two calls.
364 'chr extend_history'( Self, Tuple) :-
365 arg( 5, Self, Ref),
366 Ref = mutable(History), % get_mutable( History, Ref), % XXX Inlined
367 put_assoc( Tuple, History, x, NewHistory),
368 update_mutable( NewHistory, Ref).
370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
371 constraint_generation( Susp, State, Generation) :-
372 arg( 2, Susp, Mref),
373 Mref = mutable(State), % get_mutable( State, Mref), % XXX Inlined
374 arg( 4, Susp, Gref),
375 Gref = mutable(Generation). % get_mutable( Generation, Gref). % not incremented meanwhile % XXX Inlined
377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378 'chr allocate_constraint'( Closure, Self, F, Args) :-
379 'chr empty_history'( History),
380 create_mutable( passive(Args), Mref),
381 create_mutable( 0, Gref),
382 create_mutable( History, Href),
383 'chr gen_id'( Id),
384 Self =.. [suspension,Id,Mref,Closure,Gref,Href,F|Args].
387 % 'chr activate_constraint'( -, +, -).
389 % The transition gc->active should be rare
391 'chr activate_constraint'( Vars, Susp, Generation) :-
392 arg( 2, Susp, Mref),
393 Mref = mutable(State), % get_mutable( State, Mref), % XXX Inlined
394 update_mutable( active, Mref),
395 ( nonvar(Generation) -> % aih
396 true
398 arg( 4, Susp, Gref),
399 Gref = mutable(Gen), % get_mutable( Gen, Gref), % XXX Inlined
400 Generation is Gen+1,
401 update_mutable( Generation, Gref)
403 ( compound(State) -> % passive/1
404 term_variables( State, Vs),
405 'chr none_locked'( Vs),
406 global_term_ref_1( Global),
407 Vars = [Global|Vs]
408 ; State==removed -> % the price for eager removal ...
409 Susp =.. [_,_,_,_,_,_,_|Args],
410 term_variables( Args, Vs),
411 global_term_ref_1( Global),
412 Vars = [Global|Vs]
414 Vars = []
417 'chr insert_constraint_internal'( [Global|Vars], Self, Closure, F, Args) :-
418 term_variables( Args, Vars),
419 'chr none_locked'( Vars),
420 global_term_ref_1( Global),
421 'chr empty_history'( History),
422 create_mutable( active, Mref),
423 create_mutable( 0, Gref),
424 create_mutable( History, Href),
425 'chr gen_id'( Id),
426 Self =.. [suspension,Id,Mref,Closure,Gref,Href,F|Args].
428 insert_constraint_internal( [Global|Vars], Self, Term, Closure, F, Args) :-
429 term_variables( Term, Vars),
430 'chr none_locked'( Vars),
431 global_term_ref_1( Global),
432 'chr empty_history'( History),
433 create_mutable( active, Mref),
434 create_mutable( 0, Gref),
435 create_mutable( History, Href),
436 'chr gen_id'( Id),
437 Self =.. [suspension,Id,Mref,Closure,Gref,Href,F|Args].
439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
440 change_state( Susp, State) :-
441 arg( 2, Susp, Mref),
442 update_mutable( State, Mref).
444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
445 'chr empty_history'( E) :- empty_assoc( E).
447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
448 'chr gen_id'( Id) :-
449 incval( id, Id).
451 incval(id,Id) :-
452 nb_getval(id,Id),
453 NextId is Id + 1,
454 nb_setval(id,NextId).
456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
457 create_mutable(V,mutable(V)).
459 'chr get_mutable'(V, mutable(V)).
461 'chr update_mutable'(V,M) :-
462 setarg(1,M,V).
464 get_mutable(V, mutable(V)).
466 update_mutable(V,M) :-
467 setarg(1,M,V).
469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
470 'chr global_term_ref_1'(X) :-
471 global_term_ref_1(X).
473 global_term_ref_1(X) :-
474 nb_getval(chr_global,X).
476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
478 'chr sbag_member'( Element, [Head|Tail]) :-
479 sbag_member( Element, Tail, Head).
481 % auxiliary to avoid choicepoint for last element
483 sbag_member( E, _, E).
484 sbag_member( E, [Head|Tail], _) :-
485 sbag_member( E, Tail, Head).
487 'chr sbag_del_element'( [], _, []).
488 'chr sbag_del_element'( [X|Xs], Elem, Set2) :-
489 ( X==Elem ->
490 Set2 = Xs
492 Set2 = [X|Xss],
493 'chr sbag_del_element'( Xs, Elem, Xss)
496 sbag_union( A, B, C) :-
497 sbag_merge( A, B, C).
499 sbag_merge([],Ys,Ys).
500 sbag_merge([X | Xs],YL,R) :-
501 ( YL = [Y | Ys] ->
502 arg(1,X,XId),
503 arg(1,Y,YId),
504 ( XId < YId ->
505 R = [X | T],
506 sbag_merge(Xs,YL,T)
507 ; XId > YId ->
508 R = [Y | T],
509 sbag_merge([X|Xs],Ys,T)
511 R = [X | T],
512 sbag_merge(Xs,Ys,T)
515 R = [X | Xs]
518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
520 :- multifile
521 chr:debug_event/2, % +State, +Event
522 chr:debug_interact/3. % +Event, +Depth, -Command
524 'chr debug_event'(Event) :-
525 nb_getval(chr_debug,mutable(State)),
526 ( State == off ->
527 true
528 ; chr:debug_event(State, Event) ->
529 true
530 ; debug_event(State,Event)
533 chr_trace :-
534 nb_setval(chr_debug,mutable(trace)).
535 chr_notrace :-
536 nb_setval(chr_debug,mutable(off)).
538 % chr_leash(+Spec)
540 % Define the set of ports at which we prompt for user interaction
542 chr_leash(Spec) :-
543 leashed_ports(Spec, Ports),
544 nb_setval(chr_leash,mutable(Ports)).
546 leashed_ports(none, []).
547 leashed_ports(off, []).
548 leashed_ports(all, [call, exit, redo, fail, wake, try, apply, insert, remove]).
549 leashed_ports(default, [call,exit,fail,wake,apply]).
550 leashed_ports(One, Ports) :-
551 atom(One), One \== [], !,
552 leashed_ports([One], Ports).
553 leashed_ports(Set, Ports) :-
554 sort(Set, Ports), % make unique
555 leashed_ports(all, All),
556 valid_ports(Ports, All).
558 valid_ports([], _).
559 valid_ports([H|T], Valid) :-
560 ( memberchk(H, Valid)
561 -> true
562 ; throw(error(domain_error(chr_port, H), _))
564 valid_ports(T, Valid).
567 :- initialization
568 leashed_ports(default, Ports),
569 nb_setval(chr_leash, mutable(Ports)).
571 % debug_event(+State, +Event)
574 %debug_event(trace, Event) :-
575 % functor(Event, Name, Arity),
576 % writeln(Name/Arity), fail.
577 debug_event(trace,Event) :-
578 Event = call(_), !,
579 get_debug_history(History,Depth),
580 NDepth is Depth + 1,
581 chr_debug_interact(Event,NDepth),
582 set_debug_history([Event|History],NDepth).
583 debug_event(trace,Event) :-
584 Event = wake(_), !,
585 get_debug_history(History,Depth),
586 NDepth is Depth + 1,
587 chr_debug_interact(Event,NDepth),
588 set_debug_history([Event|History],NDepth).
589 debug_event(trace,Event) :-
590 Event = redo(_), !,
591 get_debug_history(_History, Depth),
592 chr_debug_interact(Event, Depth).
593 debug_event(trace,Event) :-
594 Event = exit(_),!,
595 get_debug_history([_|History],Depth),
596 chr_debug_interact(Event,Depth),
597 NDepth is Depth - 1,
598 set_debug_history(History,NDepth).
599 debug_event(trace,Event) :-
600 Event = fail(_),!,
601 get_debug_history(_,Depth),
602 chr_debug_interact(Event,Depth).
603 debug_event(trace, Event) :-
604 Event = remove(_), !,
605 get_debug_history(_,Depth),
606 chr_debug_interact(Event, Depth).
607 debug_event(trace, Event) :-
608 Event = insert(_), !,
609 get_debug_history(_,Depth),
610 chr_debug_interact(Event, Depth).
611 debug_event(trace, Event) :-
612 Event = try(_,_,_,_), !,
613 get_debug_history(_,Depth),
614 chr_debug_interact(Event, Depth).
615 debug_event(trace, Event) :-
616 Event = apply(_,_,_,_), !,
617 get_debug_history(_,Depth),
618 chr_debug_interact(Event,Depth).
620 debug_event(skip(_,_),Event) :-
621 Event = call(_), !,
622 get_debug_history(History,Depth),
623 NDepth is Depth + 1,
624 set_debug_history([Event|History],NDepth).
625 debug_event(skip(_,_),Event) :-
626 Event = wake(_), !,
627 get_debug_history(History,Depth),
628 NDepth is Depth + 1,
629 set_debug_history([Event|History],NDepth).
630 debug_event(skip(SkipSusp,SkipDepth),Event) :-
631 Event = exit(Susp),!,
632 get_debug_history([_|History],Depth),
633 ( SkipDepth == Depth,
634 SkipSusp == Susp ->
635 set_chr_debug(trace),
636 chr_debug_interact(Event,Depth)
638 true
640 NDepth is Depth - 1,
641 set_debug_history(History,NDepth).
642 debug_event(skip(_,_),_) :- !,
643 true.
645 % chr_debug_interact(+Event, +Depth)
647 % Interact with the user on Event that took place at Depth. First
648 % calls chr:debug_interact(+Event, +Depth, -Command) hook. If this
649 % fails the event is printed and the system prompts for a command.
651 chr_debug_interact(Event, Depth) :-
652 chr:debug_interact(Event, Depth, Command), !,
653 handle_debug_command(Command,Event,Depth).
654 chr_debug_interact(Event, Depth) :-
655 print_event(Event, Depth),
656 ( leashed(Event)
657 -> ask_continue(Command)
658 ; Command = creep
660 handle_debug_command(Command,Event,Depth).
662 leashed(Event) :-
663 functor(Event, Port, _),
664 nb_getval(chr_leash, mutable(Ports)),
665 memberchk(Port, Ports).
667 ask_continue(Command) :-
668 print_message(debug, chr(prompt)),
669 get_single_char(CharCode),
670 ( CharCode == -1
671 -> Char = end_of_file
672 ; char_code(Char, CharCode)
674 ( debug_command(Char, Command)
675 -> print_message(debug, chr(command(Command)))
676 ; print_message(help, chr(invalid_command)),
677 ask_continue(Command)
681 'chr debug command'(Char, Command) :-
682 debug_command(Char, Command).
684 debug_command(c, creep).
685 debug_command(' ', creep).
686 debug_command('\r', creep).
687 debug_command(s, skip).
688 debug_command(g, ancestors).
689 debug_command(n, nodebug).
690 debug_command(a, abort).
691 debug_command(f, fail).
692 debug_command(b, break).
693 debug_command(?, help).
694 debug_command(h, help).
695 debug_command(end_of_file, exit).
698 handle_debug_command(creep,_,_) :- !.
699 handle_debug_command(skip, Event, Depth) :- !,
700 Event =.. [Type|Rest],
701 ( Type \== call,
702 Type \== wake ->
703 handle_debug_command('c',Event,Depth)
705 Rest = [Susp],
706 set_chr_debug(skip(Susp,Depth))
709 handle_debug_command(ancestors,Event,Depth) :- !,
710 print_chr_debug_history,
711 chr_debug_interact(Event,Depth).
712 handle_debug_command(nodebug,_,_) :- !,
713 chr_notrace.
714 handle_debug_command(abort,_,_) :- !,
715 abort.
716 handle_debug_command(exit,_,_) :- !,
717 halt.
718 handle_debug_command(fail,_,_) :- !,
719 fail.
720 handle_debug_command(break,Event,Depth) :- !,
721 break,
722 chr_debug_interact(Event,Depth).
723 handle_debug_command(help,Event,Depth) :- !,
724 print_message(help, chr(debug_options)),
725 chr_debug_interact(Event,Depth).
726 handle_debug_command(Cmd, _, _) :-
727 throw(error(domain_error(chr_debug_command, Cmd), _)).
729 print_chr_debug_history :-
730 get_debug_history(History,Depth),
731 print_message(debug, chr(ancestors(History, Depth))).
733 print_event(Event, Depth) :-
734 print_message(debug, chr(event(Event, Depth))).
736 % {set,get}_debug_history(Ancestors, Depth)
738 % Set/get the list of ancestors and the depth of the current goal.
740 get_debug_history(History,Depth) :-
741 nb_getval(chr_debug_history,mutable(History,Depth)).
743 set_debug_history(History,Depth) :-
744 nb_getval(chr_debug_history,Mutable),
745 setarg(1,Mutable,History),
746 setarg(2,Mutable,Depth).
748 set_chr_debug(State) :-
749 nb_getval(chr_debug,Mutable),
750 setarg(1,Mutable,State).
752 'chr chr_indexed_variables'(Susp,Vars) :-
753 Susp =.. [_,_,_,_,_,_,_|Args],
754 term_variables(Args,Vars).