TeamSPoon / swipl-devel-unstable

DIFF https://github.com/SWI-Prolog/swipl-devel/compare/master...logicmoo:master_dvard
https://docs.google.com/document/d/1jo8aG_C7wwh1lZzPsFMfh3DEcRjhTQ-MMT_D2_GimEQ/edit
Other
4 stars 1 forks source link

meta_predicate/1 should module_transparent/1 in all cases (otherwise users should use mode/1) #10

Closed TeamSPoon closed 8 years ago

TeamSPoon commented 8 years ago

meta_predicate/1 should module_transparent/1 in all cases Otherwise users should use mode/1.

meta_predicate(Modes):-
  compound_name_arity(Modes,F,A),
  module_transparent(F/A),
  mode(Modes).
JanWielemaker commented 8 years ago

There is no point. meta_predicate tags the meta-qualified arguments and *restores the context to the source content of the predicate. Making predicates with only +,-,? transparent has at best inconsistent results. The context module of (real) meta-predicates is supposed to be the definition context. That might not be true if you make a +,-,? transparent as it might not generate the code to restore the context (not checked).

TeamSPoon commented 8 years ago

I know I seem dense on this, but maybe the answer to the next question will finally make it clear to me:

"Would anyone ever have a use for a non transparent predicate?"

The only reason I can think of is: so that a predicate can see other predicates (non exported) from its module.

JanWielemaker commented 8 years ago

I don't understand this. Transparency is the ability to inherit the context for resolving callable terms to predicates from your caller. It used to implement a way to deal with meta-predicates. It is replaced by meta-predicate that makes arguments module aware rather than the whole body. Making the whole body listen to the context module proved a bad idea and is not compatible to other Prolog systems. It was simply a bad design decision by me. The current implementation hijacks the old one, which comes with the advantage that the caller does not need to be aware it is calling a meta predicate which simplifies dependency management. Just :- meta_predicate p(+). does nothing at all, except for making the declaration available to whoever wants to see it.

TeamSPoon commented 8 years ago

It was simply a bad design decision by me.

I liked those years you did that :+1: and developed an unfortunate style perhaps:

https://github.com/TeamSPoon/PrologMUD/blob/master/pack/logicmoo_base/prolog/logicmoo/mpred/mpred_loader.pl#L1252-L1273


%% mpred_ops is semidet.
%
% Managed Predicate Oper.s.
%
mpred_ops:-  prolog_load_context(module,M),mpred_ops(M).

mpred_ops(M):- mpred_op_each(mpred_op_unless(M)).

mpred_op_unless(M,A,B,C):- current_op(_,B,M:C)->true;op(A,B,M:C).

mpred_op_each(OpEach):-
            call(OpEach,1199,fx,('==>')), % assert
            call(OpEach,1199,fx,('?->')), % ask
            call(OpEach,1190,xfy,('::::')), % Name something
            call(OpEach,1180,xfx,('==>')), % Forward chaining
            call(OpEach,1170,xfx,('<==>')), % Forward and backward chaining
            call(OpEach,1160,xfx,('<==')), % backward chain PFC sytle
            call(OpEach,1160,xfx,('<-')), % backward chain PTTP sytle (currely really PFC)
            call(OpEach,1160,xfx,('<=')), % backward chain DRA sytle
            call(OpEach,1150,xfx,('=>')), % Logical implication
            call(OpEach,1130,xfx,('<=>')), % Logical bi-implication
            call(OpEach,600,yfx,('&')), 
            call(OpEach,600,yfx,('v')),
            call(OpEach,400,fx,('~')),
            % call(OpEach,300,fx,('-')),
            call(OpEach,350,xfx,('xor')).

When I am compiling code specifically in term_expansion/2s I can inspect prolog_load_context(module,M) Which is very useful

https://github.com/TeamSPoon/PrologMUD/blob/master/pack/logicmoo_base/prolog/logicmoo/mpred/mpred_loader.pl#L1900-L2151


%% transform_opers_0( ?AIS, ?AIS) is semidet.
%
% transform opers  Primary Helper.
%
transform_opers_0(AIS,AIS):- if_defined(leave_as_is(AIS)),!.
transform_opers_0((A/B),C):- !, must_maplist(transform_opers_0,[A,B],[AA,BB]),conjoin_op((/),AA,BB,C).
transform_opers_0(PFCM,PFC):- transform_opers_1(PFCM,PFC),!.
transform_opers_0(=>(A),=>(C)):- !, transform_opers_0(A,C).
transform_opers_0(==>(A),==>(C)):- !, transform_opers_0(A,C).
transform_opers_0(~(A),~(C)):- !, transform_opers_0(A,C).
transform_opers_0(nesc(A),nesc(C)):- !, transform_opers_0(A,C).
transform_opers_0({A},{A}):-!.
transform_opers_0((A;B),C):- !, must_maplist(transform_opers_0,[A,B],[AA,BB]),conjoin_op((;),AA,BB,C).
transform_opers_0((B=>A),(BB=>AA)):- !, must_maplist(transform_opers_0,[A,B],[AA,BB]).
transform_opers_0((B==>A),(BB==>AA)):- !, must_maplist(transform_opers_0,[A,B],[AA,BB]).
transform_opers_0(<=(A,B),<=(AA,BB)):- !, must_maplist(transform_opers_0,[A,B],[AA,BB]).
transform_opers_0((A<-B),(AA<-BB)):- !, must_maplist(transform_opers_0,[A,B],[AA,BB]).
transform_opers_0((A<=>B),(AA<=>BB)):- !, must_maplist(transform_opers_0,[A,B],[AA,BB]).
transform_opers_0((A<==>B),(AA<==>BB)):- !, must_maplist(transform_opers_0,[A,B],[AA,BB]).
transform_opers_0((A<==>B),(AA<==>BB)):- !, must_maplist(transform_opers_0,[A,B],[AA,BB]).
transform_opers_0(if(A,B),if(AA,BB)):- !, must_maplist(transform_opers_0,[A,B],[AA,BB]).
transform_opers_0(iff(A,B),iff(AA,BB)):- !, must_maplist(transform_opers_0,[A,B],[AA,BB]).
transform_opers_0(implies(A,B),implies(AA,BB)):- !, must_maplist(transform_opers_0,[A,B],[AA,BB]).
transform_opers_0(equiv(A,B),equiv(AA,BB)):- !, must_maplist(transform_opers_0,[A,B],[AA,BB]).
transform_opers_0((B:-A),OUTPUT):- !, must_maplist(transform_opers_0,[A,B],[AA,BB]),=((BB:-AA),OUTPUT).
transform_opers_0(not(A),OUTPUT):- !, must_maplist(transform_opers_0,[A],[AA]),=(not(AA),OUTPUT).
transform_opers_0(not(A),C):- !, transform_opers_0(~(A),C).
%transform_opers_0((A),OUTPUT):- !, must_maplist(transform_opers_0,[A],[AA]),=((AA),OUTPUT).
transform_opers_0(O,O).

