[英]Imposing an order to facts in Prolog
假设f(X)
是一个可以assert
和retract
的动态事实,并假设X
总是数字。 现在,假设执行最多的查询是关于找到最小的f(X)
。 在SWI-Prolog我可以写:
min_f(R) :- aggregate(min(X), f(X), R).
但是,显然,这总是会导致Prolog对所有事实进行线性搜索。 现在,假设会有大量(例如1,000,000)这样的事实。 既然我事先知道我会经常执行min_f/1
:
f/1
上强加一个排序,这样引擎可以在O(1)中找到最小值吗? assert
包含所有事实的min-heap,然后查看头部; 可以将事实隐含地存储在最小堆中吗? 我对Prolog方言没有任何限制,所以任何替代的Prolog实现都可以。
可以快速传递最小值或最大值的数据结构的替代方案是使用模式定向制表。 在模式定向制表中,可以指定所需的聚合函数:
f(5).
f(4).
f(6).
:- table min_f(min).
min_f(X) :- f(X).
最小值只计算一次,这是一个示例查询。 可以在SWI-Prolog中使用,也可以在Jekejeke Prolog的1.4.0版本中使用:
?- min_f(X).
X = 4.
从理论上讲,它留给了表格实现,它如何计算最小值。 目前还有一些进展,增量制表,这将使f / 1动态化,然后跟踪变化。
:- 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)).
使用assert_f / 1而不是assert / 1。 f / 1的第一个解决方案总是最小值,但不要假设f / 1的解决方案从低到高列出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.