1/* Part of LogicMOO Base Logicmoo Debug Tools
    2% ===================================================================
    3% File '$FILENAME.pl'
    4% Purpose: An Implementation in SWI-Prolog of certain debugging tools
    5% Maintainer: Douglas Miles
    6% Contact: $Author: dmiles $@users.sourceforge.net ;
    7% Version: '$FILENAME.pl' 1.0.0
    8% Revision: $Revision: 1.1 $
    9% Revised At:  $Date: 2002/07/11 21:57:28 $
   10% Licience: LGPL
   11% ===================================================================
   12*/
   13:- module(rtrace,
   14   [
   15   restart_rtrace/0,
   16   tAt_rtrace/0,
   17      rtrace/1,  % Non-interactive tracing
   18      rtrace_break/1,  % Interactive tracing
   19      quietly/1,  % Non-det notrace/1
   20      restore_trace/1, % After call restore trace/debug settings
   21      rtrace/0, % Start non-intractive tracing
   22      srtrace/0, % Start non-intractive tracing at System level
   23      nortrace/0, % Stop non-intractive tracing
   24      push_tracer/0,pop_tracer/0,reset_tracer/0, % Reset Tracer to "normal"
   25      on_x_debug/1, % Non-intractive tracing when exception occurs
   26      on_f_rtrace/1, % Non-intractive tracing when failure occurs
   27      maybe_leash/1, % Set leash only when it makes sense
   28      should_maybe_leash/0,
   29      non_user_console/0,
   30      ftrace/1, % rtrace showing only failures
   31      visible_rtrace/2,
   32      push_guitracer/0,pop_guitracer/0,
   33      on_x_rtrace/1,
   34      call_call/1
   35   ]).   36
   37
   38:- set_module(class(library)).   39:- module_transparent(nortrace/0).   40:- system:use_module(library(logicmoo_startup)).   41
   42%:- prolog_load_context(directory,Dir),add_file_search_path_safe(library,Dir).
   43
   44
   45
   46:-thread_local(t_l:rtracing/0).   47:-thread_local(t_l:tracer_reset/1).   48:-thread_local(t_l:was_gui_tracer/1).   49:-thread_local(t_l:wastracer/1).   50
   51:- 'meta_predicate'(call_call(:)).   52call_call(G):-call(G).
   53
   54
   55:- meta_predicate
   56   rtrace(:),
   57   restore_trace(:),
   58   on_x_debug(:),
   59   on_f_rtrace(:),
   60
   61   rtrace_break(:),
   62   quietly(:),
   63   quietly1(:),
   64   quietly2(:),
   65   quietly3(:),
   66   quietly4(:),
   67   ftrace(:),
   68   visible_rtrace(+,:).
 on_f_rtrace(:Goal) is det
If :Goal fails trace it
   76% on_f_rtrace(Goal):-  Goal *-> true; ((nortrace,notrace,debugCallWhy(failed(on_f_rtrace(Goal)),Goal)),fail).
   77
   78on_f_rtrace(Goal):-  Goal *-> true; (ignore(rtrace(Goal)),debugCallWhy(on_f_rtrace(Goal),Goal)).
   79
   80
   81:- meta_predicate on_x_rtrace(*).   82on_x_rtrace(G):-on_x_debug(G).
 on_x_debug(:Goal) is det
If there If Is an exception in :Goal then rtrace.
   88on_x_debug(Goal):-
   89 ((( tracing; t_l:rtracing),!,maybe_leash(+exception)))
   90  -> Goal
   91   ;
   92   (catchv(quietly(Goal),E,(ignore(debugCallWhy(on_x_debug(E,Goal),rtrace(Goal))),throw(E)))).
   93
   94
   95
   96unhide(Pred):- old_set_predicate_attribute(Pred, trace, true),mpred_trace_childs(Pred).
 maybe_leash(+Flags) is det
