来自docs:
add_to_heap(+Heap0, +Priority, ?Key, -Heap)
是semidet将
Key
优先级Priority
添加到Heap0
,在Heap
中构建新堆。
如果我理解正确,那么add_to_heap
将一个密钥及其优先级添加到Heap0
,然后将Heap0
添加到Heap
?所以Heap
基本上是一堆堆?
答案 0 :(得分:1)
否。 Prolog是一种声明性语言。这意味着 - 除了进一步接地 - 一旦变量具有值,您就不能再改变该值(通过回溯您可以撤消 ,但在这种情况下,你当然会丢失前一个调用路径的上下文)。因此,您无法将密钥添加到现有堆。
因此,声明性语言构造 new 结构。例如,append(A,B,C)
将构建一个新列表C
,该列表相当于A
,后跟B
。另一个例子是finger tree。
这也是这个谓词的工作原理:你构建一个等于Heap
的新堆 Heap0
,但区别在于Key
是添加了给定的Priority
。因此,您仍然可以使用旧的Heap
。
例如:
demonstrate_use_old :-
empty_heap(H0),
add_to_heap(H0,0,foo,H1),
heap_size(H0,0),
heap_size(H1,1).
这样可以测试添加H0
后第一个空堆foo
的大小为0。 foo
仅添加到新堆H1
(大小为1)。
你可以 - 公正地说 - 构建新的数据结构在计算上是昂贵的。这就是为什么声明性语言通常具有一组专用数据结构的原因 - 例如,Haskell和Prolog默认使用(链接)列表而不是数组,因为这允许在 O(1)中添加头部。 手指树是一种树状数据结构,允许快速推/弹/检查/...