/* File: flrstoragebase.P - access to base facts ** ** Author(s): Michael Kifer ** ** 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. ** ** */ %% This file exists in order to isolate Flora's access to base facts %% and make it possible to easily switch the access methods :- compiler_options([xpp_on]). #include "flora_terms.flh" #include "flora_porting.flh" :- export flora_db_insert_base/2, flora_db_delete_base/2, flora_db_insert_base_bt/2, flora_db_delete_base_bt/2, flora_db_find_base/2, flora_db_commit/1, flora_db_reclaim_space/1. #define FLORA_USE_TRIES #ifdef FLORA_USE_TRIES :- import storage_find_fact/2, storage_insert_fact/3, storage_delete_fact/3, storage_insert_fact_bt/3, storage_delete_fact_bt/3, storage_commit/1, storage_reclaim_space/1 from storage. flora_db_insert_base(StorageName,Call) :- storage_insert_fact(StorageName,Call,_ResultFlag). flora_db_delete_base(StorageName,Call) :- storage_delete_fact(StorageName,Call,_ResultFlag). flora_db_insert_base_bt(StorageName,Call) :- storage_insert_fact_bt(StorageName,Call,_ResultFlag). flora_db_delete_base_bt(StorageName,Call) :- storage_delete_fact_bt(StorageName,Call,_ResultFlag). flora_db_find_base(StorageName,Call) :- storage_find_fact(StorageName,Call). flora_db_commit(StorageName) :- storage_commit(StorageName). flora_db_reclaim_space(StorageName) :- storage_reclaim_space(StorageName). #else %% Here we need to implement backtrackable updates using assert and retract_nr #include "storage_xsb_defs.h" #include "builtin.h" storage_builtin(_BuiltinNumber,_StorageName,_Handle,_Snapshot,_Changed) :- '_$builtin'(STORAGE_BUILTIN). %% Inserts facts. On backtracking, the fact is deleted. storage_insert_fact_bt(StorageName,Fact,Inserted) :- triehandle_for_storage(StorageName,H,Snapshot), trie_intern(Fact, H, Leaf, New, _), (New == 0 -> Inserted=1, % new fact inserted mark_storage_changed_bt(StorageName), ( true ; %% On backtracking triehandle_for_storage(StorageName,_,NewSnapshot), (NewSnapshot =< Snapshot -> trie_unintern_nr(H, Leaf), fail ) ) ; Inserted=0 % fact was already there: no action ). %% Nonbacktrackable insert storage_insert_fact(StorageName,Fact,Inserted) :- triehandle_for_storage(StorageName,H,_), trie_intern(Fact, H, _Leaf, New, _), (New == 0 -> Inserted=1 % new fact inserted ; Inserted=0 % fact was already there: no action ). %% Backtrackable delete. %% Doesn't remove anything, but instead "marks" for deletion. %% On backtracking: unmarks facts that are marked for deletion storage_delete_fact_bt(StorageName,Fact,Deleted) :- triehandle_for_storage(StorageName,H,Snapshot), (trie_interned(Fact, H, Leaf, _) -> Deleted=1, % existing fact deleted mark_storage_changed_bt(StorageName), ( trie_unintern_nr(H, Leaf) ; %% On backtracking triehandle_for_storage(StorageName,_,NewSnapshot), (NewSnapshot =< Snapshot -> unmark_uninterned_nr(H, Leaf), fail ) ) ; Deleted=0 % non-existing fact: no action ). %% Nonbacktrackable delete storage_delete_fact(StorageName,Fact,Deleted) :- triehandle_for_storage(StorageName,H,_), (trie_interned(Fact, H, Leaf, _) -> Deleted=1, % existing fact deleted trie_unintern_nr(H, Leaf) ; Deleted=0 % non-existing fact: no action ). %% deletes the whole trie storage_delete_all(StorageName) :- triehandle_for_storage(StorageName,H,_), storage_builtin(DESTROY_STORAGE_HANDLE,StorageName,_,_,_), delete_trie(H). %% Find fact in storage storage_find_fact(StorageName,Fact) :- triehandle_for_storage(StorageName,H,_), trie_interned(Fact, H, _, _). %% Commit changes to the storage trie associated with StorageName %% (only if storage has been changed) storage_commit(StorageName) :- ( storage_builtin(INCREMENT_STORAGE_SNAPSHOT,StorageName,_,_,_), ! %% don't backtrack over it ; fail ). %% Reclaims space by removing nodes from the backtrackable insert/keypair trie %% which were marked for deletion. This should be done only at the top %% level of a query. storage_reclaim_space(StorageName) :- triehandle_for_storage(StorageName,H,_), trie_reclaim_uninterned_nr(H). %% Create a new trie or use an existing one %% that is already saved as a property of StorageName triehandle_for_storage(StorageName,Handle,Snapshot) :- storage_builtin(GET_STORAGE_HANDLE,StorageName,Handle,Snapshot,_). %% This one seems no longer used. Check!!! mark_storage_changed_bt(StorageName) :- storage_builtin(MARK_STORAGE_CHANGED,StorageName,_,_,_). #endif