%% transform_opers_1( ?AB, ?BBAA) is semidet.
%
% transform opers  Secondary Helper.
%
transform_opers_1(not(AB),(BBAA)):- get_op_alias(not(OP),rev(OTHER)), atom(OP),atom(OTHER),AB=..[OP,A,B],!, must_maplist(transform_opers_0,[A,B],[AA,BB]),BBAA=..[OTHER,BB,AA].
transform_opers_1(not(AB),(BOTH)):- get_op_alias(not(OP),dup(OTHER,AND)),atom(OTHER), atom(OP),AB=..[OP,A,B],!, must_maplist(transform_opers_0,[A,B],[AA,BB]),AABB=..[OTHER,AA,BB],BBAA=..[OTHER,BB,AA],BOTH=..[AND,AABB,BBAA].
transform_opers_1(not(AB),~(NEG)):- get_op_alias(not(OP),~(OTHER)),atom(OTHER), atom(OP),AB=..[OP|ABL],!, must_maplist(transform_opers_0,ABL,AABB),NEG=..[OTHER|AABB].
transform_opers_1(not(AB),(RESULT)):- get_op_alias(not(OP),(OTHER)), atom(OP),atom(OTHER),AB=..[OP|ABL],!, must_maplist(transform_opers_0,ABL,AABB),RESULT=..[OTHER|AABB].
transform_opers_1((AB),(BBAA)):- get_op_alias(OP,rev(OTHER)), atom(OP),atom(OTHER),AB=..[OP,A,B],!, must_maplist(transform_opers_0,[A,B],[AA,BB]),BBAA=..[OTHER,BB,AA].
transform_opers_1((AB),(BOTH)):- get_op_alias(OP,dup(OTHER,AND)), atom(OP),atom(OTHER),AB=..[OP,A,B],!, must_maplist(transform_opers_0,[A,B],[AA,BB]),AABB=..[OTHER,AA,BB],BBAA=..[OTHER,BB,AA],BOTH=..[AND,AABB,BBAA].
transform_opers_1((AB),(RESULT)):- get_op_alias(OP,(OTHER)),atom(OP), atom(OTHER),AB=..[OP|ABL],!, must_maplist(transform_opers_0,ABL,AABB),RESULT=..[OTHER|AABB].
transform_opers_1(OP,OTHER):- get_op_alias(OPO,OTHER),OPO=OP,!.

%% in_mpred_kb_module is det.
%
% Possibly should term expand since we are
% in a Managed Predicate Knowledge Base Module.
%
in_mpred_kb_module:- prolog_load_context(module,MT),conrext_module(MT2),MT==MT2.

Just :- meta_predicate p(+). does nothing at all, except for making the declaration available to whoever wants to see it.

However, at runtime, sometimes I must inspect and maintain goal_expansion/2s and call the code above code. So I agree instead of

:- meta_predicate p(+).

I meant

:- module_transparent(p/1).
:- mode(p(+)).

In the code below I have to ensure the call module context is not lost

 :- meta_predicate      
    load_init_world(+, :),
    module_typed_term_expand(+, -),
    mpred_expander(+, +, +, -),
    get_user_abox(-),
    mpred_op_each(3),
    mpred_term_expansion(+, -),
    myDebugOnError(0),        
    with_mpred_expansions(0),
    with_no_mpred_expansions(0),
    with_source_module(:, -),
    each_E(:,+,-),
    pfcl_do(+),
    lookup_u(:),
    mpred_get_support(+,-),
    mpred_fact(+,0),
    mpred_test(+),
    mpred_test_fok(+),
    mpred_METACALL(1,-,+),
    mpred_METACALL(1,-,+),
    mpred_METACALL(1,+),
    mpred_call_no_bc(+),
    call_u(+),
    mpred_BC_CACHE(+),
    foreachl_do(+,?),
    with_no_mpred_breaks(0),
    fc_eval_action(0,-),
    clause_u(:,+,-),
    clause_u(:,-),
    mpred_call_no_bc(+),
    with_umt(+),
    brake(0),
    with_no_mpred_trace_exec(0),
    with_mpred_trace_exec(0),
    with_fc_mode(+,0),
    bagof_or_nil(+,^,-),
    kb_dynamic(+),
    make_declared(+,-),
    make_reachable(+,-),
    call_file_command(+, ?, ?, -),
    call_with_module(+, 0),
    call_with_source_module(+, 0),
    doall_and_fail(0),
    ensure_loaded_no_mpreds(0),
    ensure_mpred_file_loaded(:),
    ensure_mpred_file_loaded(+, :),
    force_reload_mpred_file(+),
    get_last_time_file(+, +, +),
    expand_term_to_load_calls(+, -),
    mpred_expander_now_physically(+, ?, -),
    with_ukb(+, 0),
    cl_assert(+, -),
    show_bool(0),
    convert_side_effect(+, +, -),
    .....