Only leashes interactive consoles
  102maybe_leash(Some):- is_list(Some),!,maplist(maybe_leash,Some).
  103maybe_leash(-Some):- !, leash(-Some).
  104maybe_leash(Some):- notrace((should_maybe_leash->leash(Some);true)).
  105
  106old_swi(_).
  107with_unlocked_pred_local(MP,Goal):- strip_module(MP,M,P),Pred=M:P,
  108   (predicate_property(Pred,foreign)-> true ;
  109 setup_call_cleanup(unlock_predicate(Pred),
  110   catch(Goal,E,throw(E)),lock_predicate(Pred))),!.
  111
  112my_totally_hide(G):-
  113  with_unlocked_pred_local(G, '$hide'(G)), old_swi(totally_hide(G)).
  114
  115:- my_totally_hide(maybe_leash/1).  116
  117should_maybe_leash:- notrace((\+ current_prolog_flag(runtime_must,keep_going), \+ non_user_console)).
  118
  119%non_user_console:- !,fail.
  120non_user_console:- notrace(non_user_console0).
  121non_user_console0:- thread_self(main),!,fail.
  122non_user_console0:- \+ stream_property(current_input, tty(true)),!.
  123non_user_console0:- \+ stream_property(current_input,close_on_abort(false)).
 get_trace_reset(-Reset) is det
Get Tracer Reset.
  128get_trace_reset(Reset):- tracing, notrace, !,
  129                '$leash'(OldL, OldL),'$visible'(OldV, OldV),
  130		 (current_prolog_flag(gui_tracer, GuiWas)->true;GuiWas=false),
  131                 reset_macro(tAt(GuiWas,OldV,OldL,tracing),Reset),
  132		 trace,!.
  133get_trace_reset(Reset):-
  134                 '$leash'(OldL, OldL),'$visible'(OldV, OldV),
  135                 current_prolog_flag(debug,WasDebug),
  136		 (current_prolog_flag(gui_tracer, GuiWas)->true;GuiWas=false),
  137                 reset_macro(tAt(GuiWas,OldV,OldL,WasDebug),Reset),!.
  138
  139reset_macro(tAt(false, 271, 271, false),tAt_normal).
  140reset_macro(tAt(false, 319, 256, tracing),tAt_rtrace).
  141reset_macro(tAt(false, 271, 319, false),tAt_quietly).
  142reset_macro(X,X).
  143
  144:- my_totally_hide(get_trace_reset/1).  145tAt_normal:- tAt(false, 271, 271, false).
  146tAt_rtrace:- tAt(false, 319, 256, tracing).
  147tAt_quietly:- tAt(false, 271, 319, false).
  148system:tAt(GuiWas,OldV,OldL,WasDebug):-
  149  notrace, set_prolog_flag(gui_tracer,GuiWas),
  150  '$leash'(_, OldL),'$visible'(_, OldV),
  151   (WasDebug\==tracing->set_prolog_flag(debug,WasDebug) ;trace).
  152
  153:- my_totally_hide(tAt/4).  154:- my_totally_hide(tAt_normal/0).  155:- my_totally_hide(tAt_rtrace/0).  156:- my_totally_hide(tAt_quietly/0).
 push_guitracer is det
Save Guitracer.
  164push_guitracer:-  notrace(ignore(((current_prolog_flag(gui_tracer, GuiWas);GuiWas=false),asserta(t_l:was_gui_tracer(GuiWas))))).
  165:- my_totally_hide(push_guitracer/0).
 pop_guitracer is det
Restore Guitracer.
  172pop_guitracer:- notrace(ignore(((retract(t_l:was_gui_tracer(GuiWas)),set_prolog_flag(gui_tracer, GuiWas))))).
  173:- my_totally_hide(pop_guitracer/0).
 push_tracer is det
Push Tracer.
  180push_tracer:- get_trace_reset(Reset)->asserta(t_l:tracer_reset(Reset)).
  181:- my_totally_hide(push_tracer/0).
 pop_tracer is det
Pop Tracer.
  187pop_tracer:- notrace((retract(t_l:tracer_reset(Reset))))->Reset;notrace(true).
  188:- my_totally_hide(pop_tracer/0).
 reset_tracer is det
Reset Tracer.
  194reset_tracer:- ignore((t_l:tracer_reset(Reset)->Reset;true)).
  195:- my_totally_hide(reset_tracer/0).  196
  197
  198:- multifile(user:prolog_exception_hook/4).  199:- dynamic(user:prolog_exception_hook/4).  200:- module_transparent(user:prolog_exception_hook/4).  201
  202% Make sure interactive debugging is turned back on
  203
  204user:prolog_exception_hook(error(_, _),_, _, _) :- leash(+all),fail.
  205
  206user:prolog_exception_hook(error(_, _),_, _, _) :- fail,
  207   notrace((  reset_tracer ->
  208     should_maybe_leash ->
  209     t_l:rtracing ->
  210     leash(+all),
  211     fail)).
 quietly(:Goal) is nondet
