1/* Part of SWI-Prolog 2 3 Author: Jan Wielemaker 4 E-mail: J.Wielemaker@vu.nl 5 WWW: http://www.swi-prolog.org 6 Copyright (c) 2019-2020, VU University Amsterdam 7 CWI, Amsterdam 8 All rights reserved. 9 10 Redistribution and use in source and binary forms, with or without 11 modification, are permitted provided that the following conditions 12 are met: 13 14 1. Redistributions of source code must retain the above copyright 15 notice, this list of conditions and the following disclaimer. 16 17 2. Redistributions in binary form must reproduce the above copyright 18 notice, this list of conditions and the following disclaimer in 19 the documentation and/or other materials provided with the 20 distribution. 21 22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 POSSIBILITY OF SUCH DAMAGE. 34*/ 35 36:- module(tables, 37 [ abolish_all_tables/0, 38 abolish_module_tables/1, % +Module 39 abolish_table_pred/1, % :CallableOrPI 40 abolish_table_call/1, % :Callable 41 abolish_table_call/2, % :Callable, +Options 42 abolish_table_subgoals/2, % :Callable, +Options 43 44 tfindall/3, % +Template, :Goal, -Answers 45 't not'/1, % :Goal 46 47 get_call/3, % :CallTerm, -AnswerTrie, -Templ 48 get_calls/3, % :CallTerm, -AnswerTrie, -Templ 49 get_returns/2, % +AnswerTrie, -Return 50 get_returns/3, % +AnswerTrie, -Return, -NodeID 51 get_returns_and_dls/3, % +AnswerTrie, -Return, -DL 52 get_returns_and_tvs/3, % +AnswerTrie, -Return, -TVs 53 get_returns_for_call/2, % :CallTerm, ?AnswerTerm 54 get_residual/2, % :CallTerm, -DelayList 55 56 set_pil_on/0, 57 set_pil_off/0, 58 59 op(900, fy, tnot) 60 ]). 61:- autoload(library(apply), [maplist/3]). 62:- autoload(library(error), [type_error/2, must_be/2, domain_error/2]). 63:- autoload(library(lists), [append/3]).
73:- meta_predicate
74 abolish_table_pred( ),
75 abolish_table_call( ),
76 abolish_table_call( , ),
77 abolish_table_subgoals( , ),
78 tfindall( , , ),
79 't not'( ),
80 get_call( , , ),
81 get_calls( , , ),
82 get_returns_for_call( , ),
83 get_returns_and_dls( , , ),
84 get_residual( , ).
92't not'(Goal) :-
93 tnot(Goal).
104tfindall(Template, Goal, Answers) :-
105 findall(Template, Goal, Answers).
114set_pil_on. 115set_pil_off.
124get_call(Goal0, Trie, Return) :- 125 '$tbl_implementation'(Goal0, M:Goal), 126 M:'$table_mode'(Goal, Table, Moded), 127 current_table(M:Goal, Trie), 128 '$tbl_table_status'(Trie, _Status, M:Table, Skeleton), 129 extend_return(Moded, Skeleton, Return). 130 131extend_return(Moded, Skeleton, Return) :- 132 '$tbl_trienode'(Reserved), 133 Moded == Reserved, 134 !, 135 Return = Skeleton. 136extend_return(Moded, Skeleton, Return) :- 137 var(Moded), 138 !, 139 Skeleton =.. [ret|Args0], 140 append(Args0, [Moded], Args), 141 Return =.. [ret|Args]. 142extend_return(Moded, Skeleton, Return) :- 143 Moded =.. [_|Extra], 144 Skeleton =.. [ret|Args0], 145 append(Args0, Extra, Args), 146 Return =.. [ret|Args].
154get_calls(Goal0, Trie, Return) :-
155 '$tbl_variant_table'(VariantTrie),
156 '$tbl_implementation'(Goal0, M:Goal),
157 M:'$table_mode'(Goal, Table, Moded),
158 trie_gen(VariantTrie, M:Table, Trie),
159 '$tbl_table_status'(Trie, _Status, M:Table, Skeleton),
160 extend_return(Moded, Skeleton, Return).
168get_returns(ATrie, Return) :- 169 '$tbl_table_status'(ATrie, _Status, M:Table, Skeleton), 170 M:'$table_mode'(_Goal, Table, Moded), 171 '$tbl_trienode'(Reserved), 172 Moded \== Reserved, 173 !, 174 extend_return(Moded, Skeleton, Return), 175 '$tabling':moded_gen_answer(ATrie, Skeleton, Moded). 176get_returns(ATrie, Return) :- 177 trie_gen(ATrie, Return).
186get_returns(AnswerTrie, Return, NodeID) :-
187 '$trie_gen_node'(AnswerTrie, Return, NodeID).
t
if the answer is
unconditional and to u
if it is conditional. If a conditional
answer has multiple delay lists, this predicate will succeed only
once, so that using this predicate may be more efficient than
get_residual/2 (although less informative)198get_returns_and_tvs(ATrie, Return, TruthValue) :- 199 '$tbl_table_status'(ATrie, _Status, M:Table, Skeleton), 200 M:'$table_mode'(_Goal, Table, Moded), 201 '$tbl_trienode'(Reserved), 202 Moded \== Reserved, 203 !, 204 extend_return(Moded, Skeleton, Return), 205 trie_gen(ATrie, Skeleton), 206 '$tbl_answer_dl'(ATrie, Skeleton, Moded, AN), 207 ( AN == true 208 -> TruthValue = t 209 ; TruthValue = u 210 ). 211get_returns_and_tvs(AnswerTrie, Return, TruthValue) :- 212 '$tbl_answer_dl'(AnswerTrie, Return, AN), 213 ( AN == true 214 -> TruthValue = t 215 ; TruthValue = u 216 ).
224get_returns_and_dls(AnswerTrie, Return, M:DelayLists) :- 225 '$tbl_answer'(AnswerTrie, Return, Condition), 226 condition_delay_lists(Condition, M, DelayLists). 227 228condition_delay_lists(true, _, []) :- 229 !. 230condition_delay_lists((A;B), M, List) :- 231 !, 232 phrase(semicolon_list((A;B)), L0), 233 maplist(conj_list(M), L0, List). 234condition_delay_lists(One, M, [List]) :- 235 conj_list(M, One, List). 236 237semicolon_list((A;B)) --> 238 !, 239 semicolon_list(A), 240 semicolon_list(B). 241semicolon_list(G) --> 242 [G].
The delay condition is a disjunction of conjunctions and is
represented as such in the native SWI-Prolog interface as a nested
term of ;/2 and ,/2, using true
if the answer is unconditional.
This XSB predicate returns the associated conjunctions
non-deterministically as a list.
See also call_residual_program/2 from library(wfs).
260get_residual(Goal0, DelayList) :- 261 '$tbl_implementation'(Goal0, Goal), 262 Goal = M:Head, 263 '$tbl_trienode'(Reserved), 264 M:'$table_mode'(Head, Variant, Moded), 265 '$tbl_variant_table'(VariantTrie), 266 trie_gen(VariantTrie, M:Variant, Trie), 267 '$tbl_table_status'(Trie, _Status, M:Variant, Skeleton), 268 ( Reserved == Moded 269 -> '$tbl_answer'(Trie, Skeleton, Condition) 270 ; '$tbl_answer'(Trie, Skeleton, Moded, Condition) 271 ), 272 condition_delay_list(Condition, M, DelayList). 273 274condition_delay_list(true, _, List) :- 275 !, 276 List = []. 277condition_delay_list((A;B), M, List) :- 278 !, 279 ( condition_delay_list(A, M, List) 280 ; condition_delay_list(B, M, List) 281 ). 282condition_delay_list(Conj, M, List) :- 283 !, 284 conj_list(M, Conj, List). 285 286conj_list(M, Conj, List) :- 287 phrase(comma_list(Conj, M), List). 288 289comma_list((A,B), M) --> 290 !, 291 comma_list(A, M), 292 comma_list(B, M). 293comma_list(M:G, M) --> 294 !, 295 [G]. 296comma_list(tnot(M:G), M) --> 297 !, 298 [tnot(G)]. 299comma_list(system:G, _) --> 300 !, 301 [G]. 302comma_list(G, _) --> 303 [G].
310get_returns_for_call(CallTerm, M:AnswerTerm) :- 311 current_table(CallTerm, Trie), 312 '$tbl_table_status'(Trie, _Status, Q:AnswerTerm0, Skeleton), 313 ( Q == M 314 -> AnswerTerm = AnswerTerm0 315 ; AnswerTerm = Q:AnswerTerm0 316 ), 317 '$tbl_answer_update_dl'(Trie, Skeleton). 318 319 320 /******************************* 321 * TABLES * 322 *******************************/
334abolish_table_pred(M:Name/Arity) :- 335 !, 336 functor(Head, Name, Arity), 337 abolish_table_subgoals(M:Head). 338abolish_table_pred(M:Head) :- 339 callable(Head), 340 !, 341 functor(Head, Name, Arity), 342 functor(Generic, Name, Arity), 343 abolish_table_subgoals(M:Generic). 344abolish_table_pred(PI) :- 345 type_error(callable_or_predicate_indicator, PI).
354abolish_table_call(Head) :- 355 abolish_table_subgoals(Head). 356 357abolish_table_call(Head, Options) :- 358 abolish_table_subgoals(Head, Options).
table_gc_action
to be over-ridden with a flag, which can be either
abolish_tables_transitively
or abolish_tables_singly
.
369abolish_table_subgoals(Head, Options) :-
370 must_be(list, Options),
371 ( Options == []
372 -> abolish_table_subgoals(Head)
373 ; memberchk(abolish_tables_transitively, Options)
374 -> abolish_table_subgoals(Head)
375 ; memberchk(abolish_tables_singly, Options)
376 -> abolish_table_subgoals(Head)
377 ; domain_error([abolish_tables_transitively,abolish_tables_singly], Options)
378 )
XSB interface to tables
This module provides an XSB compatible library to access tables as created by tabling (see table/1). The aim of this library is first of all compatibility with XSB. This library contains some old and internal XSB predicates that are marked deprecated. */