Suppose that f(X)
is a dynamic fact that can be assert
ed and retract
ed, and suppose that X
is always number. Now, suppose that the most executed query is about finding the f(X)
such that is minimum. In SWI-Prolog I may write:
min_f(R) :- aggregate(min(X), f(X), R).
But, apparently, this always causes Prolog to perform a linear search on all facts. Now, suppose that there will be a large number (eg 1,000,000) of such facts. Since I know before hand that I will often execute min_f/1
:
f/1
, so that the engine can find the minimum in O(1) ? assert
a min-heap containing all the facts, and then peek at the head; could the facts be stored in a min-heap implicitly ? I have no restriction on the Prolog dialect, so any alternative Prolog implementation would be fine.
An alternative to data structures that can quickly deliver a minimum or maximum, would be to use mode directed tabling. In mode directed tabling one can specify desired aggregate functions:
f(5).
f(4).
f(6).
:- table min_f(min).
min_f(X) :- f(X).
The minimum will be only computed once, here is an example query. Works in SWI-Prolog and since release 1.4.0 also in Jekejeke Prolog:
?- min_f(X).
X = 4.
Theoretically it is left to the tabling implementation, how it calculates min. There are currently also developments going on, incremental tabling, which would allow making f/1 dynamic and then track changes.
:- dynamic(f/1).
min_f(X) :-
f(X),
!.
assert_f(X) :-
min_f(Min),
Min<X,
assertz(f(X)),
!.
assert_f(X) :-
asserta(f(X)).
Use assert_f/1 instead of assert/1. First solution to f/1 will allways be the minimun value, but don't assume that solutions to f/1 are listed low to high.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.