如http://homepages.inf.ed.ac.uk/pbrna/prologbook/node180.html所述,打开列表是用于实现差异列表的工具.
打开列表是列表中某个位置有未分配变量的任何列表,例如:[a,b,c|X].您可以使用开放列表来实现名为差异列表的数据结构,该结构正式指定了指向第一个元素和开放端的两个术语的结构,传统上定义为:[a,b,c|X]-X,以便更容易地对这些列表进行操作.
例如,如果您拥有的只是一个打开的列表,则可以在末尾添加元素,但您需要迭代所有项目.在差异列表中,您可以使用list-of-list变量(Hole在上面的页面上称为a )来跳过迭代并在恒定时间内执行操作.
这两个概念看起来都是列表,但实际上并非如此。一个是具体术语,另一个是约定。
开放式列表是不是列表但可以实例化为列表的术语。用标准术语来说,它们被称为部分列表。以下是部分列表:X、[a|X]、[X|X]都是部分列表。
开放式列表的概念建议使用此类列表来模拟某些开放式状态。想象一本可以用开放式列表表示的字典。每次添加新项目时,“部分列表末尾”的变量都会实例化为新元素。虽然这种编程技术在 Prolog 中很有可能实现,但它有一个很大的缺点:程序将严重依赖于过程解释。在许多情况下,根本无法进行声明性解释。
差异列表实际上不是列表本身,而是以某种方式使用列表,使得预期列表由两个变量表示:一个用于列表的开头,一个用于列表的结尾。因此,谈论列表差异而不是差异列表会很有帮助。
考虑:
el(E, [E|L],L).
Run Code Online (Sandbox Code Playgroud)
在这里,最后两个参数可以被视为形成差异:包含单个元素 的列表[E]。现在,您可以从更简单的列表中构造更复杂的列表,前提是您遵守某些约定,这些约定本质上是第二个参数仅进一步传递。这种差异永远不会相互比较!
el2(E, F, L0,L) :-
el(E, L0,L1),
el(F, L1,L).
Run Code Online (Sandbox Code Playgroud)
请注意,这只是一个约定。该清单并未强制执行。考虑到:
?- el2(E, F, L, nonlist).
L = [E,F|nonlist].
Run Code Online (Sandbox Code Playgroud)
该技术也用于对dcg进行编码。