6
$\begingroup$

If I have assigned values to a, b and c:

a=7;
b=5;
c=6;

and I select the expression:

(a+b)/c

and I press cmd + enter in the Mathematica frontend, the expression will be replaced by 2.

I would like to do something similar which would fill in the values of the symbols without evaluating the result. So (a+b)/c would be replaced by (7+5)/6.

Is there a way of doing this? If so, can you also assign this to a keyboard shortcut that would replace the selected expression?

Note: Assume you don't know the values or the names of the variables. Inputting (a+b)/c to a function, should be able to produce something like (7+5)/6 without having to input a, b and c or 7, 5 and 6.

$\endgroup$
8
  • 1
    $\begingroup$ What should happen when b = -5? $\endgroup$
    – Kuba
    Jan 10, 2014 at 13:00
  • $\begingroup$ @Kuba either (7-5)/6 or (7+(-5))/6. $\endgroup$
    – Tyilo
    Jan 10, 2014 at 13:12
  • $\begingroup$ I swear this question is a duplicate. People, please help me find it. $\endgroup$
    – Mr.Wizard
    Jan 10, 2014 at 13:39
  • $\begingroup$ @Mr.Wizard I've only found this, only partially duplicate, so I took the liberty to answer. $\endgroup$ Jan 10, 2014 at 13:44
  • $\begingroup$ @István That's not the one, but thank you for looking first. $\endgroup$
    – Mr.Wizard
    Jan 10, 2014 at 13:45

5 Answers 5

7
$\begingroup$

Using OwnValues and HoldForm:

{a = 7, b = 5, c = 6};

HoldForm[(a + b)/c] /. OwnValues@a /. OwnValues@b /. OwnValues@c
(7 + 5)/6
With[{a = a, b = b, c = c}, HoldForm[(a + b)/c]]
(7 + 5)/6

Assuming that variables are already defined and you don't want to bother with listing the symbols, and you want to have a function that does it in one go:

Attributes[hold] = {HoldAll};
hold[x_] := HoldForm@x /. Cases[Hold@x, s_Symbol :> (HoldPattern@s -> s), Infinity];

hold[(a + b)/c]
(7 + 5)/6
$\endgroup$
4
  • $\begingroup$ Given that I don't want to type the names of the symbols again, is there a way of just inputting (a+b)/c and the function would figure out to do /. OwnValues@symbol for each symbol? $\endgroup$
    – Tyilo
    Jan 10, 2014 at 13:26
  • $\begingroup$ I know this a probably even harder, but would it be possible to output (7+5)/(-6) instead of -(1/6)*(7+5) when c=-6? $\endgroup$
    – Tyilo
    Jan 10, 2014 at 13:37
  • 1
    $\begingroup$ a = b = c = 1; hold[(a + b)/c] $\endgroup$
    – Kuba
    Jan 10, 2014 at 13:38
  • $\begingroup$ @Tyilo If you examine FullForm[(a + b)/c] (without values for a, b, c), you will realize that it is already represented as Times[Plus[a, b], Power[c, -1]]. So that is again an entirely different question. $\endgroup$ Jan 10, 2014 at 13:43
5
$\begingroup$
Hold[(a + b)/c] /. {a -> 1, b -> 3, c -> 4} /. Hold -> Defer

(*   (1 + 3)/4   *)

Hold[(a + b)/c] /. {a -> 1, b -> -3, c -> 4} /. Hold -> Defer

(*   (1 - 3)/4   *)

    Hold[(a + b)/c] /. {a -> 1, b -> -3, c -> -4} /. Hold -> Defer

