1/* Part of LogicMOO Base logicmoo_util_bb_env
    2% Provides a prolog database *env*
    3% ===================================================================
    4% File '$FILENAME.pl'
    5% Purpose: An Implementation in SWI-Prolog of certain debugging tools
    6% Maintainer: Douglas Miles
    7% Contact: $Author: dmiles $@users.sourceforge.net ;
    8% Version: '$FILENAME.pl' 1.0.0
    9% Revision: $Revision: 1.1 $
   10% Revised At:  $Date: 2002/07/11 21:57:28 $
   11% Licience: LGPL
   12% ===================================================================
   13*/

   14
   15% File: /opt/PrologMUD/pack/logicmoo_base/prolog/logicmoo/util/logicmoo_util_structs.pl
   16:- module(ru,
   17[	% uses_predicate/3,
   18         uses_undefined_hook/0,
   19         install_retry_undefined/2,
   20         % uses_predicate/5,
   21         %     retry_undefined/3,
   22         is_parent_goal/1,
   23         is_parent_goal/2,
   24         is_parent_goal/1,
   25         is_parent_goal/2
   26]).
   27
   28:- thread_local(was_prolog_flag/1).
   29:- current_prolog_flag(retry_undefined,Was)->asserta(was_prolog_flag(retry_undefined,Was));asserta(was_prolog_flag(retry_undefined,none)).
   30%:- use_module(library(loop_check)).
   31:- use_module(library(bugger)).
   32:- use_module(library(hook_database)).
   33
   34:- create_prolog_flag(retry_undefined, none,[type(term),keep(false)]).
   35
   36:- module_transparent((	
   37   uses_predicate/2,
   38   uses_undefined_hook/0,				
   39   uses_predicate/5,
   40   retry_undefined/3,
   41   is_parent_goal/1,
   42   install_retry_undefined/2,
   43   is_parent_goal/2,
   44   is_parent_goal/1,
   45   get_retry_undefined_hook/2,
   46   is_parent_goal/2)).
   47
   48:- dynamic(ru:retry_undefined_hook/2).
   49
   50get_retry_undefined_hook(X,Y):- ru:retry_undefined_hook(X,Y).
   51get_retry_undefined_hook(_M,Was):- current_prolog_flag(retry_undefined, Was), Was\==module.
   52
   53install_retry_undefined(Module,Setting):- asserta((ru:retry_undefined_hook(Module,Was):-!,Was=Setting)).
   54
   55:- install_retry_undefined('$toplevel',error).
   56:- install_retry_undefined('user',error).
   57
   58uses_undefined_hook.
   59
   60
   61
   62 :- meta_predicate uses_predicate(*,*,*,*,*,*).
   63 :- meta_predicate uses_predicate(*,*,*,*,*,*).
   64 :- meta_predicate uses_predicate(1,*,*,*,*,*).
   65
   66
   67dumpST_dbreak:- dumpST,break.
   68
   69% baseKBOnly mark_mark/3 must be findable from every module (dispite the fact that baseKB is not imported)
   70% :- dynamic baseKB:mpred_prop/4.
   71
   72% hybrid_support (like spft/3) must be defined directly in every module and then aggregated thru genlMts (thus to baseKB)
   73/*
   74is_parent_goal(G):- prolog_current_frame(F),is_parent_goal(F,G).
   75% The user must ensure the checked parent goal is not removed from the stack due 
   76% to last-call optimisation 
   77is_parent_goal(F,G):- nonvar(G),prolog_frame_attribute(F,parent_goal, G).
   78%and be aware of the slow operation on deeply nested calls.
   79is_parent_goal(F,G):- prolog_frame_attribute(F,parent,P),parent_frame_goal(P,G).
   80
   81parent_frame_goal(F,V):- parent_frame_goal_0(F,V0),contains_goalf(V0,V).
   82parent_frame_goal_0(F,V):- prolog_frame_attribute(F,goal,V);
   83   (prolog_frame_attribute(F,parent,P),parent_frame_goal_0(P,V)).
   84
   85contains_goalf(V0,V):- nonvar(V),same_goalf(V0,V),!.
   86contains_goalf(V0,_):- \+ compound(V0),!,fail.
   87contains_goalf(V0,V):- var(V),same_goalf(V0,V).
   88contains_goalf(_:V0,V):- !, contains_goalf(V0,V).
   89contains_goalf('$execute_directive_3'(V0),V):-!, same_goalf(V0,V).
   90contains_goalf('<meta-call>'(V0),V):-!, same_goalf(V0,V).
   91contains_goalf(catch(V0,_,_),V):- same_goalf(V0,V).
   92contains_goalf(catch(_,_,V0),V):- same_goalf(V0,V).
   93same_goalf(V,V).
   94*/

   95
   96% make sure we ignore calls to predicate_property/2  (or thus '$define_predicate'/1)
   97uses_predicate(_DEF,_,_,_,_,Error):- 
   98   prolog_current_frame(F), (is_parent_goal(F,'$define_predicate'(_));
   99   (is_parent_goal(F,_:'assert_u'(_)));is_parent_goal(F,'$syspreds':property_predicate(_,_))),!,
  100   error = Error.
  101
  102uses_predicate(_Was,_CM,_M,_F,_A,Error):- is_parent_goal(check:check),!,Error=error.
  103uses_predicate(_Was,_CM,_M,_F,_A,Error):- is_parent_goal(check:check),!,Error=error.
  104uses_predicate(_Was,_CM,_M,_F,_A,Error):- show_success(is_parent_goal('$define_predicate')),!,Error=error.
  105
  106uses_predicate(_Was,_CM,'$toplevel',_F,_A,Error):- !,Error=error.
  107
  108uses_predicate(_DEF,_, _, ~, 1, error) :- !.
  109uses_predicate(_DEF,_,CallerMt,'$pldoc',4,retry):- make_as_dynamic(uses_predicate,CallerMt,'$pldoc',4),!.
  110uses_predicate(_DEF,User, User, module, 2, error):-!.
  111uses_predicate(_DEF,_,_, (:-), _, error) :- !, fail. 
  112uses_predicate(_DEF,_,_, (/), _, error) :- !. 
  113uses_predicate(_DEF,_,_, ( '//' ), _, error) :- !. 
  114uses_predicate(_DEF,_,_, F, _, error) :- atom_concat('__',_,F),!.
  115uses_predicate(_DEF,_,_, F, _, error) :- atom_concat('$',_,F),!.
  116
  117uses_predicate(_DEF,_,_, (:), _, error) :- !. % ,dumpST_dbreak.
  118% uses_predicate(_DEF,_,_, '[|]', _, error) :- !,dumpST_dbreak.
  119% uses_predicate(_DEF,_,_, '>>',  4, error) :- !,dumpST_dbreak.
  120% uses_predicate(_DEF,_,M, inherit_above,_,retry):- M:use_module(library(virtualize_source)).
  121
  122% makes sure we ignore calls to predicate_property/2  (or thus '$define_predicate'/1)
  123% uses_predicate(_DEF,_,M,F,A,R):- prolog_current_frame(FR), functor(P,F,A),(prolog_frame_attribute(FR,parent_goal,predicate_property(M:P,_))),!,R=error.
  124uses_predicate(_DEF,_,Module,Name,Arity,Action) :-
  125      current_prolog_flag(autoload, true),
  126	'$autoload'(Module, Name, Arity), !,
  127	Action = retry.
  128
  129
  130uses_predicate(E,_,_,_,_,Error):- E=error, !,Error=error.
  131uses_predicate(fail,_,_,_,_,_):- !,fail.
  132uses_predicate(break,_,_,_,_,Error):- !,dumpST_dbreak,Error=error.
  133
  134
  135uses_predicate(_DEF,_,System, _,_, error):- module_property(System,class(system)),!.
  136uses_predicate(_DEF,_,System, _,_, error):- module_property(System,class(library)),!.
  137
  138uses_predicate(Setting,SM,M,F,A,Act):- Setting\==kb_shared, SM\==user, M\==baseKB,
  139     (dmsg(uses_predicate(Setting,SM,M,F,A,Act))),fail.
  140
  141uses_predicate(kb_shared,System, M, F,A, retry):-   
  142   show_failure(uses_undefined_hook(M)),
  143   create_predicate_inheritance(kb_shared(M:F/A),M,F,A),
  144   nop(System:import(M:F/A)),!.
  145
  146% uses_predicate(true,_, M,F,A, Retry):-  retry_undefined(M,F,A),!,Retry=retry.
  147
  148uses_predicate(_,_, M,F,A, Retry):-  retry_undefined(M,F,A),!,Retry=retry.
  149
  150uses_predicate(DEF,_, M, F,A, Retry):-  call(DEF, M:F/A),!,Retry=retry.
  151
  152:- if(\+ current_predicate(autoload_library_index/4)).
  153in_autoload_library_index(F,A,_PredMt,File):- '$in_library'(F,A,File).
  154:- else.
  155in_autoload_library_index(F,A,PredMt,File):- autoload_library_index(F,A,PredMt,File).
  156:- endif.
  157
  158:- meta_predicate with_no_retry_undefined(:).
  159with_no_retry_undefined(Goal):- locally(set_prolog_flag(retry_undefined, none),
  160                                     locally(set_prolog_flag(runtime_debug,0),Goal)).
  161
  162
  163% Every module has it''s own
  164retry_undefined(CallerMt,'$pldoc',4):- multifile(CallerMt:'$pldoc'/4),discontiguous(CallerMt:'$pldoc'/4),dynamic(CallerMt:'$pldoc'/4),!.
  165% System-like Autoloads (TODO: confirm these can be removed)
  166retry_undefined(CallerMt,debug,1):- use_module(CallerMt:library(debug)),!.
  167retry_undefined(CallerMt,debugging,1):- use_module(CallerMt:library(debug)),!.
  168retry_undefined(CallerMt,member,2):- use_module(CallerMt:library(lists)),!.
  169retry_undefined(CallerMt,directory_file_path,3):- use_module(CallerMt:library(filesex)),!.
  170% 3 very special Mts
  171% Module defines the type
  172% retry_undefined(baseKB,F,A):- make_as_dynamic(retry_undefined(baseKB),baseKB,F,A),!.
  173retry_undefined(lmcache,F,A):- volatile(lmcache:F/A),make_as_dynamic(retry_undefined(lmcache),lmcache,F,A),!.
  174retry_undefined(t_l,F,A):- thread_local(t_l:F/A),!,make_as_dynamic(retry_undefined(t_l),t_l,F,A),!.
  175
  176
  177:- if(false).
  178
  179% adult-like Mt
  180retry_undefined_falsed_out(Mt, F, A):-  clause_b(mtCycLBroad(Mt)), clause_b(hybrid_support(F,A)),
  181   make_as_dynamic(mtCycLBroad(Mt),Mt,F,A).
  182
  183% child-like Mt
  184retry_undefined_falsed_out(CallerMt,F,A):- clause_b(mtGlobal(CallerMt)), clause_b(hybrid_support(F,A)),
  185   % find_and_call(baseKB:mtGlobal(CallerMt)),
  186   create_predicate_inheritance(retry_undefined_falsed_out(CallerMt:F/A),CallerMt,F,A).
  187
  188% import built-ins ?
  189retry_undefined_falsed_out(CallerMt,F,A):- current_predicate(system:F/A), current_module(M),M\=system,
  190  current_predicate(M:F/A),functor(P,F,A),predicate_property(M:P,defined),\+predicate_property(M:P,imported_from(_)),
  191  CallerMt:import(M:F/A).
  192
  193% our autoloader hacks
  194retry_undefined_falsed_out(CallerMt,F,A):-
  195   in_autoload_library_index(F,A,_PredMt,File),
  196   use_module(CallerMt:File),!.
  197
  198% Autoloads importing the entire other module
  199retry_undefined_falsed_out(CallerMt,F,A):- fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,
  200       in_autoload_library_index(F,A,PredMt,File),
  201       asserta(lmcache:how_registered_pred(PredMt:use_module(CallerMt:File),CallerMt,F,A)),
  202       use_module(system:File),!.
  203       % system:add_import_module(CallerMt,system,start).
  204
  205
  206retry_undefined_falsed_out(CallerMt,F,A):- fail,
  207       in_autoload_library_index(F,A,_,File),
  208       load_files(CallerMt:File,[if(true),imports([F/A]),register(false),silent(false)]),!.
  209
  210% Autoloads importing the entire other module
  211retry_undefined_falsed_out(CallerMt,F,A):- fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,
  212       in_autoload_library_index(F,A,PredMt,File),
  213       asserta(lmcache:how_registered_pred(PredMt:use_module(CallerMt:File),CallerMt,F,A)),
  214       use_module(CallerMt:File),!.
  215
  216/*
  217retry_undefined(CallerMt,F,A):-
  218      in_autoload_library_index(F,A,PredMt,File),
  219      ((current_module(PredMt),current_predicate(PredMt:F/A))
  220       -> add_import_module(CallerMt,PredMt,start) ;
  221       (PredMt:ensure_loaded(PredMt:File),add_import_module(CallerMt,PredMt,start))),!.
  222*/

  223
  224retry_undefined_falsed_out(CallerMt,F,A):- fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,fail,
  225   functor(P,F,A),find_module(P,M),show_call(CallerMt:import(M:F/A)),!.
  226
  227
  228
  229%retry_undefined(PredMt:must/1) % UNDO % :- add_import_module(PredMt,logicmoo_util_catch,start),!.
  230%retry_undefined(PredMt:debugm/2) % UNDO % :- add_import_module(PredMt,logicmoo_util_dmsg,start),!.
  231
  232:- endif.
  233
  234
  235
  236%uses_undefined_hook(CM):- (clause_b(genlMt(CM,_));clause_b(mtHybrid(CM))).
  237uses_undefined_hook(CM):- nonvar(CM),clause(mtNoInheritance(CM),true),!,fail.
  238uses_undefined_hook(CM):- clause_b(genlMt(CM,_)),!.
  239% uses_undefined_hook(CM):- is_pfc_module(CM),!.
  240uses_undefined_hook(baseKB).
  241%uses_undefined_hook(user).
  242
  243
  244user_exception_undefined_predicate(CM,M,F,A,ActionO):- 
  245  \+ prolog_load_context(reloading,true),
  246  current_prolog_flag(retry_undefined, Was), Was \== false, Was \== none,
  247  get_retry_undefined_hook(M,Setting),!, Setting\==error,    
  248   CM:setup_call_cleanup(set_prolog_flag(retry_undefined, false),
  249                      (uses_predicate(Setting,CM,M,F,A, ActionO), ActionO \== error),
  250                      set_prolog_flag(retry_undefined, Was)),!.
  251
  252
  253:- fixup_exports.
  254
  255:- multifile(prolog:make_hook/2).
  256:- dynamic(prolog:make_hook/2).
  257:- multifile(lmcache:was_retry_undefined/2).
  258:- dynamic(lmcache:was_retry_undefined/2).
  259:- dynamic(prolog:make_hook/2).
  260prolog:make_hook(before, C):- current_prolog_flag(retry_undefined, WAS),asserta(lmcache:was_retry_undefined(WAS,C)),set_prolog_flag(retry_undefined, false),fail.
  261
  262prolog:make_hook(after, C):- retract(lmcache:was_retry_undefined(WAS,C)),set_prolog_flag(retry_undefined, WAS),fail.
  263
  264:- multifile(user:exception/3).
  265:- module_transparent(user:exception/3).
  266:- dynamic(user:exception/3).
  267/*
  268user:exception(undefined_predicate, F/A, ActionO):- !, strip_module(F/A,CM,_), 
  269  user_exception_undefined_predicate(CM,CM,F,A, ActionO).
  270user:exception(undefined_predicate, M:F/A, ActionO):- !, strip_module(F/A,CM,_), 
  271  user_exception_undefined_predicate(CM,M,F,A, ActionO).
  272
  273*/