How do I SetDelayed $Assumptions
As I somehow forgot but Szabolcs reminded me many System variables (typically with names beginning with $
) check the values they are set to, e.g.:
$MinPrecision := -6
$MinPrecision
\$MinPrecision::precset: Cannot set \$MinPrecision to -6; value must be a non-negative number or Infinity. >>
0
In this case the check causes evaluation you do not want. You can bypass it by modifying the OwnValues
directly. A helper function to make this cleaner:
SetAttributes[mySet, HoldAll]
mySet[LHS_Symbol, RHS_] := (OwnValues[LHS] = {HoldPattern[LHS] :> RHS};)
Now:
mySet[$Assumptions, Print["y"]; x > 0] (* nothing prints *)
and:
Refine[{x < 0, x == 0, x > 0}]
y
{False, False, True}
Also:
mySet[$Assumptions, Print["y = ", y]; x > y]
y = 1;
Refine[{x > 1, x > 2, x > 3}]
y = 2;
Refine[{x > 1, x > 2, x > 3}]
y = 3;
Refine[{x > 1, x > 2, x > 3}]
y = 1
{True, x > 2, x > 3}
y = 2
{True, True, x > 3}
y = 3
{True, True, True}
To change the assumptions dynamically, this can be used:
$Assumptions := b
b = {c > 0};
Refine[{c < 0, c == 0, c > 0}]
b = {c < 0};
Refine[{c < 0, c == 0, c > 0}]
If you need to evaluate the Print
every time, this can be used:
$Assumptions := Evaluate[b]
b = {c > 0, Unevaluated@Print[kount]};
kount = 1;
Refine[{c < 0, c == 0, c > 0}]
kount = 2;
Refine[{c < 0, c == 0, c > 0}]
b = {c < 0, Unevaluated@Print[kount]};
kount = 3;
Refine[{c < 0, c == 0, c > 0}]
kount = 4;
Refine[{c < 0, c == 0, c > 0}]
Beware, however, that using Print
in the assumptions could have unintended consequences. Print
returns Null
, so the effect will be that Null
will be assumed to be True
, as illustrated here:
$Assumptions = {Print["beware"]};
Refine[Null]
(* beware *)
(* True *)