Function Repository Resource:

SimplifyRepeatedSubexpressions

Source Notebook

Replace repeated subexpressions in an expression with new symbols

Contributed by: Jon McLoone

ResourceFunction["SimplifyRepeatedSubexpressions"][expr]

returns a list of the expr with repeated subexpressions removed, along with the replacement rules used to rewrite them in simpler form.

Details and Options

ResourceFunction["SimplifyRepeatedSubexpressions"] supports the following options:
"MinLeafCount"2minimum size of the subexpressions to be extracted
"VariableNames"Unique[]&method to generate the names of the subexpressions

Examples

Basic Examples (2) 

Find the repeated term in the expression (a+b+c)3+(a+b+c)2:

In[1]:=
result = ResourceFunction[
  "SimplifyRepeatedSubexpressions"][(a + b + c)^3 + (a + b + c)^2]
Out[1]=

Reconstruct the original expression from the decomposed form:

In[2]:=
ReplaceRepeated @@ result
Out[2]=

Options (6) 

Finding many small common subexpressions may not be helpful:

In[3]:=
ResourceFunction["SimplifyRepeatedSubexpressions"][
 Solve[a x^2 + b x + c == 0, x]]
Out[3]=

Find only the largest with "MinLeafCount":

In[4]:=
ResourceFunction["SimplifyRepeatedSubexpressions"][
 Solve[a x^2 + b x + c == 0, x], "MinLeafCount" -> 10]
Out[4]=

You can control the prefix used for subexpressions by providing a string:

In[5]:=
ResourceFunction["SimplifyRepeatedSubexpressions"][
 Solve[a x^2 + b x + c == 0, x], "VariableNames" -> "var"]
Out[5]=

You can also control the names used for subexpressions by providing a list of variable names:

In[6]:=
ResourceFunction["SimplifyRepeatedSubexpressions"][
 Solve[a x^2 + b x + c == 0, x], "VariableNames" -> {"discriminant"}, "MinLeafCount" -> 10]
Out[6]=

Or by providing a generating function:

In[7]:=
i = 0; ResourceFunction["SimplifyRepeatedSubexpressions"][
 Solve[a x^2 + b x + c == 0, x], "VariableNames" -> (newVar[i++] &)]
Out[7]=

The "VariableNames" option takes the subexpression as an argument:

In[8]:=
i = 0; ResourceFunction["SimplifyRepeatedSubexpressions"][
 Solve[a x^2 + b x + c == 0, x], "VariableNames" -> ("Hash" <> ToString[Hash[#]] &)]
Out[8]=

Applications (1) 

Remove the discriminant from the quadratic solution equations:

In[9]:=
ResourceFunction["SimplifyRepeatedSubexpressions"][
 Solve[a x^2 + b x + c == 0, x], "MinLeafCount" -> 10]
Out[9]=

Properties and Relations (1) 

Reconstruct the original expression from the decomposed form by applying ReplaceRepeated:

In[10]:=
result = ResourceFunction[
  "SimplifyRepeatedSubexpressions"][(a + b + c)^3 + (a + b + c)^2]
Out[10]=
In[11]:=
ReplaceRepeated @@ result
Out[11]=

Possible Issues (2) 

The FullForm of subexpressions must match; in this case, no match is found:

In[12]:=
ResourceFunction["SimplifyRepeatedSubexpressions"][
 a + b + c + (a + b + c)^2]
Out[12]=

This is because the outermost Plus has four arguments and not just the a, b and c:

In[13]:=
FullForm[a + b + c + (a + b + c)^2]
Out[13]=

If the input expression contains elements with HoldAll, HoldRest or HoldFirst, the contents will evaluate during the search:

In[14]:=
ResourceFunction["SimplifyRepeatedSubexpressions"][
 Hold[Print[{2 + 2, 2 + 2}]]]
Out[14]=

Neat Examples (3) 

Simplify the third-degree polynomial solution:

In[15]:=
ResourceFunction["SimplifyRepeatedSubexpressions"][
 Solve[a x^3 + b x^2 + c x + d == 0, x], "MinLeafCount" -> 30]
Out[15]=

And the fourth-degree polynomial solution:

In[16]:=
ResourceFunction["SimplifyRepeatedSubexpressions"][
 Solve[a x^4 + b x^3 + c x^2 + d x + e == 0, x], "MinLeafCount" -> 30]
Out[16]=

Construct meaningful variable names based on their content:

In[17]:=
abbreviate[s_String] := Decapitalize@
   Transliterate@
    StringJoin[StringTake[s, 1], StringDelete[StringTake[s, 2 ;;], "a" | "e" | "i" | "o" | "u"]];
nameVariable[QuantityVariable[name_String, dim_String]] := abbreviate[name <> dim];
nameVariable[1/symb_] := "inv" <> nameVariable[symb];
nameVariable[
   QuantityVariable[Subscript[a_String, b_String], dim_String]] := abbreviate[a] <> "Sub" <> abbreviate[b <> dim];
nameVariable[func_[con_]] := abbreviate[ToString[func] <> nameVariable@con];
nameVariable[else_] := Unique[];
In[18]:=
First@ResourceFunction["SimplifyRepeatedSubexpressions"][
  FormulaData["RunningInTheRain"], "VariableNames" -> nameVariable]
Out[18]=

Publisher

Jon McLoone

Requirements

Wolfram Language 11.3 (March 2018) or above

Version History

  • 1.1.0 – 29 November 2021

License Information