The question you might have is why are all my +s not 0s like in call_u(+) ?

The answer is the system mixes non prolog with prolog code so barely everything passing thru the + arguments are supposed to be defined in prolog.

Like in foreachl_do(+,?) is basically maplist/2 however the argument might be a command ran by the MUD player not defined from prolog.

I just want to give a small sample of an 80 thousand line program where most of it needs module transparency.

    .....
%%  mpred_unfwc(+P) 
%
% "un-forward-chains" from fact P.  That is, fact P has just
%  been removed from the database, so remove all support relations it
%  participates in and check the things that they support to see if they
%  should stay in the database or should also be removed.
%
mpred_unfwc(F):- 
  show_call(mpred_retract_supported_relations(F)),
  mpred_unfwc1(F).

mpred_unfwc1(F):-
  mpred_unfwc_check_triggers(F),
  % is this really the right place for mpred_run<?
  mpred_run.   % mpred_run/0 must be module_transparent

mpred_unfwc_check_triggers(F):-
  mpred_db_type(F,fact(_FT)),
  copy_term(F,Fcopy),
  lookup_u(nt(Fcopy,Condition,Action)),
  \+ mpred_call_no_bc(Condition),
  mpred_eval_lhs(Action,((\+F),nt(F,Condition,Action))),
  fail.
mpred_unfwc_check_triggers(_).

mpred_retract_supported_relations(Fact):-
  mpred_db_type(Fact,Type),
  (Type=trigger -> mpred_rem_support_if_exists(P,(_,Fact))
                ; mpred_rem_support_if_exists(P,(Fact,_))),
  must(nonvar(P)),
  remove_if_unsupported(P),
  fail.
mpred_retract_supported_relations(_).

%  remove_if_unsupported(+Ps) checks to see if all Ps are supported and removes
%  it from the DB if they are not.
remove_if_unsupported(P):- 
   mpred_supported(P) -> true ;  must(mpred_undo(P)).

%%  mpred_fwc(+X) is det.
%
% forward chains from a fact or a list of facts X.
% 
mpred_fwc(Ps):- each_E(mpred_fwc0,Ps,[]).
:- module_transparent((mpred_fwc0)/1).

%%  mpred_fwc0(+X) is det.
%
%  Avoid loop while calling mpred_fwc1(P)
% 
mpred_fwc0(Fact):- mpred_fwc1(Fact).
%mpred_fwc0(Fact):- loop_check(mpred_fwc1(Fact),true).

%% mpred_fwc1(+P) is det.
%
% forward chains for a single fact.
%
mpred_fwc1(Fact):-
  mpred_do_rule(Fact),
  copy_term(Fact,F),
  % check positive triggers
  functor(Fact,MF,MA),
  loop_check_term(mpred_do_fcpt(Fact,F),MF/MA,true),
  % check negative triggers
  mpred_do_fcnt(Fact,F).

% 
%  mpred_ain_rule_if_rule(P) does some special, built in forward chaining if P is
%  a rule.
%  

mpred_do_rule((P==>Q)):-  
  !,  
  process_rule(P,Q,(P==>Q)).
mpred_do_rule((Name::::P==>Q)):- 
  !,  
  process_rule(P,Q,(Name::::P==>Q)).
mpred_do_rule((P<==>Q)):- 
  !, 
  process_rule(P,Q,(P<==>Q)), 
  process_rule(Q,P,(P<==>Q)).
mpred_do_rule((Name::::P<==>Q)):- 
  !, 
  process_rule(P,Q,((Name::::P<==>Q))), 
  process_rule(Q,P,((Name::::P<==>Q))).

mpred_do_rule(('<-'(P,Q))):-
  !,
  mpred_define_bc_rule(P,Q,('<-'(P,Q))).

mpred_do_rule(_).

mpred_do_fcpt(Fact,F):- 
  lookup_u(pt(F,Body)),  
  mpred_trace_msg('~N~n\tFound positive trigger: ~p~n\t\tbody: ~p~n',
        [F,Body]),  
  mpred_eval_lhs(Body,(Fact,pt(F,Body))),
  fail.

%mpred_do_fcpt(Fact,F):- 
%  lookup_u(pt(presently(F),Body)),
%  mpred_eval_lhs(Body,(presently(Fact),pt(presently(F),Body))),
%  fail.

mpred_do_fcpt(_,_).

mpred_do_fcnt(_ZFact,F):-
  NT = nt(F,Condition,Body),
  SPFT = spft_mod:spft(X,F1,NT),
  lookup_u(SPFT),
  mpred_trace_msg('~N~n\tFound negative trigger: ~p~n\t\tcond: ~p~n\t\tbody: ~p~n\tSupport: ~p~n',
                 [F,Condition,Body,SPFT]),
  mpred_call_no_bc(Condition),
  mpred_withdraw(X,(F2,NT)),
  must(F1=F2),
  fail.
mpred_do_fcnt(_,_).

%% mpred_define_bc_rule(+Head,+Body,+Parent_rule) 
%  
% defines a backward chaining rule and adds the 
% corresponding bt triggers to the database.
% 
mpred_define_bc_rule(Head,_ZBody,Parent_rule):-
  (\+ mpred_literal(Head)),
  mpred_warn("Malformed backward chaining rule.  ~p not atomic.",[Head]),
  mpred_error("rule: ~p",[Parent_rule]),
  !,
  fail.

