0

在玩弄 SWI-Prolog (SWISH) 中不同的列表谓词时,我试图检查一个原子a是否是List1我在程序中定义为List1 = [a,b,c,d].

我将我的查询表述为member(a, List1).,期待类似于简单的“是”的内容(正如它在 59:25 的这个youtube 视频中显示的那样),但是我收到了一个警告

单例变量:[List1]

和一个错误

无权修改静态过程 `(=)/2'

根据我在网上查找的了解,这里的警告并不重要。但是,我不明白为什么我a显然是List1.

我尝试了两种不同的方式:

1)通过添加List1 = [a,b,c,d].到程序并查询member(a,List1).(导致上述错误);

2)List1 = [a,b,c,d]直接传递给解释器,然后使用相同的member(a,List1).查询a

List1 = [a|_1186]
List1 = [_1062, a|_1070]
List1 = [_1062, _1068, a|_1076]
List1 = [_1062, _1068, _1074, a|_1082]
List1 = [_1062, _1068, _1074, _1080, a|_1088]

这是关于我正在使用的特定 Prolog 版本的问题,还是我错过了一些非常简单的东西?

编辑

我知道这里提出了一个类似的问题,但我没有完全理解答案(也不是问题),因为它立即dynamic涉及我在 Prolog 中尚未遇到的事情。我正在寻找一个更普遍、更“高级”的答案,我通过提出这个问题找到了这个答案。

4

1 回答 1

1

我在程序中定义为List1 = [a,b,c,d].

这不是它的作用。它所做的是定义一个谓词=/2

2 ?- write_canonical( (List1 = [a,b,c,d]) ).
=(_,[a,b,c,d])

(您在此处看到的?-或是 Prolog 系统的交互式提示;在我的例子中是 SWI Prolog。在它之后的那一行是我输入的内容;然后在下一行我们看到系统的响应)。2 ?-

=当然,这践踏了已经存在的作为统一谓词的内置定义。因此,这个错误恰恰说明了这一点。是的,这重要。

为了在 Prolog 中“定义”一个列表,我们可以定义一个谓词

8 ?- [user].
p([1,2,3,4]).

这样我们就可以查询

9 ?- p(List1).
List1 = [1, 2, 3, 4].

并与List1,

10 ?- p(List1), member(A,List1).
List1 = [1, 2, 3, 4],
A = 1 ;
List1 = [1, 2, 3, 4],
A = 2 ;
List1 = [1, 2, 3, 4],
A = 3 ;
List1 = [1, 2, 3, 4],
A = 4.

我们也可以直接将列表指定为查询的子目标,

11 ?- List1 = [1,2,3,4], member(A,List1).
List1 = [1, 2, 3, 4],
A = 1 ;
List1 = [1, 2, 3, 4],
A = 2 ;
List1 = [1, 2, 3, 4],
A = 3 ;
List1 = [1, 2, 3, 4],
A = 4.

使用谓词=/2,而不是重新定义它,这是禁止的。


以上回答了你的1)。至于2),你没有告诉我们全部真相。您似乎所做的是首先进行查询

12 ?- List1 = [a,b,c,d].
List1 = [a, b, c, d].

这很好,花花公子;然后进行另一个查询,

13 ?- member(a,List1).
List1 = [a|_G2181] ;
List1 = [_G2180, a|_G2184] ;
List1 = [_G2180, _G2183, a|_G2187] ;
List1 = [_G2180, _G2183, _G2186, a|_G2190] ;
List1 = [_G2180, _G2183, _G2186, _G2189, a|_G2193] .

Prolog 提示符不是 REPL。我们不对它下定义。我们进行查询

于 2017-07-27T21:23:19.260 回答