Unlike notrace/1, it allows nondet tracing

But also may be break when excpetions are raised during Goal.

version 21

  220quietly1(Goal):- \+ tracing -> Goal ; scce_orig(notrace,Goal,trace).
  221
  222% version 2
  223quietly2(Goal):- \+ tracing -> Goal ; (setup_call_cleanup(notrace,scce_orig(notrace,Goal,trace),trace)).
  224
  225:- old_swi('set_pred_attrs'(quietly(_),[trace=1,hide_childs=1])).  226
  227% version 3
  228% quietly(Goal):- !, Goal.  % for overiding
  229quietly3(Goal):- \+ tracing -> Goal ;
  230 (notrace,
  231  (((Goal,deterministic(YN))) *->
  232     (YN == true -> trace ; (trace;(notrace,fail)));
  233  (trace,!,notrace(fail)))).
  234
  235quietly(Goal):- quietly3(Goal).
  236
  237% version 4
  238quietly4(M:Goal):- \+ tracing
  239 -> M:Goal ;
  240  (get_trace_reset(W), scce_orig(notrace(visible(-all)),M:Goal,W)).
  241
  242
  243% :- 'my_totally_hide'(rtrace:quietly/1).
  244:- old_swi(old_set_predicate_attribute(rtrace:quietly/1, hide_childs, true)).  245:- '$hide'(quietly/1).  246
  247% Alt version?
  248quietlySE(Goal):- %JUNIT \+ tracing
  249 true
  250 -> Goal ;
  251 notrace((S = notrace, E = trace)),
  252 (S,
  253  (((Goal,deterministic(YN))) *->
  254     (YN == true -> E ; (E;(S,fail)));
  255  (E,!,notrace(fail)))).
  256
  257% Alt version?
  258rtraceSE(Goal):-
  259 notrace((S = rtrace, E = nortrace)),
  260 (S,
  261  (((Goal,deterministic(YN))) *->
  262     (YN == true -> E ; (E;(S,fail)));
  263  (E,!,notrace(fail)))).
  264
  265
  266
  267deterministically_must(G):- (call(call,G),deterministic(YN),true),
  268  (YN==true -> true;
  269     ((wdmsg(failed_deterministically_must(G)),(!)))),!.
  270
  271
  272%:- my_totally_hide(quietly/1).
 rtrace is det
Start RTracer.
  280rtrace:- push_tracer,start_rtrace,trace.
  281
  282:- 'my_totally_hide'(rtrace/0).  283
  284% start_rtrace:- notrace((t_l:rtracing, !,  leash(-all), assert(t_l:rtracing), push_guitracer)).
  285start_rtrace:-
  286      nodebug,
  287      leash(-all),
  288      assert(t_l:rtracing),
  289      push_guitracer,
  290      set_prolog_flag(gui_tracer,false),
  291      visible(+all),
  292      maybe_leash(+exception).
  293
  294:- 'my_totally_hide'(start_rtrace/0).
 srtrace is det
Start RTracer.
  300srtrace:- notrace, set_prolog_flag(access_level,system), rtrace.
  301
  302:- my_totally_hide(srtrace/0).  303:- system:import(srtrace/0).
 nortrace is det
Stop Tracer.
  310stop_rtrace:-
  311  notrace,
  312  maybe_leash(+all),
  313  visible(+all),
  314  maybe_leash(+exception),
  315  retractall(t_l:rtracing),
  316  !.
  317
  318:- 'my_totally_hide'(stop_rtrace/0).  319:- system:import(stop_rtrace/0).  320
  321nortrace:- stop_rtrace,ignore(pop_tracer).
  322
  323:- my_totally_hide(nortrace/0).  324
  325
  326
  327:- thread_local('$leash_visible'/2).
 restore_trace(:Goal) is det
restore Trace.

! restore_trace( :Goal) is det.

