如何使用 SWI-Prolog ./2 函数?

Guy*_*der 4 prolog swi-prolog

需要使用 SWI-Prolog ./2 的示例

签名是

.(+Int,[])
Run Code Online (Sandbox Code Playgroud)

此外,如果有此运算符的名称,也很高兴知道。正在搜索“.” 毫无意义。

最接近名称的是 SWI 文档部分 F.3 Arithmetic Functions

List of one character: character code
Run Code Online (Sandbox Code Playgroud)

我试过的

?- X is .(97,[]).
Run Code Online (Sandbox Code Playgroud)

结果是

ERROR: Type error: `dict' expected, found `97' (an integer)
ERROR: In:
ERROR:   [11] throw(error(type_error(dict,97),_5812))
ERROR:    [8] '<meta-call>'(user:(...,...)) <foreign>
ERROR:    [7] <user>
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
Run Code Online (Sandbox Code Playgroud)

也试过

?- X is .(97,['a']).
Run Code Online (Sandbox Code Playgroud)

结果相同。

lur*_*ker 6

在标准 Prolog 中,'.'函子是实际的列表项函子。具体来说,[H|T]相当于'.'(H, T)。例如,如果您运行 GNU Prolog,您将得到以下信息:

| ?- write_canonical([H|T]).
'.'(_23,_24)

yes
| ?- X = .(H,T).

X = [H|T]

yes
| ?-
Run Code Online (Sandbox Code Playgroud)

is/2运算符将允许您直接从由单个字符代码组成的列表中读取字符代码。所以以下在 Prolog 中有效:

| ?- X is [97].

X = 97

yes
| ?- X is .(97,[]).

X = 97

yes
Run Code Online (Sandbox Code Playgroud)

开始变得有趣的是,在 SWI Prolog 中,他们引入了依赖 的字典'.'作为指定字典键的一种方式。这会与'.'用作列表函子的函子产生冲突。这在词典的链接中进行了解释。因此,当您尝试将'.'函子用于列表时,您会得到如下结果:

1 ?- X is [97].
X = 97.

2 ?- X is .(97, []).
ERROR: Type error: `dict' expected, found `97' (an integer)
ERROR: In:
ERROR:   [11] throw(error(type_error(dict,97),_5184))
ERROR:    [9] '$dicts':'.'(97,[],_5224) at /usr/local/lib/swipl-7.4.2/boot/dicts.pl:46
ERROR:    [8] '<meta-call>'(user:(...,...)) <foreign>
ERROR:    [7] <user>
ERROR:
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

3 ?- X = .(H,T).
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:   [11] throw(error(instantiation_error,_6914))
ERROR:    [9] '$dicts':'.'(_6944,_6946,_6948) at /usr/local/lib/swipl-7.4.2/boot/dicts.pl:46
ERROR:    [8] '<meta-call>'(user:(...,...)) <foreign>
ERROR:    [7] <user>
ERROR:
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
Run Code Online (Sandbox Code Playgroud)

因此,SWI 定义了另一个函子 ,[|]来服务于'.'传统的用途,即列表函子。

4 ?- X is '[|]'(97, []).
X = 97.

5 ?- X = '[|]'(H, T).
X = [H|T].

6 ?-
Run Code Online (Sandbox Code Playgroud)

奇怪的是,你可能会认为这会发生:

7 ?- write_canonical([H|T]).
'[|]'(_, _)
Run Code Online (Sandbox Code Playgroud)

然而,发生的事情是这样的:

7 ?- write_canonical([H|T]).
[_|_]
true.
Run Code Online (Sandbox Code Playgroud)

所以对于 SWI Prolog,列表表示[H|T]已经是列表的规范表示。