在 Prolog 中生成带有自变量的列表

Generate lists with independent variables in Prolog

我在创建要用来填充的列表时遇到问题。我试图用自变量创建它,这样我就可以将地图列表与其他一些列表统一起来。 为此,我做了:

length(Subs, Len),
maplist(=([_, _, _]), Subs),

然而,结果是:

Subs = [[_22998, _23020, _23042], [_22998, _23020, _23042], [_22998, _23020, _23042]].

所以,当我尝试用下一种方式统一时:

maplist(nth1(1), Subs, Com1),
maplist(nth1(2), Subs, Perm_sub),
maplist(nth1(3), Subs, Com3).

与:

Perm_sub = [5, 7, 6],
Com1 = [P23, P34, P36],
Com3 = [1, 3, 2].

它失败了,因为 5 与 _22998 统一,因此与 7 发生冲突。是否有一种简单、优雅的方法来实现我的意图,或者我是否必须创建一个新函数来处理这个问题,如果是的话,我该怎么做这个功能?

您可以创建一个辅助谓词,如下所示:

triple([_, _, _]).

然后问:

?- length(L, 3), maplist(triple, L).
L = [[_2404, _2410, _2416], [_2422, _2428, _2434], [_2440, _2446, _2452]].

或者,您可以使用 lambda 表达式,如下所示:

?- length(L, 3), maplist([[_,_,_]]>>true, L).
L = [[_7198, _7204, _7210], [_7276, _7282, _7288], [_7354, _7360, _7366]].

编辑 2021 年 5 月 10 日

请注意,术语中使用的变量与其环境共享(它们是“全局的”,不受 lambda 约束),因此,它们在 maplist 的所有调用中都存在。例如,在下面的查询中,变量 X 被实例化为 1,之后,它的值将在下一次调用中保持不变。

?- trace, maplist(=(X), [1,Y,1]).
^  Call: (11) apply:maplist(=(_1882), [1, _1892, 1]) ? creep
   Call: (12) apply:maplist_([1, _1892, 1], user: =(_1882)) ? creep
   Call: (13) _1882=1 ? creep
   Exit: (13) 1=1 ? creep
   Call: (13) apply:maplist_([_1892, 1], user: =(1)) ? creep
   Call: (14) 1=_1892 ? creep
   Exit: (14) 1=1 ? creep
   Call: (14) apply:maplist_([1], user: =(1)) ? creep
   Call: (15) 1=1 ? creep
   Exit: (15) 1=1 ? creep
   Call: (15) apply:maplist_([], user: =(1)) ? creep
   Exit: (15) apply:maplist_([], user: =(1)) ? creep
   Exit: (14) apply:maplist_([1], user: =(1)) ? creep
   Exit: (13) apply:maplist_([1, 1], user: =(1)) ? creep
   Exit: (12) apply:maplist_([1, 1, 1], user: =(1)) ? creep
^  Exit: (11) apply:maplist(user: =(1), [1, 1, 1]) ? creep
X = Y, Y = 1.

另一方面,用作谓词参数的变量是“局部的”,它们的实例化不会从一个调用到另一个调用持续存在。例如:

?- [user].
|    equal(_X).
|    ^Z
% user://1 compiled 0.02 sec, 1 clauses
true.

?- trace, maplist(equal, [1,Y,1]).
^  Call: (11) apply:maplist(equal, [1, _1752, 1]) ? creep
   Call: (12) apply:maplist_([1, _1752, 1], user:equal) ? creep
   Call: (13) equal(1) ? creep
   Exit: (13) equal(1) ? creep
   Call: (13) apply:maplist_([_1752, 1], user:equal) ? creep
   Call: (14) equal(_1752) ? creep
   Exit: (14) equal(_1752) ? creep
   Call: (14) apply:maplist_([1], user:equal) ? creep
   Call: (15) equal(1) ? creep
   Exit: (15) equal(1) ? creep
   Call: (15) apply:maplist_([], user:equal) ? creep
   Exit: (15) apply:maplist_([], user:equal) ? creep
   Exit: (14) apply:maplist_([1], user:equal) ? creep
   Exit: (13) apply:maplist_([_1752, 1], user:equal) ? creep
   Exit: (12) apply:maplist_([1, _1752, 1], user:equal) ? creep
^  Exit: (11) apply:maplist(user:equal, [1, _1752, 1]) ? creep
true.