我是Prolog的新手并注意到'和'给出了不同的行为,但我很好奇为什么.具体来说,加载文件时,?- ['test1.pl'].工作,而?- ["test1.pl"].不是.
当使用字符(字符列表,因此长度为一的原子)来表示文本时,我们可以使用以下选项将它们写入术语中:
"First,"双引号列表表示法 (6.3.7) 是最有效的一种,至少需要n+2 个字符。double_quotes但只有当 Prolog 标志设置为chars时才能读回。
['N',e,x,t,',']出现至少2n+1 个字符的列表符号。虽然它很好并且相对紧凑,但它意味着在写入其他数据时也会使用运算符,因为它是通过 启用的ignore_ops(false),并且这需要在读取时出现相同的运算符,这使得它非常脆弱。
'.'('L','.'(a,'.'(s,'.'(t,'.'(',',[])))))使用函数形式的规范表示法也适用于需要至少7n+2 个字符的列表。这是很多,但对于互操作性(包括与同一系统的互操作性)来说这是最好的,因为它既不依赖于标志double_quotes也不依赖于各种运算符声明。
以规范表示法写入字符可以在常量空间中完成。但对于阅读来说,情况就有点棘手了。毕竟,以 开头的序列'.'(a,也可以指代术语'.'(a,Further,b)。因此,天真的阅读必须等待(并使用空间),直到读入整个字符列表。另一方面,这似乎是一个安全的赌注,'.'(a,将是一个列表构造函数'.'(a,Further)。换句话说,
如何使用规范符号来读取术语,并使用恒定的辅助空间来读取其中的字符?
如果有帮助,请考虑条款sampleterm/1。因此,请考虑阅读以规范形式编写的所有此类术语。并且,如果您愿意,可以将其表述为 DCG。
sampleterm([]).
sampleterm(a).
sampleterm(b).
sampleterm('.'(E,Es)) :- % the real list constructor
sampleterm(E),
sampleterm(Es).
sampleterm('.'(E,F,G)) :- % no list constructor
sampleterm(E),
sampleterm(F),
sampleterm(G).
Run Code Online (Sandbox Code Playgroud)
如果这种节省空间的读取是可能的,那么支持诸如 Scryer 和 Trealla 之类的紧凑内部字符表示的系统甚至可以更进一步。
啊,以免我忘记我尝试过的:read/1确实如此,但目前并不理想。
我在prolog中有一个字符代码列表.
我想把它们改成字符.
例如,
L = "abc"
回报 L = [97,98,99]
假设我开始 L = [97,98,99]
无论如何将L转换回abc,如果存在方法
convert(L, X) 回报 X = abc
谢谢.
在使用DCG解析3 GB的大文件时,效率至关重要。
我的词法分析器的当前版本主要使用or或谓词; / 2,但我读到索引可以提供帮助。
索引是一种用于为特定目标快速选择谓词的候选子句的技术。在大多数Prolog系统中,(仅)对头部的第一个参数进行索引。如果将此参数用函子实例化为原子,整数,浮点或复合项,则使用散列法快速选择第一个参数可以与目标的第一个参数统一的所有子句。SWI-Prolog支持即时和多参数索引。参见2.18节。
有人可以举一个使用索引进行词法化的例子,并可能解释一下它如何提高效率吗?
细节
注意:在将源代码处理到此问题之前,我更改了一些名称。如果您发现错误,请随时在此处进行编辑或给我留言,我们将很乐意解决。
当前我的词法分析器/令牌生成器(基于mzapotoczny / prolog-interpreter parser.pl)是这个
% N.B.
% Since the lexer uses "" for values, the double_quotes flag has to be set to `chars`.
% If double_quotes flag is set to `code`, the the values with "" will not be matched.
:- use_module(library(pio)).
:- use_module(library(dcg/basics)).
:- set_prolog_flag(double_quotes,chars).
lexer(Tokens) -->
white_space,
(
( ":", !, { Token = tokColon }
; "(", !, { Token …Run Code Online (Sandbox Code Playgroud)