mpred_define_bc_rule(Head,Body,Parent_rule):-
  get_source_ref1(U),
  copy_term(Parent_rule,Parent_ruleCopy),
  build_rhs(Head,Rhs),
  foreachl_do(mpred_nf(Body,Lhs),
          (build_trigger(Parent_ruleCopy,Lhs,rhs(Rhs),Trigger),
           mpred_ain(bt(Head,Trigger),(Parent_ruleCopy,U)))).

% for cutting between KIF code 

:-nb_setval('$pfc_current_choice',[]).

push_current_choice(CP):- b_getval('$pfc_current_choice',Was), b_setval('$pfc_current_choice',[CP|Was]).

cut_c:-
  must(nb_current('$pfc_current_choice',[CP|_WAS])),prolog_cut_to(CP).

%% mpred_eval_lhs(X,Support) is nondet.
%
%  eval something on the LHS of a rule.
% 
mpred_eval_lhs(X,S):-
   prolog_current_choice(CP),push_current_choice(CP),
   with_current_why(S,mpred_eval_lhs_nondet(X,S)).

%% mpred_eval_lhs_nondet(X,Support) is det.
%
%  eval something on the LHS of a rule.
% 
mpred_eval_lhs_nondet((Test->Body),Support):- 
  !,
  mpred_call_no_bc(Test),
   mpred_eval_lhs_nondet(Body,Support).

mpred_eval_lhs_nondet(rhs(X),Support):- !,
   mpred_eval_rhs(X,Support).

mpred_eval_lhs_nondet(X,Support):- mpred_db_type(X,trigger), !, mpred_ain_trigger_reprop(X,Support).
mpred_eval_lhs_nondet(X,_):- mpred_warn("Unrecognized item found in trigger body, namely ~p.",[X]).

%% mpred_eval_lhs_det(X,Support) is det.
%
%  eval something on the LHS of a rule.
% 
mpred_eval_lhs_det((Test->Body),Support):- 
  !, 
  (mpred_call_no_bc(Test) -> mpred_eval_lhs_det(Body,Support)),
  !.

mpred_eval_lhs_det(rhs(X),Support):-
  !,
  mpred_eval_rhs(X,Support),
  !.

mpred_eval_lhs_det(X,Support):-
  mpred_db_type(X,trigger),
  !,
  mpred_ain_trigger_reprop(X,Support),
  !.

%mpred_eval_lhs_det(snip(X),Support):- 
%  snip(Support),
%  mpred_eval_lhs_det(X,Support).

mpred_eval_lhs_det(X,_):-
  mpred_warn("Unrecognized item found in trigger body, namely ~p.",[X]).

%%  mpred_eval_rhs1(What,Support) is nondet.
%
%  eval something on the RHS of a rule.
% 
mpred_eval_rhs([],_):- !.
mpred_eval_rhs([Head|Tail],Support):- 
  mpred_eval_rhs1(Head,Support),
  mpred_eval_rhs(Tail,Support).

mpred_eval_rhs1({Action},Support):-
 % evaluable Prolog code.
 !,
 fc_eval_action(Action,Support).

% Dmiles replaced with this
mpred_eval_rhs1( P,Support):-
 % predicate to remove.
  mpred_negation( P , PN),
  %TODO Shouldn''t we be mpred_withdrawing the Positive version?  
  % perhaps we aready negated here from mpred_nf1_negation?!
  mpred_trace_msg('~n\t\tWithdrawing Negation: ~p \n\tSupport: ~p~n',[P,Support]),
  !,
  mpred_withdraw(PN).

mpred_eval_rhs1( P,Support):-
 % predicate to remove.
  mpred_negated_literal( P),
  % TODO SAME AS ABOVE: Shouldn''t we be mpred_withdrawing the Positive version?  
  % perhaps we already negated here different nf1_*
  mpred_trace_msg('~N~n =pred_eval_rhs1= ~n\t\tWithdrawing: ~p \n\tSupport: ~p~n',[P,Support]),
  !,
  mpred_withdraw(P).

mpred_eval_rhs1([X|Xrest],Support):-
 % embedded sublist.
 !,
 mpred_eval_rhs([X|Xrest],Support).

mpred_eval_rhs1(Assertion,Support):- !,
 % an assertion to be added.
 mpred_trace_msg('~N~n =pred_eval_rhs1= ~n\tPost1: ~p \n\tSupport: ~p~n',[Assertion,Support]),!,
 (must(mpred_post(Assertion,Support)) *->
    true;
    mpred_warn("\n\t\t\n\t\tMalformed rhs of a rule (mpred_post1 failed)\n\t\tPost1: ~p\n\t\tSupport=~p.",[Assertion,Support])).

% mpred_eval_rhs1(X,_):-  mpred_warn("Malformed rhs of a rule: ~p",[X]).

%% fc_eval_action(+Action,+Support)
%
%  evaluate an action found on the rhs of a rule.
% 

fc_eval_action(Action,Support):-
  mpred_call_no_bc(Action), 
  (action_is_undoable(Action) 
     -> mpred_ain_actiontrace(Action,Support) 
      ; true).

% 
%  
% 

trigger_trigger(Trigger,Body,_ZSupport):-
 trigger_trigger1(Trigger,Body).
trigger_trigger(_,_,_).

%trigger_trigger1(presently(Trigger),Body):-
%  !,
%  copy_term(Trigger,TriggerCopy),
%  call_u(Trigger),
%  mpred_eval_lhs(Body,(presently(Trigger),pt(presently(TriggerCopy),Body))),
%  fail.

trigger_trigger1(Trigger,Body):-
  copy_term(Trigger,TriggerCopy),
  call_u(Trigger),
  mpred_eval_lhs(Body,(Trigger,pt(TriggerCopy,Body))),
  fail.

%%  call_u(F) is det.
% 
%  is true iff F is a fact available *for* forward chaining 
%  (or *from* the backchaining rules)
%  Note: a bug almost fixed is that this sometimes the side effect of catching 
%  facts and not assigning the correct justifications
%
% So if you call_u/1  in module  'AirlineKB' and that caches some zipcodes
% These should be unloaded when  'AirlineKB' is unloaded

