What is wrong with RuleCondition here?
Here is an observation, not really an answer:
Hold@1.`5 /. x_Real :> RuleCondition[N[x] + $MachineEpsilon, True]
(* -> Hold[1.0000] *)
But:
Block[{Internal`$SameQTolerance = -Infinity},
Hold@1.`5 /. x_Real :> RuleCondition[N[x] + $MachineEpsilon, True] ] (* -> Hold[1.] *)
It does not help your test case because 1.`5
is SameQ
1.
But I think this makes it a question of SameQ
's problem, rather than RuleCondition
's.
For completeness: Internal`$EqualTolerance
and Internal`$HashTolerance
have no effect. The test is definitely SameQ
.
Since Alexey mentions that things were better in version 5 with respect to a tangentially related bug/oddity, it may be worth noting as well that in versions of Mathematica up to and including 7, we have a different result:
Hold@1`5 /. x_Real :> RuleCondition[N@x, True]
(* -> Hold[1.] *)
Hold@1`5 /. x_Real :> RuleCondition[N@2`5, True]
(* -> Hold[2.] *)
Hold@2`5 /. x_Real :> RuleCondition[N@2`5, True]
(* -> Hold[2.] *)
Hold@1`5 /. x_Real :> RuleCondition[N@t, True]
(* -> Hold[t] *)
This looks absolutely as one would expect. The optimization of SameQ
in version 8 is the clear culprit.
Unfortunately, we cannot work around the problem by replacing SameQ
with a more stringent test:
Internal`HashSameQ[1., 1.`5]
(* -> False *)
Block[{SameQ = Internal`HashSameQ, Internal`$HashTolerance = -Infinity},
Hold@1.`5 /. x_Real :> RuleCondition[N[x], True]
]
(* -> Hold[1.0000] *)
It seems that RuleCondition
is hard-coded to call the SameQ
code no matter how SameQ
is defined at the top level. This might be considered a bug in RuleCondition
in addition to the one in SameQ
.
I am of the view that the SameQ
behavior is a bug, because while I have always thought that the value of Internal`$SameQTolerance
being anything other than -Infinity
is a bad idea, for numbers with different Precision
to compare as being the same is an explicit violation of Mathematica's numerical model of floating-point numbers being distributions. I think one cannot have a serious conceptual inconsistency like this and not call it a bug.
Update Jan 22nd: WRI Tech Support indicates that the fixes for all the test cases below, including the ones that don't depend on SameQ
, may land in the next point release. The fixes could miss the point release if they cause other problems with higher severity.
It appears that there may be some indirect dependence on RuleCondition
as well as other structures. I found this out while trying to explain the problem to WRI technical support.
In all cases, these answers should be a number (1. or 2.) followed by answers with that same number in a list. The spots where the number has extra zeroes indicate a rule that went unused when it should have been. Note the difference between the second to last cases for 1. vs. 2., which appear to depend on the use of RuleCondition
and the size of the number (which affects the SameQ
code).
In[1]:= $Version
Out[1]= "10.0 for Microsoft Windows (64-bit) (June 29, 2014)"
In[2]:= 1`5 /. {1`5 :> 1.}
Out[2]= 1.
In[3]:= {1`5} /. {1`5 :> 1.}
Out[3]= {1.0000}
In[4]:= {1`5} /. {1`5 :> 1. + 0}
Out[4]= {1.}
In[5]:= {1`5} /. {1`5 :> 1. + $MachineEpsilon}
Out[5]= {1.}
In[6]:= Block[{Internal`$SameQTolerance = -Infinity}, {1`5} /. {1`5 :>1. + $MachineEpsilon}]
Out[6]= {1.}
In[7]:= Block[{Internal`$SameQTolerance = -Infinity}, {1.`5} /. x_Real :> RuleCondition[N[x] + $MachineEpsilon, True]]
Out[7]= {1.}
In[8]:= Block[{Internal`$SameQTolerance = -Infinity}, {1.`5} /. x_Real :> N[x] + $MachineEpsilon]
Out[8]= {1.}
In[9]:= 2`5 /. {2`5 :> 2.}
Out[9]= 2.
In[10]:= {2`5} /. {2`5 :> 2.}
Out[10]= {2.0000}
In[11]:= {2`5} /. {2`5 :> 2. + 0}
Out[11]= {2.}
In[12]:= {2`5} /. {2`5 :> 2. + $MachineEpsilon}
Out[12]= {2.}
In[13]:= Block[{Internal`$SameQTolerance = -Infinity}, {2`5} /. {2`5 :>2. + $MachineEpsilon}]
Out[13]= {2.}
In[14]:= Block[{Internal`$SameQTolerance = -Infinity}, {2.`5} /. x_Real :> RuleCondition[N[x] + $MachineEpsilon, True]]
Out[14]= {2.0000}
In[15]:= Block[{Internal`$SameQTolerance = -Infinity}, {2.`5} /. x_Real :> N[x] + $MachineEpsilon]
Out[15]= {2.}