让我详细说明一下,因为您的问题突出了 Prolog/ECLiPSe 的一个功能,该功能经常让来自其他编程语言的用户感到惊讶:
- 默认情况下,每个术语/表达式只是一个没有内在含义的符号结构
- 对此类符号结构的任何解释/评估仅在特定上下文中发生,或在明确要求时发生
也许最明显的例子是看起来像“算术表达式”的东西:
?- writeln(3+4).
3 + 4
Prolog 将参数3+4
简单地作为符号项+(3,4)
并将其传递给 writeln/1,未解释。将术语作为参数传递给用户定义的谓词不会改变这一点,在调用时没有隐式评估:
p(X) :- writeln(received(X)).
?- p(3+4).
received(3 + 4)
如果我们想将参数解释为算术表达式并对其求值,我们必须明确提出要求:
parith(Expr) :- Num is Expr, writeln(evaluated_to(Num)).
?- parith(3 + 4).
evaluated_to(7)
ECLiPSe 中的数组访问表达式的行为方式相同。它们只是符号表达式,直到被理解它们的谓词显式评估:
?- Array = [](11,22,33), p(Array[2]).
received([](11,22,33)[2])
?- Array = [](11,22,33), parith(Array[2]).
evaluated_to(22)
所以,最后回到你原来的问题:当你调用时my_procedure(Vars[1..N,1..2])
,传递的参数是符号表达式Vars[1..N,1..2]
,这就是my_procedure/1
接收的。要将其转换为您想要的平面列表,必须将其解释为产生列表的表达式,并且
collection_to_list/2(或者,从 ECLiPSe 7.0 开始,eval_to_list/2)正是这样做的:
plist(Expr) :- eval_to_list(Expr, List), writeln(evaluated_to(List)).
?- A = [](11, 22, 33), p(A[2 .. 3]).
received([](11, 22, 33)[2 .. 3])
?- A = [](11, 22, 33), plist(A[2 .. 3]).
evaluated_to([22, 33])