Strange behaviour of ValueQ inside loops

TL;DR: I have a series of variables $x_1, x_2, x_3, \dots$ which to which I assign values inside a loop. However, when I use ValueQ to determine which values I've already assigned, the results don't appear to make much sense.

Minimal example: Code:

Clear[x];
For[i = 1, i < 4, i = i + 1,
x[i] = i;
Print[i, ": ", ValueQ[x[i]], " ", ValueQ [x[i + 1]], " ", ValueQ [x[i + 10]] , " ", ValueQ[x]]]

Output:

1: True True True False
2: True True True True
3: True True True True

Explanation: In $i$-th iteration of the loop, I assign the value to x[i]. Hence, in $i$-th iteration the values x, x, ..., x[i] are defined, but x[i+1], x[i+2], ... are not. However, when I try to check if x[j] are defined, Mathematica tells me that: 1) x[i] is defined, as expected; 2) x[i+1] is defined, although it is not yet defined; 3) x[i+10] is defined, although it is never defined at all; 4) x is defined if and only if $i \geq 2$, as expected.

Motivation: In the application I have in mind, I'm computing values $x_i$ in a somewhat haphazard order. It so happens that to compute $x_i$ it is useful to know $x_j$ where $j$ is a function of $i$ (a non-trivial one). At the time $x_i$ is computed, I would like to check if $x_j$ has already been computed, and use its value if it has (if it has not, then I need to compute $x_i$ in a more time-consuming way). However, when I try to implement this using ValueQ, I get the unexpected behaviour described above.

Question: How does this behaviour arise, and how can I change the above code to make it work?

• "ValueQ gives False only if expr would not change if it were to be entered as Wolfram Language input. " - x[i + 10] would change, becoming x[10+i] Feb 5 '18 at 21:02
• For your application here, use a smarter test function, like IntegerQ or NumericQ Feb 5 '18 at 21:19
• @JasonB Actually, it would change also because i has a value within the loop. Feb 5 '18 at 21:21
• From my experience, lists work much faster than constructions like x[i]. And they have no such weird artifacts. Feb 5 '18 at 21:28
• Sounds like you should be using memoization? Feb 5 '18 at 21:48

since x[1+1] evaluates (at least) to x, ValueQ returns True as it is already different than the input.

You don't have to check if you already calculated x for e.g. 2. You can use memoization:

x[n_]:=x[n] = ...

So once e.g. x is called, each subsequent x will not require recomputation.

• Thank you for explaining where the issue comes from. However, in this particular case, momoization is not the solution: I specifically need to check if x[i] (say) is defined, and do one of two different things depending on the outcome (i.e. if I learn that I could speed up computing x by knowing the value of x but I haven't yet computed x, I don't want to compute x but rather I want to run a completely different routine). Feb 6 '18 at 16:54
• @JakubKonieczny I see, without details I can only suggest to check MatchQ[x[i], _x].
– Kuba
Feb 6 '18 at 17:35
• @JakubKonieczny or ValueQ[x[#]]&[1+1]
– Kuba
Feb 12 '18 at 12:58