SWI-Prolog (SWISH): 无权修改静态过程`(=)/2'

SWI-Prolog (SWISH): No permission to modify static procedure `(=)/2'

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

我将我的查询表述为 member(a, List1).,期待一些简单的 'yes' 的内容(正如它在 59:25 的 youtube video 中显示的那样),但是相反,我收到了警告

Singleton variables: [List1]

和一个错误

No permission to modify static procedure `(=)/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 版本的问题,还是我遗漏了一些非常简单的东西?

编辑

我知道有人提出了一个类似的问题 here ,但我没有设法完全理解答案(也不是问题),因为它立即发生了 dynamic 的事情,我Prolog中还没有遇到过。我一直在寻找一个更笼统、更 'high-level' 的答案,我通过提出这个问题找到了这个答案。

I defined in the program as List1 = [a,b,c,d].

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

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

(你在那里看到的?-2 ?-是Prolog 系统的交互式 prompt;在我的例子中是 SWI Prolog。无论在那一行之后发生什么,都是我输入的;然后在下一行我们看到系统的响应)。

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

为了"define" 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。我们不对其进行定义。我们进行查询.