restore Trace.

  337restore_trace(Goal):-
  338  setup_call_cleanup(
  339   push_leash_visible,
  340   scce_orig(push_tracer,Goal,pop_tracer),
  341   restore_leash_visible).
  342
  343restore_trace0(Goal):-
  344  '$leash'(OldL, OldL),'$visible'(OldV, OldV),
  345   scce_orig(restore_leash_visible,
  346   ((Goal*-> (push_leash_visible, '$leash'(_, OldL),'$visible'(_, OldV)) ; fail)),
  347   ('$leash'(_, OldL),'$visible'(_, OldV))).
  348
  349:- my_totally_hide(system:'$leash'/2).  350:- my_totally_hide(system:'$visible'/2).  351
  352push_leash_visible:- notrace((('$leash'(OldL0, OldL0),'$visible'(OldV0, OldV0), asserta('$leash_visible'(OldL0,OldV0))))).
  353restore_leash_visible:- notrace((('$leash_visible'(OldL1,OldV1)->('$leash'(_, OldL1),'$visible'(_, OldV1));true))).
  354
  355% restore_trace(Goal):- setup_call_cleanup(get_trace_reset(Reset),Goal,notrace(Reset)).
  356:- my_totally_hide(restore_trace/1).
 rtrace(:Goal) is nondet
Trace a goal non-interactively until the first exception on total failure

?- rtrace(member(X,[1,2,3])). Call: (9) [lists] lists:member(_7172, [1, 2, 3]) Unify: (9) [lists] lists:member(_7172, [1, 2, 3]) Call: (10) [lists] lists:member_([2, 3], _7172, 1) Unify: (10) [lists] lists:member_([2, 3], 1, 1) Exit: (10) [lists] lists:member_([2, 3], 1, 1) Exit: (9) [lists] lists:member(1, [1, 2, 3]) X = 1 ; Redo: (10) [lists] lists:member_([2, 3], _7172, 1) Unify: (10) [lists] lists:member_([2, 3], _7172, 1) Call: (11) [lists] lists:member_([3], _7172, 2) Unify: (11) [lists] lists:member_([3], 2, 2) Exit: (11) [lists] lists:member_([3], 2, 2) Exit: (10) [lists] lists:member_([2, 3], 2, 1) Exit: (9) [lists] lists:member(2, [1, 2, 3]) X = 2 ; Redo: (11) [lists] lists:member_([3], _7172, 2) Unify: (11) [lists] lists:member_([3], _7172, 2) Call: (12) [lists] lists:member_([], _7172, 3) Unify: (12) [lists] lists:member_([], 3, 3) Exit: (12) [lists] lists:member_([], 3, 3) Exit: (11) [lists] lists:member_([3], 3, 2) Exit: (10) [lists] lists:member_([2, 3], 3, 1) Exit: (9) [lists] lists:member(3, [1, 2, 3]) X = 3.

?- rtrace(fail). Call: (9) [system] fail Fail: (9) [system] fail ^ Redo: (8) [rtrace] rtrace:rtrace(user:fail) false.

  397/*
  398  ?- rtrace((member(X,[writeln(1),throw(good),writen(failed)]),X)).
  399   Call: (10) [lists] lists:member(_13424, [writeln(1), throw(good), writen(failed)])
  400   Unify: (10) [lists] lists:member(_13424, [writeln(1), throw(good), writen(failed)])
  401   Call: (11) [lists] lists:member_([throw(good), writen(failed)], _13424, writeln(1))
  402   Unify: (11) [lists] lists:member_([throw(good), writen(failed)], writeln(1), writeln(1))
  403   Exit: (11) [lists] lists:member_([throw(good), writen(failed)], writeln(1), writeln(1))
  404   Exit: (10) [lists] lists:member(writeln(1), [writeln(1), throw(good), writen(failed)])
  405   Call: (10) [system] writeln(1)
  4061
  407   Exit: (10) [system] writeln(1)
  408X = writeln(1) ;
  409   Redo: (11) [lists] lists:member_([throw(good), writen(failed)], _13424, writeln(1))
  410   Unify: (11) [lists] lists:member_([throw(good), writen(failed)], _13424, writeln(1))
  411   Call: (12) [lists] lists:member_([writen(failed)], _13424, throw(good))
  412   Unify: (12) [lists] lists:member_([writen(failed)], throw(good), throw(good))
  413   Exit: (12) [lists] lists:member_([writen(failed)], throw(good), throw(good))
  414   Exit: (11) [lists] lists:member_([throw(good), writen(failed)], throw(good), writeln(1))
  415   Exit: (10) [lists] lists:member(throw(good), [writeln(1), throw(good), writen(failed)])
  416   Call: (10) [system] throw(good)
  417ERROR: Unhandled exception: good
  418*/
  419
  420set_leash_vis(OldL,OldV):- '$leash'(_, OldL),'$visible'(_, OldV),!.
  421:- my_totally_hide(set_leash_vis/2).  422
  423restart_rtrace:- restart_rtrace1,!.
  424restart_rtrace.
  425restart_rtrace1:-
  426   notrace,leash(-all),
  427   set_prolog_flag(gui_tracer,false),
  428   visible(+all),
  429   maybe_leash(+exception),
  430   trace.
  431:- 'my_totally_hide'(restart_rtrace/0).  432:- export(restart_rtrace/0).  433
  434rtrace(Goal):- %trace,
  435  get_trace_reset(W),scce_orig(restart_rtrace,Goal,W).
  436
  437%:- '$hide'(system:tracing/0).
  438%:- '$hide'(system:notrace/1).
  439%:- old_set_predicate_attribute(system:notrace/1, hide_childs, true).
  440%:- '$hide'(system:notrace/0).
  441%:- '$hide'(system:trace/0).
  442
  443:- 'my_totally_hide'(rtrace:rtrace/1).  444:- old_swi(old_set_predicate_attribute(rtrace:rtrace/1, hide_childs, false)).  445:- '$hide'(rtrace:reset_rtrace0/1).  446:- old_swi(old_set_predicate_attribute(rtrace:reset_rtrace0/1, hide_childs, true)).  447%:- old_set_predicate_attribute(rtrace:reset_rtrace0/1, hide_childs, false).
 rtrace_break(:Goal) is nondet
