10.3. Derivations and Reaction Networks

10.3.1. Rule Application

Transformation rules (reaction patterns) can be applied to graphs (molecules) to create new graphs (molecules). The transformations (reactions) implicitly form a directed (multi-)hypergraph (chemical reaction network).

Explore in the playground.

 1include("../000_basics/050_formoseGrammar.py")
 2# Reaction networks are expaned using a strategy:
 3strat = (
 4   # A molecule can be active or passive during evaluation.
 5   addUniverse(formaldehyde) # passive
 6   >> addSubset(glycolaldehyde) # active
 7   # Aach reaction must have a least 1 active educt.
 8   >> inputRules
 9)
10# We call a reaction network a 'derivation graph'.
11dg = DG(graphDatabase=inputGraphs)
12dg.build().execute(strat)
13# They can also be visualised.
14dg.print()

10.3.2. Repetition

A sub-strategy can be repeated.

Explore in the playground.

 1include("../000_basics/050_formoseGrammar.py")
 2strat = (
 3   addUniverse(formaldehyde)
 4   >> addSubset(glycolaldehyde)
 5   # Iterate the rule application 4 times.
 6   >> repeat[4](
 7      inputRules
 8   )
 9)
10dg = DG(graphDatabase=inputGraphs)
11dg.build().execute(strat)
12dg.print()

10.3.3. Application Constraints

We may want to impose constraints on which reactions are accepted. E.g., in formose the molecules should not have too many carbon atoms.

Explore in the playground.

 1include("../000_basics/050_formoseGrammar.py")
 2strat = (
 3   addUniverse(formaldehyde)
 4   >> addSubset(glycolaldehyde)
 5   # Constrain the reactions:
 6   # No molecules with more than 20 atoms can be created.
 7   >> rightPredicate[
 8      lambda derivation: all(g.numVertices <= 20 for g in derivation.right)
 9   ](
10      # Iterate until nothing new is found.
11      repeat(
12         inputRules
13      )
14   )
15)
16dg = DG(graphDatabase=inputGraphs)
17dg.build().execute(strat)
18dg.print()

10.3.4. Advanced Printing

Reaction networks can become large, and often it is necessary to hide parts of the network, or in general change the appearance.

Explore in the playground.

 1include("212_dgPredicate.py")
 2# Create a printer with default options:
 3p = DGPrinter()
 4# Hide "large" molecules: those with > 4 Cs:
 5p.pushVertexVisible(lambda v: v.graph.vLabelCount("C") <= 4)
 6# Hide the reactions with the large molceules as well:
 7def edgePred(e):
 8   if any(v.graph.vLabelCount("C") > 4 for v in e.sources): return False
 9   if any(v.graph.vLabelCount("C") > 4 for v in e.targets): return False
10   return True
11p.pushEdgeVisible(edgePred)
12# Add the number of Cs to the molecule labels:
13p.pushVertexLabel(lambda v: "#C=" + str(v.graph.vLabelCount("C")))
14# Highlight the molecules with 4 Cs:
15p.pushVertexColour(lambda v: "blue" if v.graph.vLabelCount("C") == 4 else "")
16# Print the network with the customised printer.
17dg.print(p)

10.3.5. Double Pushout Printing

Each reaction/derivation can be visualised as a DPO diagram.

Explore in the playground.

1include("212_dgPredicate.py")
2for e in dg.edges:
3   e.print()