(*   -(1/4) (1 - 3)   *)
$\endgroup$
7
  • $\begingroup$ Just a note: Defer @@ Hold[(a + b)/c] ... etc. works as well. $\endgroup$
    – Yves Klett
    Jan 10, 2014 at 13:22
  • $\begingroup$ Given that I don't want to type the names of the symbols and the values again, is there a way of just inputting (a+b)/c and the function would figure out the values itself? $\endgroup$
    – Tyilo
    Jan 10, 2014 at 13:24
  • 1
    $\begingroup$ Also, this doesn't work when the variables has already been defined. $\endgroup$
    – Tyilo
    Jan 10, 2014 at 13:28
  • $\begingroup$ Defer instead of Hold without replacement should work. It already holds $\endgroup$
    – Rojo
    Jan 10, 2014 at 18:28
  • $\begingroup$ @Rojo That was my first idea also, but it did not work. This (a + b)/c // Defer /. {a -> 1, b -> 3, c -> 4} returns (a + b)/c; this (a + b)/c /. {a -> 1, b -> 3, c -> 4} // Defer and this Defer[(a + b)/c /. {a -> 1, b -> 3, c -> 4}] return (a + b)/c /. {a -> 1, b -> 3, c -> 4} $\endgroup$ Jan 13, 2014 at 8:25
2
$\begingroup$

Edit: answer rewrite

This question in its base form is a duplicate, but since I cannot find the original, and since you extended the question to something more unique than what I recall, I shall provide a short answer.

You asked:

I know this a probably even harder, but would it be possible to output (7+5)/(-6) instead of -(1/6)*(7+5) when c=-6?

For that kind of control see for example: Returning an unevaluated expression with values substituted in

Combining that with RuleCondition, described in Replacement inside held expression, we can use:

SetAttributes[{defer, fill}, HoldAll]

MakeBoxes[defer[args__], fmt_] := Block[{Times}, MakeBoxes[Defer[args], fmt]]

fill[expr_] := defer[expr] /. x_Symbol :> RuleCondition[x]

Now:

{a, b, c} = {7, 5, -6};

fill[(a + b)/c]
(7+5)*-(1/6)

Because this uses Defer you can use the output of fill as input and it will fully evaluate.

$\endgroup$
1
  • $\begingroup$ I just realized that I read the comment I quoted completely backward. Time for a break I guess! I'll fix this later. $\endgroup$
    – Mr.Wizard
    Jan 10, 2014 at 15:52
0
$\begingroup$

In the same search that found your post, I also found: https://mathematica.stackexchange.com/a/100152/76328

I tailored Edmund's approach just slightly to fit my needs. I hadn't heard of Inactivate before, but it performs substitutions while not evaluating the main expression. It sounds like a simple solution to this post?

That said, I do like István Zachar's general-case approach as well.

Tailored version noted above:

InactiveAndActive = Function[expr, Column@Through@{Inactivate, Identity}@Unevaluated@expr, HoldAll];

EDIT: I just noticed that the above doesn't format things like 1/x in StandardForm. A better solution is:

HoldAndEvaluate = Function[expr, Column@Through@{Inactivate, Identity}@Unevaluated@expr /. Inactive[x_] -> HoldForm@*x, HoldAll];
$\endgroup$
-1
$\begingroup$

Mathematica has the function Hold which prevents evaluation, until you Release that Hold.

Hold[(a+b)/c] /.{a->1,b->2,c->3}

gives

Hold[(1 + 2)/3]

Then

Release[Hold[(1 + 2)/3]]

will give

1
$\endgroup$
5
  • 1
    $\begingroup$ This is almost exactly the same as Alexei's answer. I wouldn't consider it a different one. $\endgroup$ Jan 10, 2014 at 14:55
  • $\begingroup$ I posted it on an un-refreshed page, didn't see Alexi's answer until afterwards. Gotta be quick round here clearly. $\endgroup$
    – Ymareth
    Jan 10, 2014 at 18:23
  • $\begingroup$ Not really. I tried to get rid of Hold in the output. The advantage of the present approach is the ease of its later evaluation it, if needed, as it is shown above. Its penalty is to have Hold visible, which (it seems) was not desired by Tyilo. The penalty of my approach is that the way to evaluate the result is less straightforward. It may be done however by /.Defer->Evaluate. $\endgroup$ Jan 13, 2014 at 8:45
  • $\begingroup$ @AlexeiBoulbitch If you're referring to the downvote, that wasn't me. $\endgroup$
    – Tyilo
    Aug 24, 2014 at 2:52
  • $\begingroup$ @Tyilo No, the up- and downvotes are no matter for me. I just discuss the essence as I understand it. Have fun. $\endgroup$ Aug 24, 2014 at 19:28

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.