如何使用SWI-Prolog ./2功能?

时间:2018-03-12 20:08:48

标签: prolog swi-prolog

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

签名是

.(+Int,[])

此外,如果这个运营商有一个名字,那将很高兴知道。正在搜索'。'没有意义。

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

List of one character: character code

我尝试了什么

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

结果

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.

也试过

?- X is .(97,['a']).

同样的结果。

2 个答案:

答案 0 :(得分:4)

在标准的Prolog中,'.'仿函数是实际的列表术语仿函数。具体而言,[H|T]相当于'.'(H, T)。例如,如果你运行GNU Prolog,你会得到这个:

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

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

X = [H|T]

yes
| ?-

is/2运算符允许您直接从包含单个字符代码的列表中读取字符代码。以下是Prolog的工作原理:

| ?- X is [97].

X = 97

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

X = 97

yes

开始变得有趣的地方是,在SWI Prolog中,他们引入了dictionaries,它依赖于'.'作为指定字典键的手段。这会与用作列表仿函数的'.'仿函数产生冲突。这在字典链接中有解释。因此,当您尝试将'.'仿函数用于列表时,您会得到如下内容:

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.
因此,SWI已经定义了另一个仿函数[|],以实现'.'传统服务的目的,即列表仿函数。

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

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

6 ?-

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

7 ?- write_canonical([H|T]).
'[|]'(_, _)

但是,会发生什么:

7 ?- write_canonical([H|T]).
[_|_]
true.

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

答案 1 :(得分:2)

算术函数'.'/2映射 列出对相应字符字符 字符代码(诸如[C]'.'(C,[])等术语)的列表>代码。

您正在观察的特定刺激性行为是SWI-Prolog特有的。 您可以通过添加命令行参数--traditional来禁用非标准的SWI-Prolog“扩展名”(如dict),如下所示:

$ swipl --traditional
Welcome to SWI-Prolog (threaded, 64 bits, version 8.0.0) [...]

?- C = 97, V is [C].
C = 97, V = 97.

?- C = 0'a, V is [C].
C = 97, V = 97.

?- C = a, V is [C].
C = a, V = 97.

这也适用于字符串文字:

:- set_prolog_flag(double_quotes, codes).
?- Str = "a", Str = [C], V is Str.
Str = [97], C = 97, V = 97.

:- set_prolog_flag(double_quotes, chars).
?- Str = "a", Str = [C], V is Str.
Str = [a], C = a, V = 97.