Bug introduced in 8.0, fixed in 10.4, intentionally reintroduced in 11.0 and persisting through 13.0.0 or later
In the following example, inside the minimumX
's Module
, x
is initialized to 1, but the results say otherwise:
solutionQ = Function[{x, d}, IntegerQ[Sqrt[(x^2 - 1)/d]] && x != 1];
minimumX =
Compile[{{d, _Integer}},
Module[{x = 1}, While[! solutionQ[x, d], x++]; x]];
minimumX[2]
minimumX[3]
minimumX[2]
(*
3
7
17
*)
If I define minimumX
as:
minimumX =
Function[{d}, Module[{x = 1}, While[! solutionQ[x, d], x++]; x]];
or
minimumX =
Compile[{{d, _Integer}},
Module[{x = 1}, x = 1; While[! solutionQ[x, d], x++]; x]];
It works as I was expecting:
(*
3
2
3
*)
Is this expected behavior, or should I report a bug?
(Mathematica 9.0.1)
x
in the instruction{46, Function[{d}, While[ !solutionQ[x, d], x++]], {x, 2, 0, 1, Module}, 2, 0, 0, 6, 0, 17}
is clearly not being respected. The same behavior is observed forWith
in place ofModule
, but not forBlock
, which works as it should. It also works correctly in versions 7 and 5.2; the bug seems to have been introduced in version 8, when major changes were made to the VM. (The compiled code generated by all versions is functionally identical and differs only by opcode numbering.) $\endgroup$With[{solutionQ = Function[{x, d}, FractionalPart[Sqrt[(x^2 - 1)/d]] == 0 && x != 1]}, minimumX = Compile[{{d, _Integer}}, Module[{x = 1}, While[! solutionQ[x, d], x++]; x]]]
. This is somewhat beside the point as far as the question goes since the bug does not manifest in this case, but I'm sure others would have been moved to comment on it if I hadn't. Indeed, I think it's worth emphasizing to WRI support that this particular non-optimal formulation is necessary to expose the bug. $\endgroup$SetDelayed(:=)
not onlySet(=)
it works like it should. $\endgroup$