/* File: flrbtdbop.P ** ** Author(s): Guizhen Yang ** ** Contact: flora-users@lists.sourceforge.net ** ** Copyright (C) The Research Foundation of SUNY, 1999-2001 ** ** 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. ** ** */ :- compiler_options([xpp_on]). #include "flora_terms.flh" #include "flora_porting.flh" #include "flora_exceptions.flh" :- import append/3 from basics. :- import flora_fdb_storage_name/2, flora_check_module_name/1, flora_decode_module_name/2, flora_is_flogic_wrapper/3, flora_setup_flogic_fact_wrapper/1, flora_flogic_fact_wrapper/2 from flrwrapper. :- import flora_list2conjunct/2 from flrutils. :- import flora_storage_check_module_name/1, flora_storage_check_deletepredicate/2, flora_storage_convertlist/3, flora_storage_is_negation_symbol/1, flora_storage_check_existence/1 from flrstorageutils. :- import flora_db_insert_base_bt/2, flora_db_delete_base_bt/2, flora_db_find_base/2 from flrstoragebase. :- import get_canonical_form/2, convert_to_head_literal/2 from flrcanon. :- import flora_refresh_tables/1 from flrtables. :- import flora_abort/0, flora_abort/1 from flrutils. :- import flora_decode_goal_as_atom/2 from flrdecode. /********************************************************************* This file is for the following backtrackable FLORA database operations: btinsert, btinsertall, btdelete, btdeleteall, bterase, bteraseall. *********************************************************************/ /***************************************************************************** fllibbtinsert(+List) *****************************************************************************/ FLLIBBTINSERT(List) :- FLLIBBTINSERT(List,true). /***************************************************************************** fllibbtinsert(+List,+Condition) *****************************************************************************/ FLLIBBTINSERT(List,Condition) :- call(Condition), flora_storage_insertfacts_bt(List). /***************************************************************************** flora_storage_insertfacts_bt(+List) *****************************************************************************/ flora_storage_insertfacts_bt([]) :- !. flora_storage_insertfacts_bt([P|_T]) :- var(P), !, flora_abort('Uninstantiated argument in btinsert{...}'). flora_storage_insertfacts_bt([FLSYSDBUPDATE(P,StorageName,Module)|T]) :- !, flora_storage_check_existence(Module), flora_internal_db_insert_bt(StorageName,P), flora_storage_insertfacts_bt(T). flora_storage_insertfacts_bt([FLLIBMODLIT(F,Args,ModuleName)|T]) :- !, flora_storage_check_module_name(ModuleName), get_canonical_form(FLLIBMODLIT(F,Args,ModuleName), (_,_,_,P)), flora_fdb_storage_name(ModuleName,StorageName), flora_internal_db_insert_bt(StorageName,P), flora_storage_insertfacts_bt(T). flora_storage_insertfacts_bt([FLLIBMODOBJ(F,Args,ModuleName,O)|T]) :- !, flora_check_module_name(ModuleName), FLLIBMODOBJ(F,Args,ModuleName,O), flora_storage_insertfacts_bt(T). flora_storage_insertfacts_bt([','(C1,C2)|T]) :- !, %% Break up conjunction, although insertion of conjunction is not %% allowed in XSB. flora_storage_insertfacts_bt([C1,C2|T]). flora_storage_insertfacts_bt([P|T]) :- %% This is a meta programming feature, since a variable can appear %% in the list of literals to be updated. functor(P,F,N), ( flora_decode_module_name(P,ModuleName) -> flora_storage_check_module_name(ModuleName), flora_fdb_storage_name(ModuleName,StorageName), convert_to_head_literal(P,HeadP), flora_internal_db_insert_bt(StorageName,HeadP), flora_storage_insertfacts_bt(T) ; N == 2, F == ';' -> flora_decode_goal_as_atom(P,PA), flora_abort(['Insertion of disjunctive information is not allowed, ', PA]) ; N == 1, flora_storage_is_negation_symbol(F) -> flora_decode_goal_as_atom(P,PA), flora_abort(['Insertion of negative information is not allowed, ', PA]) ; flora_decode_goal_as_atom(P,PA), ( F == WRAP_HILOG -> flora_abort(['Attempt to insert a HiLog term (non-fact), ', PA]) ; flora_abort(['Attempt to insert a Prolog term (non-fact), ', PA]) ) ). /***************************************************************************** fllibbtinsertall(+List) *****************************************************************************/ FLLIBBTINSERTALL(List) :- FLLIBBTINSERT(List). /***************************************************************************** fllibbtinsertall(+List,+Condition) *****************************************************************************/ FLLIBBTINSERTALL(List,Condition) :- findall(List,Condition,FsList), !, flora_btinsertall_facts(FsList). /***************************************************************************** flora_btinsertall_facts(+FactsList) Note: This predicate always succeeds. *****************************************************************************/ flora_btinsertall_facts([]) :- !. flora_btinsertall_facts([Fs|FL]) :- flora_storage_insertfacts_bt(Fs), flora_btinsertall_facts(FL). /***************************************************************************** fllibbtdelete(+List) *****************************************************************************/ FLLIBBTDELETE(List) :- FLLIBBTDELETE(List,true). /***************************************************************************** fllibbtdelete(+List,+Condition) The semantics is such that all the literals in "List" must be base facts in the storage to be deleted. *****************************************************************************/ FLLIBBTDELETE([P],true) :- var(P), !, flora_abort('Uninstantiated argument in btdelete{...}'). FLLIBBTDELETE([FLSYSDBUPDATE(P,StorageName,Module)],true) :- !, flora_storage_check_existence(Module), flora_db_find_base(StorageName,P), flora_internal_db_delete_bt(StorageName,P). FLLIBBTDELETE([FLLIBMODLIT(F,Args,ModuleName)],true) :- !, flora_storage_check_module_name(ModuleName), get_canonical_form(FLLIBMODLIT(F,Args,ModuleName), (_,_,_,P)), flora_fdb_storage_name(ModuleName,StorageName), !, flora_db_find_base(StorageName,P), flora_internal_db_delete_bt(StorageName,P). FLLIBBTDELETE(List,Condition) :- flora_storage_convertlist(List,CallList,FactList), flora_list2conjunct([Condition|CallList],Goal), !, call(Goal), flora_storage_deletelist_bt(FactList). /***************************************************************************** flora_storage_deletelist_bt(+List) *****************************************************************************/ flora_storage_deletelist_bt([]) :- !. flora_storage_deletelist_bt([FLSYSDBUPDATE(P,StorageName)|L]) :- !, convert_to_head_literal(P,HeadP), flora_internal_db_delete_bt(StorageName,HeadP), flora_storage_deletelist_bt(L). flora_storage_deletelist_bt([H|L]) :- !, flora_storage_deletelist_bt(H), flora_storage_deletelist_bt(L). /***************************************************************************** flora_storage_deleteall_bt(+Predicate,+StorageName) Note: This predicate always succeeds. *****************************************************************************/ flora_storage_deleteall_bt(P,StorageName) :- findall(FLSYSDBUPDATE(P,StorageName),flora_db_find_base(StorageName,P),L), !, flora_storage_deletelist_bt(L). /***************************************************************************** fllibbtdeleteall(+List) *****************************************************************************/ FLLIBBTDELETEALL(List) :- FLLIBBTDELETEALL(List,true). /***************************************************************************** fllibbtdeleteall(+List,+Condition) The semantics is such that all the literals in "List" must be base facts in the storage to be deleted. This call always succeeds. *****************************************************************************/ FLLIBBTDELETEALL([P],true) :- var(P), !, flora_abort('Uninstantiated argument in btdeleteall{...}'). FLLIBBTDELETEALL([FLSYSDBUPDATE(P,StorageName,Module)],true) :- !, flora_storage_check_existence(Module), flora_storage_deleteall_bt(P,StorageName). FLLIBBTDELETEALL([FLLIBMODLIT(F,Args,ModuleName)],true) :- !, flora_storage_check_module_name(ModuleName), get_canonical_form(FLLIBMODLIT(F,Args,ModuleName), (_,_,_,P)), flora_fdb_storage_name(ModuleName,StorageName), !, flora_storage_deleteall_bt(P,StorageName). FLLIBBTDELETEALL(List,Condition) :- flora_storage_convertlist(List,CallList,FactList), flora_list2conjunct([Condition|CallList],Goal), findall(FactList,Goal,FsList), !, flora_btdeleteall_facts(FsList). /***************************************************************************** flora_btdeleteall_facts(+FactList,-DeletedFactList) Note: This predicate always succeeds. *****************************************************************************/ flora_btdeleteall_facts([]) :- !. flora_btdeleteall_facts([Fs|FL]) :- flora_storage_deletelist_bt(Fs), flora_btdeleteall_facts(FL). /***************************************************************************** fllibbterase(+List) *****************************************************************************/ FLLIBBTERASE(List) :- FLLIBBTERASE(List,true). /***************************************************************************** fllibbterase(+List,+Condition) *****************************************************************************/ FLLIBBTERASE(List,Condition) :- flora_storage_convertlist(List,CallList,FactList), flora_list2conjunct([Condition|CallList],Goal), call(Goal), flora_storage_deletelist_bt(FactList), flora_bterase_facts(FactList). /***************************************************************************** flora_bterase_facts(+List) *****************************************************************************/ flora_bterase_facts([]) :- !. flora_bterase_facts([FLSYSDBUPDATE(P,StorageName)|Fs]) :- !, flora_bterase_one_fact(P,StorageName), flora_bterase_facts(Fs). flora_bterase_facts([H|Fs]) :- !, flora_bterase_facts(H), flora_bterase_facts(Fs). /***************************************************************************** flora_bterase_one_fact(+Fact,+StorageName) Note: For an F-logic fact this predicate continues to trace links and delete other F-logic facts. It always succeeds. Works for Flora user modules and system modules. *****************************************************************************/ flora_bterase_one_fact(Fact,StorageName) :- Fact =.. [Funct|Args], ( flora_is_flogic_wrapper(Funct,ModuleName,Base) -> ( Base == WRAP_ISA -> Args=[O,_C] ; Base == WRAP_SUB -> Args=[O,_C] ; Base == WRAP_FD -> Args=[_S,_A,O] ; Base == WRAP_MVD -> Args=[_S,_A,O] ; Base == WRAP_IFD -> Args=[_S,_IA,O] ; Base == WRAP_IMVD -> Args=[_S,_IA,O] ; Base == WRAP_METH -> Args=[O,_M] ; Base == WRAP_IMETH -> Args=[O,_IM] ; Base == WRAP_EXISTS -> Args=[O] ; Base == WRAP_MVDDEF -> Args=[O,_A] ; Base == WRAP_IMVDDEF -> Args=[O,_IA] ; Base == WRAP_TRAN -> Args=[O,_T] ; Base == WRAP_FDSIG -> Args=[_S,_AS,O] ; Base == WRAP_IFDSIG -> Args=[_S,_IAS,O] ; Base == WRAP_MVDSIG -> Args=[_S,_AS,O] ; Base == WRAP_IMVDSIG -> Args=[_S,_IAS,O] ) ; true ), !, ( var(O) -> true ; flora_setup_flogic_fact_wrapper(ModuleName), flora_bterase_objects([O],StorageName) ). /***************************************************************************** flora_bterase_objects(+ObjectList,+StorageName) *****************************************************************************/ flora_bterase_objects([],_StorageName) :- !. flora_bterase_objects([O|OList],StorageName) :- !, flora_flogic_fact_wrapper(WRAP_ISA,WSBisa), flora_flogic_fact_wrapper(WRAP_SUB,WSBsub), flora_flogic_fact_wrapper(WRAP_METH,WSBmeth), flora_flogic_fact_wrapper(WRAP_IMETH,WSBimeth), flora_flogic_fact_wrapper(WRAP_TRAN,WSBtran), flora_flogic_fact_wrapper(WRAP_FD,WSBfd), flora_flogic_fact_wrapper(WRAP_IFD,WSBifd), flora_flogic_fact_wrapper(WRAP_FDSIG,WSBfdsig), flora_flogic_fact_wrapper(WRAP_IFDSIG,WSBifdsig), flora_flogic_fact_wrapper(WRAP_MVD,WSBmvd), flora_flogic_fact_wrapper(WRAP_IMVD,WSBimvd), flora_flogic_fact_wrapper(WRAP_MVDSIG,WSBmvdsig), flora_flogic_fact_wrapper(WRAP_IMVDSIG,WSBimvdsig), flora_flogic_fact_wrapper(WRAP_EXISTS,WSBexists), flora_flogic_fact_wrapper(WRAP_MVDDEF,WSBmvddef), flora_flogic_fact_wrapper(WRAP_IMVDDEF,WSBimvddef), Wfd =.. [WSBfd,O,_,X], Wifd =.. [WSBifd,O,_,X], Wfdsig =.. [WSBfdsig,O,_,X], Wifdsig =.. [WSBifdsig,O,_,X], Wmvd =.. [WSBmvd,O,_,X], Wimvd =.. [WSBimvd,O,_,X], Wmvdsig =.. [WSBmvdsig,O,_,X], Wimvdsig =.. [WSBimvdsig,O,_,X], findall(X,( flora_db_find_base(StorageName,Wfd) ; flora_db_find_base(StorageName,Wifd) ; flora_db_find_base(StorageName,Wfdsig) ; flora_db_find_base(StorageName,Wifdsig) ; flora_db_find_base(StorageName,Wmvd) ; flora_db_find_base(StorageName,Wimvd) ; flora_db_find_base(StorageName,Wmvdsig) ; flora_db_find_base(StorageName,Wimvdsig) ), AddedOList ), append(OList,AddedOList,NewOList), sort(NewOList,NextOList), Pisa =.. [WSBisa,O,_], Psub =.. [WSBsub,O,_], Pmeth =.. [WSBmeth,O,_], Pimeth =.. [WSBimeth,O,_], Ptran =.. [WSBtran,O,_], Pfd =.. [WSBfd,O,_,_], Pifd =.. [WSBifd,O,_,_], Pfdsig =.. [WSBfdsig,O,_,_], Pifdsig =.. [WSBifdsig,O,_,_], Pmvd =.. [WSBmvd,O,_,_], Pimvd =.. [WSBimvd,O,_,_], Pmvdsig =.. [WSBmvdsig,O,_,_], Pimvdsig =.. [WSBimvdsig,O,_,_], Pexists =.. [WSBexists,O], Pmvddef =.. [WSBmvddef,O,_], Pimvddef =.. [WSBimvddef,O,_], !, flora_storage_deleteall_bt(Pisa,StorageName), flora_storage_deleteall_bt(Psub,StorageName), flora_storage_deleteall_bt(Pmeth,StorageName), flora_storage_deleteall_bt(Pimeth,StorageName), flora_storage_deleteall_bt(Ptran,StorageName), flora_storage_deleteall_bt(Pfd,StorageName), flora_storage_deleteall_bt(Pifd,StorageName), flora_storage_deleteall_bt(Pfdsig,StorageName), flora_storage_deleteall_bt(Pifdsig,StorageName), flora_storage_deleteall_bt(Pmvd,StorageName), flora_storage_deleteall_bt(Pimvd,StorageName), flora_storage_deleteall_bt(Pmvdsig,StorageName), flora_storage_deleteall_bt(Pimvdsig,StorageName), flora_storage_deleteall_bt(Pexists,StorageName), flora_storage_deleteall_bt(Pmvddef,StorageName), flora_storage_deleteall_bt(Pimvddef,StorageName), flora_bterase_objects(NextOList,StorageName). /***************************************************************************** fllibbteraseall(+List) *****************************************************************************/ FLLIBBTERASEALL(List) :- FLLIBBTERASEALL(List,true). /***************************************************************************** fllibbteraseall(+List,+Condition) *****************************************************************************/ FLLIBBTERASEALL(List,Condition) :- flora_storage_convertlist(List,CallList,FactList), flora_list2conjunct([Condition|CallList],Goal), findall(FactList,Goal,FsList), !, flora_btdeleteall_facts(FsList), flora_bteraseall_facts(FsList). /***************************************************************************** flora_bteraseall_facts(+FactList) Note: This predicate always succeeds. *****************************************************************************/ flora_bteraseall_facts([]) :- !. flora_bteraseall_facts([Fs|FL]) :- !, flora_bterase_facts(Fs), flora_bteraseall_facts(FL). flora_internal_db_insert_bt(StorageName,Call) :- flora_db_insert_base_bt(StorageName,Call), flora_refresh_tables(Call). flora_internal_db_delete_bt(StorageName,Call) :- flora_db_delete_base_bt(StorageName,Call), flora_refresh_tables(Call).