I sometimes need fine grain control over equations in Mathematica in order to help me understand how to solve a problem manually. A greatly simplified example of a session might be something like this:
2x + 3 == 5x - 7
2 x + 3 == 5 x - 7
% /. lhs_ == rhs_ -> lhs - 2x == rhs - 2x
3 == 3 x - 7
% /. lhs_ == rhs_ -> lhs + 7 == rhs + 7
10 == 3 x
% /. lhs_ == rhs_ -> lhs / 3 == rhs / 3
10 / 3 == x
Instead of constantly writing expressions like lhs_ == rhs_ -> lhs - 2x == rhs - 2x
, I would like to write function calls like eqnx[e - 2x]
where the e
represents the expression being modified and is applied to both the lhs and rhs of the equation.
My intuition leads me to believe that this is exactly inline with Mathematica's strengths, but my rational mind cannot deduce anything close to a correctly working function. Is this possible? Or, should I be taking a different approach?
Edit: Xerxes gives an excellent method below for accomplishing this task using the built-in Distribute[expr, g]
function. Now that I understand how Distribute
works, I can see that it is very useful. I have been using his technique with a small tweak to reduce the amount of typing required and here is a sample session:
eqx[e_] := Distribute[e, Equal]
2 x + 3 == 5 x - 7
eqx[% - 2x]
3 = -7 + 5 x
eqx[% + 7]
10 = 3 x
eqx[% / 3]
10/3 = x
The intention of my original question, however, was a rule based technique so that I could more easily work with lines of input or output that already existed (I think my question states this but my detailed description did not reiterate that point). The function approach is efficient as long as you can use %
, but in most of my work I am iteratively trying different things on the same input and I cannot reliable use %
and must be remember to grab the correct In[#]
or Out[#]
.
Based on the answers to this question and others on this forum, I was able to figure out a rule based solution. While the functionality is similar, the specifics of using the function make for a different user experience. Here is a sample session:
reqx[e_] := lhs_ == rhs_ -> (e /. expr -> lhs) == (e /. expr -> rhs)
2 x + 3 == 5 x - 7 /. reqx[expr - 2x]
3 == -7 + 3 x /. reqx[expr + 7]
10 == 3 x /. reqx[expr / 3]
10/3 == x
The one issue that I don't understand how to address relates to the placeholder expr
that I use in calls to the reqx
function. Inside the function this symbol gets replaced by the lhs
and rhs
expressions to produce the result. Its only function is to serve as a placeholder in the expression given to the reqx
function.
As long as expr
does not have a value (or rule in Mathematica parlance), everything works fine. Is there something I can do to mitigate or eliminate this potential snafu in usage?
Edit 2: I believe the following definition appropriately protects the placeholder from evaluation:
reqx[e_] := lhs_ == rhs_ -> (Unevaluated[e] /. HoldPattern[expr] -> lhs)
== (Unevaluated[e] /. HoldPattern[expr] -> rhs)
SetAttributes[reqx, HoldAllComplete]