3
$\begingroup$

Consider an expression exp = a^2 + b + c which has variables a, b, and c, and its values are stored in aval = 1, bval = 2, and cval = 3.

If cval is not given I would like the expression to get evaluated to 3 + c.

The function I have written is:

rulesVal[exp_] := 
 Cases[Variables@exp, 
  x_ /; Head[x] == Symbol :> (x -> Symbol[ToString[x] <> "val"])]

toVal[exp_] := exp /. rulesVal[exp]

When I input a^2 + b + c to toVal function, I get 3 + cval.

How do I get 3 + c?

$\endgroup$
  • 2
    $\begingroup$ Have you seen ValueQ? $\endgroup$ – Michael E2 Dec 13 '16 at 1:44
  • 2
    $\begingroup$ The typical way this is written in MMA is exp=a^2+b+c and exp/.{a->1,b->2} which yields 3+c $\endgroup$ – Manuel --Moe-- G Dec 13 '16 at 1:46
  • $\begingroup$ @ Manuel, I know that. That is good enough for a small expression. However, when it contains so many variables in an expression, it becomes difficult to see which variables are in the expression, and correspondingly writing a rule for that variable. $\endgroup$ – Anjan Kumar Dec 13 '16 at 2:15
  • 2
    $\begingroup$ BTW, did you generate the assignments aval = 1 etc., or are they given to you in a data file or something? I ask because there are better ways to manage such data. val[x_] := x and then val[a] = 1; val[b] = 2; usage something like exp /. Thread[# -> val /@ #]&@Variables[exp]. Or similarly with Association. $\endgroup$ – Michael E2 Dec 13 '16 at 2:21
  • 1
    $\begingroup$ Yes, I reckon ValuesQ is perhaps not so easy because it is HoldAll: it's tricky to pass it the unevaluated symbol. If the assignments are all numeric values, try NumericQ. $\endgroup$ – Michael E2 Dec 13 '16 at 2:32
5
$\begingroup$

Direct solution

aval = 1;
bval = 2;
cval =.;

exp = a^2 + b + c;

rule =
 s_Symbol :>
  With[{sv = ToHeldExpression[ToString[s] <> "val"]},
    ReleaseHold[sv] /; ValueQ @@ sv
  ];

exp /. rule
3 + c

Reference:

Recommended alternative

However this (the method above) really is a poor way to approach this problem in my opinion.

It should not really be difficult to make a Rule list (as proposed by Manuel --Moe-- G). If you use an Association it is even easier:

asc = <||>;
asc[a] = 1;
asc[b] = 2;

exp = a^2 + b + c;

exp /. asc
3 + c

If you are using an older version of Mathematica that does not have Associations then a DownValues definition (indexed object) as Michael proposed is a good alternative:

val[a] = 1;
val[b] = 2;

exp = a^2 + b + c;

exp /. s_Symbol /; ValueQ[val[s]] :> val[s]
3 + c
|improve this answer|||||
$\endgroup$

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.