35
36:- module(increval,
37 [ incr_assert/1, 38 incr_asserta/1, 39 incr_assertz/1, 40 incr_retractall/1, 41 incr_retract/1, 42
43 is_incremental_subgoal/1, 44 incr_directly_depends/2, 45 incr_trans_depends/2, 46 incr_invalid_subgoals/1, 47 incr_is_invalid/1, 48
49 incr_invalidate_call/1, 50 incr_invalidate_calls/1, 51 incr_table_update/0,
52
53 incr_propagate_calls/1 54 ]). 55:- use_module(library(tables)).
72:- meta_predicate
73 incr_assert(:),
74 incr_asserta(:),
75 incr_assertz(:),
76 incr_retractall(:),
77 incr_retract(:),
78 is_incremental_subgoal(:),
79 incr_directly_depends(:,:),
80 incr_trans_depends(:, :),
81 incr_is_invalid(:),
82 incr_invalidate_call(:),
83 incr_invalidate_calls(:),
84 incr_propagate_calls(:). 85
86incr_assert(T) :- assertz(T).
87incr_asserta(T) :- asserta(T).
88incr_assertz(T) :- assertz(T).
89incr_retractall(T) :- retractall(T).
90incr_retract(T) :- retract(T).
97is_incremental_subgoal(SubGoal) :-
98 '$tbl_variant_table'(VTrie),
99 trie_gen(VTrie, SubGoal, ATrie),
100 ( '$idg_edge'(ATrie, _Dir, _Value)
101 -> true
102 ).
111incr_directly_depends(Goal1, Goal2) :-
112 '$tbl_variant_table'(VTrie),
113 ( nonvar(Goal2)
114 -> trie_gen(VTrie, Goal2, ATrie2),
115 '$idg_edge'(ATrie2, affected, ATrie1),
116 '$tbl_table_status'(ATrie1, _Status, Goal1, _Return)
117 ; trie_gen(VTrie, Goal1, ATrie1),
118 '$idg_edge'(ATrie1, dependent, ATrie2),
119 '$tbl_table_status'(ATrie2, _Status, Goal2, _Return)
120 ).
127incr_trans_depends(Goal1, Goal2) :-
128 '$tbl_variant_table'(VTrie),
129 ( nonvar(Goal1)
130 -> trie_gen(VTrie, Goal1, ATrie1),
131 incr_trans_depends(ATrie1, dependent, ATrie2, []),
132 '$tbl_table_status'(ATrie2, _Status, Goal2, _Return)
133 ; trie_gen(VTrie, Goal2, ATrie2),
134 incr_trans_depends(ATrie2, affected, ATrie1, []),
135 '$tbl_table_status'(ATrie1, _Status, Goal1, _Return)
136 ).
137
138incr_trans_depends(ATrie1, Dir, ATrie, Done) :-
139 '$idg_edge'(ATrie1, Dir, ATrie2),
140 \+ memberchk(ATrie2, Done),
141 ( ATrie = ATrie2
142 ; incr_trans_depends(ATrie2, Dir, ATrie, [ATrie2|Done])
143 ).
150incr_invalid_subgoals(List) :-
151 findall(Invalid, invalid_subgoal(Invalid, _), List0),
152 sort(List0, List).
153
154invalid_subgoal(Goal, ATrie) :-
155 '$tbl_variant_table'(VTrie),
156 trie_gen(VTrie, Goal, ATrie),
157 ( '$idg_edge'(ATrie, _Dir, _Value)
158 -> true
159 ),
160 '$idg_falsecount'(ATrie, Count),
161 Count > 0,
162 \+ '$tbl_table_status'(ATrie, dynamic, _Goal, _Return).
168incr_is_invalid(Subgoal) :-
169 get_calls(Subgoal, Table, _Return),
170 '$idg_falsecount'(Table, Count),
171 Count > 0.
178incr_invalidate_calls(Goal) :-
179 '$tbl_variant_table'(VTable),
180 !,
181 forall(trie_gen(VTable, Goal, ATrie),
182 '$idg_changed'(ATrie)).
183incr_invalidate_calls(_).
192incr_invalidate_call(Goal) :-
193 incr_invalidate_calls(Goal).
199incr_table_update :-
200 repeat,
201 ( invalid_subgoal(Goal, ATrie)
202 -> '$tabling':reeval(ATrie, Goal, _Return),
203 fail
204 ; !
205 ).
213incr_propagate_calls(Answer) :-
214 setup_call_cleanup(
215 '$tbl_propagate_start'(Old),
216 '$tabling':incr_propagate_assert(Answer),
217 '$tbl_propagate_end'(Old))
Incremental dynamic predicate modification
This module emulates the XSB module
increval
. This module serves two goals: (1) provide alternatives for the dynamic clause manipulation predicates that propagate into the incremental tables and (2) query the dynamically maintained Incremental Depency Graph (IDG).The change propagation for incremental dynamic predicates. SWI-Prolog relies in prolog_listen/2 to forward any change to dynamic predicates to the table IDG and incr_assert/1 and friends thus simply call the corresponding database update.