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(_))