/* File: flrundefined.P -- Catcher of undefined predicates and methods ** ** Author(s): Chang Zhao ** ** Contact: flora-users@lists.sourceforge.net ** ** Copyright (C) The Research Foundation of SUNY, 2002 ** ** FLORA-2 is free software; you can redistribute it and/or modify it under the ** terms of the GNU Library General Public License as published by the Free ** Software Foundation; either version 2 of the License, or (at your option) ** any later version. ** ** FLORA-2 is distributed in the hope that it will be useful, but WITHOUT ANY ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ** FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for ** more details. ** ** You should have received a copy of the GNU Library General Public License ** along with FLORA-2; if not, write to the Free Software Foundation, ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** $Id: flrundefined.P,v 1.11 2003/06/18 07:01:35 kifer Exp $ ** */ :- compiler_options([xpp_on]). #include "flora_terms.flh" #include "flora_exceptions.flh" #include "flora_porting.flh" #define MOST_GENERAL most_general /*********************************************************************** * flora_debug_code(+CompileList) * Generate facts that will be loaded into fld storage * from facts and rule heads ***********************************************************************/ flora_debug_code(TermList, File) :- retractall(term_seen(_)), flora_build_debug_inter_codelist(TermList), telling(PreOut), tell(File), writeln('#include "flrheader.flh"'), nl, generate_patches, told, tell(PreOut). /*********************************************************************** * flora_build_debug_inter_codelist(+CompileList) * patch facts will be asserted into ter_seen(Term) to remove duplicates ***********************************************************************/ flora_build_debug_inter_codelist([]) :- !. flora_build_debug_inter_codelist([T|L]) :- flora_build_debug_inter_code(T), flora_build_debug_inter_codelist(L). flora_build_debug_inter_code(Term) :- ( (is_prrule(Term,Head,_);is_prfact(Term,Head)) -> ( flora_build_debug_skeleton(Head,Code,GFlag) -> ( var(Code) -> true ; ( GFlag==MOST_GENERAL -> (term_seen(OldTerm), subsumes(OldTerm,Code) -> true ; retractall(term_seen(Code)), assert(term_seen(Code)) ) ; ( term_seen(Code) -> true ; assert(term_seen(Code)) ) ) ) ; true ) ; true ). /*********************************************************** * flora_build_debug_skeleton(+Term, -Code, -Flag) * builds the intermediate form of the skeletons of all facts * and rule heads and returns a flag showing whether the * skeleton is of the most general form, eg. fd's whose second * parameter is a variable ***********************************************************/ flora_build_debug_skeleton(Term,Atom,_GFlag) :- is_pratom(Term,Atom,_Index), !. flora_build_debug_skeleton(Term,_NewVar,MOST_GENERAL) :- is_prvariable(Term,_Name,_Index), !. flora_build_debug_skeleton(Term,Sk,GFlag) :- is_prterm(Term,FObj,N,_ObjList), !, ( is_pratom(FObj,FAtom,_Index), flora_prlgdef(FAtom,N) -> fail ; flora_build_debug_skeleton(FObj,FCode,GFlag), var_list(N,ObjListCode), Sk =.. [WRAP_HILOG,FCode|ObjListCode] ). flora_build_debug_skeleton(Term,Sk,_GFlag) :- is_pratomlit(Term,A,_Index), !, ( flora_prlgdef(A,0) -> fail ; Sk=WRAP_HILOG(A) ). flora_build_debug_skeleton(Term,Sk,GFlag) :- is_prtermlit(Term,FObj,N,_ObjList), !, ( is_pratom(FObj,FAtom,_Index) -> ( flora_prlgdef(FAtom, N) -> fail ; var_list(N,ObjListCode), Sk=..[WRAP_HILOG,FAtom|ObjListCode] ) ; var_list(N,ObjListCode), flora_build_debug_skeleton(FObj,FCode,GFlag), Sk=..[WRAP_HILOG,FCode|ObjListCode] ). flora_build_debug_skeleton(PRISA(_Obj1,Obj2),WRAP_ISA(_NewVar,CCode),GFlag) :- !, flora_build_debug_skeleton(Obj2,CCode,GFlag). flora_build_debug_skeleton(PRSUB(_Obj1,Obj2),WRAP_SUB(_NewVar,CCode),GFlag) :- !, flora_build_debug_skeleton(Obj2,CCode,GFlag). flora_build_debug_skeleton(PRMETH(_Obj1,Meth),WRAP_METH(_NewVar,MCode),GFlag) :- !, flora_build_debug_skeleton(Meth,MCode,GFlag). flora_build_debug_skeleton(PRIMETH(_Obj1,IMeth),WRAP_IMETH(_NewVar,MCode),GFlag) :- !, flora_build_debug_skeleton(IMeth,MCode,GFlag). flora_build_debug_skeleton(PRFDDEF(_Obj,Attr),WRAP_FDDEF(_NewVar,ACode),GFlag) :- !, flora_build_debug_skeleton(Attr,ACode,GFlag). flora_build_debug_skeleton(PRMVDDEF(_Obj,Attr),WRAP_MVDDEF(_NewVar,ACode),GFlag) :- !, flora_build_debug_skeleton(Attr,ACode,GFlag). flora_build_debug_skeleton(PRIFDDEF(_Obj,Attr),WRAP_IFDDEF(_NewVar,ACode),GFlag) :- !, flora_build_debug_skeleton(Attr,ACode,GFlag). flora_build_debug_skeleton(PRIMVDDEF(_Obj,Attr),WRAP_IMVDDEF(_NewVar,ACode),GFlag) :- !, flora_build_debug_skeleton(Attr,ACode,GFlag). flora_build_debug_skeleton(PRTRAN(_Obj,Tran),WRAP_TRAN(_NewVar,TCode),GFlag) :- !, flora_build_debug_skeleton(Tran,TCode,GFlag). flora_build_debug_skeleton(PRFD(_Obj,Att,_Val),WRAP_FD(_OCode,ACode,_VCode),GFlag) :- !, flora_build_debug_skeleton(Att,ACode,GFlag). flora_build_debug_skeleton(PRIFD(_Obj,Att,_Val),WRAP_IFD(_OCode,ACode,_VCode),GFlag) :- !, flora_build_debug_skeleton(Att,ACode,GFlag). flora_build_debug_skeleton(PRFDSIG(_Obj,Att,_Val),WRAP_FDSIG(_OCode,ACode,_VCode),GFlag) :- !, flora_build_debug_skeleton(Att,ACode,GFlag). flora_build_debug_skeleton(PRMVDSIG(_Obj,Att,_Val),WRAP_MVDSIG(_OCode,ACode,_VCode),GFlag) :- !, flora_build_debug_skeleton(Att,ACode,GFlag). flora_build_debug_skeleton(PRIFDSIG(_Obj,Att,_Val),WRAP_IFDSIG(_OCode,ACode,_VCode),GFlag) :- !, flora_build_debug_skeleton(Att,ACode,GFlag). flora_build_debug_skeleton(PRIMVDSIG(_Obj,Att,_Val),WRAP_IMVDSIG(_OCode,ACode,_VCode),GFlag) :- !, flora_build_debug_skeleton(Att,ACode,GFlag). flora_build_debug_skeleton(PRMVD(_Obj,Att,_Val),WRAP_MVD(_OCode,ACode,_VCode),GFlag) :- !, flora_build_debug_skeleton(Att,ACode,GFlag). flora_build_debug_skeleton(PRIMVD(_Obj,Att,_Val),WRAP_IMVD(_OCode,ACode,_VCode),GFlag) :- !, flora_build_debug_skeleton(Att,ACode,GFlag). flora_build_debug_skeleton(PRMVDINC(_Obj,Att,_Val),WRAP_MVDINC(_OCode,ACode,_VCode),GFlag) :- !, flora_build_debug_skeleton(Att,ACode,GFlag). flora_build_debug_skeleton(PRIMVDINC(_Obj,Att,_Val),WRAP_IMVDINC(_OCode,ACode,_VCode),GFlag) :- !, flora_build_debug_skeleton(Att,ACode,GFlag). flora_build_debug_skeleton(PRMVDTOLIST(_Obj,Att,_Val),WRAP_MVDTOLIST(_OCode,ACode,_VCode),GFlag) :- !, flora_build_debug_skeleton(Att,ACode,GFlag). flora_build_debug_skeleton(PRIMVDTOLIST(_Obj,Att,_Val),WRAP_IMVDTOLIST(_OCode,ACode,_VCode),GFlag) :- !, flora_build_debug_skeleton(Att,ACode,GFlag). flora_build_debug_skeleton(_, _, _) :- !. /********************************************* * generate_patches * generate a fact in intermediate form * for each Term asserted in term_seen(Term) *********************************************/ generate_patches :- term_seen(Term), Term =.. [F|Args], flora_write_atom('FLORA_THIS_WORKSPACE('), flora_write_quoted_atom(F), put(0')), put(0'(), write_args(Args), put(0')), put(0'.), nl, fail. generate_patches :- !. write_args([]) :- !. write_args([A]) :- !, write_canonical(A). write_args([H|L]) :- write_canonical(H), put(0',), write_args(L). /*********************************************************** * utilities for flora_build_skeleton ***********************************************************/ is_flogic_2params(WRAP_ISA) :- !. is_flogic_2params(WRAP_SUB) :- !. is_flogic_2params(WRAP_METH) :- !. is_flogic_2params(WRAP_IMETH) :- !. is_flogic_2params(WRAP_FDDEF) :- !. is_flogic_2params(WRAP_MVDDEF) :- !. is_flogic_2params(WRAP_IFDDEF) :- !. is_flogic_2params(WRAP_IMVDDEF) :- !. is_flogic_2params(WRAP_TRAN) :- !. is_flogic_3params(WRAP_FD) :- !. is_flogic_3params(WRAP_IFD) :- !. is_flogic_3params(WRAP_FDSIG) :- !. is_flogic_3params(WRAP_MVDSIG) :- !. is_flogic_3params(WRAP_IFDSIG) :- !. is_flogic_3params(WRAP_IMVDSIG) :- !. is_flogic_3params(WRAP_MVD) :- !. is_flogic_3params(WRAP_IMVD) :- !. is_flogic_3params(WRAP_MVDINC) :- !. is_flogic_3params(WRAP_IMVDINC) :- !. is_flogic_3params(WRAP_MVDTOLIST) :- !. is_flogic_3params(WRAP_IMVDTOLIST) :- !. /*********************************************************** * flora_build_skeleton(+Term, -Code) * builds the skeleton of Term * this is similar to flora_build_debug_skeleton, but the * term is not in intermediate form. * This predicate is called at run time ***********************************************************/ flora_build_skeleton(Term,Term) :- atom(Term), !. flora_build_skeleton(Term,Term) :- var(Term), !. flora_build_skeleton([Wrap,_Obj1,Obj2],[Wrap,_,CCode]) :- is_flogic_2params(Wrap), !, flora_build_skeleton(Obj2,CCode). flora_build_skeleton([Wrap,_Obj,Att,_Val],[Wrap,_,ACode,_]) :- is_flogic_3params(Wrap), !, flora_build_skeleton(Att,ACode). flora_build_skeleton([WRAP_HILOG,F|Arg],[WRAP_HILOG,FSkeleton|VList]) :- !, length(Arg,N), var_list(N, VList), flora_build_skeleton(F,FSkeleton). flora_build_skeleton([F|Arg],[FSkeleton,VList]) :- length(Arg,N), var_list(N,VList), flora_build_skeleton(F,FSkeleton). flora_build_skeleton(WRAP_ISA(_Obj1,Obj2),WRAP_ISA(_,CCode)) :- !, flora_build_skeleton(Obj2,CCode). flora_build_skeleton(WRAP_SUB(_Obj1,Obj2),WRAP_SUB(_,CCode)) :- !, flora_build_skeleton(Obj2,CCode). flora_build_skeleton(WRAP_METH(_Obj1,Meth),WRAP_METH(_,MCode)) :- !, flora_build_skeleton(Meth,MCode). flora_build_skeleton(WRAP_IMETH(_Obj1,IMeth),WRAP_IMETH(_,MCode)) :- !, flora_build_skeleton(IMeth,MCode). flora_build_skeleton(WRAP_FDDEF(_Obj,Attr),WRAP_FDDEF(_,ACode)) :- !, flora_build_skeleton(Attr,ACode). flora_build_skeleton(WRAP_MVDDEF(_Obj,Attr),WRAP_MVDDEF(_,ACode)) :- !, flora_build_skeleton(Attr,ACode). flora_build_skeleton(WRAP_IFDDEF(_Obj,Attr),WRAP_IFDDEF(_,ACode)) :- !, flora_build_skeleton(Attr,ACode). flora_build_skeleton(WRAP_IMVDDEF(_Obj,Attr),WRAP_IMVDDEF(_,ACode)) :- !, flora_build_skeleton(Attr,ACode). flora_build_skeleton(WRAP_TRAN(_Obj,Tran),WRAP_TRAN(_,TCode)) :- !, flora_build_skeleton(Tran,TCode). flora_build_skeleton(WRAP_FD(_Obj,Att,_Val),WRAP_FD(_,ACode,_)) :- !, flora_build_skeleton(Att,ACode). flora_build_skeleton(WRAP_IFD(_Obj,Att,_Val),WRAP_IFD(_,ACode,_)) :- !, flora_build_skeleton(Att,ACode). flora_build_skeleton(WRAP_FDSIG(_Obj,Att,_Val),WRAP_FDSIG(_,ACode,_)) :- !, flora_build_skeleton(Att,ACode). flora_build_skeleton(WRAP_MVDSIG(_Obj,Att,_Val),WRAP_MVDSIG(_,ACode,_)) :- !, flora_build_skeleton(Att,ACode). flora_build_skeleton(WRAP_IFDSIG(_Obj,Att,_Val),WRAP_IFDSIG(_,ACode,_)) :- !, flora_build_skeleton(Att,ACode). flora_build_skeleton(WRAP_IMVDSIG(_Obj,Att,_Val),WRAP_IMVDSIG(_,ACode,_)) :- !, flora_build_skeleton(Att,ACode). flora_build_skeleton(WRAP_MVD(_Obj,Att,_Val),WRAP_MVD(_,ACode,_)) :- !, flora_build_skeleton(Att,ACode). flora_build_skeleton(WRAP_IMVD(_Obj,Att,_Val),WRAP_IMVD(_,ACode,_)) :- !, flora_build_skeleton(Att,ACode). flora_build_skeleton(WRAP_MVDINC(_Obj,Att,_Val),WRAP_MVDINC(_,ACode,_)) :- !, flora_build_skeleton(Att,ACode). flora_build_skeleton(WRAP_IMVDINC(_Obj,Att,_Val),WRAP_IMVDINC(_,ACode,_)) :- !, flora_build_skeleton(Att,ACode). flora_build_skeleton(WRAP_MVDTOLIST(_Obj,Att,_Val),WRAP_MVDTOLIST(_,ACode,_)) :- !, flora_build_skeleton(Att,ACode). flora_build_skeleton(WRAP_IMVDTOLIST(_Obj,Att,_Val),WRAP_IMVDTOLIST(_,ACode,_)) :- !, flora_build_skeleton(Att,ACode). flora_build_skeleton(Term,Skeleton) :- functor(Term, WRAP_HILOG, N), !, Term =.. [WRAP_HILOG, MainFunct|_Args], M is N-1, var_list(M, VarList), flora_build_skeleton(MainFunct, MainFunctSkeleton), Skeleton =.. [WRAP_HILOG, MainFunctSkeleton|VarList]. flora_build_skeleton(Term, Skeleton) :- functor(Term, MainFunct, N), functor(Skeleton, MainFunct, N). var_list(0, []) :- !. var_list(N, [_|Rest]) :- M is N-1, var_list(M, Rest). /***************************************** * flora_define_predicate(+Predicate) * compute the skeleton of Predcate and insert it to the corresponding trie * (for the heads of dynamically inserted rules) *****************************************/ flora_define_predicate(Predicate) :- flora_decode_predicate(Predicate,PType,MName,_WPrefix,PSymbol,AList), flora_module_type_and_name(MName,ModuleType,ModuleName), ( (PType==hilog) -> QCode = [WRAP_HILOG,PSymbol|AList] ; QCode = [PSymbol|AList] ), candidate_list([QCode],ModuleType,ModuleName,[Skeleton]), flora_module_storage(ModuleType,ModuleName,fld,FldStorage), flora_db_insert_base(FldStorage,Skeleton). /************************************************************ * flora_module_type_and_name(+MName,-ModuleType,-ModuleName) ************************************************************/ flora_module_type_and_name(MName,ModuleType,ModuleName) :- ( (MName = flora(ModuleName)) -> ModuleType=system ; ModuleName=MName, ModuleType=user ). /********************************************************************* * flora_module_storage(+ModuleType,+ModuleName,+StorageType,-Storage) *********************************************************************/ :- table flora_module_storage/4. flora_module_storage(ModuleType,ModuleName,StorageType,Storage) :- ( ModuleType==user -> (StorageType==fdb -> flora_concat_atoms([FLORA_USER_FDB_TRIE_PREFIX, ''''], S) ; flora_concat_atoms([FLORA_USER_FLD_TRIE_PREFIX, ''''], S) ) ; (StorageType==fdb -> flora_concat_atoms([FLORA_SYSTEM_FDB_TRIE_PREFIX, ''''], S) ; flora_concat_atoms([FLORA_SYSTEM_FLD_TRIE_PREFIX, ''''], S) ) ), flora_concat_atoms([S, ModuleName],Storage). /***************************************************************************** * flora_temp_protect_call(+Predicate,+Id) * flora_temp_unprotect_call(+Id) :- * +Predicate is the call to be recorded as temporarily protected * from the undefinedness check. * +Id is a unique Id that is used to delete the call from the registry. * * This is similar to flora_define_predicate/1 above. * * Compute the skeleton of Predcate and insert it to a temporary storage * to prevent signalling undefinedness errrors. This is used for calls * like Call@Var in flrdynmod.P, because when Var is a variable then * undefinedness check for Call doesn't make sense. *****************************************************************************/ flora_temp_protect_call(Predicate,Id) :- flora_decode_predicate(Predicate,PType,MName,_WPrefix,PSymbol,AList), flora_module_type_and_name(MName,ModuleType,ModuleName), ( (PType==hilog) -> QCode = [WRAP_HILOG,PSymbol|AList] ; QCode = [PSymbol|AList] ), candidate_list([QCode],ModuleType,ModuleName,[Skeleton]), assert(flora_disabled_undefinedness_check_registry(MName,Id,Skeleton)). flora_temp_unprotect_call(Id) :- retractall(flora_disabled_undefinedness_check_registry(_,Id,_)). %% Tell if call is protected temporarily_protected_call(PredicateSkel) :- flora_disabled_undefinedness_check_registry(_Mod,_Id,PredicateSkel). /**************************************************************************** ** defined_by(+What,-ByWhat) ** +What is a list that represents a query. ** -ByWhat is a representation of a rule head that might define the call. ****************************************************************************/ defined_by([WRAP_ISA,X,Y],[WRAP_ISA,X,Y]). defined_by([WRAP_ISA,X,Y],[WRAP_SUB,X,Y]). defined_by([WRAP_SUB,X,Y],[WRAP_SUB,X,Y]). defined_by([WRAP_METH,X,Y],[WRAP_METH,X,Y]). defined_by([WRAP_METH,X,Y],[WRAP_IMETH,X,Y]). defined_by([WRAP_IMETH,X,Y],[WRAP_IMETH,X,Y]). defined_by([WRAP_FD,X,Y,Z],[WRAP_FD,X,Y,Z]). defined_by([WRAP_FD,X,Y,Z],[WRAP_IFD,X,Y,Z]). defined_by([WRAP_IFD,X,Y,Z],[WRAP_IFD,X,Y,Z]). defined_by([WRAP_FDDEF,X,Y],[WRAP_FD,X,Y,_Z]). defined_by([WRAP_FDDEF,X,Y],[WRAP_IFD,X,Y,_Z]). defined_by([WRAP_IFDDEF,X,Y],[WRAP_IFD,X,Y,_Z]). defined_by([WRAP_FDSIG,X,Y,Z],[WRAP_FDSIG,X,Y,Z]). defined_by([WRAP_FDSIG,X,Y,Z],[WRAP_IFDSIG,X,Y,Z]). defined_by([WRAP_FDSIGDEF,X,Y],[WRAP_FDSIGDEF,X,Y]). defined_by([WRAP_FDSIGDEF,X,Y],[WRAP_IFDSIGDEF,X,Y]). defined_by([WRAP_IFDSIG,X,Y,Z],[WRAP_IFDSIG,X,Y,Z]). defined_by([WRAP_IFDSIGDEF,X,Y],[WRAP_IFDSIGDEF,X,Y]). defined_by([WRAP_MVD,X,Y,Z],[WRAP_MVD,X,Y,Z]). defined_by([WRAP_MVD,X,Y,Z],[WRAP_IMVD,X,Y,Z]). defined_by([WRAP_MVD,X,Y,_Z],[WRAP_MVDDEF,X,Y]). defined_by([WRAP_MVD,X,Y,_Z],[WRAP_IMVDDEF,X,Y]). defined_by([WRAP_IMVD,X,Y,Z],[WRAP_IMVD,X,Y,Z]). defined_by([WRAP_IMVD,X,Y,_Z],[WRAP_IMVDDEF,X,Y]). defined_by([WRAP_MVDDEF,X,Y],[WRAP_MVD,X,Y,_Z]). defined_by([WRAP_MVDDEF,X,Y],[WRAP_IMVD,X,Y,_Z]). defined_by([WRAP_MVDDEF,X,Y],[WRAP_MVDDEF,X,Y]). defined_by([WRAP_MVDDEF,X,Y],[WRAP_IMVDDEF,X,Y]). defined_by([WRAP_IMVDDEF,X,Y],[WRAP_IMVD,X,Y,_Z]). defined_by([WRAP_IMVDDEF,X,Y],[WRAP_IMVDDEF,X,Y]). defined_by([WRAP_MVDSIG,X,Y,Z],[WRAP_MVDSIG,X,Y,Z]). defined_by([WRAP_MVDSIG,X,Y,Z],[WRAP_IMVDSIG,X,Y,Z]). defined_by([WRAP_IMVDSIG,X,Y,Z],[WRAP_IMVDSIG,X,Y,Z]). defined_by([WRAP_MVDSIGDEF,X,Y],[WRAP_MVDSIGDEF,X,Y]). defined_by([WRAP_MVDSIGDEF,X,Y],[WRAP_IMVDSIGDEF,X,Y]). defined_by([WRAP_IMVDSIGDEF,X,Y],[WRAP_IMVDSIGDEF,X,Y]). defined_by([WRAP_MVDINC,X,Y,Z],[WRAP_MVD,X,Y,Z]). defined_by([WRAP_MVDINC,X,Y,Z],[WRAP_IMVD,X,Y,Z]). defined_by([WRAP_IMVDINC,X,Y,Z],[WRAP_IMVD,X,Y,Z]). defined_by([WRAP_MVDTOLIST,X,Y,Z],[WRAP_MVD,X,Y,Z]). defined_by([WRAP_MVDTOLIST,X,Y,Z],[WRAP_IMVD,X,Y,Z]). defined_by([WRAP_IMVDTOLIST,X,Y,Z],[WRAP_IMVD,X,Y,Z]). defined_by([WRAP_TRAN,X,Y],[WRAP_TRAN,X,Y]). candidate_list([],_ModuleType,_ModuleName,[]) :- !. candidate_list([QCode|Rest],ModuleType,ModuleName,[QSk|CanRest]) :- flora_build_skeleton(QCode,QSkeleton), QSkeleton = [QFunct|QArgs], ( ModuleType==user -> flora_concat_atoms([FLORA_USER_MODULE_PREFIX, ''''], F) ; flora_concat_atoms([FLORA_SYSTEM_MODULE_PREFIX, ''''], F) ), flora_concat_atoms([F,ModuleName,'''',QFunct],QNewFunct), QSk =.. [QNewFunct|QArgs], candidate_list(Rest,ModuleType,ModuleName,CanRest). check_candidate_list([QSk|L],FdbStorage,Q) :- flora_db_find_base(FdbStorage,QSk),!,Q=QSk; check_candidate_list(L,FdbStorage,Q). %% Check skeletons in the candidate list against temporarily protected calls %% Succeeds, if matches check_temporarily_protected_calls([QSk|L]) :- temporarily_protected_call(QSk), !; check_temporarily_protected_calls(L). /***************************************** * flora_error_undefined(+Predicate) * if a fact with the same skeleton as * Predicate, then it is not really * undefined(fact is inserted at run time) * else print 'undefined predicate message *****************************************/ flora_error_undefined(Predicate) :- flora_decode_predicate(Predicate, PType, MName, _WPrefix, PSymbol, AList), flora_module_type_and_name(MName,ModuleType,ModuleName), flora_module_storage(ModuleType,ModuleName,fld,FldStorage), flora_module_storage(ModuleType,ModuleName,fdb,FdbStorage), ( (PType==hilog) -> QCode = [WRAP_HILOG,PSymbol|AList], candidate_list([QCode],ModuleType,ModuleName,CanList) ; findall(QCode,defined_by([PSymbol|AList],QCode),QCodeList), candidate_list(QCodeList,ModuleType,ModuleName,CanList) ), (check_candidate_list(CanList,FdbStorage,QSk) -> flora_decode_predicate(QSk, _PT, _MN, _WPrefix, _PS, FAList), ( (PType==hilog) -> FCode = [WRAP_HILOG,PSymbol|FAList] ; FCode = [PSymbol|FAList] ), flora_build_skeleton(FCode,FSkeleton), FSkeleton = [_FFunct|FArgs], QSk =.. [QNewFunct|_QArgs], FSk =.. [QNewFunct|FArgs], flora_db_insert_base(FldStorage,FSk), !, fail ; check_temporarily_protected_calls(CanList) -> fail ; predicate_msg(PSymbol, AList, PMsg), ( PType==flogic, (PSymbol==WRAP_ISA ; PSymbol==WRAP_SUB) -> TypeMsg = 'Undefined class' ; PType==flogic -> TypeMsg = 'Undefined method' ; TypeMsg = 'Undefined predicate' ), ( MName=flora(Name) -> flora_concat_items([TypeMsg,' ',PMsg,' in system module ',Name], ErrorMsg) ; flora_concat_items([TypeMsg,' ',PMsg,' in user module ',MName], ErrorMsg) ) ), close_open_tables, throw(FLORA_UNDEFINED_EXCEPTION(Predicate,ErrorMsg)). /************************************************** * predicate_msg(+PredicateSymbol, +ArgList, -PMsg) * generate a string from the predicate which is * more readable to the user **************************************************/ predicate_msg(Term,Term) :- atom(Term), !. predicate_msg(Term,'_') :- var(Term), !. predicate_msg(Term,PMsg) :- Term =.. [WRAP_HILOG,MainFunct|ArgList], !, predicate_msg(MainFunct, FMsg), ( ArgList = [] -> PMsg = FMsg ; varlist_to_str(ArgList, VMsg), flora_concat_atoms([FMsg,'(',VMsg,')'],PMsg) ). predicate_msg(WRAP_ISA,[_O1, O2], PMsg) :- !, predicate_msg(O2, O2Msg), flora_concat_atoms(['_:', O2Msg],PMsg). predicate_msg(WRAP_SUB,[_O1, O2], PMsg) :- !, predicate_msg(O2, O2Msg), flora_concat_atoms(['_::', O2Msg],PMsg). predicate_msg(WRAP_METH,[_O1, O2], PMsg) :- !, predicate_msg(O2, O2Msg), flora_concat_atoms(['_[',O2Msg,']'],PMsg). predicate_msg(WRAP_IMETH,[_O1, O2], PMsg) :- !, predicate_msg(O2, O2Msg), flora_concat_atoms(['_[*',O2Msg,']'],PMsg). predicate_msg(WRAP_FDDEF,[_O1, O2], PMsg) :- !, predicate_msg(O2, O2Msg), flora_concat_atoms(['_.',O2Msg,'[]'],PMsg). predicate_msg(WRAP_MVDDEF,[_O1, O2], PMsg) :- !, predicate_msg(O2, O2Msg), flora_concat_atoms(['_..',O2Msg,'[]'],PMsg). predicate_msg(WRAP_IFDDEF,[_O1, O2], PMsg) :- !, predicate_msg(O2, O2Msg), flora_concat_atoms(['_!',O2Msg,'[]'],PMsg). predicate_msg(WRAP_IMVDDEF,[_O1, O2], PMsg) :- !, predicate_msg(O2, O2Msg), flora_concat_atoms(['_!!',O2Msg,'[]'],PMsg). predicate_msg(WRAP_TRAN,[_O1, O2], PMsg) :- !, predicate_msg(O2, O2Msg), flora_concat_atoms(['_[#',O2Msg,']'],PMsg). predicate_msg(WRAP_FD, [_Obj, Att, _Val], PMsg) :- !, predicate_msg(Att,AMsg), flora_concat_atoms(['_[',AMsg,'->_]'],PMsg). predicate_msg(WRAP_IFD, [_Obj, Att, _Val], PMsg) :- !, predicate_msg(Att,AMsg), flora_concat_atoms(['_[',AMsg,'*->_]'],PMsg). predicate_msg(WRAP_FDSIG, [_Obj, Att, _Val], PMsg) :- !, predicate_msg(Att,AMsg), flora_concat_atoms(['_[',AMsg,'=>_]'],PMsg). predicate_msg(WRAP_MVDSIG, [_Obj, Att, _Val], PMsg) :- !, predicate_msg(Att,AMsg), flora_concat_atoms(['_[',AMsg,'=>>_]'],PMsg). predicate_msg(WRAP_IFDSIG, [_Obj, Att, _Val], PMsg) :- !, predicate_msg(Att,AMsg), flora_concat_atoms(['_[',AMsg,'*=>_]'],PMsg). predicate_msg(WRAP_IMVDSIG, [_Obj, Att, _Val], PMsg) :- !, predicate_msg(Att,AMsg), flora_concat_atoms(['_[',AMsg,'*=>>_]'],PMsg). predicate_msg(WRAP_MVD, [_Obj, Att, _Val], PMsg) :- !, predicate_msg(Att,AMsg), flora_concat_atoms(['_[',AMsg,'->>_]'],PMsg). predicate_msg(WRAP_IMVD, [_Obj, Att, _Val], PMsg) :- !, predicate_msg(Att,AMsg), flora_concat_atoms(['_[',AMsg,'*->>_]'],PMsg). predicate_msg(PredicateSymbol, ArgList, PMsg) :- predicate_msg(PredicateSymbol, PredMsg), varlist_count(ArgList, N), flora_concat_items([PredMsg,'/',N],PMsg). /***************************************************** * varlist_to_str(+List, -String) * produce a string of underscores seperated by comma * the number of underscores is the same as the number * of elements in the input list *****************************************************/ varlist_to_str([_], '_') :- !. varlist_to_str([_H|T], Str) :- varlist_to_str(T, RestStr), flora_concat_atoms(['_,',RestStr],Str). /***************************************************** * varlist_count(+List, -Number) * count the number of elements in a list *****************************************************/ varlist_count([], 0) :- !. varlist_count([_H|T], M) :- varlist_count(T, N), M is N+1.