Evaluate an expression with variable values stored in the form "variable name" + val

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?

• Have you seen ValueQ? Dec 13 '16 at 1:44
• The typical way this is written in MMA is exp=a^2+b+c and exp/.{a->1,b->2} which yields 3+c Dec 13 '16 at 1:46
• @ 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. Dec 13 '16 at 2:15
• 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. Dec 13 '16 at 2:21
• 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. Dec 13 '16 at 2:32

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