I'm using ECLiPSe 6.1. I have an array of variables of dimension N x N, let's call it Vars. Now I call a procedure with, say, my_procedure(Vars[1..N,1..2]).
Inside the procedure (my_procedure(List) :- ...), something like (foreach(X, List) do ...) is used.
This doesn't work. I have to write something like L is List inside the procedure before looping over L (instead of List) to make it work.
Why is this? And how can I address it? Because later on I try to call the procedure with flatten(Vars[1..N,1..2]) and then it gets even worse.
I started using collection_to_list/2 (with flatten) to resolve the issue, but I was wondering if there's an elegant way to address it.
Let me elaborate a bit, because your question highlights a feature of Prolog/ECLiPSe that regularly surprises users coming from other programming languages:
Maybe the most blatant example is with what looks like an "arithmetic expression":
Prolog takes the argument
3+4simply as the symbolic term+(3,4)and passes it to writeln/1, uninterpreted. Passing a term as an argument to a user-defined predicate doesn't change this, there is no implicit evaluation at call time:If we want to interpret the argument as an arithmetic expression and evaluate it, we have to request this explicitly:
Array access expressions in ECLiPSe behave in the same way. They are just symbolic expressions until explicitly evaluated by a predicate that understands them:
So, to finally come back to your original problem: when you call
my_procedure(Vars[1..N,1..2]), the argument that gets passed is the symbolic expressionVars[1..N,1..2], and this is whatmy_procedure/1receives. To turn that into the flat list that you want, it has to be interpreted as an expression that yields a list, and collection_to_list/2 (or, starting from ECLiPSe 7.0, eval_to_list/2) do exactly that: