Chemical reactions can be categorized according to their specific properties, which can be used to predict information about unseen reactions without an empirical process. This project builds functions that classify elementary chemical reactions based on properties such as reaction type and molecularity, and approximate the standard enthalpy change,
Δ
r
H
, for reactions via bond energies.

Introduction

The classification of chemical reactions is key to understanding and analyzing chemical processes. By detecting certain properties from reactions and grouping those with common traits, we can estimate reaction mechanisms and products for unknown reactions. Moreover, it allows us to handle large amounts of data of chemical reactions by organizing them into similar reactions. To expedite this sorting process, I have created functions that categorize and provide details about any given elementary chemical reaction. Most broadly, reactions can be labelled as one of these four reaction types—synthesis, decomposition, single displacement, and double displacement—the basic forms of which are represented by the table below.
In[]:=
TextGrid[{{"Synthesis","A+B → C"},{"Decomposition","A → B+C"},{"Single Displacement","AB+C → A+BC"},{"Double Displacement","AB+CD → AC+BD"}},Frame->All,Spacings->4,ItemSize->16,BaseStyle->14]
Out[]=
Synthesis
A+B → C
Decomposition
A → B+C
Single Displacement
AB+C → A+BC
Double Displacement
AB+CD → AC+BD
Another property that provides information about reaction mechanisms is molecularity. The molecularity of a reaction refers to the number of molecules that are colliding to react in the rate-determining step, and is categorized into unimolecular, bimolecular, and termolecular. In the case of elementary reactions, which occur in one step, the rate-determining step is the reaction itself. As shown in this table, the colliding reactants can be different molecules, or two or more of the same kind of molecule.
In[]:=
TextGrid[{{"Unimolecular","A → products"},{"Bimolecular","A+B → products","2A → products"},{"Termolecular","A+B+C → products","2A+B → products"}},Frame->All,Spacings->4,ItemSize->16,BaseStyle->14]
Out[]=
Unimolecular
A → products
​
Bimolecular
A+B → products
2A → products
Termolecular
A+B+C → products
2A+B → products
Thermochemistry, the study of describing the energy changes during a chemical reaction, involves key properties of chemical reactions related to enthalpy (heat). Bond Energy, or Bond Dissociation Energy (referred to as BDE from here), is the energy required to break a particular bond in a molecule in the gas phase.[1] BDE is measured in kJ/mol, which means that it takes that much kilojoules of energy to break a mole of those bonds. The value of BDE increases as the strength of the bond/bond order increases. In a chemical reaction, bonds of the reactants break, formulating an activated complex, before certain bonds form to create products. Energy is required in order to break the bonds of the reactants and is released when bonds of the products form. These bond energies can be used to approximate the enthalpy of the reaction.
Enthalpy of Reaction,
Δ
r
H
, is the change in enthalpy of a chemical reaction. In thermodynamics, change in enthalpy is useful for calculating the amount of energy per mole either released or produced in a reaction, and is a property specific to a certain reaction.[2] Numerically, the change in enthalpy of a reaction can be calculated by the equation ∑(heat of formation of products) - ∑(heat of formation of reactants). In this project, we calculate an approximation of this route, given by the equation ∑(bond energy of reactants) - ∑(bond energy of products).

Determining the Reaction Type

Most elementary chemical reactions follow certain patterns, and thus can be grouped into categories based on the types of reactants and products. Synthesis reactions typically involve two molecules combining to form one complex product, and decomposition reactions have one reactant splitting into two products. In single displacement reactions, one element replaces another element that is part of a compound because of the difference in reactivity between the element replacing and that being replaced. Meanwhile, double displacement reactions happen when two salts swap the matching of anions and cations to form two new compounds. Now, let’s work through the process of building a function with the example reaction,
.

Defining Variables

First, define variables that each represent the number of reactants, number of products, list of ions in the reactants, and a list of ions in the products.
Obtaining the length of list of reactants/products:
In[]:=
reaction=ChemicalReaction
Mg
+
Cu
(N
O
3
)
2
⟶
Mg
(N
O
3
)
2
+
Cu
;​​moleculeList[option1_String]:=Length[Values[reaction[option1]]];​​moleculeList/@{"ReactantCounts","ProductCounts"}
Out[]=
{2,2}
Mapping the built-in property “IonCounts” onto a list of reactants/products, deleting empty lists, and sorting the list in alphabetical order:
In[]:=
ionList[option2_String]:=Sort[Flatten[Normal[EntityValue[#,"IonCounts"]&/@ReactionBalance[reaction][option2]/.{}->Nothing]]]​​ionList/@{"Reactants","Products"}
Out[]=
{{IonCopperII1,IonNitrate2},{IonMagnesium1,IonNitrate2}}

Matching Numbers to Labels

Comparing these variables to specific conditions, we can directly assign reaction types. Synthesis and decomposition reactions can easily be distinguished by examining their number of reactants and products. Synthesis reactions have two molecules merging into one compound, so there would be two reactants and one product; the opposite applies to decomposition reactions. Picking out single and double replacement reactions require a more specific criteria. Single replacement reactions involve two reactant ions and two product ions, and the reactant and product sides share one common ion. Double replacement reactions involve four reactant ions and four product ions, and the sorted list of reactant ions must be identical to that of product ions. For the sample reaction
, since the lengths of lists for reactant ions and product ions are both two and they have IonNitrate in common, the reaction is a single displacement reaction. ​Single and double replacement reactions involving water in either the products or the reactants must be picked out separately. This is because water is considered a molecular compound rather than an ionic compound, but it can still participate in replacement reactions by splitting into
+
H
and
-
OH
ions.
Using the Switch function to employ multiple conditions and their corresponding outputs:
In[]:=
SwitchreactantNumber,productNumber,Length@reactantIonList,Length@productIonList,​​Keys@reactantIonList===Keys@productIonList,If[Length[reactantIonList]>=2,MemberQ[Keys[productIonList],Keys[reactantIonList][[1]]]||MemberQ[Keys[productIonList],Keys[reactantIonList][[2]]],False],​​MemberQreaction["Products"],
water
CHEMICAL
,​​MemberQreaction["Reactants"],
water
CHEMICAL
​​,​​{2,1,__},"Synthesis",​​{1,2,__},"Decomposition",​​{_,_,4,4,True,__},"Double Replacement",​​{_,_,4,2,False,_,True,_},"Double Replacement; Acid-Base Neutralization",​​{_,_,2,2,False,True,__},"Single Replacement",​​{_,_,0,2,False,_,_,True},"Single Replacement",​​{__},"Not Classified"​​
Out[]=
Single Replacement

Putting it All Together

Assembling the codes above into a module, a complete function that takes a chemical reaction as input and outputs the type of reaction is built.
In[]:=
reactionType[reaction_ChemicalReaction]:=Module{​​reactantNumber=Length[Values[reaction["ReactantCounts"]]],productNumber=Length[Values[reaction["ProductCounts"]]],​​reactantIonList=Sort[Flatten[Normal[EntityValue[#,"IonCounts"]&/@ReactionBalance[reaction]["Reactants"]/.{}->Nothing]]],​​productIonList=Sort[Flatten[Normal[EntityValue[#,"IonCounts"]&/@ReactionBalance[reaction]["Products"]/.{}->Nothing]]]​​},​​SwitchreactantNumber,productNumber,Length@reactantIonList,Length@productIonList,​​Keys@reactantIonList===Keys@productIonList,If[Length[reactantIonList]>=2,MemberQ[Keys[productIonList],Keys[reactantIonList][[1]]]||MemberQ[Keys[productIonList],Keys[reactantIonList][[2]]],False],​​MemberQreaction["Products"],
water
CHEMICAL
,​​MemberQreaction["Reactants"],
water
CHEMICAL
​​,​​{2,1,__},"Synthesis",​​{1,2,__},"Decomposition",​​{_,_,4,4,True,__},"Double Replacement",​​{_,_,4,2,False,_,True,_},"Double Replacement;Acid-Base Neutralization",​​{_,_,2,2,False,True,__},"Single Replacement",​​{_,_,0,2,False,_,_,True},"Single Replacement",​​{__},"Not Classified"​​​​

Results

Below is a sample list of chemical reactions, and each of its elements represent a different reaction type.
Map the function onto reactionsList to get a list of corresponding types of reaction:
In[]:=
reactionsList=ChemicalReaction
N
2
+
H
2
⟶
N
H
3
,ChemicalReaction
CaC
O
3
⟶
CaO
+
C
O
2
,ChemicalReaction
Mg
+
Cu
(N
O
3
)
2
⟶
Mg
(N
O
3
)
2
+
Cu
,ChemicalReaction
KI
+
Pb
(N
O
3
)
2
⟶
Pb
I
2
+
KN
O
3
,ChemicalReaction
HCl
+
NaOH
⟶
H
2
O
+
NaCl
;reactionType/@reactionsList
Out[]=
{Synthesis,Decomposition,Single Replacement,Double Replacement,Double Replacement;Acid-Base Neutralization}

Determining Molecularity

The number of reactants determines the molecularity of a chemical reaction. The reaction is unimolecular if there is one molecule of reactant, bimolecular if there are two, and termolecular if there are three. Since this project only deals with elementary reactions, and it is extremely unlikely for more than three molecules to collide at once, molecularity is only defined up to termolecular. I made a recursive function called ReactionMolecularity (currently published in the Wolfram Function Repository) that can take input in the form of either PatternReaction or Chemical Reaction. Because multiple molecules of the same kind must be repeated in PatternReactions, one can simply find the length of the reactants list to determine the number of molecules used. When a ChemicalReaction is inputted, the coefficients of the balanced reaction must be taken into account, so the function adds up the coefficients of all reactants. If anything other than an elementary reaction is inputted, the function returns “NotAnElementaryReaction.”
Print the number of reactants:
In[]:=
ReactionMolecularity[reaction_PatternReaction]:=ReactionMolecularity[Length[reaction["Reactants"]]]​​ReactionMolecularity[reaction_ChemicalReaction]:=ReactionMolecularity[Total[ReactionBalance[reaction]["ReactantCounts"]]]
Use the Switch function to match the integer input to the corresponding molecularity. Both Which and Switch could have been used, but Switch is faster:
In[]:=
ReactionMolecularity[reactants_]:=Switch[reactants,1,"Unimolecular",2,"Bimolecular",3,"Termolecular",_,Missing["NotAnElementaryReaction"]]
Results

Determining Broken/Formed Bonds

Enthalpy of reaction is crucial information in understanding thermodynamics, as it tells us how much heat energy of the system was lost or gained. This is a useful tool in predicting whether a chemical reaction will give off heat, which can be used to do work in industrial processes, or requires energy supply. As aforementioned, the enthalpy change can be estimated through BDE calculations because bond destruction and formation are closely related to heat energy. Bond breaking is an endothermic process absorbing heat, and bond making is an exothermic process releasing heat. Bonds present in the reactants that are not part of the products’ bond list are bonds broken in the reaction; conversely, bonds present in the reactants that were not part of the reactants are bonds formed.

Counting Bonds

Using ReactantCounts on a balanced reaction to obtain each reactant and its corresponding coefficient:
Making a list of bonds using BondList and mapping the Sort function onto it:
An If condition that checks whether each bond is part of any molecule in reactantCoeff, and appends the bond to reactantBonds if True:
Then, the format of the list is tidied up by deleting the numbered index expression of each bond and grouping like bonds together. Repeating the same process for product bonds, the following associations are stored respectively into reactantBondTally and productBondTally.
Make a list of the distinct elements and their multiplicities using Tally:

Deleting Duplicate Bonds

Duplicate bonds between the reactants and products must be deleted from both lists. I attempted to use the Complement function as below, but this was inappropriate for our purpose because it does not take into account which side has more of the bond; rather, it simply removes all mutual elements.
Complement deletes all elements in the first item that are in the second item:
Thus, each bond must be examined one by one. For each bond on the products side, check if it is part of any reactant. If a common bond is detected, now we can cancel them out from both sides. For instance, if there are 4 N-O bonds on the reactants side and 2 N-O bonds on the products side, the goal is to delete all N-O bonds on the products side and update the number of N-O bonds on the reactants to become 4 - 2 = 2. The problem is divided into two scenarios for each bond type: when there are more on the products side than on the reactants side, and vice versa. The side with less is made 0, and the side with more is subtracted by how many there were on the other side. Then, we polish up the tallies by deleting the rules whose value is 0. The function outputs two associations in a list—the first item is an association for bonds broken and their multiplicities, and the second item is the equivalent for bonds formed.
Extracting the keys (the types of bonds) from the tallied associations:
Using Which to treat each case separately:

Putting it All Together

Similarly to the previous function, we can put together all the parts above into a module and save it a function named “bondIdentify.”

Results

Calculating Reaction Enthalpy Change

For this task, I started by making a data set in the form of an association that lists the standard BDE. The data is retrieved from WolframAlpha and the source cited below.[4] While not complete, the dataset contains many of the bonds commonly found in organic and inorganic chemical reactions. Below is a small portion of the entire association that contains rules in the format of “bond → BDE.” For convenient detection, a rule with the bond A-B is repeated with the bond B-A, as bonds should be treated as the same kind regardless of its atom order. For instance, the BDE of 362 kJ/mol is entered for both H-Br and Br-H bonds.
Building an association with rules that assign BDE to bonds:
Iconized version of the entire dataset:
Within a Module, the function takes the output from bondIdentify and saves the type of bonds into a list. For each item in the list, the corresponding values for the bond type in bondEnergies dataset is added/subtracted to enthalpyChange. The BDE is added to enthalpyChange if it is a bond broken, and subtracted if it is a bond created.
AssociationMap allows the expression to be mapped over an association, as opposed to a list for a normal Map function:

Results

Here is the calculation done above broken down step by step:
2(H-H BDE) + (O=O BDE) - 4(O-H BDE)
= 2*436 + 495 - 4*459
= -469 (kJ/mol rxn)
Here is the calculation done above broken down step by step:
(N≡N BDE) + 3(H-H BDE) - 6(N-H BDE)
= 941 + 3*436 - 6*386
= -67 (kJ/mol rxn)

Interactive Summary

Given the functions built in this project, now we can arrange this information into a visual representation that shows different properties of reactions. This summary table contains the 3D picture of the molecules in the reactants and products, data on bonds broken and formed, the balanced reaction, molecularity, reaction type, and the approximated enthalpy of reaction. The function MoleculeGridPlot3D from the Wolfram Language Packet Repository is used to picture the molecules of reactants and products. [3]
Manipulate allows the user to click options for different reactions in the drop-down menu:

Conclusion

Through this project, I have created functions that can classify a wide range of chemical reactions based on their properties. These functions can be used on a vast amount of data to effectively group like reactions. I hope to further contribute to Wolfram’s chemistry department by publishing more of these functions on the Wolfram Function Repository. I would like to express exceptional gratitude to my mentor Jason Sonnenberg for consistently guiding me through difficulties and helping me explore diverse avenues of research.

Future Work

Works Cited

1. Libretexts. (2023c, July 12). 10.9: Bond energies. Chemistry LibreTexts.
2. Libretexts. (2023a, January 30). Heat of reaction. Chemistry LibreTexts.
3. Wolfram Language paclet repository. ChemistryFunctions | Wolfram Language Paclet Repository. (n.d.-b).
4. Bond enthalpy (bond energy). (n.d.).