Позвольте мне остановиться подробнее, потому что в вашем вопросе подчеркивается особенность Prolog / ECLiPSe, которая регулярно удивляет пользователей, приходящих с других языков программирования:
- Каждый термин / выражение по умолчанию является просто символической структурой без присущего ей значения
- Любая интерпретация / оценка такой символической структуры происходит только в определенных контекстах или при явном запросе
Возможно, самый вопиющий пример с тем, что выглядит как "арифметическое выражение":
?- writeln(3+4).
3 + 4
Пролог принимает аргумент 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])