% File: /opt/PrologMUD/pack/logicmoo_base/prolog/logicmoo/util/logicmoo_util_loop_check.pl :- module(loop_check, [ any_term_overlap/2, any_term_overlap_atoms_of/2, atoms_of_0/2, call_setof_tabled/4, call_t/1, call_tabled/1, call_tabled/2, call_tabled0/4, call_tabled1/4, call_vars_tabled/3, can_fail/1, cannot_table_call/1, cannot_use_tables/1, maybe_save_memoized_on/0, cc_key/2, ex/0, expire_dont_add/0, expire_tabled_list/1, findall_nodupes/3, get_where/1, get_where0/1, memoize_on/3, memoize_on/4, is_loop_checked/1, lco_goal_expansion/2, lex/0, cyclic_break/1, loop_check/1, loop_check/2, loop_check_early/2, loop_check_term/3, loop_check_term_key/3, make_key/2, make_tabled_perm/1, mpred_expire_caches/1, no_loop_check/1, no_loop_check/2, no_loop_check_term_key/3, outside_of_loop_check/0, really_can_table/0, reduce_make_key/2, retract_can_table/0, skipped_table_call/1, transitive/3, transitive_except/4, transitive_lc/3 ]). :- multifile system:goal_expansion/2. :- meta_predicate call_setof_tabled(?, ?, 0, -), call_t(0), call_tabled(0), call_tabled(?, 0), call_tabled0(?, ?, ?, ?), call_tabled1(?, ?, ?, ?), call_vars_tabled(?, ?, 0), cannot_table_call(0), cannot_use_tables(0), findall_nodupes(?, 0, -), loop_check(0), loop_check(0, 0), loop_check_early(0, 0), loop_check_term(0, ?, 0), loop_check_term_key(0, ?, 0), make_tabled_perm(0), memoize_on(+,+,0), memoize_on(+,+,+,0), no_loop_check(0), no_loop_check(0, 0), no_loop_check_term_key(0, ?, 0), reduce_make_key(+, -), skipped_table_call(0), transitive(2, +, -), transitive_except(+, 2, +, -), transitive_lc(2, +, -). :- meta_predicate(go_as_last(0,0)). :- meta_predicate no_loop_check(0). :- meta_predicate no_loop_check(0,0). :- meta_predicate no_loop_check_term_key(0,?,0). :- meta_predicate call_tabled(?,0). :- meta_predicate loop_check(0). :- meta_predicate loop_check(0,0). :- meta_predicate call_tabled1(*,?,0,-). :- meta_predicate call_tabled0(*,?,0,-). :- export(go_as_last/2). :- thread_local lmcache:going_last/1. % go_as_last(Call1,Call2):- \+ lmcache:going_last(Call1),locally(lmcache:going_last(Call1), (Call1->true;(must(catch(Call2,_,fail))))),!. end_of_file. end_of_file. end_of_file. end_of_file. end_of_file. end_of_file. end_of_file. end_of_file. end_of_file. end_of_file. end_of_file. end_of_file. end_of_file. end_of_file. end_of_file. /* :- meta_predicate call_no_cuts_loop_checked(0). :- module_transparent call_no_cuts_loop_checked/1. :- meta_predicate call_no_cuts_loop_checked(0,0). :- module_transparent call_no_cuts_loop_checked/2. call_no_cuts_loop_checked(Call):-call_no_cuts_loop_checked(Call, fail). call_no_cuts_loop_checked(Call, TODO):-!, loop_check(Call,TODO). call_no_cuts_loop_checked(Call, TODO):- clause(Call,Body),make_key(Body,Key),loop_check_term(Body,Key,TODO). */ % ===================================================================================================================== :- export((call_tabled/2)). :- export((cannot_table_call/1)). :- export((cannot_use_tables/1)). :- export((skipped_table_call/1)). % ===================================================================================================================== :- meta_predicate call_tabled(0). :- module_transparent call_tabled/1. :- meta_predicate call_vars_tabled(?,?,0). :- module_transparent call_vars_tabled/3. % = :- meta_predicate((cannot_table_call(0))). % = :- meta_predicate((cannot_use_tables(0))). % = :- meta_predicate((skipped_table_call(0))). :- meta_predicate call_setof_tabled(?,?,0,-). :- meta_predicate findall_nodupes(?,0,-). :- module_transparent call_setof_tabled/4. :- dynamic(lmcache:call_tabled_cached_results/2). :- dynamic(lmcache:call_tabled_perm/2). :- thread_local lmcache:maybe_table_key/1. %= %% retract_can_table is semidet. % % Retract Can Table. % retract_can_table :- retractall(maybe_table_key(_)). % = :- meta_predicate(make_key(?,-)). :- multifile(baseKB:mpred_on_expire_caches/1). :- dynamic(baseKB:mpred_on_expire_caches/1). :- module_transparent((ex)/0). :- dynamic(baseKB:already_added_this_round/1). :- export(baseKB:already_added_this_round/1). %= %% expire_dont_add is semidet. % % Expire Dont Add. % expire_dont_add:-retractall(baseKB:already_added_this_round(_)),mpred_expire_caches(all),nop(dmsg(expire_dont_add)). %= %% lex is semidet. % % Lex. % lex:-listing(lmcache:ilc(_)),forall(current_predicate(lmcache:F/A),listing(lmcache:F/A)), catch(listing(baseKB:already_added_this_round),_,true). %= %% ex is semidet. % % Ex. % (ex):-mpred_expire_caches(_),retractall(lmcache:ilc(_)),dmsg_showall(_),forall(current_predicate(lmcache:F/A),(functor(RA,F,A),retractall(RA))), catch(expire_dont_add,_,true). %= %% mpred_expire_caches( ?A) is semidet. % % Managed Predicate Expire Caches. % mpred_expire_caches(A):-doall(call_no_cuts(must(baseKB:mpred_on_expire_caches(A)))). :-multifile(baseKB:mpred_on_expire_caches/1). :-asserta((baseKB:mpred_on_expire_caches(A):-expire_tabled_list(A))). %= %= %% any_term_overlap_atoms_of( ?A1, ?T2) is semidet. % % Any Term Overlap Atoms Of. % any_term_overlap_atoms_of(A1,T2):-atoms_of_0(T2,A2),!,member(A,A1),member(A,A2),!. %= %% any_term_overlap( ?T1, ?T2) is semidet. % % Any Term Overlap. % any_term_overlap(T1,T2):- atoms_of_0(T1,A1),atoms_of_0(T2,A2),!,member(A,A1),member(A,A2),!. % = :- meta_predicate(make_tabled_perm(0)). %= %% make_tabled_perm( :GoalCall) is semidet. % % Make Tabled Perm. % make_tabled_perm(Call):- must(really_can_table),must(outside_of_loop_check), term_variables(Call,Vars),!,make_key(Vars+Call,LKey),reduce_make_key(LKey,Key), findall(Vars,locally_hide(lmcache:cannot_save_table,no_loop_check(no_repeats_old(Call))),KList), must(KList=[_|_]),!, asserta(lmcache:call_tabled_perm(Key,KList)),!, member(Vars,KList). memoize_on(M,(In->_),G):- \+ ground(In),nop((retractall(lmcache:memoized_on(M,In,_)))),!,G,!. % memoize_on(M,(In->Out),G):-make_key(In,Key),memoize_on(M,Key,Out,G). memoize_on(M,(In->Out),G):- memoize_on(M,In,Out,G),!. :- multifile(lmcache:cached_memoized_on/3). :- dynamic(lmcache:cached_memoized_on/3). memoize_on(M,In,Out,_):- lmcache:cached_memoized_on(M,In,Out),!. memoize_on(M,In,Out,G):- G,!,call(assert_if_new,lmcache:cached_memoized_on(M,In,Out)),!, maybe_save_memoized_on. maybe_save_memoized_on:-!. maybe_save_memoized_on:- flag('$memoized_on_count',X,X+1),1 is X mod 300,!,tell(memoized_on), format(' :- multifile(lmcache:cached_memoized_on/3). :- dynamic(lmcache:cached_memoized_on/3). ', []), forall(lmcache:cached_memoized_on(A,B,C), % (write_term(lmcache:cached_memoized_on(A,B,C),[ignore_ops(true),quoted(true),fullstop(true),numbervars(true),nl(true)])) (write_canonical(lmcache:cached_memoized_on(A,B,C)),writeln('.')) ), told. :- if(exists_source('memoized_on')). :- ensure_loaded(memoized_on). :- endif. %= %% atoms_of_0( :TermC, ?L) is semidet. % % atoms of Primary Helper. % atoms_of_0(Var,[]):- (var(Var);Var==[]),!. atoms_of_0(':',[]). atoms_of_0('moo',[]). atoms_of_0('t',[]). atoms_of_0(',',[]). atoms_of_0(':-',[]). atoms_of_0('$VAR',[]):-!. atoms_of_0(Atom,[]):-number(Atom),!. atoms_of_0(Atom,[Atom]):-atomic(Atom),!. atoms_of_0([H|T],L):-!,atoms_of_0(H,HL),atoms_of_0(T,TL),append(HL,TL,L),!. atoms_of_0(C,L):-C=..CL,atoms_of_0(CL,L),!. :- thread_local lmcache:cannot_save_table/0. :- thread_local lmcache:cannot_use_any_tables/0. %= %% skipped_table_call( :GoalCall) is semidet. % % Skipped Table Call. % skipped_table_call(Call):- cannot_use_tables(cannot_table_call(Call)). %= %% cannot_table_call( :GoalCall) is semidet. % % Cannot Table Call. % cannot_table_call(Call):- locally( lmcache:cannot_save_table,Call). %= %% cannot_use_tables( :GoalCall) is semidet. % % Cannot Use Tables. % cannot_use_tables(Call):- locally( lmcache:cannot_use_any_tables,Call). %= %% call_tabled( :GoalA) is semidet. % % Call Tabled. % call_tabled(A):-call_tabled(A,A). %= %% call_tabled( ?Key, :GoalC) is semidet. % % Call Tabled. % call_tabled(Key,setof(Vars,C,List)):- !,call_setof_tabled(Key,Vars,C,List). call_tabled(Key,findall(Vars,C,List)):- !,call_setof_tabled(Key,Vars,C,List). call_tabled(Key,C):- sanity(nonvar(C)), term_variables(C,Vars),!,call_vars_tabled(Key,Vars,C). %= %% call_vars_tabled( ?Key, ?Vars, :GoalC) is semidet. % % Call Variables Tabled. % call_vars_tabled(Key,Vars,C):- call_setof_tabled(Key,Vars,C,Set),!,member(Vars,Set). %= %% call_setof_tabled( ?KeyIn, ?Vars, :GoalC, -List) is semidet. % % Call Setof Tabled. % call_setof_tabled(KeyIn,Vars,C,List):- make_key(KeyIn+Vars,Key),call_tabled0(Key,Vars,C,List). %= %% findall_nodupes( ?Vs, :GoalC, -List) is semidet. % % Findall Nodupes. % findall_nodupes(Vs,C,List):- ground(Vs),!,(C->List=[Vs];List=[]),!. findall_nodupes(Vs,C,L):- findall(Vs,no_repeats_old(Vs,call_t(C)),L). %findall_nodupes(Vs,C,L):- setof(Vs,no_repeats_old(Vs,C),L). % = :- meta_predicate(call_tabled0(?,?,?,?)). % = :- meta_predicate(call_tabled1(?,?,?,?)). %call_tabled0(Key,Vars,C,List):- lmcache:maybe_table_key(Key),dmsg(looped_findall_nodupes(Vars,C,List)),fail. %= %% call_tabled0( ?Key, ?UPARAM2, ?UPARAM3, ?List) is semidet. % % Call Tabled Primary Helper. % call_tabled0( Key,_,_,List):- reduce_make_key(Key,RKey),lmcache:call_tabled_perm(RKey,List),!. call_tabled0( Key,_,_,List):- \+ (lmcache:cannot_use_any_tables), lmcache:call_tabled_cached_results(Key,List),!. call_tabled0(_Key,Vars,C,List):- lmcache:cannot_save_table,!,findall_nodupes(Vars,C,List). call_tabled0(Key,Vars,C,List):- outside_of_loop_check,!, findall_nodupes(Vars,C,List), ignore((really_can_table,!,asserta_if_ground(lmcache:call_tabled_cached_results(Key,List)))),!. %call_tabled0(Key,Vars,C,List):- lmcache:maybe_table_key(Key),!,findall_nodupes(Vars,C,List). call_tabled0(Key,Vars,C,List):-call_tabled1(Key,Vars,C,List). %= %% call_tabled1( ?Key, ?Vars, ?C, ?List) is semidet. % % Call Tabled Secondary Helper. % call_tabled1(Key,Vars,C,List):- asserta(lmcache:maybe_table_key(Key)), findall_nodupes(Vars,C,List), ignore((really_can_table,!, % if lmcache:maybe_table_key(Key) is now missing that meant a loop_checker had limited some results show_failure(why,retract(lmcache:maybe_table_key(Key))),!, asserta_if_ground(lmcache:call_tabled_cached_results(Key,List)))),!. %= %% really_can_table is semidet. % % Really Can Table. % really_can_table:- not(test_tl(lmcache:cannot_save_table)),!. %= %% outside_of_loop_check is semidet. % % Outside Of Loop Check. % outside_of_loop_check:- (clause(lmcache:ilc(_),B)->B=(!,fail);true). %system:goal_expansion(LC,LCOO):-nonvar(LC),transitive(lco_goal_expansion,LC,LCO),LC\=@=LCO,must(LCO=LCOO),!. %system:term_expansion(LC,LCOO):-nonvar(LC),transitive(lco_goal_expansion,LC,LCO),LC\=@=LCO,must(LCO=LCOO),!. % user:term_expansion(LC,LCOO):-nonvar(LC),(LC=(H:-B)),lco_goal_expansion(B,BE),B\=@=BE,((H:-BE)=LCOO). %= %% goal_expansion( ?LC, ?LCOO) is semidet. % % Hook To [system:goal_expansion/2] For Module Logicmoo_util_loop_check. % Goal Expansion. % % system:goal_expansion(LC,PIn,LCOO,PIn):- system:body_expansion(LC,PIn,LCOO,PIn):- notrace((source_location(_,_), compound(LC), must(var(LCOO)), lco_goal_expansion(LC,LCOO), LC\=@=LCOO)).