7
$\begingroup$

I am trying to understand what AlgebraicRules is all about in the answer to this question. It apparently returns an AlgebraicRulesData with the following usage:

AlgebraicRulesData is an object returned by AlgebraicRules. Its OutputForm appears to be a list of rules, but the rules will be used algebraically rather than syntactically by Replace and related functions.

That's weird! Observe:

ex = AlgebraicRules[
  {x^2 + 2y - 4 == 6, x^2 + y^2 == 0}, {x, y}]
AlgebraicRulesData[{Solve`SolvVar[x],Solve`SolvVar[y]},{x,y},
  -10+Solve`SolvVar[x]^2+2 Solve`SolvVar[y]==0&&Solve`SolvVar[x]^2+Solve`SolvVar[y]^2==0,
  {{{0,{{2,1},{1,-2},{0,10}}}},{{2,{{0,1}}},{0,{{1,2},{0,-10}}}}},
  {x,y},{y^2->-10+2 y,x^2->10-2 y},Rational]

Apparently, I can use ReplaceAll (/.) with this, and I don't get a ReplaceAll::reps error!

x^2 /. ex

(*  10 - 2*y  *)

Even weirder is that if I copy the entire output and try to literally replace with it, it doesn't work! I get an AlgebraicRules::algdat error.

x^2 /. AlgebraicRulesData[{Solve`SolvVar[x],Solve`SolvVar[y]},{x,y},
  -10+Solve`SolvVar[x]^2+2 Solve`SolvVar[y]==0&&Solve`SolvVar[x]^2+Solve`SolvVar[y]^2==0,
  {{{0,{{2,1},{1,-2},{0,10}}}},{{2,{{0,1}}},{0,{{1,2},{0,-10}}}}},
  {x,y},{y^2->-10+2 y,x^2->10-2 y},Rational]

(* x^2 *)

Would someone explain to me what is happening that allows ex to be used as a replacement rule, but not the literal expression?

$\endgroup$
  • 2
    $\begingroup$ You've run into the fact that Mathematica isn't actually an immutable perfectly homoiconic language (BTW I'm pretty sure there is no such language since they all need some kind of mutable internal representation). In essence, there's a constructed AlgebraicRulesData that the C++ side of the kernel knows how to work with, but which can't be constructed by just calling AlgebraicRulesData on its data. It's good to keep in mind that everything we work with in Mathematica is really a C++ object. Helps you write better code. $\endgroup$ – b3m2a1 Jan 20 at 6:46
  • 2
    $\begingroup$ Think about this: {AssociationQ@<|1 -> 2|>, AssociationQ@Unevaluated[<|1 -> 2|>], Head@Unevaluated[<|1 -> 2|>]} The data itself is the same, and yet AssociationQ says that one is True and one is not. You can also set special bits with, e.g. System`Private`HoldSetNoEntry that won't be copied if you copy-paste the expression, but which will be held if you keep them bound to a variable or otherwise preserve the identity of the expression (e.g. by just passing it through your code). There are good number of places where this is used productively on this site. $\endgroup$ – b3m2a1 Jan 20 at 6:57
  • 3
    $\begingroup$ (1) What AlgebraicRulesData really is, is obsolete.Yes, it is still supported. Or ignored, to be more accurate. As for the copy/paste business, it has an internal validation flag. Those do not survive copying and in the case of AlgebraicRulesData there is no way (or attempt) to revalidate them. Without the flag being set, rule replacement will not handle them. $\endgroup$ – Daniel Lichtblau Jan 20 at 15:18
  • 3
    $\begingroup$ (2) The comments by @b3m2a1 are quite on the mark, especially in giving an indication of how validation flags might be used. $\endgroup$ – Daniel Lichtblau Jan 20 at 15:19
  • 1
    $\begingroup$ Very interesting! Thanks for the explanations. Either @b3m2a1 or DanielLichtblau should write this as an answer so I can accept it. $\endgroup$ – QuantumDot Jan 20 at 17:49
5
+50
$\begingroup$

(1) What AlgebraicRulesData really is, is obsolete.Yes, it is still supported. Or ignored, to be more accurate. As for the copy/paste business, it has an internal validation flag. Those do not survive copying and in the case of AlgebraicRulesData there is no way (or attempt) to revalidate them. Without the flag being set, rule replacement will not handle them.

(2) The comments by @b3m2a1 are quite on the mark, especially in giving an indication of how validation flags might be used.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Hi @DanielLichtblau, Is it possible internally flag an user-created expressions for validation? This seems to be especially useful for avoiding expensive revalidation of large expressions. $\endgroup$ – QuantumDot Sep 30 at 21:59
  • $\begingroup$ @QuantumDot Could try using System`Private` context functions such as SetValid but I will note that this can have unforeseen consequences. $\endgroup$ – Daniel Lichtblau Oct 1 at 19:24
  • $\begingroup$ Thank you. It seems System`Private`ValidQ yields True for expressions that were not previously declared with System`Private`SetValid. For example System`Private`ValidQ[x+1] yields True. Have I miss understood it? Thank you again! $\endgroup$ – QuantumDot Oct 1 at 21:45
  • $\begingroup$ @QuantumDot Probably means the evaluator has marked them as valid already, so they do not get reevaluated ad infinitum. $\endgroup$ – Daniel Lichtblau Oct 2 at 14:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.