call_u(P):- mpred_METACALL(mpred_BC_w_cache, P).

mpred_BC_w_cache(P):- mpred_BC_CACHE(P),mpred_call_no_bc(P).

mpred_BC_CACHE(P0):-  ignore( \+ loop_check_early(mpred_BC_CACHE0(P0),true)).

mpred_BC_CACHE0(P00):- var(P00),!.
mpred_BC_CACHE0(must(P00)):-!,mpred_BC_CACHE0(P00).
mpred_BC_CACHE0(P):- predicate_property(P,static),!.
mpred_BC_CACHE0(bt(_,_)):-!.
mpred_BC_CACHE0(P):- 
 ignore((
  cyclic_break(P),
 % acyclic_term(P),
 % trigger any bc rules.
  lookup_u(bt(P,Trigger)),
  copy_term(bt(P,Trigger),bt(CP,CTrigger)),
  must(mpred_get_support(bt(CP,Trigger),S)),
% And though the justification is 'by_authority'
% We must still justify why we even cached based on an authority
% Which turns out because 'TJBooker'  thus unload based on 'TJBooker' 
  mpred_eval_lhs(CTrigger,S),
  fail)).

%% supporters_list(+F,-ListofSupporters) is det.
%
% where ListOfSupports is a list of the
% supports for one justification for fact F -- i.e. a list of facts which,
% together allow one to deduce F.  One of the facts will typically be a rule.
% The supports for a user-defined fact are: [u] or 'TJBooker'
%
supporters_list(F,[Fact|MoreFacts]):-
  mpred_get_support(F,(Fact,Trigger)),
  triggerSupports(Trigger,MoreFacts).

triggerSupports(uWas(_),[]):-!.
triggerSupports(ax,[]):-!.
triggerSupports(U,[(U)]):- get_source_ref1(U),!.
triggerSupports(U,[uWas(U)]):- get_source_ref((U1,U2)),member(U,[U1,U2]).
triggerSupports(Trigger,[Fact|MoreFacts]):-
  mpred_get_support(Trigger,(Fact,AnotherTrigger)),
  triggerSupports(AnotherTrigger,MoreFacts).

% I''d like to remove this soon

:- module_transparent((pp_why)/0).
:- module_transparent((mpred_notrace_exec)/0).
:- module_transparent((maybe_mpred_break)/1).
:- module_transparent((to_u)/2).
:- module_transparent((mpred_BC_CACHE0)/1).
:- module_transparent((mpred_eval_lhs_det)/2).
:- module_transparent((mpred_eval_lhs_nondet)/2).
:- module_transparent((cut_c)/0).
:- module_transparent((push_current_choice)/1).
:- module_transparent((set_fc_mode)/1).
:- module_transparent((get_mpred_current_db)/1).
:- module_transparent((body_true)/1).
:- module_transparent((is_source_ref1)/1).
:- module_transparent(log_failure/1).
:- module_transparent(mpred_undo1/1).
:- module_transparent(mpred_post1_rem1/2).
:- module_transparent(mpred_post1_rem/2).
:- module_transparent(assert_u_confirmed_if_missing/1).
:- module_transparent(clause_asserted_u/1).

mpred_call_no_bc(M:P):- nonvar(P),current_predicate(_,M:P),!, with_umt(M:P).
mpred_call_no_bc(P):-  var(P),!,fail,trace,  mpred_fact(P).
mpred_call_no_bc(P):-  mpred_METACALL(with_umt, P).

mpred_METACALL(How,P):- mpred_METACALL(How, Cut, P), (var(Cut)->true;(Cut=cut(CutCall)->(!,CutCall);mpred_call_no_bc(Cut))).

mpred_METACALL(How, Cut,Var):- var(Var),!,trace_or_throw(var_mpred_CALL_MI(How,Cut,Var)).
mpred_METACALL(How, Cut, mpred_call_no_bc(G0)):- !,mpred_METACALL(How, Cut, (G0)).
mpred_METACALL(How, Cut, mpred_METACALL(G0)):- !,mpred_METACALL(How, Cut, (G0)).
mpred_METACALL(How, Cut, mpred_call_no_bc(G0)):- !,mpred_METACALL(How, Cut, (G0)).
mpred_METACALL(_How, cut(true), !):- !.
mpred_METACALL(How, Cut, (P1,P2)):- !, mpred_METACALL(How, Cut, P1), mpred_METACALL(How, Cut, P2).
mpred_METACALL(How, Cut, (P1;P2)):- !, mpred_METACALL(How, Cut, P1); mpred_METACALL(How, Cut, P2).
mpred_METACALL(How, Cut, (P1->P2)):- !, mpred_METACALL(How, Cut, P1)-> mpred_METACALL(How, Cut, P2).
mpred_METACALL(How, Cut, (P1*->P2)):- !, mpred_METACALL(How, Cut, P1)*-> mpred_METACALL(How, Cut, P2).
%  check for system predicates first
% mpred_METACALL(_How, _SCut, P):- predicate_property(P,built_in),!, with_umt(P).
mpred_METACALL( How,   Cut, P) :- fail, predicate_property(P,number_of_clauses(_)),!,
     clause_u(P,Condition),
     mpred_METACALL(How,Cut,Condition),
       (var(Cut)->true;(Cut=cut(CutCall)->(!,CutCall);mpred_call_no_bc(Cut))).

% mpred_METACALL(_How,_SCut, P):- must(current_predicate(_,M:P)),!, with_umt(M:P).
mpred_METACALL(How, _SCut, P):- call(How,P).

%% action_is_undoable(?A) 
%
% an action is action_is_undoable if there exists a method for undoing it.
%
action_is_undoable(A):- lookup_u(do_and_undo(A,_)).