Trace a goal non-interactively and break on first exception or on total failure
  455rtrace_break(Goal):- \+ should_maybe_leash, !, rtrace(Goal).
  456rtrace_break(Goal):- stop_rtrace,trace,debugCallWhy(rtrace_break(Goal),Goal).
  457%:- my_totally_hide(rtrace_break/1).
  458:- old_swi(old_set_predicate_attribute(rtrace_break/1, hide_childs, false)).  459
  460:- export(old_swi/1).  461
  462
  463
  464%:- '$hide'(quietly/1).
  465%:- if_may_hide('my_totally_hide'(notrace/1,  hide_childs, 1)).
  466%:- if_may_hide('my_totally_hide'(notrace/1)).
  467:- my_totally_hide(system:tracing/0).  468:- my_totally_hide(system:notrace/0).  469:- my_totally_hide(system:notrace/1).  470:- my_totally_hide(system:trace/0).
 ftrace(:Goal) is nondet
Trace failure.
  476ftrace(Goal):- visible_rtrace([-all,+unify,+fail,+exception],Goal).
  477
  478etrace(Goal):- visible_rtrace([-all,+exception],Goal).
  479
  480visible_rtrace(List,Goal):-
  481 restore_trace((
  482   visible(-all), visible(+exception),
  483   maplist(visible,List),
  484   maybe_leash(-all),maybe_leash(+exception),trace,Goal)).
  485
  486
  487
  488how_must(How, Goal):- locally(set_prolog_flag(runtime_must,How),Goal).
  489
  490keep_going(Goal):- how_must(keep_going, Goal).
  491
  492ignore_must(Goal):- how_must(fail, Goal).
  493
  494
  495
  496:- ignore((source_location(S,_),prolog_load_context(module,M),module_property(M,class(library)),
  497 forall(source_file(M:H,S),
  498 ignore((functor(H,F,A),
  499  ignore(((\+ atom_concat('$',_,F),(export(F/A) , current_predicate(system:F/A)->true; system:import(M:F/A))))),
  500  ignore(((\+ predicate_property(M:H,transparent), module_transparent(M:F/A), \+ atom_concat('__aux',_,F),
  501   prolog_debug:debug(modules,'~N:- module_transparent((~q)/~q).~n',[F,A]))))))))).  502
  503% % % OFF :- system:use_module(library(logicmoo_utils_all)).
  504:- fixup_exports.  505:- my_totally_hide('$toplevel':save_debug/0).  506:- my_totally_hide('$toplevel':toplevel_call/1).  507%:- my_totally_hide('$toplevel':residue_vars/2).
  508:- my_totally_hide('$toplevel':save_debug/1).  509:- my_totally_hide('$toplevel':no_lco/1).  510%:- ignore(rtrace(non_user_console)).
  511:- '$hide'(rtrace/1).