Reputation: 307
After this
restart; about(x); assume(x>0); f:=3*x; x:='x': about(x);
Originally x, renamed x~:
is assumed to be: RealRange(Open(0),infinity)
f := 3*x~
x:
nothing known about this object
I can use indets
to access the variable x
(looks like it's still x~
in f
), for example
eval(f,indets(f)[1]=2);
6
but it's not efficient when f
has many variables. I've tried to access variable x
(or x~
) directly, but it didn't work:
eval(f,x=2);
eval(f,x~=2);
eval(f,'x'=2);
eval(f,'x~'=2);
eval(f,`x`=2);
eval(f,`x~`=2);
eval(f,cat(x,`~`)=2);
since the result in all those cases was 3*x~
(not 6
).
Is there a way to access a specific variable directly (i.e. without using indets
) after its assumptions are cleared?
Upvotes: 1
Views: 94
Reputation: 7271
There is no direct way, if utilizing assume
, without programatically extracting/converting/replacing the assumed names in the previously assigned expression.
You can store the (assumed) name in another variable, and utilize that -- even after unassigning x
.
Or you can pick off the names (including previously assumed names) from f
using indets
-- even after unassigning x
.
But both of those are awkward, and it gets more cumbersome if there are many such names.
That is one reason why some people prefer to utilize assuming
instead of the assume
facility.
You can construct lists/sets/sequences of the relevant assumptions, and then re-utilize those in multiple assuming
instances. But the global names are otherwise left alone, and your problematic mismatch situation avoided.
Another alternative is to utilize the command Physics:-assume
instead of assume
.
Here's an example. Notice that the assumption that x
is positive still allows some simplification that depend upon it.
restart;
Physics:-Assume(x>0);
{x::(RealRange(Open(0),
infinity))}
about(x);
Originally x, renamed x:
is assumed to be:
RealRange(Open(0),infinity)
f:=3*x;
f := 3 x
simplify(sqrt(x^2));
x
Physics:-Assume('clear'={x});
{}
about(x);
x:
nothing known about this object
eval(f, [x=2]);
6
As for handling the original example utilizing assume
, and substituting in f
for the (still present, assumed names), it can be done programmatically to alleviate some awkwardness with, say, a larger set of assumptions. For example,
restart;
# re-usable utility
K:=(e,p)->eval(e,
eval(map(nm->nm=parse(sprintf("%a",nm)),
indets(e,And(name,
satisfies(hasassumptions)))),
p)):
assume(x>0, y>0, t<z);
f:=3*x;
f := 3 x
g:=3*x+y-sin(t);
g := 3 x + y - sin(t)
x:='x': y:='y': t:='t':
K(f,[x=2]);
6
K(g,[x=2,y=sqrt(2),t=11]);
(1/2)
6 + 2 - sin(11)
Upvotes: 1