Obviously this is very specialized type of code .. after all 10% of the times it might be in a meta-interpreter.

I suppose I'd would have a different viewpoint if not working on this code. For instance, my tune might change when I get called by
foomodule1:some_pred/5 and it appears in user :(
I can easily look up their context foomodule1 so if there is a side effect trigger I can localize it to foomodule1 and not the code calling them by accident.
Meaning, this will only work out only if foomodule1 is careful about whether they are a utility for another module or a user class module. So I can see your reasoning to why I might not want EVERYTHING in the system module_transparent/1 but only specifically contracted code that should be.

Thus I do agree its a big pain with the additional understanding that we also need to be compatible with other prologs. So surgically selecting what is module transparent is pretty important (rather that selecting the opposite)

So if in fact this is such a specialized usecase by me it further warrants the code below:

:-module_transparent(mpred_ain/1).
:-module_transparent(mpred_aina/1).
:-module_transparent(mpred_ainz/1).
:-module_transparent(logicmoo_util_database:ain/1).
:-module_transparent(logicmoo_util_database:aina/1).
:-module_transparent(logicmoo_util_database:ainz/1).
:-multifile(logicmoo_util_database:ain/1).
:-multifile(logicmoo_util_database:aina/1).
:-multifile(logicmoo_util_database:ainz/1).

% NOW mpred_pfc takes over for logicmoo_util_database 
:-asserta_new((logicmoo_util_database:ainz(G):- !, call(mpred_pfc:mpred_ainz,G))).
:-asserta_new((logicmoo_util_database:ain(G):- !, call(mpred_pfc:mpred_ain,G))).
:-asserta_new((logicmoo_util_database:aina(G):- !, call(mpred_pfc:mpred_aina,G))).

% :- mpred_set_default(mpred_warnings(_), mpred_warnings(true)).
:- asserta_new(mpred_warnings(true)).

:- module_transparent((mpred_clause_u)/1).
:- module_transparent((mpred_remove1)/2).
:- module_transparent((mpred_te)/2).
:- module_transparent((mpred_te)/0).
:- module_transparent((mpred_current_db)/1).
:- module_transparent((listing_u)/1).
:- module_transparent((mpred_test_fok)/1).
:- module_transparent((mpred_test)/1).
:- module_transparent((set_user_abox)/1).
:- module_transparent((get_user_abox)/1).
:- module_transparent((get_source_ref1)/1).
:- module_transparent((get_source_ref)/1).
:- module_transparent((setup_mpred_ops)/0).
:- module_transparent((mpred_load_term)/1).
:- module_transparent((mpred_call_no_bc)/1).
:- module_transparent((call_u)/1).
:- module_transparent((mpred_BC_w_cache)/1).
:- module_transparent((justifications)/2).
:- module_transparent((ain_fast)/2).
:- module_transparent((ain_fast)/1).
:- module_transparent((fix_mp)/2).
:- module_transparent((why_was_true)/1).
:- module_transparent((mpred_is_silient)/0).
:- module_transparent((get_mpred_is_tracing)/1).
:- module_transparent((triggerSupports)/2).
:- module_transparent((supporters_list)/2).
:- module_transparent((well_founded_list)/2).
:- module_transparent((well_founded_0)/2).
:- module_transparent((well_founded)/1).
:- module_transparent((mpred_supported)/2).
:- module_transparent((get_tms_mode)/2).
:- module_transparent((mpred_supported)/1).
:- module_transparent((mpred_select_justification_node)/3).
:- module_transparent((mpred_prompt_ask)/2).
:- module_transparent((mpred_pp_db_justifications2)/3).
:- module_transparent((mpred_pp_db_justification1)/2).
:- module_transparent((mpred_pp_db_justifications)/2).
:- module_transparent((mpred_unhandled_command)/3).
:- module_transparent((mpred_handle_why_command)/3).
:- module_transparent((mpred_whyBrouse)/2).
:- module_transparent((mpred_why1)/1).
:- module_transparent((mpred_why)/1).
:- module_transparent((mpred_why)/0).
:- module_transparent((pp_db_supports)/0).
:- module_transparent((pp_db_triggers)/0).
:- module_transparent((pp_db_rules)/0).
:- module_transparent((mpred_classifyFacts)/4).
:- module_transparent((pp_db_items)/1).
:- module_transparent((pp_db_facts)/2).
:- module_transparent((pp_db_facts)/1).
:- module_transparent((pp_db_facts)/0).
:- module_transparent((pp_DB)/0).
:- module_transparent((mpred_trigger_key)/2).
:- module_transparent((mpred_make_supports)/1).
:- module_transparent((mpred_support_relation)/1).
:- module_transparent((mpred_collect_supports)/1).
:- module_transparent((mpred_rem_support)/2).
:- module_transparent((mpred_rem_support_if_exists)/2).
:- module_transparent((mpred_add_support)/2).
:- module_transparent((mpred_descendants)/2).
:- module_transparent((mpred_descendant1)/3).
:- module_transparent((mpred_descendant)/2).
:- module_transparent((mpred_children)/2).
:- module_transparent((mpred_child)/2).
:- module_transparent((do_assumpts)/2).
:- module_transparent((mpred_assumptions)/2).
:- module_transparent((mpred_assumption)/1).
:- module_transparent((mpred_axiom)/1).
:- module_transparent((bases_union)/2).
:- module_transparent((mpred_basis_list)/2).
:- module_transparent((justification)/2).
:- module_transparent((mpred_set_warnings)/1).
:- module_transparent((nompred_warn)/0).
:- module_transparent((mpred_warn)/0).
:- module_transparent((mpred_load)/1).
:- module_transparent((mpred_nowatch)/0).
:- module_transparent((mpred_trace_exec)/0).
:- module_transparent((mpred_watch)/0).
:- module_transparent((mpred_error)/2).
:- module_transparent((mpred_error)/1).
:- module_transparent((mpred_warn)/2).
:- module_transparent((mpred_warn)/1).
:- module_transparent((mpred_trace_msg)/2).
:- module_transparent((mpred_trace_msg)/1).
:- module_transparent((mpred_untrace)/1).
:- module_transparent((mpred_untrace)/0).
:- module_transparent((mpred_notrace)/0).
:- module_transparent((mpred_nospy)/3).
:- module_transparent((mpred_nospy)/1).
:- module_transparent((mpred_nospy)/0).
:- module_transparent((mpred_spy1)/3).
:- module_transparent((mpred_spy)/3).
:- module_transparent((mpred_spy)/2).
:- module_transparent((mpred_spy)/1).
:- module_transparent((mpred_trace)/2).
:- module_transparent((mpred_trace)/1).
:- module_transparent((mpred_trace)/0).
:- module_transparent((mpred_trace_maybe_break)/3).
:- module_transparent((mpred_trace_maybe_print)/3).
:- module_transparent((mpred_trace_op)/3).
:- module_transparent((mpred_trace_op)/2).
:- module_transparent((mpred_facts)/3).
:- module_transparent((mpred_facts)/2).
:- module_transparent((mpred_facts)/1).
:- module_transparent((mpred_fact)/1).
:- module_transparent((mpred_retract_i_or_warn)/1).
:- module_transparent((mpred_database_item)/1).
:- module_transparent((mpred_reset)/0).
:- module_transparent((mpred_database_term)/2).
:- module_transparent(lmcache:(has_pfc_database_preds)/1).
:- module_transparent((mpred_conjoin)/3).
:- module_transparent((mpred_union)/3).
:- module_transparent((mpred_assertz_w_support)/2).
:- module_transparent((mpred_asserta_w_support)/2).
:- module_transparent((mpred_assert_w_support)/2).
:- module_transparent((mpred_db_type)/2).
:- module_transparent((build_consequent)/3).
:- module_transparent((all_closed)/1).
:- module_transparent((code_sentence_op)/1).
:- module_transparent((build_code_test)/3).
:- module_transparent((fa_to_p)/3).
:- module_transparent((really_mpred_mark)/5).
:- module_transparent((mpred_mark_fa_as)/6).
:- module_transparent((mpred_mark_as)/4).
:- module_transparent((pos_2_neg)/2).
:- module_transparent((mpred_mark_as_ml)/4).
:- module_transparent((check_never_retract)/1).
:- module_transparent((check_never_assert)/1).
:- module_transparent((build_neg_test)/4).
:- module_transparent((build_trigger)/4).
:- module_transparent((build_rule)/3).
:- module_transparent((process_rule)/3).
:- module_transparent((mpred_connective)/1).
:- module_transparent((mpred_positive_literal)/1).
:- module_transparent((mpred_literal)/1).
:- module_transparent((mpred_negated_literal)/1).
:- module_transparent((mpred_negation)/2).
:- module_transparent((mpred_compile_rhs_term)/2).
:- module_transparent((mpred_compile_rhs_term)/3).
:- module_transparent((build_rhs)/2).
:- module_transparent((mpred_nf_negation)/2).
:- module_transparent((mpred_nf_negations)/2).
:- module_transparent((mpred_nf1_negation)/2).
:- module_transparent((mpred_nf1)/2).
:- module_transparent((mpred_nf)/2).
:- module_transparent((action_is_undoable)/1).
:- module_transparent((mpred_eval_rhs1)/2).
:- module_transparent((mpred_eval_rhs)/2).
:- module_transparent((mpred_eval_lhs)/2).
:- module_transparent((mpred_define_bc_rule)/3).
:- module_transparent((mpred_do_fcnt)/2).
:- module_transparent((mpred_do_fcpt)/2).
:- module_transparent((mpred_do_rule)/1).
:- module_transparent((mpred_fwc1)/1).
:- module_transparent((mpred_fwc)/1).
:- module_transparent((remove_if_unsupported)/1).
:- module_transparent((mpred_retract_supported_relations)/1).
:- module_transparent((mpred_unfwc_check_triggers)/1).
:- module_transparent((mpred_unfwc1)/1).
:- module_transparent((mpred_unfwc)/1).
:- module_transparent((mpred_undo)/1).
:- module_transparent((mpred_remove_supports_quietly)/1).
:- module_transparent((mpred_remove_supports)/1).
:- module_transparent((mpred_blast)/1).
:- module_transparent((mpred_remove)/2).
:- module_transparent((mpred_remove)/1).
:- module_transparent((mpred_withdraw1)/2).
:- module_transparent((mpred_withdraw)/2).
:- module_transparent((mpred_withdraw)/1).
:- module_transparent((mpred_ain_by_type)/2).
:- module_transparent((mpred_ain_object)/1).
:- module_transparent((mpred_retract_type)/2).
:- module_transparent((mpred_retract)/1).
:- module_transparent((mpred_undo_action)/1).
:- module_transparent((mpred_ain_actiontrace)/2).
:- module_transparent((mpred_bt_pt_combine)/3).
:- module_transparent((mpred_ain_trigger_reprop)/2).
:- module_transparent((stop_trace)/1).
:- module_transparent((mpred_halt)/1).
:- module_transparent((mpred_halt)/2).
:- module_transparent((mpred_halt)/0).
:- module_transparent((defaultmpred_select)/1).
:- module_transparent((select_next_fact)/1).
:- module_transparent((remove_selection)/1).
:- module_transparent((get_next_fact)/1).
:- module_transparent((mpred_step)/0).
:- module_transparent((mpred_run)/0).
:- module_transparent((mpred_remove_old_version)/1).
:- module_transparent((mpred_enqueue)/2).
:- module_transparent((get_fc_mode)/3).
:- module_transparent((mpred_unique_u)/1).
:- module_transparent((mpred_ain_db_to_head)/2).
:- module_transparent((mpred_post1)/2).
:- module_transparent((mpred_post)/2).
:- module_transparent((mpred_ain)/2).
:- module_transparent((ain)/2).
:- module_transparent((mpred_aina)/2).
:- module_transparent((mpred_ainz)/2).
:- module_transparent((mpred_set_default)/2).
:- module_transparent((pp_qu)/0).
:- module_transparent((lookup_u)/2).
:- module_transparent((lookup_u)/1).
:- module_transparent((clause_u)/2).
:- module_transparent((retractall_u)/1).
:- module_transparent((retract_u)/1).
:- module_transparent((assertz_u)/1).
:- module_transparent((asserta_u)/1).
:- module_transparent((assert_u)/1).
:- module_transparent((with_umt)/1).
:- module_transparent((clause_u)/3).
:- module_transparent((mpred_BC_CACHE)/1).
:- module_transparent((mpred_call_no_bc)/1).
:- module_transparent((mpred_get_support)/2).
:- module_transparent((pp_why)/1).
:- module_transparent((pp_why)/0).
:- module_transparent((mpred_notrace_exec)/0).
:- module_transparent((maybe_mpred_break)/1).
:- module_transparent((to_u)/2).
:- module_transparent((mpred_BC_CACHE0)/1).
:- module_transparent((mpred_eval_lhs_det)/2).
:- module_transparent((mpred_eval_lhs_nondet)/2).
:- module_transparent((cut_c)/0).
:- module_transparent((push_current_choice)/1).
:- module_transparent((set_fc_mode)/1).
:- module_transparent((get_mpred_current_db)/1).
:- module_transparent((body_true)/1).
:- module_transparent((is_source_ref1)/1).
:- module_transparent(log_failure/1).
:- module_transparent(mpred_undo1/1).
:- module_transparent(mpred_post1_rem1/2).
:- module_transparent(mpred_post1_rem/2).
:- module_transparent(assert_u_confirmed_if_missing/1).
:- module_transparent(clause_asserted_u/1).
:- module_transparent(mpred_pfc_file/1).
% the ^above^ is produced by the code below:

%% mpred_pfc_file is det.
%
% PFC Forward Chaining File.
%
mpred_pfc_file :- source_location(S,_),prolog_load_context(module,M),
 forall(source_file(M:H,S),ignore((functor(H,F,A),
   \+ mpred_database_term(F/A,_),
   F\=='$mode',
   F\=='$pldoc',
   ignore(((\+ atom_concat('$',_,F),\+ mpred_database_term(F/A,_),M:export(F/A)))),
   \+ predicate_property(M:H,transparent),M:module_transparent(M:F/A),
   ignore(((\+ atom_concat('__aux',_,F),format('~N:- module_transparent(~q/~q).~n',[F,A]))))
   ))).

Something unfortunate is that I cannot use the systems maplist/2 because the caller's context ends up being somehow becoming apply due to maplist_/2 (the helper) being defined in apply. Yet, the behaviour is unpredictable since sometimes the goal_expansion/2 of expand_maplist/3 gets involved and my code might work.

I do not mean to argue with myself here. But perhaps I could say since only 60% of my code needs to know the caller's context_module/1 rather than making ALL transparent I should make NONE transparent and instead use a global variable that maintains the name of the module I am working with. (or even a list of them.) So for instance I need to resolve usercode based on M1->M2->M3->Me , I ( Me ) can still see M2 as well as M3 Certainly anything is better than passing a module sensitive argument. OR adding CallModule to all of the above predicates or even using : or 0 since these inspire xref to believe non prolog code needs cross refed (or worse defined).

Why I seem so to grim have persistence about this topic is I am operating on the notion you one day hope to remove either source_context or caller_module or both. Perhaps this is unfounded fear! Oh even worse fear, would be to see them merged into the same thing.

@JanWielemaker

DouglasRMiles commented 8 years ago

@JanWielemaker


:- module_transparent(mpred_ops/0).

%% mpred_ops is semidet.
%
% Managed Predicate Oper.s.
%
mpred_ops:-  
   prolog_load_context(module,SM),
   context_module(CM),
   mpred_ops(SM,CM).  

mpred_ops(SM,CM):- mpred_op_each(mpred_op_unless(SM,CM)).

mpred_op_unless(SM,CM,Prio,YFX,OP):-  
   current_op(_,YFX,SM:OP)-> true;  
   (op(_,_,SM:OP),
     (CM==SM % nothing to do
       -> true;
        (module_property(SM,exported_operators(List)),member(op(_,_,OP),List))
          -> true ; 
          (current_op(_,YFX,CM:OP) 
            -> true ;  
          op(Prio,YFX,CM:OP))).

mpred_op_each(OpEach):-
            call(OpEach,1199,fx,('==>')), % assert
            call(OpEach,1199,fx,('?->')), % ask
            call(OpEach,1190,xfy,('::::')), % Name something
            call(OpEach,1180,xfx,('==>')), % Forward chaining
            call(OpEach,1170,xfx,('<==>')), % Forward and backward chaining
            call(OpEach,1160,xfx,('<==')), % backward chain PFC sytle
            call(OpEach,1160,xfx,('<-')), % backward chain PTTP sytle (currely really PFC)
            call(OpEach,1160,xfx,('<=')), % backward chain DRA sytle
            call(OpEach,1150,xfx,('=>')), % Logical implication
            call(OpEach,1130,xfx,('<=>')), % Logical bi-implication
            call(OpEach,600,yfx,('&')), 
            call(OpEach,600,yfx,('v')),
            call(OpEach,400,fx,('~')),
            % call(OpEach,300,fx,('-')),
            call(OpEach,350,xfx,('xor')).