Advertisement
logicmoo

Untitled

Apr 7th, 2015
471
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ZXBasic 78.89 KB | None | 0 0
  1. /** <module> dbase_i_mpred_pfc
  2. % Provides a prolog database replacent that uses PFC
  3. %  
  4. %
  5. % Logicmoo Project PrologMUD: A MUD server written in Prolog
  6. % Maintainer: Douglas Miles
  7. % Dec 13, 2035
  8. %   File   : pfc
  9. %   Author : Tim Finin, finin@umbc.edu
  10. %   Updated: 10/11/87, ...
  11. %   Purpose: consult system file FOR ensure
  12. %
  13. */
  14.  
  15. :- include(dbase_i_header).
  16.  
  17. pmsg(S,Args):- sformat(SF,S,Args),dmsg(pfc(SF)).
  18.  
  19. :- asserta(tlbugger:no_colors).
  20.  
  21. :-meta_predicate(if_defined(0)).
  22. if_defined(Call):-current_predicate(_,Call),!,Call.
  23.  
  24. :- op(500,fx,'~').
  25. :- op(1075,xfx,('=>')).
  26. :- op(1075,xfx,'<=>').
  27. :- op(1075,xfx,('<=')).
  28. :- op(1100,fx,('=>')).
  29. :- op(1150,xfx,('::::')).
  30. :- op(1200,xfx,'-->>').
  31. :- op(1200,xfx,'--*>>').
  32. % :- op(1200,xfx,'<<--').
  33. :- op(400,yfx,'\\\\').
  34.  
  35. :-thread_local pfc_slow_search/0.
  36.  
  37. :- dynamic(neg/1).
  38. :- multifile(neg/1).
  39. :- meta_predicate(neg(1)).
  40.  
  41. :- op(1200,fx,(user:disabled)).
  42. :- op(1200,fx,(user:enabled)).
  43. :- user:op(1199,fx,(:-)).
  44. :- user:op(1199,xfx,(:-)).
  45.  
  46. make_functor(PO,M:F,A):-must(ground(F/A)),!,functor(P,F,A),(P=PO;P=M:PO),!.
  47. make_functor(PO,F,A):-must(ground(F/A)),!,functor(P,F,A),(P=PO;P=_:PO),!.
  48. pfc_mpred_prop(F,TZ,T):-clause(user:mpred_prop(F,TZ,T),true).
  49.  
  50. pfc_fully_expand(Type,B,A):-if_defined(fully_expand(Type,B,A)).
  51. pfc_fully_expand(_Type,B,A):-loop_check(expand_goal(B,A)),!.
  52. pfc_fully_expand_warn(Type,B,A):-pfc_fully_expand(Type,B,A),(B\=@=A->dmsg(pfc_fully_expand_warn(Type,B,A));true),!.
  53.  
  54. :- ignore((current_predicate(NOT/1),abolish(system:NOT/1),abolish(NOT/1),dynamic(NOT/1),assert(((NOT(P):- nonvar(P), \+ P))),meta_predicate(NOT(0)))).
  55. :- op(0,fx,'decl_mpred_pfc').
  56. user:isa(pfcMetaPred,tCol).
  57. user:isa(pfcMustFC,tCol).
  58. decl_mpred_pfc(F/A):-!,export(F/A),dynamic(F/A),asserta_if_new(user:mpred_prop(F,TZ,prologOnly)),asserta_if_new(arity(F,A)),asserta_if_new(user:mpred_prop(F,TZ,pfcMetaPred)),
  59.   asserta_if_new(user:mpred_prop(F,TZ,arity(A))).
  60. decl_mpred_pfc(F):-atom(F),!,decl_mpred_pfc(F/0).
  61. :- op(1150,fx,'decl_mpred_pfc').
  62.  
  63. has_numvars(P):-term_variables(P,PV),unnumbervars(P,UP),term_variables(UP,UPV),!,UPV\==[],PV\=@=UPV.
  64.  
  65. must_numvars(P):- must(ground(P);has_numvars(P)),!.
  66. must_no_numvars(P):-must(NOT(has_numvars(P))),!.
  67.  
  68. :-meta_predicate(loop_check_nr(0)).
  69. loop_check_nr(G):-no_repeats(loop_check(G)).
  70.  
  71.  
  72. user:decl_database_hook(Op,Hook):- loop_check_nr(pfc_provide_mpred_storage_op(Op,Hook)).
  73.  
  74. is_retract_first(one).
  75. is_retract_first(a).
  76.  
  77. pfc_provide_mpred_storage_op(Op,(I1,I2)):-!,pfc_provide_mpred_storage_op(Op,I1),pfc_provide_mpred_storage_op(Op,I2).
  78. pfc_provide_mpred_storage_op(Op,(=>(P))):-!,pfc_provide_mpred_storage_op(Op,P).
  79. %pfc_provide_mpred_storage_op(change(assert,_AorZ),Fact):- loop_check_nr(pfcAddPreTermExpansion(Fact)).
  80. % pfcRem1 TO just get the first
  81. pfc_provide_mpred_storage_op(change(retract,OneOrA),FactOrRule):- is_retract_first(OneOrA),!,loop_check_nr(pfcRem1(FactOrRule)),ignore((ground(FactOrRule),pfcRem2(FactOrRule))).
  82. % pfcRem2 should be forcefull enough
  83. pfc_provide_mpred_storage_op(change(retract,all),FactOrRule):- loop_check_nr(pfcRem2(FactOrRule)),!.
  84. % pfc_provide_mpred_storage_op(is_asserted,FactOrRule):- nonvar(FactOrRule),!,loop_check_nr(pfcClauseInt(FactOrRule)).
  85.  
  86. pfc_clause_is_asserted(H,B):- var(H),nonvar(B),!,fail.
  87. pfc_clause_is_asserted(H,B):- one_must(pfc_clause_db_unify(H,B),pfc_clause_is_asserted_hb_nonunify(H,B)).
  88. pfc_clause_is_asserted(H,B,Ref):-pfc_clause_db_ref(H,B,Ref).
  89.  
  90. pfc_clause_is_asserted_hb_nonunify(H,B):- pfc_clause_db_unify( =>( B , H) , true).
  91. pfc_clause_is_asserted_hb_nonunify(H,B):- pfc_clause_db_unify( <=( H , B) , true).
  92. pfc_clause_is_asserted_hb_nonunify(_,_):-!,fail.
  93. pfc_clause_is_asserted_hb_nonunify(G, T   ):- T==true,!,notrace(pfcRuleOutcomeHeadBody(G,H,B)),G\=@=H,!,pfc_clause_is_asserted(H,B).
  94. pfc_clause_is_asserted_hb_nonunify(H,(T,B)):- T==true,!,pfc_clause_is_asserted_hb_nonunify(H,B).
  95. pfc_clause_is_asserted_hb_nonunify(H,(B,T)):- T==true,!,pfc_clause_is_asserted_hb_nonunify(H,B).
  96. pfc_clause_is_asserted_hb_nonunify(H,B):- pfc_clause_db_unify( <=( H , B) , true).
  97. pfc_clause_is_asserted_hb_nonunify(H,B):-pfc_mpred_storage_clauses(H,B,_).
  98.  
  99.  
  100. pfcDatabaseGoal(G):-compound(G),get_functor(G,F,A),pfcDatabaseTerm(F/A).
  101.  
  102. user:provide_mpred_storage_clauses(Type,H,B,Proof):-pfc_mpred_storage_clauses(Type,H,B,Proof).
  103.  
  104. pfc_mpred_storage_clauses('=>'(H),B,forward(Proof)):- nonvar(H),!, user:provide_mpred_storage_clauses(H,B,Proof).
  105. pfc_mpred_storage_clauses(H,B, forward(R)):- R=(=>(B,H)),clause(R,true).
  106. pfc_mpred_storage_clauses(H,B,backward(R)):- R=(<=(H,B)),clause(R,true).
  107. pfc_mpred_storage_clauses(equiv,H,B,   equiv(R)):- R=(<=>(LS,RS)),clause(R,true),(((LS=H,RS=B));((LS=B,RS=H))).
  108. % pfc_mpred_storage_clauses(H,true, pfcTypeFull(R,Type)):-nonvar(H),!,pfcDatabaseTerm(F/A),make_functor(R,F,A),pfcRuleOutcomeHead(R,H),clause(R,true),pfcTypeFull(R,Type),Type\=rule.
  109. % pfc_mpred_storage_clauses(H,true, pfcTypeFull(R)):-pfcDatabaseTerm(F/A),make_functor(R,F,A),pfcTypeFull(R,Type),Type\=rule,clause(R,true),once(pfcRuleOutcomeHead(R,H)).
  110.  
  111. :-dynamic(pfcExpectedClauseCount_db/3).
  112. pfcGetExpectedClauseCount(F,A,C):- (pfcExpectedClauseCount_db(F,A,C);C=0).
  113. pfcGetActualClauseCount(F,A,C):-make_functor(P,F,A),predicate_property(P,number_of_clauses(C)).
  114. pfcIsClauseCountWrong(F,A):-pfcGetExpectedClauseCount(F,A,E),pfcGetActualClauseCount(F,A,C),!,C\=E.
  115. pfcCountsClauses(F,A):- arity(F,A),pfcWatches(F/A).
  116.  
  117. pfcCheckClauseCounts :- forall(pfcCountsClauses(F,A),pfcUpdateClauses(F,A)).
  118.  
  119. pfcUpdateClauses(F,A):-NOT(pfcIsClauseCountWrong(F,A)),!.
  120. pfcUpdateClauses(F,A):-make_functor(P,F,A),forall((clause(P,T),is_true(T)),hooked_asserta(P)),retractall(pfcExpectedClauseCount_db(F,A,_)),
  121.    predicate_property(P,number_of_clauses(C)),
  122.    asserta(pfcExpectedClauseCount_db(F,A,C)).
  123.  
  124. :-IF(current_predicate(onEachLoad/1)).
  125. :-onEachLoad(pfcCheckClauseCounts).
  126. :-endif.
  127.  
  128. % :-asserta(thlocal:pfcExpansion).
  129.  
  130. :- thread_local thlocal:pfcExpansion/0.
  131. :- dynamic thlocal:pfcExpansionWas.
  132.  
  133. maybe_hybrid(F/_):-pfc_mpred_prop(F,TZ,prologOnly),!.
  134. maybe_hybrid(F/_):-pfc_mpred_prop(F,TZ,prologHybrid),!.
  135. maybe_hybrid(F/_):-pfc_mpred_prop(F,TZ,pfcMetaPred),!.
  136. maybe_hybrid(F/_):-pfc_mpred_prop(F,TZ,X),atom(X),!.
  137. maybe_hybrid(F/A):-atom(F),debugOnError(current_predicate(F/A)),!.
  138. maybe_hybrid(_/A):-A=1,!.
  139. % maybe_hybrid(C/1):-ignore((nonvar(C)->decl_mpred_hybrid(C/1);ignore(decl_mpred_hybrid(isa/2))))
  140. maybe_hybrid(F/A):- current_predicate((decl_mpred_hybrid)/1), ignore(must((atom(F),decl_mpred_hybrid(F/A)))).
  141.  
  142. pfcDoConjs(Pred,List):-pfcDoConjs(Pred,List,[]).
  143.  
  144. pfcLambda([A1],Body,A1):-Body.
  145. pfcLambda([A1,A2],Body,A1,A2):-Body.
  146. pfcLambda([A1,A2,A3],Body,A1,A2,A3):-Body.
  147. pfcLambda([A1,A2,A3,A4],Body,A1,A2,A3,A4):-Body.
  148.  
  149. % :-call(pfcLambda([E],writeln(E)),hello_lambda).
  150.  
  151. :-dynamic(pfcMetaPred/1).
  152. :-dynamic(pfcControlled/1).
  153. :-dynamic(pfcWatched/1).
  154. :-dynamic(pfcMustFC/1).
  155.  
  156. pfcDoConjs(_,[],_) :- !.
  157. pfcDoConjs(Pred,H,S):-var(H),!,apply(Pred,[H|S]).
  158. pfcDoConjs(Pred,(H,T),S):-!, apply(Pred,[H|S]), pfcDoConjs(Pred,T,S).
  159. pfcDoConjs(Pred,[H|T],S):-!, apply(Pred,[H|S]), pfcDoConjs(Pred,T,S).
  160. pfcDoConjs(Pred,H,S):-apply(Pred,[H|S]).
  161.  
  162. deny_pfc_Permission_to_remove(pfcInternal,_,_):-!,fail. %allow
  163. deny_pfc_Permission_to_remove(_,P,NOT(pfcControlled)):-get_functor(P,F,A), NOT(pfc_local(P,F,A);pfc_mpred_prop(F,TZ,pfcControlled)).
  164.  
  165. pfc_pre_expansion_each(X,X):-NOT(compound((X))),!.
  166. pfc_pre_expansion_each(X,X):-if_defined(as_is_term(X)),!.
  167. pfc_pre_expansion_each(X,isa(I,C)):- if_defined(was_isa(X,I,C)),!,( \+ \+ maybe_hybrid(C/1)).
  168. pfc_pre_expansion_each(Sent,OUT):-Sent=..[AND|C12],current_predicate(is_logical_functor/1),is_logical_functor(AND),!,maplist(pfc_pre_expansion_each,C12,O12),OUT=..[AND|O12],!.
  169. pfc_pre_expansion_each(C12,OUT):-is_list(C12),!,maplist(pfc_pre_expansion_each,C12,OUT),!.
  170. pfc_pre_expansion_each(X,X):- \+ \+ ((get_functor(X,F,A),must(maybe_hybrid(F/A)))),!.
  171.  
  172. % {G}:-mpred_call(G).
  173. user:arity(F,A):-pfcDatabaseTerm(F/A).
  174. user:mpred_prop(F,TZ,argIsa(_,ftAskable)):-pfcDatabaseTerm(F/_).
  175.  
  176. user:mpred_prop(isa,2,pfcMustFC).
  177.  
  178. pfcMustFC(H):-get_functor(H,F),pfc_mpred_prop(F,TZ,pfcMustFC).
  179. pfcPreferBC(H):-get_functor(H,F,A),pfc_mpred_prop(F,TZ,pfcPreferBC),dynamic(F/A),functor(PHead,F,A),assertz_if_new(((PHead:-callBC(PHead)))).
  180.  
  181. pfc_manage_hybrids :- if_defined(thglobal:pfcManageHybrids).
  182.  
  183. :- decl_mpred_pfc pfc_local/1.
  184. pfc_local(G):-get_functor(G,F,A),pfc_local(G,F,A).
  185.  
  186. pfc_local(_,F,A):-pfcDatabaseTerm(F/A),!.
  187. pfc_local(_,F,_):-pfc_mpred_prop(F,TZ,pfcMetaPred),!.
  188. pfc_local(_,F,_):-pfc_mpred_prop(F,TZ,prologOnly).
  189. pfc_local(G,_,_):-pfc_manage_hybrids,!,pfcMarkW(G),!.
  190. % pfc_local(G,_,_):-pfc_manage_hybrids,!,pfcMarkC(G),!.
  191. pfc_local(G,_,_):- NOT(current_predicate(hooked_assertz/1)),!,pfcMarkC(G).
  192. pfc_local(_,F,_):-pfc_mpred_prop(F,TZ,prologHybrid),!,fail.
  193. pfc_local(_,_,_).
  194.  
  195. % pfc_local(_).
  196.  
  197. pfcControlled(G):-notrace(pfcControlled0(G)).
  198. pfcWatches(G):-notrace(pfcWatched0(G)).
  199.  
  200. pfcControlled0(Var):-is_ftVar(Var),!.
  201. pfcControlled0((_:F)/A):-!,pfcControlled0(F/A).
  202. pfcControlled0(G):- get_functor(G,F), (pfc_mpred_prop(F,TZ,pfcControlled);pfc_mpred_prop(F,TZ,pfcMustFC)).
  203.  
  204. pfcWatched0(Var):-is_ftVar(Var),!.
  205. pfcWatched0((_:F)/A):-!,pfcWatched0(F/A).
  206. pfcWatched0(G):- get_functor(G,F), (pfc_mpred_prop(F,TZ,pfcWatched);pfc_mpred_prop(F,TZ,pfcControlled);pfc_mpred_prop(F,TZ,pfcMustFC)).
  207.  
  208. :-thread_local(thlocal:pfc_no_mark/0).
  209.  
  210.  
  211.  
  212. pfcMarkW(G):-pfcMarkAs(G,pfcWatched).
  213. pfcMarkC(G):-pfcMarkAs(G,pfcControlled).
  214. pfcMarkF(G):-pfcMarkAs(G,pfcMustFC).
  215. pfcMarkB(_):-!.
  216. pfcMarkB(G):-pfcMarkAs(G,pfcPreferBC).
  217.  
  218. pfcMarkAs(_, _):-thlocal:pfc_no_mark,!.
  219. pfcMarkAs(G,_):-is_true(G),!.
  220. pfcMarkAs(G,AS):-must(pfcDoConjs(pfcMarkAs1,G,[AS])),!.
  221.  
  222. pfcMarkAs1(F,AS):-atom(F),clause(pfc_mpred_prop(F,TZ,prologOnly),true),!,dmsg(todo(warn(wont_pfcMarkAs1(F,AS)))).
  223. pfcMarkAs1(F,AS):-atom(F),!,assert_if_new(user:mpred_prop(F,TZ,AS)).
  224. pfcMarkAs1(G,_):-NOT(compound(G)),!.
  225. pfcMarkAs1(pfcUser,_):-!.
  226. pfcMarkAs1(pfcGod,_):-!.
  227. pfcMarkAs1(pfcUser,_):-!.
  228. pfcMarkAs1(pfcGod,_):-!.
  229. pfcMarkAs1((G1,G2),AS):-!,pfcMarkAs1(G1,AS),pfcMarkAs1(G2,AS).
  230. pfcMarkAs1(forall(G1,G2),AS):-!,pfcMarkAs1(G1,AS),pfcMarkAs1(G2,AS).
  231. pfcMarkAs1(G,AS):-pfcDatabaseGoal(G),must((forall(pfcRuleOutcomeHeadBody(G,H,B),must((pfcMarkAs(H,AS),pfcMarkAs(B,pfcWatched)))))),!.
  232. pfcMarkAs1(G,AS):-predicate_property(G,meta_predicate(_)),G=..[_|LIST],!,pfcMarkAs(LIST,AS).
  233. pfcMarkAs1(G,AS):-get_functor(G,F,A),pfcMarkAs2(F,A,AS).
  234.  
  235. pfcMarkAs2(F,A,AS):-AS==pfcControlled,dynamic_safe(F/A),fail.
  236. pfcMarkAs2(F,A,AS):-AS==pfcMustFC,dynamic_safe(F/A),fail.
  237. pfcMarkAs2(F,A,AS):-assert_if_new(user:arity(F,A)),must(pfcMarkAs1(F,AS)).
  238.  
  239.  
  240. % by returning true we veto the assertion  (fail accepts assertion)
  241. throw_on_bad_fact(G):-why_throw_on_bad_fact(G,Why), dmsg(((throw_on_bad_fact(Why,G)))),!,fail.
  242.  
  243. why_throw_on_bad_fact(G,singletons(HS)):-  
  244.   head_singletons_g(G,HS),get_functor(HS,F),!,NOT(pfc_mpred_prop(F,TZ,predCanHaveSingletons)).
  245.  
  246. head_singletons_g(G,HS):- pfcRuleOutcomeHeadBody(G,H,B), head_singletons_hb(H,B,HS),!.
  247.  
  248. head_singletons_hb(HN,BN,H):- unnumbervars(HN:BN,H:B),
  249.   term_variables(H,HV),
  250.   numbervars((H:B),66,_,[singletons(true)]),!,
  251.     member('$VAR'('_'),HV).
  252.  
  253. pfc_retractall_settings(_,G):-pfc_local(G),!,ignore((retract(G),fail)).
  254. pfc_retractall_settings(_,G):-hooked_retractall(G).
  255.  
  256. pfc_retract(Why,P) :- deny_pfc_Permission_to_remove(Why,P,Because),!, pfcWarn("Denying ~w retract access to ~w because ~w",[Why,P,Because]),!.
  257. pfc_retract(_,pfcAction(A)) :-  
  258.   % undo an action by finding a method AND successfully executing it.
  259.   !,
  260.   pfcRemActionTrace(pfcAction(A)).
  261. pfc_retract(_,pfcPT3(Key,Head,Body)) :-  
  262.   % undo a positive trigger.
  263.   %
  264.   !,
  265.   (retract(pfcPT3(Key,Head,Body))
  266.     -> unFc(pfcPT(Head,Body))
  267.      ; pfcWarn("Trigger not found to pfc_retract: ~w",[pfcPT(Head,Body)])).
  268. pfc_retract(pfcInternal(_),G):- must(pfc_local(G)),!,retract(G).
  269. pfc_retract(_,G):- pfc_local(G),!,retract(G),loop_check(run_database_hooks_depth_1(change(retract,a),G),true).
  270. pfc_retract(_,G):- hooked_retract(G).
  271.  
  272.  
  273. pfc_ignored(argIsa(F, A, argIsaFn(F, A))).
  274. pfc_ignored(genls(A,A)).
  275. pfc_ignored(isa(tCol,tCol)).
  276. pfc_ignored(isa(W,tCol)):-if_defined(user:hasInstance_dyn(tCol,W)).
  277. pfc_ignored(isa(W,_)):-compound(W),isa(W,predArgTypes).
  278.  
  279. pfc_ignored(isa(_,Atom)):-atom(Atom),atom_concat(ft,_,Atom),!.
  280. pfc_ignored(isa(_,argIsaFn(_, _))).
  281.  
  282. pfc_assert(G):- pfc_dbase_transform(G,GG),must(pfc_assert0(GG)).
  283.  
  284. pfc_assert0(G):- NOT(NOT(pfc_ignored(G))).
  285. pfc_assert0(G):- throw_on_bad_fact(G),!.
  286. pfc_assert0(G):- pfc_manage_hybrids,!,pfc_local(G),!,assertz_if_new(G),add_meta_facts(assertz_if_new,G).
  287. pfc_assert0(G):- pfc_local(G),!,
  288.    ( \+ predicate_property(G,dynamic) -> must(G) ; (assertz_if_new(G),ignore(if_defined(hooked_assertz(G))))),
  289.    add_meta_facts(assertz,G).
  290.  
  291. pfc_assert0(G):- add(G),pfcMarkC(G).
  292.  
  293. user:mpred_prop(F,TZ,prologOnly):-user:mpred_prop(F,TZ,pfcMetaPred).
  294.  
  295. add_meta_facts(How,(H:-True)):-is_true(True),must(nonvar(H)),!,add_meta_facts(How,H).
  296. add_meta_facts(How,(H<=B)):- add_meta_facts(How,(H:-infoF(H<=B))),!,add_meta_facts(assertz_if_new,(H:-callBC(H))).
  297. add_meta_facts(How,(B=>H)):- add_meta_facts(How,(H:-infoF(B=>H))),!.
  298. add_meta_facts(How,(B<=>H)):- add_meta_facts(How,(H:-infoF(B<=>H))),!,add_meta_facts(How,(B:-infoF(B<=>H))),!.
  299. add_meta_facts(How,((A,B):-INFOC)):-is_meta_info(INFOC),(nonvar(A);nonvar(B)),!,add_meta_facts(How,((A):-INFOC)),add_meta_facts(How,((B):-INFOC)),!.
  300. add_meta_facts(How,((A;B):-INFOC)):-is_meta_info(INFOC),(nonvar(A);nonvar(B)),!,add_meta_facts(How,((A):-INFOC)),add_meta_facts(How,((B):-INFOC)),!.
  301. add_meta_facts(How,(~(A):-infoF(C))):-nonvar(C),nonvar(A),!,add_meta_facts(How,((A):-infoF(~(C)))). % ,call(How,(~(A):-infoF(C))).
  302. add_meta_facts(How,(A:-INFOC)):-is_meta_info(INFOC),rewrap_h(A,AA),call(How,(AA:-INFOC)),!.
  303. add_meta_facts(_,_).
  304.  
  305.  
  306. is_meta_info(callBC(C)):-nonvar(C),!.
  307. is_meta_info(infoF(C)):-nonvar(C),!.
  308.  
  309. rewrap_h(A,A):-nonvar(A),!.
  310. rewrap_h(A,not_not(A)):-!.
  311.  
  312. % used TO annotate a predciate TO indicate PFC support
  313. infoF(_):-fail.
  314.  
  315. pfc_dbase_transform(G,GGG):-must((pfc_fully_expand_warn(pfc_dbase_transform,G,GG))),!,unnumbervars(GG,GGG).
  316.  
  317.  
  318. pfc_clause_db_unify(H,B):- must(pfc_local(H)),
  319.    (current_predicate(_,H) -> (predicate_property(H,number_of_clauses(_)) -> clause(H,B) ; B = call(H)); % simulates a body FOR system predicates
  320.                                              B = mpred_call(H)).
  321. pfc_clause_db_check(H,B):- copy_term(H:B,HH:BB), clause(HH,BB,Ref),clause(CH,CB,Ref),H:B=@=CH:CB,!.
  322. pfc_clause_db_ref(H,B,Ref):-must(pfc_local(H)),!,pfc_clause_local_db_ref(H,B,Ref).
  323.  
  324. pfc_clause_local_db_ref(H,B,Ref):- copy_term(H:B,HH:BB),clause(HH,BB,Ref),clause(CH,CB,Ref),H:B=@=CH:CB,!.
  325.  
  326. % pfc_call_prolog_native(G):- pfc_call_prolog_native(nonPFC,G).
  327. pfc_call_prolog_native(_,true):-!.
  328. pfc_call_prolog_native(_,G):- pfc_local(G),!,show_call_failure(predicate_property(G,_)),!, debugOnError(call(G)).
  329. pfc_call_prolog_native(Why,X):-dbase_op(call(Why),X).
  330.  
  331. :-thread_local ntd_max_depth/2.
  332.  
  333. % not_too_deep(_,G):-!,G.
  334. not_too_deep(Key,G):-stack_depth(CD),
  335.   (ntd_max_depth(Key,MD)->
  336.       ( (CD > MD) -> (!,fail) ; G) ;
  337.     (MD is CD+200,call_cleanup(asserta(ntd_max_depth(Key,MD),REF),G,erase(REF)))).
  338.  
  339. % :- set_prolog_flag(unknown,fail).
  340. :- decl_mpred_pfc(GO/0).
  341.  
  342. pfcRuleOutcomeHead(Outcome,OutcomeO):-var(Outcome),!,OutcomeO=Outcome.
  343. pfcRuleOutcomeHead((Outcome1,Outcome2),OutcomeO):-!,pfcRuleOutcomeHead(Outcome1,Outcome1O),pfcRuleOutcomeHead(Outcome2,Outcome2O),pfcConjoin(Outcome1O,Outcome2O,OutcomeO).
  344. pfcRuleOutcomeHead(_=>Outcome,OutcomeO):-!,pfcRuleOutcomeHead(Outcome,OutcomeO).
  345. pfcRuleOutcomeHead(Outcome<=_,OutcomeO):-!,pfcRuleOutcomeHead(Outcome,OutcomeO).
  346. pfcRuleOutcomeHead(Outcome<=>_,OutcomeO):-pfcRuleOutcomeHead(Outcome,OutcomeO).
  347. pfcRuleOutcomeHead(_<=>Outcome,OutcomeO):-!,pfcRuleOutcomeHead(Outcome,OutcomeO).
  348. pfcRuleOutcomeHead(_::::Outcome,OutcomeO):-!,pfcRuleOutcomeHead(Outcome,OutcomeO).
  349. pfcRuleOutcomeHead(pfcBT(Outcome,_),OutcomeO):-!,pfcRuleOutcomeHead(Outcome,OutcomeO).
  350. pfcRuleOutcomeHead(pfcNT(_,_,Outcome),OutcomeO):-!,pfcRuleOutcomeHead(Outcome,OutcomeO).
  351. pfcRuleOutcomeHead(pfcPT(_,Outcome),OutcomeO):-!,pfcRuleOutcomeHead(Outcome,OutcomeO).
  352. pfcRuleOutcomeHead(pfcPT3(_,_,Outcome),OutcomeO):-!,pfcRuleOutcomeHead(Outcome,OutcomeO).
  353. pfcRuleOutcomeHead(support1(Outcome,_,_),OutcomeO):-!,pfcRuleOutcomeHead(Outcome,OutcomeO).
  354. pfcRuleOutcomeHead(support3(_,_,Outcome),OutcomeO):-!,pfcRuleOutcomeHead(Outcome,OutcomeO).
  355. pfcRuleOutcomeHead(support2(_,Outcome,_),OutcomeO):-!,pfcRuleOutcomeHead(Outcome,OutcomeO).
  356. pfcRuleOutcomeHead(pfcQueue(Outcome),OutcomeO):-!,pfcRuleOutcomeHead(Outcome,OutcomeO).
  357. % pfcRuleOutcomeHead(pfc Default(Outcome),OutcomeO):-!,pfcRuleOutcomeHead(Outcome,OutcomeO).
  358. pfcRuleOutcomeHead(Outcome:-_,Outcome):-!.
  359. pfcRuleOutcomeHead(Outcome,Outcome).
  360.  
  361.  
  362. pfcRuleOutcomeHeadBody(Outcome,OutcomeO,AnteO):-pfcRuleOutcomeHeadBody_0(Outcome,OutcomeO,Ante),pfcRuleOutcomeHead(Ante,AnteO).
  363.  
  364. pfcRuleOutcomeHeadBody_0(Outcome,OutcomeO,true):-is_ftVar(Outcome),!,OutcomeO=Outcome.
  365. pfcRuleOutcomeHeadBody_0((Outcome1,Outcome2),OutcomeO,AnteO):-!,pfcRuleOutcomeHeadBody(Outcome1,Outcome1O,Ante1),pfcRuleOutcomeHeadBody(Outcome2,Outcome2O,Ante2),
  366.                    pfcConjoin(Outcome1O,Outcome2O,OutcomeO),
  367.                    pfcConjoin(Ante1,Ante2,AnteO).
  368. pfcRuleOutcomeHeadBody_0(Ante1=>Outcome,OutcomeO,(Ante1,Ante2)):-!,pfcRuleOutcomeHeadBody(Outcome,OutcomeO,Ante2).
  369. pfcRuleOutcomeHeadBody_0(Outcome<=Ante1,OutcomeO,(Ante1,Ante2)):-!,pfcRuleOutcomeHeadBody(Outcome,OutcomeO,Ante2).
  370. pfcRuleOutcomeHeadBody_0(Outcome<=>Ante1,OutcomeO,(Ante1,Ante2)):-pfcRuleOutcomeHeadBody(Outcome,OutcomeO,Ante2).
  371. pfcRuleOutcomeHeadBody_0(Ante1<=>Outcome,OutcomeO,(Ante1,Ante2)):-!,pfcRuleOutcomeHeadBody(Outcome,OutcomeO,Ante2).
  372. pfcRuleOutcomeHeadBody_0(_::::Outcome,OutcomeO,Ante2):-!,pfcRuleOutcomeHeadBody_0(Outcome,OutcomeO,Ante2).
  373. pfcRuleOutcomeHeadBody_0(pfcBT(Outcome,Ante1),OutcomeO,(Ante1,Ante2)):-!,pfcRuleOutcomeHeadBody(Outcome,OutcomeO,Ante2).
  374. pfcRuleOutcomeHeadBody_0(pfcPT(Ante1,Outcome),OutcomeO,(Ante1,Ante2)):-!,pfcRuleOutcomeHeadBody(Outcome,OutcomeO,Ante2).
  375. pfcRuleOutcomeHeadBody_0(pfcPT3(Ante1a,Ante1b,Outcome),OutcomeO,(Ante1a,Ante1b,Ante2)):-!,pfcRuleOutcomeHeadBody(Outcome,OutcomeO,Ante2).
  376. pfcRuleOutcomeHeadBody_0(pfcNT(Ante1a,Ante1b,Outcome),OutcomeO,(Ante1a,Ante1b,Ante2)):-!,pfcRuleOutcomeHeadBody(Outcome,OutcomeO,Ante2).
  377. pfcRuleOutcomeHeadBody_0(support1(Outcome,Ante1a,Ante1b),OutcomeO,(Ante1a,Ante1b,Ante2)):-!,pfcRuleOutcomeHeadBody(Outcome,OutcomeO,Ante2).
  378. pfcRuleOutcomeHeadBody_0(support3(Ante1a,Ante1b,Outcome),OutcomeO,(Ante1a,Ante1b,Ante2)):-!,pfcRuleOutcomeHeadBody(Outcome,OutcomeO,Ante2).
  379. pfcRuleOutcomeHeadBody_0(support2(Ante1a,Outcome,Ante1b),OutcomeO,(Ante1a,Ante1b,Ante2)):-!,pfcRuleOutcomeHeadBody(Outcome,OutcomeO,Ante2).
  380. pfcRuleOutcomeHeadBody_0(pfcQueue(Outcome),OutcomeO,Ante2):-!,pfcRuleOutcomeHeadBody(Outcome,OutcomeO,Ante2).
  381. % pfcRuleOutcomeHeadBody_0(pfc Default(Outcome),OutcomeO,Ante2):-!,pfcRuleOutcomeHeadBody(Outcome,OutcomeO,Ante2).
  382. pfcRuleOutcomeHeadBody_0((Outcome:-Ante),Outcome,Ante):-!.
  383. pfcRuleOutcomeHeadBody_0(Outcome,Outcome,true).
  384.  
  385.  
  386. pfcVersion(1.2).
  387.  
  388. % pfcFile('pfcsyntax'). % operator declarations.
  389.  
  390. %   File   : pfcsyntax.pl
  391. %   Author : Tim Finin, finin@prc.unisys.com
  392. %   Purpose: syntactic sugar FOR Pfc - operator definitions AND term expansions.
  393.  
  394.  
  395. pfcPreferedDir(H,B,(B=>H)):-pfcMustFC(H).
  396. pfcPreferedDir(H,B,(H<=B)):-pfcPreferBC(H).
  397.  
  398.  
  399.  
  400. fwc:-true.
  401. bwc:-true.
  402.  
  403. is_fc_body(P):- (fwc==P ; (compound(P),arg(_,P,E),is_fc_body(E))),!.
  404. is_bc_body(P):- (bwc==P ; (compound(P),arg(_,P,E),is_bc_body(E))),!.
  405.  
  406. pfc_file_expansion(A,B):-loop_check(pfc_file_expansion_lc(A,B)).
  407. pfc_file_expansion_lc(A,B) :- NOT(thlocal:into_form_code), pfc_file_expansion_each(A,B),
  408.     (thlocal:pfcExpansion -> true;  (dmsg(warn_PfcWantedToExpand(A)),dmsg(warn_into(B)),!,fail)).
  409. :-export(pfc_file_expansion/2).
  410.  
  411. /*
  412. pfc_file_expansion_each_pttp((P,Q), :- pttp_tell( (P,Q) )):- !.
  413. pfc_file_expansion_each_pttp((P;Q), :- pttp_tell( (P;Q) )):- !.
  414. pfc_file_expansion_each_pttp((P:-Is_pttp,Q), :- pttp_tell((P:-Q))):- Is_pttp==is_pttp.
  415.  
  416. pfc_file_expansion_each_pttp(all(Q,P), :-snark_tell(all(Q,P))):- !.
  417. pfc_file_expansion_each_pttp(exists(Q,P), :-snark_tell(exists(Q,P))):- !.
  418. pfc_file_expansion_each_pttp(~(P), :- snark_tell( (P) )):- !.
  419. pfc_file_expansion_each_pttp(implies(P,Q), :- snark_tell( =>(P,Q) )):- !.
  420. */
  421.  
  422. pfc_file_expansion_each((P -->> Q),(:- pfcAdd(Rule))) :-
  423.   pfc_translate_rule((P -->> Q), Rule).
  424. pfc_file_expansion_each((P --*>> Q),(:- pfcAdd(Rule))) :-
  425.   pfc_translate_rule((P --*>> Q), Rule).
  426. pfc_file_expansion_each(':-'(_),_):-!,fail.
  427. pfc_file_expansion_each((P=>Q),(:- pfcMarkF(Q),pfcAdd((P=>Q)))).
  428. %pfc_file_expansion_each((P=>Q),(:- pfcAdd(('<='(Q,P))))).  % DO NOT USE speed-up attempt
  429. pfc_file_expansion_each(('<='(P,Q)),(:- pfcMarkB(P),pfcAdd(('<='(P,Q))))).
  430. pfc_file_expansion_each((P<=>Q),(:- pfcMarkC(P),pfcMarkC(Q),pfcAdd((P<=>Q)))).
  431. pfc_file_expansion_each((RuleName :::: Rule),(:- pfcAdd((RuleName :::: Rule)))).
  432. pfc_file_expansion_each((=>P),(:- pfcMarkF(P),pfcAdd((=>P)))):-nonvar(P).
  433. pfc_file_expansion_each('fwc'((Q)),(:- pfcMarkF(Q),pfcAdd(=>Q))):-nonvar(Q).
  434.  
  435. pfc_file_expansion_each((disabled(Q):-P),(:- pfcRem1(Q))):-P==true, nonvar(Q), (NOT(thlocal:pfcExpansion);pfcMarkC(Q)),!.
  436. pfc_file_expansion_each((enabled(Q):-P),(:- pfcAdd(Q))):-P==true, nonvar(Q), (NOT(thlocal:pfcExpansion);pfcMarkC(Q)),!.
  437.  
  438. pfc_file_expansion_each((disabled(Q):-P),(disabled(Q):-P)):- nonvar(P),P\==true,nonvar(Q),(NOT(thlocal:pfcExpansion);pfcMarkC(Q)),!.
  439. pfc_file_expansion_each((enabled(Q):-P), (:-(pfcMarkC(Q),pfcAdd(Q<=P)))):- nonvar(P),P\==true,nonvar(Q).
  440.  
  441. pfc_file_expansion_each(((Q:-P)),(:- (pfcMarkF(Q),pfcMarkC(P=>Q),pfcAdd(P=>Q)))):- pfcMustFC(Q),!.
  442.  
  443. pfc_file_expansion_each(((Q:-P)),(:- (pfcMarkF(Q),pfcMarkC(P=>Q),pfcAdd(P=>Q)))):- nonvar(P),P\==true,nonvar(Q),is_fc_body(P),!.
  444. pfc_file_expansion_each(((Q:-P)),(:- (pfcMarkB(Q),pfcMarkC(Q),pfcAdd(Q<=P)))):- nonvar(P),P\==true,nonvar(Q),is_bc_body(P),!.
  445.  
  446. %pfc_file_expansion_each(((Q:-P)),(:- pfcMarkB(Q),pfcAdd(Q<=P))):- nonvar(P),nonvar(Q),P\==true,NOT(is_fc_body(P)),pfcControlled(Q),!.
  447. pfc_file_expansion_each(P,(:- pfcAdd(P))):- pfcMustFC(P),!.
  448. pfc_file_expansion_each(P,(:- pfcAdd(P))):-pfcControlled(P),!.
  449. %pfc_file_expansion_each(((Q:-P)),(:- (pfcMarkB(Q),pfcMarkC(Q),pfcAdd((Q:-P))))):- nonvar(P),P\==true,nonvar(Q),pfcUseAllBC((Q:-P)).
  450. %pfc_file_expansion_each((Q,(:- (pfcMarkC(Q),pfcAdd(Q))))):- nonvar(Q),pfcUseAllFact(Q).
  451.  
  452. pfcMustUseFC(G):- once(pfcRuleOutcomeHeadBody(G,H,_)),H\=@=G,!,pfcMustUseFC(H).
  453. pfcMustUseFC(G):- get_functor(G,F),NOT(pfc_mpred_prop(F,TZ,prologOnly)),pfc_mpred_prop(F,TZ,pfcMustFC).
  454.  
  455. pfcUseAllBC(((Q:-P))):-may_use_head(Q),no_head_singletons_hb(Q,P).
  456. pfcUseAllFact(Q):-may_use_head(Q),no_head_singletons_hb(Q,true).
  457.  
  458. no_head_singletons_hb(Q,P):-NOT(((head_singletons_hb(Q,P,_),get_functor(Q,F,A),decl_mpred_prolog(F/A)))).
  459.  
  460. callBC(isa(_,_)):-!,fail.
  461. callBC(G):-pfc_negation(G,POS),!,show_call(NOT(callBC(POS))),!.
  462. callBC(G):- loop_check_nr(pfcBC_NoFacts(G)).
  463.  
  464. may_never_deduce_bc_change.
  465.  
  466. may_use_head(_):-may_never_deduce_bc_change,!,fail.
  467. may_use_head(Q):-var(Q),!,fail.
  468. may_use_head(_:_):-!,fail.
  469. may_use_head(Q):-Q \= (F/A),!, get_functor(Q,F,A),!,may_use_head(F/A).
  470. may_use_head(F/_):- atom_contains(F,'_'),!,fail.
  471. may_use_head(F/_):- pfc_mpred_prop(F,TZ,prologOnly),!,fail.
  472. may_use_head(F/_):- current_predicate(F/A),make_functor(G,F,A),real_builtin_predicate(G),!,fail.
  473. may_use_head(F/A):- make_functor(G,F,A),real_builtin_predicate(G),!,fail.
  474. may_use_head(_/1):-!,fail.
  475. may_use_head(_/2).
  476. % may_use_head(_/_).
  477.  
  478.  
  479. pfcAddPreTermExpansion((I1,I2)):-!,pfcAddPreTermExpansion(I1),pfcAddPreTermExpansion(I2).
  480. pfcAddPreTermExpansion(Info):-pfc_file_expansion_each(Info,What),!,What=(:-Call),show_call(must(call(Call))).
  481.  
  482.  
  483. % pfcFile('pfccore').   % core of Pfc.
  484.  
  485. %   File   : pfccore.pl
  486. %   Author : Tim Finin, finin@prc.unisys.com
  487. %   Updated: 10/11/87, ...
  488. %            4/2/91 by R. McEntire: added calls TO valid_dbref AS a
  489. %                                   workaround FOR the Quintus 3.1
  490. %                                   bug in the recorded database.
  491. %   Purpose: core Pfc predicates.
  492.  
  493. :- use_module(library(lists)).
  494.  
  495. :- decl_mpred_pfc ('=>')/2.
  496. :- decl_mpred_pfc ('::::')/2.
  497. :- decl_mpred_pfc '<=>'/2.
  498. :- decl_mpred_pfc '<='/2.
  499. :- decl_mpred_pfc 'pfcPT'/2.
  500. :- decl_mpred_pfc 'pfcNT'/3.
  501. :- decl_mpred_pfc 'pfcBT'/2.
  502. :- decl_mpred_pfc pfcUndoMethod/2.
  503. :- decl_mpred_pfc pfcAction/2.
  504.  
  505. :- decl_mpred_pfc pfcSelect/1.
  506. :- decl_mpred_pfc pfcDatabaseTerm/1.
  507.  
  508.  
  509. %:- decl_mpred_pfc pfcTmsMode/1.
  510. :- decl_mpred_pfc pfcQueue/1.
  511. %:- decl_mpred_pfc pfc Default/1.
  512.  
  513. :- decl_mpred_pfc pfcDatabase/1.
  514. :- decl_mpred_pfc pfcHaltSignal/0.
  515. %:- decl_mpred_pfc pfcDebugging/0.
  516. %:- decl_mpred_pfc pfcSearch/1.
  517.  
  518. :- decl_mpred_pfc pfc_settings/2.
  519.  
  520. %%= initialization of global assertons
  521.  
  522. %= pfc_setting_default/1 initialized a global assertion.
  523. %=  pfc_setting_default(P,Q) - IF there is any fact unifying with P, THEN DO
  524. %=  nothing, ELSE pfcAssertS Q.
  525.  
  526. pfc_setting_default(GeneralTerm,Default) :-
  527.   clause(GeneralTerm,true) -> true ; assert(Default).
  528.  
  529. %= pfcTmsMode is one of {none,local,cycles} AND controles the tms alg.
  530. :- pfc_setting_default(pfc_settings(tmsMode,_), pfc_settings(tmsMode,cycles)).
  531.  
  532. % Pfc Search strategy. pfc_settings(searchMode,X) where X is one of {direct,depth,breadth}
  533. :- pfc_setting_default(pfc_settings(searchMode,_), pfc_settings(searchMode,direct)).
  534.  
  535.  
  536.  
  537. % pfcAdd(/*to_exp*/((:-export number/1))):-trace_or_throw(crazy_pfcAdd(/*to_exp*/((:-export number/1)))).
  538.  
  539.  
  540. %
  541.  
  542. %= add/2 AND pfcPost/2 are the main ways TO assert new clauses into the
  543. %= database AND have forward reasoning done.
  544.  
  545. %= pfcAdd(P,S) asserts P into the dataBase with support from S.
  546.  
  547. pfcAdd(P) :- current_predicate(add/1),!,add(P).
  548. pfcAdd(P) :- pfcAdd_fast(P).
  549.  
  550. pfcAdd_fast(P) :- get_user_support_for_add(P,S),pfcAdd(P,S).
  551.  
  552. pfcAdd(P,S):-pfcDoConjs(pfcAdd1,P,[S]).
  553.  
  554. pfc_correct_add(S,P,POO):- pfc_fully_expand_warn(change(assert,pfc_correct_add),P,PO), PO\=@=P, pfc_correct_add(S,PO,POO) .
  555. pfc_correct_add(S,P,P):- is_wrong(P,S,_),!.
  556. pfc_correct_add(_,(H:-B),(H<=B)) :- head_singletons_hb(H,B,_),!,pfcWarn("adding pfcBC instead of Neck ~q",[pfcAdd1(H<=B)]).
  557. pfc_correct_add(_,(B=>H),(H<=B)) :-head_singletons_hb(H,B,_),!,pfcWarn("adding pfcBC instead of pfcFWC ~q",[pfcAdd1(H<=B)]).
  558. pfc_correct_add(_,(H:-B),(G)) :-pfcPreferedDir(H,B,G),!,pfcWarn("adding ~q",[pfcPreferedDir(H,B,G)]).
  559.  
  560. is_wrong(P,S,Why):-pfc_negate_for_add(P,N),P\=@=N,pfcGetSupport(N,Why),!,dmsg(warn(want(P,S),but,N -> Why)),!,dtrace.
  561.  
  562. pfcAdd1(P,S):-transitive(pfc_correct_add(S),P,PO), P\=@=PO ,!, pfcWarn("pfcAdd1 Changed ~q",[P->PO]),pfcAdd1(PO,S).
  563. % pfcAdd1(P,_):-pfcTypeFull(P,T),T==support,!,assert_if_new(P),!.
  564. % pfcAdd1(P,S) :- is_wrong(P,S,_),!.
  565. pfcAdd1(P,_):-pfc_ignored(P),!.
  566. %pfcAdd1(PO,S0) :- is_deduced_by_god(S0),pfcGetSupport(PO,Why),!,trace_or_throw(not_needed(Why,pfcAdd1(PO,S0))).
  567. pfcAdd1(PO,S0) :- is_deduced_by_god(S0),pfcGetSupport(PO,Why),!,dmsg(not_needed(Why,pfcAdd1(PO,S0))).
  568. pfcAdd1(PO,USER) :- get_user_support_for_lookup(_,USER),pfcGetSupport(PO,Why),Why==USER,!,dmsg(already(Why,pfcAdd1(PO,S0))).
  569. pfcAdd1(PO,USER) :- get_user_support_for_lookup(_,USER),pfcGetSupport(PO,Why),Why\==USER,!,dmsg(user_needed(Why,pfcAdd1(PO,USER))),!,pfcAdd2(PO,USER).
  570.  
  571. pfcAdd1(PO,S0):-pfcAdd2(PO,S0).
  572.  
  573. pfcAdd2(PO,S0) :- copy_term(PO:S0,P1:S1),
  574.  must((pfc_pre_expansion_each(P1,P),pfc_pre_expansion_each(S1,S))),
  575.   must(copy_term(P-S,P2-S2)),
  576.   must(pfcPost(P2,S2)),
  577.   sanity(variant(P:S,P2:S2)),
  578.   pfcRun,!.
  579.  
  580. %pfcAdd1(_,_).
  581. pfcAdd2(P,S) :- pfcError("pfcAdd(~w,~w) failed",[P,S]),!,fail.
  582.  
  583.  
  584. % pfcPost(+Ps,+S) tries TO add a fact OR set of fact TO the database.  FOR
  585. % each fact (OR the singelton) pfcPost1 is called. It always succeeds.
  586.  
  587. pfcPost(Each,S) :- pfcDoConjs(pfcPost1,Each,[S]).
  588.  
  589. % pfcPost1(+P,+S) tries TO add a fact TO the database, AND, IF it succeeded,
  590. % adds an entry TO the pfc queue FOR subsequent forward chaining.
  591. % It always succeeds.
  592.  
  593. pfcPost1(P,_):-pfc_ignored(P),!.
  594. pfcPost1(P,S) :-
  595.   %= db pfcAddDbToHead(P,P2),
  596.   % pfcRemoveOldVersion(P),
  597.   copy_term(P,PC),
  598.   must((pfcAddSupport(P,S),sanity(PC=@=P))),
  599.   pfcUnique(P),sanity(PC=@=P),
  600.   must(pfcAssertIfUnknown(P)), % was simply pfc_assert(P),
  601.    pfcTraceAdd(P,S),
  602.    !,
  603.    pfcEnqueue(P,S),
  604.    !.
  605.  
  606. pfcPost1(P,S) :- (\+ \+ pfcUnique(P)),pfcError("(maybe ERROR?!) pfcAdd(~w,~w) failed",[P,S]),!.
  607. pfcPost1(_,_).
  608. pfcPost1(P,S) :-  pfcError("pfcAdd(~w,~w) failed",[P,S]).
  609.  
  610.  
  611. pfcRepropagate(P) :-
  612.   forall(must(pfcGetSupport(P,S)), pfcRepropagate(P,S)).
  613.  
  614. pfcRepropagate(P,S) :-
  615.   (\+ \+ must(pfcAssertIfUnknown(P))), % was simply pfcAssertS(P),
  616.   pfcTraceAdd(P,S),
  617.   !,
  618.   pfcEnqueue(P,S),
  619.   !.
  620.  
  621.  
  622.  
  623. %%
  624. %= pfcAddDbToHead(+P,-NewP) talkes a fact P OR a conditioned fact
  625. %= (P:-C) AND adds the Db context.
  626. %%
  627. /*
  628. pfcAddDbToHead(P,NewP) :-
  629.   pfcCurrentDb(Db),
  630.   (Db=true        -> NewP = P;
  631.    P=(Head:-Body) -> NewP = (Head :- (Db,Body));
  632.    otherwise      -> NewP = (P :- Db)).
  633. */
  634.  
  635. % pfcUnique(X) is true IF there is no assertion X in the prolog db.
  636.  
  637. pfcUnique((Head:-Tail)) :-
  638.   !,
  639.   \+ pfc_clause_db_unify(Head,Tail).
  640.  
  641. pfcUnique(P) :-
  642.   !,
  643.   \+ pfc_clause_db_unify(P,true).
  644.  
  645.  
  646. pfcEnqueue(P,S) :-
  647.   pfc_settings(searchMode,Mode)
  648.     -> (Mode=direct  -> pfcFwd(P) ;
  649.     Mode=depth   -> pfcAssertAInt(pfcQueue(P),S) ;
  650.     Mode=breadth -> pfcAssertInt(pfcQueue(P),S) ;
  651.     ELSE         -> pfcError("Unrecognized pfcSearch mode: ~w", Mode))
  652.      ; pfcWarn("No pfcSearch mode").
  653.  
  654.  
  655. % IF there is a rule of the form Identifier ::: Rule THEN delete it.
  656.  
  657. pfcRemoveOldVersion((Identifier::::Body)) :-
  658.   % this should never happen.
  659.   var(Identifier),
  660.   !,
  661.   pfcError("variable used as an  rule name in ~w :::: ~w",
  662.           [Identifier,Body]).
  663.  
  664.  
  665. pfcRemoveOldVersion((Identifier::::Body)) :-
  666.   nonvar(Identifier),
  667.   pfc_clause_db_unify((Identifier::::OldBody),_),
  668.   \+(Body=OldBody),
  669.   pfcRem1((Identifier::::OldBody)),
  670.   !.
  671. pfcRemoveOldVersion(_).
  672.  
  673.  
  674.  
  675. %
  676.  
  677. % pfcRun compute the deductive closure of the current database.
  678. % How this is done depends on the searching mode:
  679. %    direct -  fc has already done the job.
  680. %    depth OR breadth - use the pfcQueue mechanism.
  681.  
  682. pfcRun :-
  683.   (\+ pfc_settings(searchMode,direct)),
  684.   pfcStep,
  685.   pfcRun.
  686. pfcRun.
  687.  
  688.  
  689. % pfcStep removes one entry from the pfcQueue AND reasons from it.
  690.  
  691.  
  692. pfcStep :-  
  693.   % IF pfcHaltSignal is true, reset it AND fail, thereby stopping inferencing.
  694.   pfcRetractInternal(pfcHaltSignal),
  695.   !,
  696.   fail.
  697.  
  698. pfcStep :-
  699.   % DRAW immediate conclusions from the NEXT fact TO be considered.
  700.   % fails iff the queue is empty.
  701.   get_next_fact(P),
  702.   pfcdo(pfcFwd(P)),
  703.   !.
  704.  
  705. get_next_fact(P) :-
  706.   %identifies the nect fact TO fc from AND removes it from the queue.
  707.   select_next_fact(P),
  708.   remove_selection(P).
  709.  
  710. remove_selection(P) :-
  711.   pfcRetractInternal(pfcQueue(P)),
  712.   pfcRemoveSupportsQuietly(pfcQueue(P)),
  713.   !.
  714. remove_selection(P) :-
  715.   brake(pmsg("pfc:get_next_fact - selected fact not on Queue: ~w", [P])).
  716.  
  717.  
  718. % select_next_fact(P) identifies the NEXT fact TO reason from.  
  719. % It tries the user defined predicate first AND, failing that,
  720. %  the default mechanism.
  721.  
  722. select_next_fact(P) :-
  723.   pfcSelect(P),
  724.   !.  
  725. select_next_fact(P) :-
  726.   defaultpfcSelect(P),
  727.   !.  
  728.  
  729. % the default selection predicate takes the item AT the froint of the queue.
  730. defaultpfcSelect(P) :- pfcQueue(P),!.
  731.  
  732. % pfcHalt stops the forward chaining.
  733. pfcHalt :-  pfcHalt("",[]).
  734.  
  735. pfcHalt(Format) :- pfcHalt(Format,[]).
  736.  
  737. pfcHalt(Format,Args) :-
  738.   pmsg(Format,Args),
  739.   pfcHaltSignal ->
  740.        pfcWarn("pfcHalt finds pfcHaltSignal already set")
  741.      ; pfcAssertS(pfcHaltSignal).
  742.  
  743.  
  744. %%
  745. %%
  746. %= predicates FOR manipulating triggers
  747. %%
  748.  
  749.  
  750. pfcAddTrigger(pfcPT(Trigger,Body),Support) :-
  751.   !,
  752.   pfc_trace_msg('      Adding positive trigger ~q~n',
  753.         [pfcPT(Trigger,Body)]),
  754.   pfcAssertInt(pfcPT(Trigger,Body),Support),
  755.   copy_term(pfcPT(Trigger,Body),Tcopy),
  756.   pfcCall(Trigger),
  757.   pfcEvalLHS(Body,(Trigger,Tcopy)),
  758.   fail.
  759.  
  760.  
  761. pfcAddTrigger(pfcNT(Trigger,Test,Body),Support) :-
  762.   !,
  763.   pfc_trace_msg('      Adding negative trigger: ~q~n       test: ~q~n       body: ~q~n',
  764.         [Trigger,Test,Body]),
  765.   copy_term(Trigger,TriggerCopy),
  766.   pfcAssertInt(pfcNT(TriggerCopy,Test,Body),Support),
  767.   \+Test,
  768.   pfcEvalLHS(Body,((\+Trigger),pfcNT(TriggerCopy,Test,Body))).
  769.  
  770. pfcAddTrigger(pfcBT(Trigger,Body),Support) :-
  771.   !,
  772.   pfcAssertInt(pfcBT(Trigger,Body),Support),
  773.   pfcBtPtCombine(Trigger,Body).
  774.  
  775. pfcAddTrigger(X,Support) :-
  776.   pfcError("Unrecognized trigger to pfcAddtrigger: ~w",[trigger(X,Support)]).
  777.  
  778.  
  779. pfcBtPtCombine(Head,Body,Support) :-
  780.   %= a backward trigger (pfcBT) was just added with head AND Body AND support Support
  781.   %= find any pfcPT's with unifying heads and add the instantied pfcBT body.
  782.   pfcGetTriggerQuick(pfcPT(Head,_PtBody)),
  783.   pfcEvalLHS(Body,Support),
  784.   fail.
  785. pfcBtPtCombine(_,_,_) :- !.
  786.  
  787. pfcGetTriggerQuick(Trigger) :-  pfc_clause_db_unify(Trigger,true).
  788.  
  789. pfcGetTrigger(Trigger):-pfcGetTriggerQuick(Trigger).
  790.  
  791. %%
  792. %%
  793. %= predicates FOR manipulating action traces.
  794. %%
  795.  
  796. pfcAddActionTrace(Action,Support) :-
  797.   % adds an action trace AND it's support.
  798.   pfcAddSupport(pfcAction(Action),Support).
  799.  
  800. pfcRemActionTrace(pfcAction(A)) :-
  801.   pfcUndoMethod(A,M),
  802.   M,
  803.   !.
  804.  
  805.  
  806. %%
  807. %= predicates TO remove pfc facts, triggers, action traces, AND queue items
  808. %= from the database.
  809. %%
  810.  
  811. pfcRetractInternal(X) :-
  812.   %= pfc_retract an arbitrary thing.
  813.   pfcType(X,Type),
  814.   pfcRetractTypeInternal(Type,X),
  815.   !.
  816.  
  817. pfcRetractTypeInternal(rule,X) :-
  818.   %= db  pfcAddDbToHead(X,X2),  pfc_retract(pfcInternal(rule),X2).
  819.   pfc_retract(pfcInternal(rule),X).
  820.  
  821. pfcRetractTypeInternal(trigger,X) :-
  822.   pfc_retract(pfcInternal(trigger),X)
  823.     -> unFc(X)
  824.      ; pfcWarn("Trigger not found to pfc_retract: ~w",[X]).
  825.  
  826. pfcRetractTypeInternal(action,X) :- pfcRemActionTrace(X).
  827.  
  828. pfcRetractTypeInternal(support,X) :-  pfc_retract(pfcInternal(support),X).
  829.  
  830. pfcRetractTypeInternal(fact,X) :-  
  831.   %= db pfcAddDbToHead(X,X2), pfc_retract(pfcInternal,X2).
  832.   pfc_retract(pfcInternal(fact),X).
  833.  
  834. %= pfcAddSome(X) adds item X TO some database
  835.  
  836. pfcAddSome(X) :-
  837.   % what type of X DO we have?
  838.   pfcType(X,Type),
  839.   % pfc_call_prolog_native the appropriate predicate.
  840.   pfcAddType(Type,X).
  841.  
  842. pfcAddType(support,X) :-
  843.   pfcAssertS(X),!.
  844. pfcAddType(rule,X) :-
  845.   pfcUnique(X),
  846.   pfcAssertS(X),!.
  847. pfcAddType(trigger,X) :-
  848.   pfcAssertS(X).
  849. pfcAddType(action,_Action) :- !.
  850. pfcAddType(fact,X) :-
  851.   must(pfcUnique(X)),
  852.   pfc_assert(X),!,
  853.   run_database_hooks(change(assert,z),X).
  854.  
  855.  
  856.  
  857.  
  858.  
  859. %= pfcRem1(P,S) removes support S from P AND checks TO see IF P is still supported.
  860. %= IF it is NOT, THEN the fact is retreactred from the database AND any support
  861. %= relationships it participated in removed.
  862. pfcRem1(P) :-
  863.   % pfcRem1/1 is the user's interface - it withdraws user support for P.
  864.   pfcDoConjs(pfcLambda([E],pfcRem_user(E)),P).
  865.  
  866. pfcRem_user(E):- get_user_support_for_remove(E,S),!,pfcRem1(E,S).
  867.  
  868.  
  869. pfcRem1(P,S) :-
  870.   % pfcDebug(pmsg("removing support ~w from ~w",[S,P])),
  871.   pfc_trace_msg('Removing support: ~q from ~q~n',[S,P]),  
  872.   pfcRemSupport(P,S)
  873.      -> pcfRemoveIfUnsupported(P)
  874.       ; pfcWarn("pfcRem1/2 Could not find support ~w to remove from fact ~w", [S,P]).
  875.  
  876. %%
  877. %= pfcRem2 is like pfcRem1, but IF P is still in the DB after removing the
  878. %= user's support, it is retracted by more forceful means (e.g. pfcRem3/1).
  879. %%
  880.  
  881. pfcRem2(P) :-
  882.   % pfcRem2/1 is the user's interface - it withdraws user support for P.
  883.   pfcDoConjs(pfcLambda([E],pfcRem2_user(E)),P).
  884.  
  885. pfcRem2_user(E):- get_user_support_for_remove(E,S), pfcRem2(E,S).
  886.  
  887.  
  888. pfcRem2(P,S) :-
  889.   pfcRem1(P,S),
  890.   pfcCall(P)
  891.      -> pfcRem3(P)
  892.       ; true.
  893.  
  894. %%
  895. %= pfcRem3(+F) retracts fact F from the DB AND removes any dependent facts */
  896. %%
  897.  
  898. pfcRem3(F) :-
  899.   pfcRemoveSupports(F),
  900.   pfcUndo(F).
  901.  
  902.  
  903. % removes any remaining supports FOR fact F, complaining AS it goes.
  904.  
  905. pfcRemoveSupports(F) :-
  906.   pfcRemSupport(F,S),
  907.   pfcWarn("~w was still supported by ~w",[F,S]),
  908.   fail.
  909. pfcRemoveSupports(_).
  910.  
  911. pfcRemoveSupportsQuietly(F) :-
  912.   pfcRemSupport(F,_),
  913.   fail.
  914. pfcRemoveSupportsQuietly(_).
  915.  
  916. % pfcUndo(X) undoes X.
  917.  
  918.  
  919.  
  920. pfcUndo(pfcNT(Head,Condition,Body)) :-  
  921.   % undo a negative trigger.
  922.   !,
  923.   (pfc_retract(pfcInternal(pfcNT),pfcNT(Head,Condition,Body))
  924.     -> unFc(pfcNT(Head,Condition,Body))
  925.      ; pfcError("Trigger not found to pfc_retract: ~w",[pfcNT(Head,Condition,Body)])).
  926.  
  927. pfcUndo(Fact) :-
  928.   % undo a random fact, printing out the trace, IF relevant.
  929.   pfc_retract(pfcUndo,Fact),!,
  930.   pfcTraceRem(Fact),
  931.   unFc1(Fact).
  932.  
  933. pfcUndo(Fact) :- dmsg(no_pfcUndo(Fact)),sanity((functor(Fact,F,_),NOT((atom_concat(_,'Fn',F),dtrace)))).
  934.  
  935.  
  936. %= unFc(P) "un-forward-chains" from fact f.  That is, fact F has just
  937. %= been removed from the database, so remove all support relations it
  938. %= participates in AND check the things that they support TO see IF they
  939. %= should stayu in the database OR should also be removed.
  940.  
  941.  
  942. unFc(F) :-
  943.   pfcRetractSupportRelations(F),
  944.   unFc1(F).
  945.  
  946. unFc1(F) :-
  947.   pfcUnFcCheckTriggers(F),
  948.   % is this really the right place FOR pfcRun<?
  949.   pfcRun.
  950.  
  951.  
  952. pfcUnFcCheckTriggers(F) :-
  953.   pfcType(F,fact),
  954.   copy_term(F,Fcopy),
  955.   pfcNT(Fcopy,Condition,Action),
  956.   (\+ Condition),
  957.   pfcEvalLHS(Action,((\+F),pfcNT(F,Condition,Action))),
  958.   fail.
  959. pfcUnFcCheckTriggers(_).
  960.  
  961. pfcRetractSupportRelations(Fact) :-
  962.   pfcType(Fact,Type),
  963.   (Type=trigger -> pfcRemSupport(P,(_,Fact))
  964.                 ; pfcRemSupport(P,(Fact,_))),
  965.   pcfRemoveIfUnsupported(P),
  966.   fail.
  967. pfcRetractSupportRelations(_).
  968.  
  969.  
  970.  
  971. %= pcfRemoveIfUnsupported(+P) checks TO see IF P is supported AND removes
  972. %= it from the DB IF it is NOT.
  973.  
  974. pcfRemoveIfUnsupported(P) :-
  975.    pfcSupported(P) -> true ;  pfcUndo(P).
  976.  
  977.  
  978. %= pfcSupported(+P) succeeds IF P is "supported". What this means
  979. %= depends on the TMS mode selected.
  980.  
  981. pfcSupported(P) :-
  982.   pfc_settings(tmsMode,Mode),
  983.   pfcSupported2(Mode,P).
  984.  
  985. pfcSupported2(local,P) :- !, pfcGetSupport(P,A),!,A\=fail.
  986. pfcSupported2(cycles,P) :-  !, wellFounded(P).
  987. pfcSupported2(full,P) :-  !, wellFounded(P).
  988. pfcSupported2(_,_P) :- true.
  989.  
  990.  
  991. %%
  992. %= a fact is well founded IF it is supported by the user
  993. %= OR by a set of facts AND a rules, all of which are well founded.
  994. %%
  995.  
  996. wellFounded(Fact) :- pfcWFF(Fact,[]).
  997.  
  998. pfcWFF(F,_) :-
  999.   % supported by user (pfcAxiom) OR an "absent" fact (assumption/assumable).
  1000.   (pfcAxiom(F) ; pfcAssumptionBase(F)),
  1001.   !.
  1002.  
  1003. pfcWFF(F,Descendants):-
  1004.    pfcWFF_Descendants(F,Descendants).
  1005.  
  1006. pfcWFF_Descendants(F,Descendants) :-
  1007.   % first make sure we aren't in a loop.
  1008.   (\+ memberchk(F,Descendants)),
  1009.   % find a justification.
  1010.   supportsForWhy(F,Supporters),
  1011.   % all of whose members are well founded.
  1012.   pfcWFF_L(Supporters,[F|Descendants]),
  1013.   !.
  1014.  
  1015. %= pfcWFF_L(L) simply maps pfcWFF OVER the list.
  1016.  
  1017. pfcWFF_L([],_).
  1018. pfcWFF_L([X|Rest],L) :-
  1019.   pfcWFF(X,L),
  1020.   pfcWFF_L(Rest,L).
  1021.  
  1022.  
  1023. % supports(+F,-ListofSupporters) where ListOfSupports is a list of the
  1024. % supports FOR one justification FOR fact F -- i.e. a list of facts which,
  1025. % together allow one TO deduce F.  One of the facts will typically be a rule.
  1026. % The supports FOR a user-defined fact are: [pfcUser/*(Original)*/].
  1027.  
  1028. supportsForWhy(F,[Fact|MoreFacts]) :-
  1029.   pfcGetSupport(F,(Fact,Trigger)),
  1030.   triggerSupports(Trigger,MoreFacts).
  1031.  
  1032. triggerSupports(pfcUser,[]) :- !.
  1033. triggerSupports(Trigger,[Fact|MoreFacts]) :-
  1034.   pfcGetSupport(Trigger,(Fact,AnotherTrigger)),
  1035.   triggerSupports(AnotherTrigger,MoreFacts).
  1036.  
  1037.  
  1038. %%
  1039. %%
  1040. %= pfcFwd(X) forward chains from a fact OR a list of facts X.
  1041. %%
  1042. pfcFwd(X):-
  1043.   with_assertions(thlocal:pfc_no_mark,pfcDoConjs(pfcFwd1,X)).
  1044.  
  1045. %%
  1046. %= pfcFwd1(+P) forward chains FOR a single fact.
  1047. %%
  1048. pfcFwd1(Fact) :-
  1049.    pfcRuleOutcomeHead(Fact,Outcome),!,
  1050.     loop_check_term(pfcFwd1_newoutcome(Fact),Outcome,
  1051.        dmsg(looped_pfcRuleOutcomeHead(Fact,Outcome))),!.
  1052.  
  1053. pfcFwd1_newoutcome(Fact) :-
  1054.   fc_rule_check(Fact),
  1055.   copy_term(Fact,F),
  1056.   % check positive triggers
  1057.   pfcRunPT(Fact,F),
  1058.   % check negative triggers
  1059.   pfcRunNT(Fact,F).
  1060.  
  1061.  
  1062. %%
  1063. %= fc_rule_check(P) does some special, built in forward chaining IF P is
  1064. %= a rule.
  1065. %=
  1066.  
  1067. fc_rule_check((P=>Q)) :-  
  1068.   !,  
  1069.   pfcProcessRule(P,Q,(P=>Q)).
  1070. fc_rule_check((Name::::P=>Q)) :-
  1071.   !,  
  1072.   pfcProcessRule(P,Q,(Name::::P=>Q)).
  1073. fc_rule_check((P<=>Q)) :-
  1074.   !,
  1075.   pfcProcessRule(P,Q,(P<=>Q)),
  1076.   pfcProcessRule(Q,P,(P<=>Q)).
  1077. fc_rule_check((Name :::: P <=> Q)) :-
  1078.   !,
  1079.   pfcProcessRule(P,Q,((Name::::P<=>Q))),
  1080.   pfcProcessRule(Q,P,((Name::::P<=>Q))).
  1081.  
  1082. fc_rule_check(('<='(P,Q))) :-
  1083.   !,
  1084.   pfcDefineBcRule(P,Q,('<='(P,Q))).
  1085.  
  1086. fc_rule_check(_).
  1087.  
  1088.  
  1089. pfcRunPT(Fact,F) :-
  1090.   pfcGetTriggerQuick(pfcPT(F,Body)),
  1091.   pfc_trace_msg('      Found positive trigger: ~q~n       body: ~q~n',
  1092.         [F,Body]),
  1093.   not_too_deep(pfcRunPT, pfcEvalLHS(Body,(Fact,pfcPT(F,Body)))),
  1094.   fail.
  1095.  
  1096. %pfcRunPT(Fact,F) :-
  1097. %  pfcGetTriggerQuick(pfcPT(presently(F),Body)),
  1098. %  pfcEvalLHS(Body,(presently(Fact),pfcPT(presently(F),Body))),
  1099. %  fail.
  1100.  
  1101. pfcRunPT(_,_).
  1102.  
  1103. pfcRunNT(_Fact,F) :-
  1104.   support2(pfcNT(F,Condition,Body),X,_),
  1105.   Condition,
  1106.   pfcRem1(X,(_,pfcNT(F,Condition,Body))),
  1107.   fail.
  1108. pfcRunNT(_,_).
  1109.  
  1110.  
  1111. %%
  1112. %= pfcDefineBcRule(+Head,+Body,+ParentRule) - defines a backeard
  1113. %= chaining rule AND adds the corresponding pfcBT triggers TO the database.
  1114. %%
  1115.  
  1116. pfcDefineBcRule(Head,_Body,ParentRule) :-
  1117.   (\+ pfcLiteral(Head)),
  1118.   pfcWarn("Malformed backward chaining rule.  ~w not atomic.",[Head]),
  1119.   pfcWarn("rule: ~w",[ParentRule]),
  1120.   !,
  1121.   fail.
  1122.  
  1123. pfcDefineBcRule(Head,Body,ParentRule) :-
  1124.   copy_term(ParentRule,ParentRuleCopy),
  1125.   pfcBuildRhs(Head,Rhs),
  1126.   pfcForEach(pfc_nf(Body,Lhs),
  1127.           (pfcBuildTrigger(Lhs,rhs(Rhs),Trigger),
  1128.            pfcAdd(pfcBT(Head,Trigger),(ParentRuleCopy,pfcUser)))).
  1129.  
  1130.  
  1131.  
  1132. %%
  1133. %%
  1134. %= eval something on the LHS of a rule.
  1135. %%
  1136.  
  1137.  
  1138. pfcEvalLHS((Test->Body),Support) :-  
  1139.   !,
  1140.   (pfc_call_prolog_native(pfcTest,Test) -> pfcEvalLHS(Body,Support)),
  1141.   !.
  1142.  
  1143. pfcEvalLHS(rhs(X),Support) :-
  1144.   !,
  1145.   pfc_eval_rhs(X,Support),
  1146.   !.
  1147.  
  1148. pfcEvalLHS(X,Support) :-
  1149.   pfcType(X,trigger),
  1150.   !,
  1151.   pfcAddTrigger(X,Support),
  1152.   !.
  1153.  
  1154. %pfcEvalLHS(snip(X),Support) :-
  1155. %  snip(Support),
  1156. %  pfcEvalLHS(X,Support).
  1157.  
  1158. pfcEvalLHS(X,_) :-
  1159.   pfcError("Unrecognized item found in trigger body, namely ~w.",[X]).
  1160.  
  1161.  
  1162. %%
  1163. %= eval something on the RHS of a rule.
  1164. %%
  1165.  
  1166. pfc_eval_rhs([],_) :- !.
  1167. pfc_eval_rhs([Head|Tail],Support) :-
  1168.   pfc_eval_rhs1(Head,Support),
  1169.   pfc_eval_rhs(Tail,Support).
  1170.  
  1171.  
  1172.  
  1173. pfc_eval_rhs1(XXrest,Support) :- is_list(XXrest),
  1174.  % embedded sublist.
  1175.  !, pfc_eval_rhs(XXrest,Support).
  1176.  
  1177.  
  1178. pfc_eval_rhs1({Action},Support) :-
  1179.  % evaluable Prolog CODE.
  1180.  !,
  1181.  pfcEvalAction(Action,Support).
  1182.  
  1183. pfc_eval_rhs1(P,_Support) :-
  1184.  % predicate TO remove.
  1185.  pfcNegatedLiteral(P),
  1186.  !,
  1187.  pfcRem1(P).
  1188.  
  1189. pfc_eval_rhs1(Assertion,Support) :-
  1190.  % an assertion TO be added.
  1191.  pfcPost1(Assertion,Support).
  1192.  
  1193. pfc_eval_rhs1(X,_) :-
  1194.   pfcError("Malformed rhs of a rule: ~w",[X]).
  1195.  
  1196.  
  1197. %%
  1198. %= evaluate an action found on the rhs of a rule.
  1199. %%
  1200.  
  1201. pfcEvalAction(Action,Support) :-
  1202.   (pfc_call_prolog_native(pfcEvalAction,Action)),
  1203.   (pfcUndoable(Action)
  1204.      -> pfcAddActionTrace(Action,Support)
  1205.       ; true).
  1206.  
  1207.  
  1208. %%
  1209. %=
  1210. %%
  1211.  
  1212. pfc_trigger_the_trigger(Trigger,Body,_Support) :-
  1213.  trigger_trigger1(Trigger,Body).
  1214. pfc_trigger_the_trigger(_,_,_).
  1215.  
  1216.  
  1217. %trigger_trigger1(presently(Trigger),Body) :-
  1218. %  !,
  1219. %  copy_term(Trigger,TriggerCopy),
  1220. %  pfcCall(Trigger),
  1221. %  pfcEvalLHS(Body,(presently(Trigger),pfcPT(presently(TriggerCopy),Body))),
  1222. %  fail.
  1223.  
  1224. trigger_trigger1(Trigger,Body) :-
  1225.   copy_term(Trigger,TriggerCopy),
  1226.   pfcCall(Trigger),
  1227.   pfcEvalLHS(Body,(Trigger,pfcPT(TriggerCopy,Body))),
  1228.   fail.
  1229.  
  1230.  
  1231. %%
  1232. %= The predicate pfc/1 is the proper way TO access terms in the Pfc database. pfc(P) succeeds IF P is a term
  1233. %= in the current pfc database after invoking any backward chaining rules OR is provable by Prolog.
  1234. %= pfcCall(F) is true iff F is a fact available FOR forward (backward?) chaining.
  1235. %= Note that this has the side effect of catching unsupported facts AND
  1236. %= assigning them support from God.
  1237. %%
  1238. pfcCall(F):-no_repeats(loop_check_nr(pfcBC_Cache(F))).
  1239.  
  1240. pfcBC_Cache(P) :-
  1241.   % trigger any bc rules.
  1242.   pfcBT(P,Trigger),
  1243.   pfcGetSupport(pfcBT(P,Trigger),S),
  1244.   pfcEvalLHS(Trigger,S),
  1245.   maybeSupport(P,S),
  1246.   fail.
  1247.  
  1248.  
  1249. pfcBC_Cache(F) :-
  1250.   %= this is probably NOT advisable due TO extreme inefficiency.
  1251.   var(F)    ->  pfcFact(F) ;
  1252.   ( \+ current_predicate(_,F)) -> mpred_call(F) ;
  1253.   % check FOR system predicates AS well.
  1254.   NOT(predicate_property(F,number_of_clauses(_))) -> pfc_call_prolog_native(systemPred,F) ;
  1255.   otherwise ->  (pfc_clause_db_unify(F,Condition),
  1256.     pfc_call_prolog_native(neck(F),Condition), ignore((ground(F),(NOT(is_asserted_1(F)), maybeSupport(F,(pfcGod,pfcGod)))))).
  1257.  
  1258.  
  1259. maybeSupport(P,_):-pfc_ignored(P),!.
  1260. maybeSupport(P,S):-( \+ ground(P)-> true;
  1261.   (predicate_property(P,dynamic)->pfcAdd(P,S);true)).
  1262.  
  1263.  
  1264. %%
  1265. %= pfcBC_NoFacts(F) is true iff F is a fact available FOR backward chaining ONLY.
  1266. %= Note that this has the side effect of catching unsupported facts AND
  1267. %= assigning them support from God.
  1268. %= this Predicate should hide Facts from callBC/1
  1269. %%
  1270. pfcBC_NoFacts(F):- pfcBC_NoFacts_TRY(F)*-> true ; (pfc_slow_search,pfcBC_Cache(F)).
  1271.  
  1272. pfcBC_NoFacts_TRY(F) :- nonvar(F),
  1273.  (
  1274.   %= this is probably NOT advisable due TO extreme inefficiency.
  1275.   var(F)    ->  pfcFact(F) ;
  1276.   ( \+ current_predicate(_,F)) -> mpred_call(F) ;
  1277.   % check FOR system predicates AS well.
  1278.   NOT(predicate_property(F,number_of_clauses(_))) -> pfc_call_prolog_native(systemPred,F) ;
  1279.   otherwise -> pfcBC_NoFacts_TRY2(F)).
  1280.  
  1281. ruleBackward(F,Condition):-ruleBackward0(F,Condition),Condition\=mpred_call(F).
  1282. ruleBackward0(F,Condition):-pfc_clause_db_unify(F,Condition),NOT(is_true(Condition);is_meta_info(Condition)).
  1283. ruleBackward0(F,Condition):-'<='(F,Condition),not(is_true(Condition);is_meta_info(Condition)).
  1284.  
  1285. pfcBC_NoFacts_TRY2(F) :- no_repeats(ruleBackward(F,Condition)),
  1286.   pfc_call_prolog_native(neck(F),Condition),
  1287.   maybeSupport(F,(pfcGod,pfcGod)).
  1288.  
  1289.  
  1290.  
  1291.  
  1292. % an action is pfcUndoable IF there exists a method FOR undoing it.
  1293. pfcUndoable(A) :- pfcUndoMethod(A,_).
  1294.  
  1295.  
  1296.  
  1297. %%
  1298. %%
  1299. %= defining fc rules
  1300. %%
  1301.  
  1302. %= pfc_nf(+In,-Out) maps the LHR of a pfc rule In TO one normal form
  1303. %= Out.  It also does certain optimizations.  Backtracking into this
  1304. %= predicate will produce additional clauses.
  1305.  
  1306.  
  1307. pfc_nf(LHS,List) :-
  1308.   pfc_nf1(LHS,List2),
  1309.   pfc_nf_negations(List2,List).
  1310.  
  1311.  
  1312. %= pfc_nf1(+In,-Out) maps the LHR of a pfc rule In TO one normal form
  1313. %= Out.  Backtracking into this predicate will produce additional clauses.
  1314.  
  1315. % handle a variable.
  1316.  
  1317. pfc_nf1(P,[P]) :- var(P), !.
  1318.  
  1319. % these NEXT two rules are here FOR upward compatibility AND will GO
  1320. % away eventually when the P / Condition form is no longer used anywhere.
  1321.  
  1322. pfc_nf1(P / Cond,[(\+P) / Cond]) :- pfcNegatedLiteral(P), !.
  1323.  
  1324. pfc_nf1(P / Cond,[P / Cond]) :-  pfcLiteral(P), !.
  1325.  
  1326. %= handle a negated form
  1327.  
  1328. pfc_nf1(NegTerm,NF) :-
  1329.   pfc_negation(NegTerm,Term),
  1330.   !,
  1331.   pfc_nf1_negation(Term,NF).
  1332.  
  1333. %= disjunction.
  1334.  
  1335. pfc_nf1((P;Q),NF) :-
  1336.   !,
  1337.   (pfc_nf1(P,NF) ;   pfc_nf1(Q,NF)).
  1338.  
  1339.  
  1340. %= conjunction.
  1341.  
  1342. pfc_nf1((P,Q),NF) :-
  1343.   !,
  1344.   pfc_nf1(P,NF1),
  1345.   pfc_nf1(Q,NF2),
  1346.   append(NF1,NF2,NF).
  1347.  
  1348. %= handle a random atom.
  1349.  
  1350. pfc_nf1(P,[P]) :-
  1351.   pfcLiteral(P),
  1352.   !.
  1353.  
  1354. %%= shouln't we have something to catch the rest as errors?
  1355. pfc_nf1(Term,[Term]) :-
  1356.   pfcError("pfc_nf doesn't know how to normalize ~w",[Term]).
  1357.  
  1358.  
  1359. %= pfc_nf1_negation(P,NF) is true IF NF is the normal form of \+P.
  1360. pfc_nf1_negation((P / Cond),[(\+(P)) / Cond]) :- !.
  1361.  
  1362. pfc_nf1_negation((P;Q),NF) :-
  1363.   !,
  1364.   pfc_nf1_negation(P,NFp),
  1365.   pfc_nf1_negation(Q,NFq),
  1366.   append(NFp,NFq,NF).
  1367.  
  1368. pfc_nf1_negation((P,Q),NF) :-
  1369.   % this CODE is NOT correct! twf.
  1370.   !,
  1371.   pfc_nf1_negation(P,NF)
  1372.   ;
  1373.   (pfc_nf1(P,Pnf),
  1374.    pfc_nf1_negation(Q,Qnf),
  1375.    append(Pnf,Qnf,NF)).
  1376.  
  1377. pfc_nf1_negation(P,[\+P]).
  1378.  
  1379.  
  1380.  
  1381.  
  1382. %= pfc_nf_negations(List2,List) sweeps through List2 TO produce List,
  1383. %= changing ~{...} TO {\+...}
  1384. %%= ? is this still needed? twf 3/16/90
  1385.  
  1386. pfc_nf_negations(X,X) :- !.  % I think NOT! twf 3/27/90
  1387.  
  1388. pfc_nf_negations(X,X) :- var(X),!.
  1389.  
  1390. pfc_nf_negations([],[]).
  1391.  
  1392. pfc_nf_negations([H1|T1],[H2|T2]) :-
  1393.   pfc_nf_negation(H1,H2),
  1394.   pfc_nf_negations(T1,T2).
  1395.  
  1396. pfc_nf_negation(Form,{PLNeg}) :-  
  1397.   nonvar(Form),
  1398.   correct_negations(callable,Form,PLNeg),
  1399.   !.
  1400. pfc_nf_negation(X,X).
  1401.  
  1402.  
  1403. %%
  1404. %= pfcBuildRhs(+Conjunction,-Rhs)
  1405. %%
  1406.  
  1407. pfcBuildRhs(X,[X]) :-
  1408.   var(X),
  1409.   !.
  1410.  
  1411. pfcBuildRhs((A,B),[A2|Rest]) :-
  1412.   !,
  1413.   pfcCompileRhsTerm(A,A2),
  1414.   pfcBuildRhs(B,Rest).
  1415.  
  1416. pfcBuildRhs(X,[X2]) :-
  1417.    pfcCompileRhsTerm(X,X2).
  1418.  
  1419. pfcCompileRhsTerm((P/C),((P:-C))) :- !.
  1420. pfcCompileRhsTerm(P,P).
  1421.  
  1422. pfc_negate_for_add(NQ,NQ):-is_ftVar(NQ),!.
  1423. pfc_negate_for_add(','(_,Q),NQ):-!,pfc_negate_for_add(Q,NQ).
  1424. pfc_negate_for_add('<=>'(P,Q),'<=>'(P,NQ)):-!,pfc_negate_for_add(Q,NQ).
  1425. pfc_negate_for_add(In,Out):-pfc_negate(pfc_negate_for_add,In,Out).
  1426.  
  1427. pfc_negate(C,'=>'(P,Q),'=>'(P,NQ)):-!,call(C,Q,NQ).
  1428. pfc_negate(C,'<='(Q,P),'<='(NQ,P)):-!,call(C,Q,NQ).
  1429. pfc_negate(C,':-'(Q,P),':-'(NQ,P)):-!,call(C,Q,NQ).
  1430. pfc_negate(_,N,P):-pfcNegatedLiteral(N),!,pfc_negation(N,P).
  1431. pfc_negate(_,P,N):-pfcPositiveLiteral(P),!,N=NOT(P).
  1432.  
  1433. %= pfc_negation(N,P) is true IF N is a negated term AND P is the term
  1434. %= with the negation operator stripped.
  1435.  
  1436. pfc_negation((~P),P).
  1437. pfc_negation((-P),P).
  1438. pfc_negation((\+(P)),P).
  1439. pfc_negation((naf(P)),P).
  1440. % pfc_negation(NOT(P)),P).
  1441. % pfc_negation(NP,PP):-loop_check_nr(pfc_negation0(NP,PP)).
  1442. pfc_negation0(NP,PP):- compound(NP), NP=..[NF,A|RGS],negated_functor(NF,PF),!,PP=..[PF,A|RGS].
  1443.  
  1444. pfcNegatedLiteral(P) :-
  1445.   pfc_negation(P,Q),
  1446.   pfcPositiveLiteral(Q),!.
  1447.  
  1448. pfcLiteral(X) :- pfcNegatedLiteral(X),!.
  1449. pfcLiteral(X) :- pfcPositiveLiteral(X),!.
  1450.  
  1451. pfcPositiveLiteral(X) :- nonvar(X),
  1452.   functor(X,F,_),
  1453.   \+ pfcConnective(F).
  1454.  
  1455. pfcConnective(';').
  1456. pfcConnective(',').
  1457. pfcConnective('/').
  1458. pfcConnective('|').
  1459. pfcConnective(('=>')).
  1460. pfcConnective(('<=')).
  1461. pfcConnective('<=>').
  1462.  
  1463. pfcConnective('-').
  1464. pfcConnective('~').
  1465. pfcConnective(('\\+')).
  1466.  
  1467. ~(F):-pfcCall(F).
  1468.  
  1469. pfcProcessRule(Lhs,Rhs,ParentRule) :-
  1470.   copy_term(ParentRule,ParentRuleCopy),
  1471.   pfcBuildRhs(Rhs,Rhs2),
  1472.   pfcForEach(pfc_nf(Lhs,Lhs2),
  1473.           pfcBuild1Rule(Lhs2,rhs(Rhs2),(ParentRuleCopy,pfcUser))).
  1474.  
  1475. pfcBuild1Rule(Lhs,Rhs,Support) :-
  1476.   pfcBuildTrigger(Lhs,Rhs,Trigger),
  1477.   pfcEvalLHS(Trigger,Support).
  1478.  
  1479. pfcBuildTrigger([],Consequent,Consequent).
  1480.  
  1481. pfcBuildTrigger([V|Triggers],Consequent,pfcPT(V,X)) :-
  1482.   var(V),
  1483.   !,
  1484.   pfcBuildTrigger(Triggers,Consequent,X).
  1485.  
  1486. pfcBuildTrigger([(T1/Test)|Triggers],Consequent,pfcNT(T2,Test2,X)) :-
  1487.   pfc_negation(T1,T2),
  1488.   !,
  1489.   pfcBuildNtTest(T2,Test,Test2),
  1490.   pfcBuildTrigger(Triggers,Consequent,X).
  1491.  
  1492. pfcBuildTrigger([(T1)|Triggers],Consequent,pfcNT(T2,Test,X)) :-
  1493.   pfc_negation(T1,T2),
  1494.   !,
  1495.   pfcBuildNtTest(T2,true,Test),
  1496.   pfcBuildTrigger(Triggers,Consequent,X).
  1497.  
  1498. pfcBuildTrigger([{Test}|Triggers],Consequent,(Test->X)) :-
  1499.   !,
  1500.   pfcBuildTrigger(Triggers,Consequent,X).
  1501.  
  1502. pfcBuildTrigger([T/Test|Triggers],Consequent,pfcPT(T,X)) :-
  1503.   !,
  1504.   pfcBuildTest(Test,Test2),
  1505.   pfcBuildTrigger([{Test2}|Triggers],Consequent,X).
  1506.  
  1507.  
  1508. %pfcBuildTrigger([snip|Triggers],Consequent,snip(X)) :-
  1509. %  !,
  1510. %  pfcBuildTrigger(Triggers,Consequent,X).
  1511.  
  1512. pfcBuildTrigger([T|Triggers],Consequent,pfcPT(T,X)) :-
  1513.   !,
  1514.   pfcBuildTrigger(Triggers,Consequent,X).
  1515.  
  1516. %%
  1517. %= pfcBuildNtTest(+,+,-).
  1518. %%
  1519. %= builds the test used in a negative trigger (pfcNT/3).  This test is a
  1520. %= conjunction of the check than no matching facts are in the db AND any
  1521. %= additional test specified in the rule attached TO this ~ term.
  1522. %%
  1523.  
  1524. pfcBuildNtTest(T,Testin,Testout) :-
  1525.   pfcBuildTest(Testin,Testmid),
  1526.   pfcConjoin((pfcCall(T)),Testmid,Testout).
  1527.  
  1528.  
  1529. % this just strips away any currly brackets.
  1530.  
  1531. pfcBuildTest({Test},Test) :- !,pfcMarkW(Test).
  1532. pfcBuildTest(Test,Test):-pfcMarkW(Test).
  1533.  
  1534. %%
  1535.  
  1536. mpred_listing(F/_):-!,term_listing(F).
  1537. mpred_listing(Pred):-
  1538.   (get_functor(Pred,F,AUsed),((AUsed==0)->ignore(arity(F,A));A=AUsed)),
  1539.   mpred_listing(F/A).
  1540.  
  1541.  
  1542. % predicate_property(P,meta_predicate(P)),arg(_,P,N),number(N)
  1543. user:listing_mpred_hook(Match):-  debugOnError(loop_check_nr(pfc_listing_mpred_hook(Match))).
  1544.  
  1545. guess_arity(F,A):- no_repeats(F/A,(current_predicate(F/A);arity(F,A))).
  1546.  
  1547. pfc_listing_mpred_hook(Match):- must(nonvar(Match)),fail.
  1548. pfc_listing_mpred_hook(M:P):- atom(M),!,pfc_listing_mpred_hook(P).
  1549. pfc_listing_mpred_hook(F/Unk):- is_ftVar(Unk),!,forall(guess_arity(F,A),pfc_listing_mpred_hook(F/A)).
  1550. pfc_listing_mpred_hook(_/0):- !.
  1551. pfc_listing_mpred_hook(F/A):-!,ground(F/A),make_functor(Match,F,A),!,pfc_listing_mpred_hook(Match).
  1552. pfc_listing_mpred_hook(F):- atom(F),!,forall(guess_arity(F,A),pfc_listing_mpred_hook(F/A)).
  1553. pfc_listing_mpred_hook(Match):- once((must((pfc_fully_expand(pfc_listing_mpred_hook,Match,New))),
  1554.                                 Match\=@=New)),
  1555.                                 current_predicate(_,New),
  1556.                                 listing(New),fail.
  1557. pfc_listing_mpred_hook(MFA):- dmsg(pfc_listing_mpred_hook(MFA)),fail.
  1558. pfc_listing_mpred_hook(Match):- NOT(NOT(pfcLiteral(Match))),pfc_listing_mpred_hook_2nd(Match).
  1559.  
  1560.  
  1561. match_clauses(H,H,B):-clause(H,B).
  1562.  
  1563. nonvar_contains_term(V,A):-atomic(A),!,sub_term(VV,V),nonvar(VV),functor_safe(VV,A,_).
  1564. nonvar_contains_term(V,A):-sub_term(VV,V),nonvar(VV),A=@=VV.
  1565. % nonvar_contains_term(V,C):-functor(C,A,_),!,nonvar_contains_term(V,A).
  1566.  
  1567. head_search_for_listing(H):-member(H,[neg(_),(_=>_),(_<=_),(_<=>_),isa(_,_),argIsa(_,_,_)]).
  1568. head_search_for_listing(H):-  pfcDatabaseTerm(F/A),functor(H,F,A).
  1569.  
  1570. pfc_listing_mpred_hook_2nd(Match):-
  1571.  no_repeats(CL,(( no_repeats(head_search_for_listing(F)),predicate_property(F,number_of_clauses(_)),match_clauses(F,H,B), CL=(H:-B),
  1572.    NOT(is_meta_info(B)),
  1573.    once(nonvar_contains_term(CL,Match))))),
  1574.    portray_clause(CL),fail.
  1575.  
  1576.  
  1577. pfcTypeFull(G,Type) :- pfcType(G,Type),Type\=fact,!.
  1578. pfcTypeFull(support1(_,_,_),support).
  1579. pfcTypeFull(support2(_,_,_),support).
  1580. pfcTypeFull(support3(_,_,_),support).
  1581. pfcTypeFull((H:-B),Type):-is_true(B),!,pfcTypeFull(H,Type).
  1582. pfcTypeFull(_,fact) :-
  1583.   %= IF it's not one of the above, it must be a fact!
  1584.   !.
  1585.  
  1586. %= simple typeing FOR pfc objects
  1587. pfcType(('=>'(_,_)),Type) :- !, Type=rule.
  1588. pfcType(('<=>'(_,_)),Type) :- !, Type=rule.
  1589. pfcType(('<='(_,_)),Type) :- !, Type=rule.
  1590. pfcType(pfcPT3(_,_,_),Type) :- !, Type=trigger.
  1591. pfcType(pfcPT(_,_),Type) :- !, Type=trigger.
  1592. pfcType(pfcNT(_,_,_),Type) :- !,  Type=trigger.
  1593. pfcType(pfcBT(_,_),Type) :- !,  Type=trigger.
  1594. pfcType(pfcAction(_),Type) :- !, Type=action.
  1595. pfcType((('::::'(_,X))),Type) :- !, pfcType(X,Type).
  1596. pfcType(_,fact) :-
  1597.   %= IF it's not one of the above, it must be a fact!
  1598.   !.
  1599.  
  1600. pfcAssertIfUnknown(B):-if_defined(into_mpred_form(B,A)),B\=@=A,pfcAssertIfUnknown(G).
  1601. pfcAssertIfUnknown(P):-unnumbervars(P,U),pfcAssertIfUnknown_nv(P,U).
  1602. pfcAssertIfUnknown_nv(_,U):- \+ \+ clause_asserted(U),!.
  1603. pfcAssertIfUnknown_nv(_,U):- \+ \+ if_defined(is_asserted_1(U)),!.
  1604. pfcAssertIfUnknown_nv(P,U):- show_call(pfc_assert(P)),no_loop_check(sanity(is_asserted_eq(U))).
  1605.  
  1606. pfcAssertS(P):-assert_if_new(P).
  1607. pfcAssertInt(P,Support) :-
  1608.   (pfcClauseInt(P) ; pfcAssertS(P)),
  1609.   !,
  1610.   pfcAddSupport(P,Support).
  1611.  
  1612. pfcAssertAInt(P,Support) :-
  1613.   (pfcClauseInt(P) ; asserta_new(P)),
  1614.   !,
  1615.   pfcAddSupport(P,Support).
  1616.  
  1617.  
  1618. pfcClauseInt((Head :- Body)) :-
  1619.   !,
  1620.   copy_term(Head,Head_copy),
  1621.   copy_term(Body,Body_copy),
  1622.   pfc_clause_db_unify(Head,Body),
  1623.   variant(Head,Head_copy),
  1624.   variant(Body,Body_copy).
  1625.  
  1626. pfcClauseInt(Head) :-
  1627.   % find a unit clause identical TO Head by finding one which unifies,
  1628.   % AND THEN checking TO see IF it is identical
  1629.   copy_term(Head,Head_copy),
  1630.   pfc_clause_db_unify(Head_copy,true),
  1631.   variant(Head,Head_copy).
  1632.  
  1633.  
  1634. pfcForEach(Binder,Body) :- Binder,pfcdo(Body),fail.
  1635. pfcForEach(_,_).
  1636.  
  1637. % pfcdo(X) executes X once AND always succeeds.
  1638. pfcdo(X) :- X,!.
  1639. pfcdo(_).
  1640.  
  1641.  
  1642. %= pfcUnion(L1,L2,L3) - true IF set L3 is the result of appending sets
  1643. %= L1 AND L2 where sets are represented AS simple lists.
  1644.  
  1645. pfcUnion([],L,L).
  1646. pfcUnion([Head|Tail],L,Tail2) :-  
  1647.   memberchk(Head,L),
  1648.   !,
  1649.   pfcUnion(Tail,L,Tail2).
  1650. pfcUnion([Head|Tail],L,[Head|Tail2]) :-  
  1651.   pfcUnion(Tail,L,Tail2).
  1652.  
  1653.  
  1654. %= pfcConjoin(+Conjunct1,+Conjunct2,?Conjunction).
  1655. %= arg3 is a simplified expression representing the conjunction of
  1656. %= args 1 AND 2.
  1657.  
  1658. pfcConjoin(TRUE,X,X) :- is_true(TRUE),!.
  1659. pfcConjoin(X,TRUE,X) :- is_true(TRUE),!.
  1660. pfcConjoin(C1,C2,(C1,C2)).
  1661.  
  1662. % pfcFile('pfcsupport').    % support maintenance
  1663.  
  1664. %%
  1665. %%
  1666. %= predicates FOR manipulating support relationships
  1667. %%
  1668.  
  1669. :-decl_mpred_pfc(support3/3).
  1670. :-decl_mpred_pfc(support1/3).
  1671. :-decl_mpred_pfc(support2/3).
  1672.  
  1673. %= pfcAddSupport(+Fact,+Support)
  1674.  
  1675. pfcAddSupport(P,(Fact,Trigger)) :-
  1676.   pfcAssertS(support1(P,Fact,Trigger)),
  1677.   pfcAssertS(support3(Fact,Trigger,P)),
  1678.   pfcAssertS(support2(Trigger,P,Fact)).
  1679.  
  1680. pfcGetSupportORNil(P,Support):- (pfcGetSupport(P,Support) *-> true ; Support = (fail)).
  1681. % FOR a litteral
  1682. pfcGetSupport1(P,(Fact,Trigger)) :-
  1683.    nonvar(P)         -> support1(P,Fact,Trigger)
  1684.    ; nonvar(Fact)    -> support3(Fact,Trigger,P)
  1685.    ; nonvar(Trigger) -> support2(Trigger,P,Fact)
  1686.    ; otherwise       -> support1(P,Fact,Trigger).
  1687.  
  1688. pfcGetSupport(P,More):- pfc_fully_expand_warn(is_asserted,P,PS),P \=@= PS,!,pfcGetSupport(PS,More).
  1689. pfcGetSupport((P1,P2),((F1,F2),(T1,T2))):-nonvar(P1),!,pfcGetSupport(P1,(F1,T1)),pfcGetSupport(P2,(F2,T2)).
  1690. pfcGetSupport(P,More):- pfcGetSupport1(P,More).
  1691. % TODO pack the T1 into T2 RETURN value is still a (Fact,Trigger) pair
  1692.  
  1693. pfcWhy(G,Proof):-pfcGetSupport(G,S),(S=(G,G)->Proof=asserted;Proof=S).
  1694.  
  1695. pfcRemoveSupportItems(P,Types):-
  1696.   pfcGetSupport(P,Support),
  1697.   show_call(pfcFilterSupports(Support,Types,Results)),
  1698.   pfcDoConjs(pfcRem1,Results).
  1699.  
  1700. pfcTypeFilter_l(ResultsO,Filter,ResultsO):-pfcTypeFilter(ResultsO,Filter).
  1701. pfcTypeFilter_l((Body,More),Filter,ResultsO):-!,pfcTypeFilter_l(Body,Filter,BodyO),pfcTypeFilter_l((More),Filter,(ResultsM)),conjoin(BodyO,ResultsM,ResultsO).
  1702. pfcTypeFilter_l(_,_Filter,!).
  1703.  
  1704. pfcFilterSupports(Support,Filter,ResultsO):-
  1705.   pfcRuleOutcomeHeadBody(Support,_,Body),
  1706.   pfcTypeFilter_l(Body,Filter,ResultsO),!.
  1707.  
  1708. pfcFilterSupports(Support,Filter,ResultsO):-
  1709.   findall(Term, ((sub_term(Term,Support),pfcLiteral(Term),compound(Term),pfcTypeFilter(Term,Filter))),Results),
  1710.   list_to_set(Results,ResultsO).
  1711.  
  1712. pfcTypeFilter(Term,Filter):- NOT(is_list(Filter)),!,pfcTypeFilter(Term,[Filter]).
  1713. pfcTypeFilter(Term,FilterS):- pfcTypeFull(Term,Type),memberchk(Type,FilterS),!.
  1714. pfcTypeFilter(Term,FilterS):- member(Filter,FilterS),append_term(Filter,Term,Call),current_predicate(_,Call),debugOnError(Call),!.
  1715.  
  1716.  
  1717. % There are three of these TO try TO efficiently handle the cases
  1718. % where some of the arguments are NOT bound but AT least one is.
  1719.  
  1720. % pfcGetSupport2(P,(P,Trigger)) :- pfcPT(isa(A, tObj), pfcNT(mudPossess(B, A), pfcCall(mudPossess(B, A)), rhs([spatialInRegion(A)])))
  1721.  
  1722. is_support(E):-compound(E),functor(E,F,_),memberchk(F,[support1,support2,support3]).
  1723.  
  1724.  
  1725. get_support_for(P,PS):-thlocal:current_why(PS,P),!.
  1726. get_support_for(_,PS):-thlocal:current_why(PS,_),!.
  1727. get_support_for(P,PS):-copy_term(P,PS).
  1728.  
  1729.  
  1730. is_user_supported(V):-pfcGetSupport1(V,(pfcUser,pfcUser)).
  1731.  
  1732.  
  1733. get_user_support_for_lookup(_,(pfcUser,pfcUser)).
  1734. get_user_support_for_remove(_,(pfcUser,pfcUser)).
  1735. get_user_support_for_add(P,(pfcUser,pfcUser)):-!. % get_support_for(P,PS).
  1736.  
  1737. get_god_support_for_lookup(_,(pfcGod,pfcGod)).
  1738. is_deduced_by_god((pfcGod,pfcGod)).
  1739. %get_god_support_for_add(P,(pfcGod,pfcGod)):-!. % get_support_for(P,PS).
  1740.  
  1741.  
  1742. pfcRemSupport(_,(P,_)) :- is_support(P),!,ignore(pfcRetractOrWarn(pfcRemoveSupport,P)).
  1743. pfcRemSupport(P,_) :-is_support(P),!,ignore(pfcRetractOrWarn(pfcRemoveSupport,P)).
  1744. pfcRemSupport(P,(Fact,Trigger)) :-
  1745.   nonvar(P),
  1746.   !,
  1747.   pfcRetractOrWarn(pfcRemoveSupport,support1(P,Fact,Trigger)),
  1748.   pfcRetractOrWarn(pfcRemoveSupport,support3(Fact,Trigger,P)),
  1749.   pfcRetractOrWarn(pfcRemoveSupport,support2(Trigger,P,Fact)).
  1750.  
  1751.  
  1752. pfcRemSupport(P,(Fact,Trigger)) :-
  1753.   nonvar(Fact),
  1754.   !,
  1755.   pfcRetractOrWarn(pfcRemoveSupport,support3(Fact,Trigger,P)),
  1756.   pfcRetractOrWarn(pfcRemoveSupport,support1(P,Fact,Trigger)),
  1757.   pfcRetractOrWarn(pfcRemoveSupport,support2(Trigger,P,Fact)).
  1758.  
  1759. pfcRemSupport(P,(Fact,Trigger)) :-
  1760.   pfcRetractOrWarn(pfcRemoveSupport,support2(Trigger,P,Fact)),
  1761.   pfcRetractOrWarn(pfcRemoveSupport,support1(P,Fact,Trigger)),
  1762.   pfcRetractOrWarn(pfcRemoveSupport,support3(Fact,Trigger,P)).
  1763.  
  1764.  
  1765. pfc_collect_supports(Tripples) :-
  1766.   bagof(Tripple, pfc_support_relation(Tripple), Tripples),
  1767.   !.
  1768. pfc_collect_supports([]).
  1769.  
  1770. pfc_support_relation((P,F,T)) :-
  1771.   support1(P,F,T).
  1772.  
  1773. pfc_make_supports((P,S1,S2)) :-
  1774.   pfcAddSupport(P,(S1,S2)),
  1775.   (pfcAddSome(P); true),
  1776.   !.
  1777.  
  1778. %= pfcTriggerKey(+Trigger,-Key)
  1779. %%
  1780. %= Arg1 is a trigger.  Key is the best term TO index it on.
  1781.  
  1782. pfcTriggerKey(pfcPT(Key,_),Key).
  1783. pfcTriggerKey(pfcPT3(Key,_,_),Key).
  1784. pfcTriggerKey(pfcNT(Key,_,_),Key).
  1785. pfcTriggerKey(Key,Key).
  1786.  
  1787.  
  1788. %%^L
  1789. %= Get a key from the trigger that will be used AS the first argument of
  1790. %= the trigger pfcBase1 pfcClauseInt that stores the trigger.
  1791. %%
  1792.  
  1793. pfc_trigger_key(X,X) :- var(X), !.
  1794. pfc_trigger_key(chart(word(W),_L),W) :- !.
  1795. pfc_trigger_key(chart(stem([Char1|_Rest]),_L),Char1) :- !.
  1796. pfc_trigger_key(chart(Concept,_L),Concept) :- !.
  1797. pfc_trigger_key(X,X).
  1798.  
  1799.  
  1800.  
  1801. % pfcFile('thlocal').   % predicates to manipulate database.
  1802.  
  1803.  
  1804. %   File   : thlocal.pl
  1805. %   Author : Tim Finin, finin@prc.unisys.com
  1806. %   Author :  Dave Matuszek, dave@prc.unisys.com
  1807. %   Author :  Dan Corpron
  1808. %   Updated: 10/11/87, ...
  1809. %   Purpose: predicates TO manipulate a pfc database (e.g. SAVE,
  1810. %%  restore, reset, etc.0 )
  1811.  
  1812. % pfcDatabaseTerm(P/A) is true iff P/A is something that pfc adds TO
  1813. % the database AND should NOT be present in an empty pfc database
  1814.  
  1815. pfcDatabaseTerm(support1/3).
  1816. pfcDatabaseTerm(support3/3).
  1817. pfcDatabaseTerm(support2/3).
  1818. pfcDatabaseTerm(pfcPT3/3).
  1819. pfcDatabaseTerm(pfcNT/3).
  1820. pfcDatabaseTerm(pfcPT/2).
  1821. pfcDatabaseTerm(pfcBT/2).
  1822. pfcDatabaseTerm('=>'/2).
  1823. pfcDatabaseTerm('<=>'/2).
  1824. pfcDatabaseTerm('<='/2).
  1825. pfcDatabaseTerm(pfcQueue/1).
  1826. % CANT BE HERE OR IT DISABLED FWD CHAINING pfc DatabaseTerm(pfc Default/1).
  1827.  
  1828. % removes all forward chaining rules AND pfcJustification_L from db.
  1829.  
  1830. pfcReset :-
  1831.   pfc_clause_db_unify(support1(P,F,Trigger),true),
  1832.   pfcRetractOrWarn(pfcReset,P),
  1833.   pfcRetractOrWarn(pfcReset,support1(P,F,Trigger)),
  1834.   pfcRetractOrWarn(pfcReset,support3(F,Trigger,P)),
  1835.   pfcRetractOrWarn(pfcReset,support2(Trigger,P,F)),
  1836.   fail.
  1837. pfcReset :-
  1838.   pfcDatabaseItem(T),
  1839.   pfcError("Pfc database not empty after pfcReset, e.g., ~p.~n",[T]).
  1840. pfcReset.
  1841.  
  1842. % true IF there is some pfc crud still in the database.
  1843. pfcDatabaseItem(Term) :-
  1844.   pfcDatabaseTerm(P/A),
  1845.   functor(Term,P,A),
  1846.   pfc_clause_db_unify(Term,_).
  1847.  
  1848. pfcRetractOrWarn(Why,X) :-  pfc_retract(Why,X), !.
  1849. pfcRetractOrWarn(Why,X) :- fail,compound(X),arg(_,X,E),compound(E),functor(E,F,_),member(F,[support1,support2,support3]),!,
  1850.   pfcError("~w couldn't pfc_retract ~p.",[Why,X]),dtrace.
  1851.  
  1852. pfcRetractOrWarn(Why,X) :-
  1853.   pfcWarn("~w couldn't pfc_retract ~p.",[Why,X]).
  1854.  
  1855.  
  1856.  
  1857. % pfcFile('pfcdebug').  % debugging aids (e.g. tracing).
  1858.  
  1859.  
  1860. %   File   : pfcdebug.pl
  1861. %   Author : Tim Finin, finin@prc.unisys.com
  1862. %   Author :  Dave Matuszek, dave@prc.unisys.com
  1863. %   Updated:
  1864. %   Purpose: provides predicates FOR examining the database AND debugginh
  1865. %   FOR Pfc.
  1866.  
  1867. :- decl_mpred_pfc pfc_settings/2.
  1868. :- decl_mpred_pfc pfc_settings/3.
  1869.  
  1870. :- pfc_setting_default(pfc_settings(warnings,_), pfc_settings(warnings,true)).
  1871.  
  1872. %= predicates TO examine the state of pfc
  1873.  
  1874. pfcQueue :- listing(pfcQueue/1).
  1875.  
  1876. pfcPrintDB :- current_predicate(must_det_l/1),!,
  1877.   must_det_l([
  1878.   pfcPrintFacts,
  1879.   pfcPrintRules,
  1880.   pfcPrintTriggers,
  1881.    pfcPrintSupports,
  1882.    pfcQueue]),!.
  1883.  
  1884. pfcPrintDB :-
  1885.    pfcPrintFacts,
  1886.    pfcPrintRules,
  1887.    pfcPrintTriggers,
  1888.   pfcPrintSupports,
  1889.   pfcQueue,!.
  1890.  
  1891. %= pfcPrintFacts ..
  1892.  
  1893. pfcPrintFacts :- pfcPrintFacts(_,true).
  1894.  
  1895. pfcPrintFacts(Pattern) :- pfcPrintFacts(Pattern,true).
  1896.  
  1897. pfcPrintFacts(P,C) :-
  1898.   pfcFacts(P,C,L),
  1899.   pfcClassifyFacts(L,User,Pfc,_Rule),
  1900.   fmt("User added facts:",[]),
  1901.   pfcPrintitems(User),
  1902.   fmt("Pfc added facts:",[]),
  1903.   pfcPrintitems(Pfc).
  1904.  
  1905.  
  1906. %= printitems clobbers it's arguments - beware (fixed .. it no longer clobers)!
  1907.  
  1908. pfcPrintitems(HIn):-copy_term(HIn,H),pfcDoConjs(pfcLambda([E],(numbervars(E,0,_),fmt(" ~q.~n",[E]))),H).
  1909.  
  1910. pfcClassifyFacts([],[],[],[]).
  1911.  
  1912. pfcClassifyFacts([H|T],User,Pfc,[H|Rule]) :-
  1913.   pfcType(H,rule),
  1914.   !,
  1915.   pfcClassifyFacts(T,User,Pfc,Rule).
  1916.  
  1917. pfcClassifyFacts([H|T],[H|User],Pfc,Rule) :-
  1918.   get_user_support_for_lookup(H,US),
  1919.   pfcGetSupport(H,US),
  1920.   !,
  1921.   pfcClassifyFacts(T,User,Pfc,Rule).
  1922.  
  1923. pfcClassifyFacts([H|T],User,[H|Pfc],Rule) :-
  1924.   pfcClassifyFacts(T,User,Pfc,Rule).
  1925.  
  1926.  
  1927. printHeadItems(Head):-ignore((bagof(Head,pfc_clause_db_unify(Head,true),R1),pfcPrintitems(R1))).
  1928. printHeadCallItems(Head):-ignore((bagof(Head,pfc_clause_db_unify(Head,true),R1),pfcPrintitems(R1))).
  1929.  
  1930. pfcPrintRules :-
  1931.   printHeadItems((P=>Q)),printHeadItems((P<=>Q)),printHeadItems((P<=Q)).
  1932.  
  1933. pfcPrintTriggers :-
  1934.   fmt("% Positive triggers...~n",[]),
  1935.      printHeadCallItems(pfcGetTrigger(pfcPT(_,_))),
  1936.   fmt("% Negative triggers...~n",[]),
  1937.      printHeadCallItems(pfcGetTrigger(pfcNT(_,_,_))),
  1938.   fmt("% Goal triggers...~n",[]),
  1939.      printHeadCallItems(pfcGetTrigger(pfcBT(_,_))),!.
  1940.  
  1941. pfcPrintSupports :-
  1942.   % temporary hack.
  1943.   setof((S > P), pfcGetSupport(P,S),L),
  1944.   pfcPrintitems(L).
  1945.  
  1946. pfcVerifyMissing(isa(I,D), isa(I,C), ((isa(I,C), {D==C});~isa(I,C))).
  1947. pfcVerifyMissing(mudColor(I,D), mudColor(I,C), ((mudColor(I,C), {D==C});~mudColor(I,C))).
  1948.  
  1949. pfcVerifyMissing(GC, GO, ((GO, {D==C});~GO) ):-
  1950.        GC=..[F,A|Args],append(Left,[D],Args),append(Left,[C],NewArgs),GO=..[F,A|NewArgs],!.
  1951.  
  1952. pfcFreeLastArg(isa(I,C),neg(isa(I,C))):-nonvar(C),!.
  1953. pfcFreeLastArg(isa(I,C),(isa(I,F),C\=F)):-!.
  1954. pfcFreeLastArg(G,GG):- G=..[F,A|Args],append(Left,[_],Args),append(Left,[_],NewArgs),GG=..[F,A|NewArgs],!.
  1955. pfcFreeLastArg(_G,false).
  1956.  
  1957. %= pfcFact(P) is true IF fact P was asserted into the database via add.
  1958. pfcFact(P) :- no_repeats(pfcFact(P,true)).
  1959.  
  1960. %= pfcFact(P,C) is true IF fact P was asserted into the database via
  1961. %= add AND condition C is satisfied.  FOR example, we might DO:
  1962. %=
  1963. %=  pfcFact(X,pfcUserFact(X))
  1964. %%
  1965.  
  1966. pfcFact(P,C) :- no_repeats(pfcFact0(P,C)).
  1967.  
  1968. pfcFact0(P,C) :-
  1969.   pfcGetSupport(P,_),
  1970.   pfcType(P,fact),
  1971.   pfc_call_prolog_native(fact,C).
  1972.  
  1973. %= pfcFacts(-ListofPfcFacts) returns a list of facts added.
  1974.  
  1975. pfcFacts(L) :- pfcFacts(_,true,L).
  1976.  
  1977. pfcFacts(P,L) :- pfcFacts(P,true,L).
  1978.  
  1979. %= pfcFacts(Pattern,Condition,-ListofPfcFacts) returns a list of facts added.
  1980.  
  1981. pfcFacts(P,C,L) :- setof(P,pfcFact(P,C),L).
  1982.  
  1983. brake(X) :-  X, break.
  1984.  
  1985. %%
  1986. %%
  1987. %= predicates providing a simple tracing facility
  1988. %%
  1989.  
  1990. pfcTraceAdd(P) :-
  1991.   % this is here FOR upward compat. - should GO away eventually.
  1992.   pfcTraceAdd(P,(o,o)).
  1993.  
  1994. pfcTraceAdd(pfcPT(_,_),_) :-
  1995.   % hack FOR now - never trace triggers.
  1996.   !.
  1997. pfcTraceAdd(pfcNT(_,_,_),_) :-
  1998.   % hack FOR now - never trace triggers.
  1999.   !.
  2000.  
  2001. pfcTraceAdd(P,S) :-
  2002.    pfcTraceAddPrint(P,S),
  2003.    pfcTraceBreak(P,S).
  2004.  
  2005. crazy_bad_fact(isa(NOT,tCol)).
  2006. crazy_bad_fact(isa(_,NOT)).
  2007. crazy_bad_fact(user:mpred_prop(_,predArgTypes)).
  2008.  
  2009. pfcTraceAddPrint(P,S) :- crazy_bad_fact(P),retractall(tlbugger:show_must_go_on),!,trace_or_throw(crazy_pfcTraceAddPrint(P,S)).
  2010.  
  2011. pfcTraceAddPrint(P,S) :-
  2012.   \+ \+ pfc_settings(mpredTracing,P),
  2013.   !,
  2014.   copy_term(P,Pcopy),
  2015.   numbervars(Pcopy,0,_),
  2016.   get_user_support_for_lookup(P,PS),
  2017.   (S = PS
  2018.        -> pmsg("Adding (u) ~q",[Pcopy])
  2019.         ; pmsg("Adding (g) ~q",[Pcopy])).
  2020.  
  2021. pfcTraceAddPrint(_,_).
  2022.  
  2023.  
  2024. pfcTraceBreak(P,_S) :-
  2025.   pfc_settings(mpredSpying,P,add) ->
  2026.    (copy_term(P,Pcopy),
  2027.     numbervars(Pcopy,0,_),
  2028.     wdmsg("Breaking on pfcAdd(~w)",[Pcopy]),
  2029.     break)
  2030.    ; true.
  2031.  
  2032. pfcTraceRem(pfcPT(_,_)) :-
  2033.   % hack FOR now - never trace triggers.
  2034.   !.
  2035. pfcTraceRem(pfcNT(_,_)) :-
  2036.   % hack FOR now - never trace triggers.
  2037.   !.
  2038.  
  2039. pfcTraceRem(P) :-
  2040.   (pfc_settings(mpredTracing,P)
  2041.      -> pmsg('Removing ~w.',[P])
  2042.       ; true),
  2043.   (pfc_settings(mpredSpying,P,REM)
  2044.    -> (pmsg("Breaking on pfcRem1(~w)",[P]),
  2045.        break)
  2046.    ; true).
  2047.  
  2048.  
  2049. pfcTrace :- pfcTrace(_).
  2050.  
  2051. pfcTrace(Form) :-
  2052.   asserta(pfc_settings(mpredTracing,Form)).
  2053.  
  2054. pfcTrace(Form,Condition) :-
  2055.   pfcAssertS((pfc_settings(mpredTracing,Form) :- Condition)).
  2056.  
  2057. pfcSpy(Form) :- pfcSpy(Form,[add,REM],true).
  2058.  
  2059. pfcSpy(Form,Modes) :- pfcSpy(Form,Modes,true).
  2060.  
  2061. pfcSpy(Form,[add,REM],Condition) :-
  2062.   !,
  2063.   pfcSpy1(Form,add,Condition),
  2064.   pfcSpy1(Form,REM,Condition).
  2065.  
  2066. pfcSpy(Form,Mode,Condition) :-
  2067.   pfcSpy1(Form,Mode,Condition).
  2068.  
  2069. pfcSpy1(Form,Mode,Condition) :-
  2070.   pfcAssertS((pfc_settings(mpredSpying,Form,Mode) :- Condition)).
  2071.  
  2072. pfcNospy :- pfcNospy(_,_,_).
  2073.  
  2074. pfcNospy(Form) :- pfcNospy(Form,_,_).
  2075.  
  2076. pfcNospy(Form,Mode,Condition) :-
  2077.   pfc_clause_db_ref(pfc_settings(mpredSpying,Form,Mode), Condition, Ref),
  2078.   erase(Ref),
  2079.   fail.
  2080. pfcNospy(_,_,_).
  2081.  
  2082. pfcNoTrace :- pfcUntrace.
  2083. pfcUntrace :- pfcUntrace(_).
  2084. pfcUntrace(Form) :- pfc_retractall_settings(pfcInternal,pfc_settings(mpredTracing,Form)).
  2085.  
  2086. % needed:  pfcTraceRule(Name)  ...
  2087.  
  2088.  
  2089. % IF the correct flag is set, trace exection of Pfc
  2090. pfc_trace_msg(Msg,Args) :- pfc_settings(trace_exec,true), !,pmsg(Msg, Args).
  2091. pfc_trace_msg(_Msg,_Args).
  2092.  
  2093. pfcWatch :- pfcAssertS(pfc_settings(trace_exec,true)).
  2094.  
  2095. pfcNoWatch :-  pfc_retractall_settings(pfcInternal,pfc_settings(trace_exec,true)).
  2096.  
  2097. pfcError(Msg) :-  pfcError(Msg,[]).
  2098.  
  2099. pfcError(Msg,Args) :-
  2100.   sformat(S,Msg,Args),
  2101.   pmsg("ERROR/Pfc: ~s",[S]), % dtrace(S),
  2102.   !,
  2103.   trace_or_throw(S),!.
  2104.  
  2105.  
  2106. %%
  2107. %= These control whether OR NOT warnings are printed AT all.
  2108. %=   pfcWarn.
  2109. %=   nopfcWarn.
  2110. %%
  2111. %= These PRINT a warning message IF the flag pfcWarnings is set.
  2112. %=   pfcWarn(+Message)
  2113. %=   pfcWarn(+Message,+ListOfArguments)
  2114. %%
  2115.  
  2116. pfcWarn :-
  2117.   pfc_retractall_settings(pfcInternal,pfc_settings(warnings,_)),
  2118.   pfcAssertS(pfc_settings(warnings,true)).
  2119.  
  2120. nopfcWarn :-
  2121.   pfc_retractall_settings(pfcInternal,pfc_settings(warnings,_)),
  2122.   pfcAssertS(pfc_settings(warnings,false)).
  2123.  
  2124. pfcWarn(Msg) :-  pfcWarn(Msg,[]).
  2125.  
  2126. pfcWarn(_,_):- !.
  2127. pfcWarn(Msg,Args) :-
  2128.   pfc_settings(warnings,true),
  2129.   !,
  2130.   sformat(S,Msg,Args),
  2131.   pmsg("WARNING/Pfc: ~s",[S]), % dtrace(S),
  2132.   !.
  2133.  
  2134. pfcWarn(_,_).
  2135.  
  2136. %%
  2137. %= pfcWarnings/0 sets flag TO cause pfc warning messages TO PRINT.
  2138. %= pfcNoWarnings/0 sets flag TO cause pfc warning messages NOT TO PRINT.
  2139. %%
  2140.  
  2141. pfcWarnings :-
  2142.   pfc_retractall_settings(pfcInternal,pfc_settings(warnings,_)),
  2143.   pfcAssertS(pfc_settings(warnings,true)).
  2144.  
  2145. pfcNoWarnings :-
  2146.   pfc_retractall_settings(pfcInternal,pfc_settings(warnings,_)).
  2147.  
  2148.  
  2149.  
  2150. % pfcFile('pfcjust').   % predicates to manipulate pfcJustification_L.
  2151.  
  2152.  
  2153. %   File   : pfcjust.pl
  2154. %   Author : Tim Finin, finin@prc.unisys.com
  2155. %   Author :  Dave Matuszek, dave@prc.unisys.com
  2156. %   Updated:
  2157. %   Purpose: predicates FOR accessing Pfc Justifications.
  2158. %   Status: more OR less working.
  2159. %   Bugs:
  2160.  
  2161. %= *** predicates FOR exploring supports of a fact *****
  2162.  
  2163.  
  2164. :- use_module(library(lists)).
  2165.  
  2166. pfcJustificationDB(F,J) :- justSupports(F,J).
  2167.  
  2168. pfcJustification_L(F,Js) :- bagof(J,pfcJustificationDB(F,J),Js).
  2169.  
  2170. justSupports(F,J):- loop_check_nr(pfcGetSupport(F,J)).
  2171.  
  2172.  
  2173. %= pfcBase1(P,L) - is true iff L is a list of "base" facts which, taken
  2174. %= together, allows us TO deduce P.  A pfcBase1 fact is an pfcAxiom (a fact
  2175. %= added by the user OR a raw Prolog fact (i.e. one w/o any support))
  2176. %= OR an assumption.
  2177.  
  2178. pfcBase1(F,[F]) :- (pfcAxiom(F) ; pfcAssumptionBase(F)),!.
  2179.  
  2180. pfcBase1(F,L) :-
  2181.   % i.e. (reduce 'append (map 'pfcBase1 (justification f)))
  2182.   pfcJustificationDB(F,Js),
  2183.   pfcBases(Js,L).
  2184.  
  2185.  
  2186. %= pfcBases(L1,L2) is true IF list L2 represents the union of all of the
  2187. %= facts on which some conclusion in list L1 is based.
  2188.  
  2189. pfcBases([],[]).
  2190. pfcBases([X|Rest],L) :-
  2191.   pfcBase1(X,Bx),
  2192.   pfcBases(Rest,Br),
  2193.   pfcUnion(Bx,Br,L).
  2194.    
  2195. pfcAxiom(F) :-
  2196.  (get_user_support_for_lookup(F,US), pfcGetSupport(F,US));
  2197.  (get_god_support_for_lookup(F,GS),pfcGetSupport(F,GS)).
  2198.  
  2199. %= an pfcAssumptionBase/1''s G was a failed goal, i.e. were assuming that our failure to
  2200. %= prove P is a proof of NOT(P)
  2201.  
  2202. pfcAssumptionBase(P) :- pfc_negation(P,_).
  2203.    
  2204. %= pfcAssumptionsSet(X,AS) IF AS is a set of assumptions which underly X.
  2205.  
  2206. pfcAssumptionsSet(X,[X]) :- pfcAssumptionBase(X).
  2207. pfcAssumptionsSet(X,[]) :- pfcAxiom(X).
  2208. pfcAssumptionsSet(X,L) :-
  2209.   pfcJustificationDB(X,Js),
  2210.   pfcAssumption1(Js,L).
  2211.  
  2212. pfcAssumption1([],[]).
  2213. pfcAssumption1([X|Rest],L) :-
  2214.   pfcAssumptionsSet(X,Bx),
  2215.   pfcAssumption1(Rest,Br),
  2216.   pfcUnion(Bx,Br,L).  
  2217.  
  2218.  
  2219. %= pfcProofTree(P,T) the proof tree FOR P is T where a proof tree is
  2220. %= of the form
  2221. %%
  2222. %=     [P , J1, J2, ;;; Jn]         each Ji is an independent P justifier.
  2223. %=          ^                         AND has the form of
  2224. %=          [J11, J12,... J1n]      a list of proof trees.
  2225.  
  2226.  
  2227. % pfcChild(P,Q) is true iff P is an immediate justifier FOR Q.
  2228. % mode: pfcChild(+,?)
  2229.  
  2230. pfcChild(P,Q) :-
  2231.   pfcGetSupport(Q,(P,_)).
  2232.  
  2233. pfcChild(P,Q) :-
  2234.   pfcGetSupport(Q,(_,Trig)),
  2235.   pfcType(Trig,trigger),
  2236.   pfcChild(P,Trig).
  2237.  
  2238. pfcChildren(P,L) :- bagof(C,pfcChild(P,C),L).
  2239.  
  2240. % pfcDescendant(P,Q) is true iff P is a justifier FOR Q.
  2241.  
  2242. pfcDescendant(P,Q) :-
  2243.    pfcDescendant1(P,Q,[]).
  2244.  
  2245. pfcDescendant1(P,Q,Seen) :-
  2246.   pfcChild(X,Q),
  2247.   (\+ member(X,Seen)),
  2248.   (P=X ; pfcDescendant1(P,X,[X|Seen])).
  2249.  
  2250. pfcDescendants(P,L) :-
  2251.   bagof(Q,pfcDescendant1(P,Q,[]),L).
  2252.  
  2253.  
  2254.  
  2255. % pfcFile('pfcwhy').    % interactive exploration of pfcJustification_L.
  2256.  
  2257.  
  2258.  
  2259. %   File   : pfcwhy.pl
  2260. %   Author : Tim Finin, finin@prc.unisys.com
  2261. %   Updated:
  2262. %   Purpose: predicates FOR interactively exploring Pfc pfcJustification_L.
  2263.  
  2264. % ***** predicates FOR brousing pfcJustification_L *****
  2265.  
  2266. :- use_module(library(lists)).
  2267.  
  2268. :-dynamic(pfcWhyMemory1/2).
  2269.  
  2270. pfcWhy :-
  2271.   pfcWhyMemory1(P,_),
  2272.   pfcWhy(P).
  2273.  
  2274. pfcWhy(N) :-
  2275.   number(N),
  2276.   !,
  2277.   pfcWhyMemory1(P,Js),
  2278.   pfcWhyCommand(N,P,Js).
  2279.  
  2280. pfcWhy(P) :-
  2281.   pfcJustification_L(P,Js),
  2282.   pfc_retractall_settings(pfcInternal,pfcWhyMemory1(_,_)),
  2283.   pfcAssertS(pfcWhyMemory1(P,Js)),
  2284.   pfcWhyBrouse(P,Js).
  2285.  
  2286. pfcWhy1(P) :-
  2287.   pfcJustification_L(P,Js),
  2288.   pfcWhyBrouse(P,Js).
  2289.  
  2290. pfcWhyBrouse(P,Js) :-
  2291.   pfcShowJustifications(P,Js),
  2292.   pfcAskUser(' >> ',Answer),
  2293.   pfcWhyCommand(Answer,P,Js).
  2294.  
  2295. pfcWhyCommand(q,_,_) :- !.
  2296. pfcWhyCommand(h,_,_) :-
  2297.   !,
  2298.   fmt("
  2299. Justification Brouser Commands:
  2300. q   quit.
  2301. N   focus on Nth justification.
  2302. N.M brouse step M of the Nth justification
  2303. u   up a level
  2304. ",[]).
  2305.  
  2306. pfcWhyCommand(N,_P,Js) :-
  2307.   FLOAT(N),
  2308.   !,
  2309.   pfcSelectJustificationNode(Js,N,Node),
  2310.   pfcWhy1(Node).
  2311.  
  2312. pfcWhyCommand(u,_,_) :-
  2313.   % u=up
  2314.   !.
  2315.  
  2316. pfcCommand(N,_,_) :-
  2317.   INTEGER(N),
  2318.   !,
  2319.   fmt("~w is a yet unimplemented command.",[N]),
  2320.   fail.
  2321.  
  2322. pfcCommand(X,_,_) :-
  2323.  fmt("~w is an unrecognized command, enter h. for help.",[X]),
  2324.  fail.
  2325.  
  2326. pfcShowJustifications(P,Js) :-
  2327.   fmt("Justifications for ~w:",[P]),
  2328.   pfcShowJustification1(Js,1).
  2329.  
  2330. pfcShowJustification1([],_).
  2331.  
  2332. pfcShowJustification1([J|Js],N) :-
  2333.   % show one justification AND recurse.
  2334.   nl,
  2335.   pfcShowJustifications2(J,N,1),
  2336.   N2 is N+1,
  2337.   pfcShowJustification1(Js,N2).
  2338.  
  2339. pfcShowJustifications2([],_,_).
  2340.  
  2341. pfcShowJustifications2([C|Rest],JustNo,StepNo) :-
  2342.   copy_term(C,CCopy),
  2343.   numbervars(CCopy,0,_),
  2344.   pmsg("    ~w.~w ~w",[JustNo,StepNo,CCopy]),
  2345.   StepNext is 1+StepNo,
  2346.   pfcShowJustifications2(Rest,JustNo,StepNext).
  2347.  
  2348. pfcAskUser(Msg,Ans) :-
  2349.   fmt0(Msg),
  2350.   read(Ans).
  2351.  
  2352. pfcSelectJustificationNode(Js,Index,STEP) :-
  2353.   JustNo is INTEGER(Index),
  2354.   nth(JustNo,Js,Justification),
  2355.   StepNo is 1+ INTEGER(Index*10 - JustNo*10),
  2356.   nth(StepNo,Justification,STEP).
  2357.  
  2358.  
  2359. :- if_startup_script(with_assertions(thlocal:pfcExpansion,ensure_loaded(dbase_i_mpred_pfc_testing))).
  2360.  
  2361. :- if_startup_script(prolog).
  2362.  
  2363. % dcg_pfc: translation of dcg-like grammar rules into pfc rules.
  2364.  
  2365. :- dynamic(pfc_term_expansion_ok/0).
  2366. % :- use_module(library(strings)), use_module(library(lists)).
  2367.  
  2368. /*
  2369. pfc_file_expansion((P=>Q),(:- pfcAdd((P=>Q)))).
  2370. %pfc_file_expansion((P=>Q),(:- pfcAdd(('<='(Q,P))))).  % speed-up attempt
  2371. pfc_file_expansion(('<='(P,Q)),(:- pfcAdd(('<='(P,Q))))).
  2372. pfc_file_expansion((P<=>Q),(:- pfcAdd((P<=>Q)))).
  2373. pfc_file_expansion((RuleName :::: Rule),(:- pfcAdd((RuleName :::: Rule)))).
  2374. pfc_file_expansion((=>P),(:- pfcAdd(P))).
  2375. pfc_file_expansion((P -->> Q),(:- pfcAdd(Rule))) :-
  2376.   pfc_translate_rule((P -->> Q), Rule).
  2377. pfc_file_expansion((P --*>> Q),(:- pfcAdd(Rule))) :-
  2378.   pfc_translate_rule((P --*>> Q), Rule).
  2379. */
  2380.  
  2381. :- multifile('term_expansion'/2).
  2382. % term_expansion(I,O):-pfc_file_expansion(I,O),I\=@=O, (pfc_term_expansion_ok -> true ; print_message(warning,pfc_file_expansion(I,O))).
  2383.  
  2384.  
  2385.  
  2386. pfc_translate_rule((LP-->>[]),H) :- !, pfc_t_lp(LP,_Id,S,S,H).
  2387.  
  2388. pfc_translate_rule((LP-->>RP),(H <= B)):-
  2389.    pfc_t_lp(LP,Id,S,SR,H),
  2390.    pfc_t_rp(RP,Id,S,SR,B1),
  2391.    pfc_tidy(B1,B).
  2392.  
  2393.  
  2394. pfc_translate_rule((LP--*>>[]),H) :- !, pfc_t_lp(LP,_Id,S,S,H).
  2395. pfc_translate_rule((LP--*>>RP),(B => H)):-
  2396.    pfc_t_lp(LP,Id,S,SR,H),
  2397.    pfc_t_rp(RP,Id,S,SR,B1),
  2398.    pfc_tidy(B1,B).
  2399.  
  2400. pfc_t_lp(X,Id,S,SR,ss(X,Id,(S \\ SR))) :- var(X),!.
  2401.  
  2402. pfc_t_lp((LP,List),Id,S,SR,ss(LP,Id,(S \\ List2))):-
  2403.    !,
  2404.    append(List,SR,List2).
  2405.  
  2406. pfc_t_lp(LP,Id,S,SR,ss(LP,Id,(S \\ SR))).
  2407.  
  2408. pfc_t_rp(!,_Id,S,S,!) :- !.
  2409. pfc_t_rp([],_Id,S,S1,S=S1) :- !.
  2410. pfc_t_rp([X],Id,S,SR,ss(word(X),Id,(S \\ SR))) :- !.
  2411. pfc_t_rp([X|R],Id,S,SR,(ss(word(X),Id,(S \\ SR1)),RB)) :-
  2412.   !,
  2413.   pfc_t_rp(R,Id,SR1,SR,RB).
  2414. pfc_t_rp({T},_Id,S,S,{T}) :- !.
  2415. pfc_t_rp((T,R),Id,S,SR,(Tt,Rt)) :- !,
  2416.    pfc_t_rp(T,Id,S,SR1,Tt),
  2417.    pfc_t_rp(R,Id,SR1,SR,Rt).
  2418. pfc_t_rp((T;R),Id,S,SR,(Tt;Rt)) :- !,
  2419.    pfc_t_or(T,Id,S,SR,Tt),
  2420.    pfc_t_or(R,Id,S,SR,Rt).
  2421. pfc_t_rp(T,Id,S,SR,ss(T,Id,(S \\ SR))).
  2422.  
  2423. pfc_t_or(X,Id,S0,S,P) :-
  2424.    pfc_t_rp(X,Id,S0a,S,Pa),
  2425.  ( var(S0a), (\==(S0a,S)), !, S0=S0a, P=Pa;
  2426.    P=(S0=S0a,Pa) ).
  2427.  
  2428. pfc_tidy((P1;P2),(Q1;Q2)) :-
  2429.    !,
  2430.    pfc_tidy(P1,Q1),
  2431.    pfc_tidy(P2,Q2).
  2432. pfc_tidy(((P1,P2),P3),Q) :-
  2433.    pfc_tidy((P1,(P2,P3)),Q).
  2434. pfc_tidy((P1,P2),(Q1,Q2)) :-
  2435.    !,
  2436.    pfc_tidy(P1,Q1),
  2437.    pfc_tidy(P2,Q2).
  2438. pfc_tidy(A,A) :- !.
  2439.  
  2440. compile_pfcg :-
  2441.   ((retract((L -->> R)), pfc_translate_rule((L -->> R), PfcRule));
  2442.     (retract((L --*>> R)), pfc_translate_rule((L --*>> R), PfcRule))),
  2443.   pfcAdd(PfcRule),
  2444.   fail.
  2445. compile_pfcg.
  2446.  
  2447. parse(Words) :-
  2448.   parse(Words,Id),
  2449.   format(" sentence id = ~w",Id),
  2450.   show(Id,sentence(_X)).
  2451.  
  2452.  
  2453. parse(Words,Id) :-
  2454.   gen_s_tag(Id),
  2455.   parse1(Words,Id),
  2456.   pfcAdd(sentence(Id,Words)).
  2457.  
  2458. parse1([],_) :- !.
  2459. parse1([H|T],Id) :-
  2460.  DO(pfcAdd(ss(word(H),Id,([H|T] \\ T)))),
  2461.  parse1(T,Id).
  2462.  
  2463.  
  2464. showSentences(Id) :- showSentences(Id,_).
  2465.  
  2466. showSentences(Id,Words) :-
  2467.   sentence(Id,Words),
  2468.   pfc(ss(s(S),Id,(Words \\ []))),
  2469.   nl,write(S),
  2470.   fail.
  2471. showSentences(_,_).
  2472.  
  2473. DO(X) :- call(X) -> true;true.
  2474.  
  2475. show(Id,C) :-
  2476.   pfc(ss(C,Id,A \\ B)),
  2477.   append(Words,B,A),
  2478.   format("~n ~w    :   ~w",[C,Words]),
  2479.   fail.
  2480.  
  2481. gen_s_tag(s(N2)) :-
  2482.   % var(_V),
  2483.   (retract(s_tag(N)); N=0),
  2484.   N2 is N+1,
  2485.   assert(s_tag(N2)).
  2486.  
  2487. make_term(ss(Constituent,Id,STRING),Term) :-
  2488.    Constituent =.. [Name|Args],
  2489.    name(Name,Name_string),
  2490.    name(Name2,[36|Name_string]),
  2491.    append([Name2|Args],[Id,STRING],Term_string),
  2492.    Term =.. Term_string.
  2493. % append([],X,X). append([H|T],L2,[H|L3]) :- append(T,L2,L3).
  2494.  
  2495.  
  2496. % user:term_expansion(A,B):- loop_check(pfc_file_expansion(A,B)),A\=@=B.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement