224 lines
5.7 KiB
Plaintext
224 lines
5.7 KiB
Plaintext
|
/*
|
||
|
Deterministcally table a predicate of the form
|
||
|
K -> RV
|
||
|
|
||
|
where the K are the first N-1 arguments.
|
||
|
|
||
|
Note that this does not include support for backtracking
|
||
|
*/
|
||
|
|
||
|
:- module(clpbn_table,
|
||
|
[clpbn_table/1,
|
||
|
clpbn_tabled_clause/2,
|
||
|
clpbn_tabled_abolish/1,
|
||
|
clpbn_tabled_asserta/1,
|
||
|
clpbn_tabled_assertz/1,
|
||
|
clpbn_tabled_asserta/2,
|
||
|
clpbn_tabled_assertz/2,
|
||
|
clpbn_tabled_dynamic/1,
|
||
|
clpbn_tabled_number_of_clauses/2,
|
||
|
clpbn_reset_tables/0,
|
||
|
clpbn_reset_tables/1,
|
||
|
clpbn_is_tabled/1
|
||
|
]).
|
||
|
|
||
|
:- use_module(library(bhash),
|
||
|
[b_hash_new/2,
|
||
|
b_hash_lookup/3,
|
||
|
b_hash_insert/3]).
|
||
|
|
||
|
:- meta_predicate clpbn_table(:),
|
||
|
clpbn_tabled_clause(:.?),
|
||
|
clpbn_tabled_abolish(:),
|
||
|
clpbn_tabled_asserta(:),
|
||
|
clpbn_tabled_assertz(:),
|
||
|
clpbn_tabled_asserta(:,-),
|
||
|
clpbn_tabled_assertz(:,-),
|
||
|
clpbn_tabled_number_of_clauses(:,-),
|
||
|
clpbn_is_tabled(:).
|
||
|
|
||
|
:- dynamic clpbn_table/3.
|
||
|
|
||
|
:- initialization(init).
|
||
|
|
||
|
init :-
|
||
|
clpbn_reset_tables.
|
||
|
|
||
|
clpbn_reset_tables :-
|
||
|
clpbn_reset_tables(1024).
|
||
|
|
||
|
clpbn_reset_tables(Sz) :-
|
||
|
b_hash_new(Tab, Sz),
|
||
|
nb_setval(clpbn_tables, Tab).
|
||
|
|
||
|
clpbn_table(M:X) :- !,
|
||
|
clpbn_table(X,M).
|
||
|
clpbn_table(X) :-
|
||
|
prolog_load_context(module, M),
|
||
|
clpbn_table(X,M).
|
||
|
|
||
|
clpbn_table(M:X,_) :- !,
|
||
|
clpbn_table(X,M).
|
||
|
clpbn_table((P1,P2),M) :- !,
|
||
|
clpbn_table(P1,M),
|
||
|
clpbn_table(P2,M).
|
||
|
clpbn_table(F/N,M) :-
|
||
|
functor(S,F,N),
|
||
|
S =.. L0,
|
||
|
take_tail(L0, V, L1, V1, L2),
|
||
|
Key =.. L1,
|
||
|
atom_concat(F, '___tabled', NF),
|
||
|
L2 = [_|Args],
|
||
|
S1 =.. [NF|Args],
|
||
|
L0 = [_|OArgs],
|
||
|
S2 =.. [NF|OArgs],
|
||
|
asserta(clpbn_table(S, M, S2)),
|
||
|
assert((M:S :- nb_getval(clpbn_tables, Tab), ( b_hash_lookup(Key, V1, Tab) -> true ; M:S1, b_hash_insert(Tab, Key, V1) ; true), ( nonvar(V) -> clpbn_evidence:put_evidence(V, V1) ; V = V1 ), ! ) ).
|
||
|
|
||
|
take_tail([V], V, [], V1, [V1]) :- !.
|
||
|
take_tail([A|L0], V, [A|L1], V1, [A|L2]) :-
|
||
|
take_tail(L0, V, L1, V1, L2).
|
||
|
|
||
|
user:term_expansion((P :- Gs), NC) :-
|
||
|
clpbn_table(P, M, NP),
|
||
|
prolog_load_context(module, M), !,
|
||
|
assert(M:(NP :- Gs)),
|
||
|
NC = (:-true).
|
||
|
|
||
|
in_table(K, V) :-
|
||
|
nb_getval(clpbn_tables, Tab),
|
||
|
b_hash_lookup(K, V, Tab).
|
||
|
|
||
|
store_in_table(K, V) :-
|
||
|
nb_getval(clpbn_tables, Tab),
|
||
|
b_hash_insert(Tab, K, V).
|
||
|
|
||
|
clpbn_tabled_clause(M:Head, Body) :- !,
|
||
|
clpbn_tabled_clause(Head, M, Body).
|
||
|
clpbn_tabled_clause(Head, Body) :-
|
||
|
prolog_load_context(module, M),
|
||
|
clpbn_tabled_clause(Head, M, Body).
|
||
|
|
||
|
clpbn_tabled_clause(M:Head, _, Body) :- !,
|
||
|
clpbn_table(Head, M, Body).
|
||
|
clpbn_tabled_clause(Head, M, Body) :-
|
||
|
clpbn_table(Head, M, THead),
|
||
|
clause(THead, Body).
|
||
|
|
||
|
|
||
|
clpbn_tabled_assertz(M:Clause) :- !,
|
||
|
clpbn_tabled_assertz2(Clause, M).
|
||
|
clpbn_tabled_assertz(Clause) :-
|
||
|
prolog_load_context(module, M),
|
||
|
clpbn_tabled_assertz2(Clause, M).
|
||
|
|
||
|
clpbn_tabled_assertz2(M:Clause, _) :- !,
|
||
|
clpbn_tabled_assertz2(Clause, M).
|
||
|
clpbn_tabled_assertz2((Head:-Body), M) :- !,
|
||
|
clpbn_table(Head, M, THead),
|
||
|
assertz(M:(THead :- Body)).
|
||
|
clpbn_tabled_assertz2(Head, M) :-
|
||
|
clpbn_table(Head, M, THead),
|
||
|
assertz(THead).
|
||
|
|
||
|
clpbn_tabled_assertz(M:Clause, Ref) :- !,
|
||
|
clpbn_tabled_assertz2(Clause, M, Ref).
|
||
|
clpbn_tabled_assertz(Clause, Ref) :-
|
||
|
prolog_load_context(module, M),
|
||
|
clpbn_tabled_assertz2(Clause, M, Ref).
|
||
|
|
||
|
clpbn_tabled_assertz2(M:Clause, _, Ref) :- !,
|
||
|
clpbn_tabled_assertz2(Clause, M, Ref).
|
||
|
clpbn_tabled_assertz2((Head:-Body), M, Ref) :- !,
|
||
|
clpbn_table(Head, M, THead),
|
||
|
assertz(M:(THead :- Body), Ref).
|
||
|
clpbn_tabled_assertz2(Head, M, Ref) :-
|
||
|
clpbn_table(Head, M, THead, Ref),
|
||
|
assertz(THead).
|
||
|
|
||
|
|
||
|
clpbn_tabled_asserta(M:Clause) :- !,
|
||
|
clpbn_tabled_asserta2(Clause, M).
|
||
|
clpbn_tabled_asserta(Clause) :-
|
||
|
prolog_load_context(module, M),
|
||
|
clpbn_tabled_asserta2(Clause, M).
|
||
|
|
||
|
clpbn_tabled_asserta2(M:Clause, _) :- !,
|
||
|
clpbn_tabled_asserta2(Clause, M).
|
||
|
clpbn_tabled_asserta2((Head:-Body), M) :- !,
|
||
|
clpbn_table(Head, M, THead),
|
||
|
asserta(M:(THead :- Body)).
|
||
|
clpbn_tabled_asserta2(Head, M) :-
|
||
|
clpbn_table(Head, M, THead),
|
||
|
asserta(THead).
|
||
|
|
||
|
clpbn_tabled_asserta(M:Clause, Ref) :- !,
|
||
|
clpbn_tabled_asserta2(Clause, M, Ref).
|
||
|
clpbn_tabled_asserta(Clause, Ref) :-
|
||
|
prolog_load_context(module, M),
|
||
|
clpbn_tabled_asserta2(Clause, M, Ref).
|
||
|
|
||
|
clpbn_tabled_asserta2(M:Clause, _, Ref) :- !,
|
||
|
clpbn_tabled_asserta2(Clause, M, Ref).
|
||
|
clpbn_tabled_asserta2((Head:-Body), M, Ref) :- !,
|
||
|
clpbn_table(Head, M, THead),
|
||
|
asserta(M:(THead :- Body), Ref).
|
||
|
clpbn_tabled_asserta2(Head, M, Ref) :-
|
||
|
clpbn_table(Head, M, THead, Ref),
|
||
|
asserta(THead).
|
||
|
|
||
|
|
||
|
clpbn_tabled_abolish(M:Clause) :- !,
|
||
|
clpbn_tabled_abolish(Clause, M).
|
||
|
clpbn_tabled_abolish(Clause) :-
|
||
|
prolog_load_context(module, M),
|
||
|
clpbn_tabled_abolish(Clause, M).
|
||
|
|
||
|
clpbn_tabled_abolish(M:Clause, _) :- !,
|
||
|
clpbn_tabled_abolish(Clause, M).
|
||
|
clpbn_tabled_abolish(N/A, M) :-
|
||
|
functor(Head, N, A),
|
||
|
clpbn_table(Head, M, THead),
|
||
|
functor(THead, TN, A),
|
||
|
abolish(M:TN/A).
|
||
|
|
||
|
clpbn_tabled_dynamic(M:Clause) :- !,
|
||
|
clpbn_tabled_dynamic(Clause, M).
|
||
|
clpbn_tabled_dynamic(Clause) :-
|
||
|
prolog_load_context(module, M),
|
||
|
clpbn_tabled_dynamic(Clause, M).
|
||
|
|
||
|
clpbn_tabled_dynamic(M:Clause, _) :- !,
|
||
|
clpbn_tabled_dynamic(Clause, M).
|
||
|
clpbn_tabled_dynamic(N/A, M) :-
|
||
|
functor(Head, N, A),
|
||
|
clpbn_table(Head, M, THead),
|
||
|
functor(THead, TN, A),
|
||
|
dynamic(M:TN/A).
|
||
|
|
||
|
clpbn_tabled_number_of_clauses(M:Clause, N) :- !,
|
||
|
clpbn_tabled_number_of_clauses(Clause, M, N).
|
||
|
clpbn_tabled_number_of_clauses(Clause, N) :-
|
||
|
prolog_load_context(module, M),
|
||
|
clpbn_tabled_number_of_clauses(Clause, M, N).
|
||
|
|
||
|
clpbn_tabled_number_of_clauses(M:Clause, _, N) :- !,
|
||
|
clpbn_tabled_number_of_clauses(Clause, M, N).
|
||
|
clpbn_tabled_number_of_clauses(Head, M, N) :-
|
||
|
clpbn_table(Head, M, THead),
|
||
|
predicate_property(M:THead,number_of_clauses(N)).
|
||
|
|
||
|
|
||
|
clpbn_is_tabled(M:Clause) :- !,
|
||
|
clpbn_is_tabled(Clause, M).
|
||
|
clpbn_is_tabled(Clause) :-
|
||
|
prolog_load_context(module, M),
|
||
|
clpbn_is_tabled(Clause, M).
|
||
|
|
||
|
clpbn_is_tabled(M:Clause, _) :- !,
|
||
|
clpbn_is_tabled(Clause, M).
|
||
|
clpbn_is_tabled(Head, M) :-
|
||
|
clpbn_table(Head, M, _).
|
||
|
|
||
|
|