I want to declare a list of lists, like so:
%% example 1
Xs = [
[[A],[[A]]],
[[A],[[A],[A]]],
[[A],[[A],[A],[A]]]
].
Here, the symbol A
refers to the same variable in each list. Executing maplist(writeln,xs) results in the following output:
[[_G1],[[_G1]]]
[[_G1],[[_G1],[_G1]]]
[[_G1],[[_G1],[_G1],[_G1]]]
I want to use the same symbol A
in each list, but for the variable to be distinct for each list, to give the following output:
[[_G1],[[_G1]]]
[[_G2],[[_G2],[_G2]]]
[[_G3],[[_G3],[_G3],[_G3]]]
The only way I make this work is give each list its own unique variable, like so:
%% example 2
Xs = [
[[A1],[[A1]]],
[[A2],[[A2],[A2]]],
[[A3],[[A3],[A3],[A3]]]
].
Is there any Prolog syntax, so that there is no need to number each variable, as per example 2? I tried adding brackets around the lists like so:
Xs = [
([[A],[[A]]]),
([[A],[[A],[A]]]),
([[A],[[A],[A],[A]]])
].
But this gives me the same output as example 1.
If you want to write out variables and specify a precise name for them, you need the write-option
variable_names/1
. This answer explains how. Alternatively, you might use the legacy predicatenumbervars/3
which unifies distinct variables with a term'$VAR'(N)
, and then use eitherwriteq/1
or the write-optionnumbervars(true)
.But both methods will not work in the case you indicate. In fact, it was sheer luck that your query
produced the same variables for the different lists. It's even worse, the very same goal writing the very same list, may produce different variable names for different invocations:
For
p(100)
, SICStus writes[_776][_46]
, SWI writes[_G517][_G3]
. Brief, you caught Prolog on a good day. This is not surprising, for the standard only requires an "implementation dependent" value for a name with a few restrictions: It starts with underscore, and the remaining characters are different for different variables, and the same for the same variable within the same write goal. Here is ISO/IEC 13211-1:1995 on this:The reason for this is that a globally consistent naming of variables would produce a lot of overhead in implementations.
To summarize: If you want to use different variable names for the same variable, then use
variable_names/1
with different arguments. If you want the variable to be actually different, then name them differently, or usecopy_term/2
accordingly.