Skip to main content

Rule Operations

Very much like Signature Operations, reaction rules can be composed as well.

There are several variants for combining rules, each determined by the specific operator employed:

  • Composition and nesting
  • Tensor product and parallel product
  • Merge product

Nesting and parallel product are analogous to composition and tensor product, respectively, but involve name sharing.

caution

Currently, only the parallel product is implemented.

Composing Rules in Parallel​

Create Reaction Rules​

Three methods are defined that create the signature, and the two rules named A and B. The rules are also displayed below for reference.

private DefaultDynamicSignature sig() {
DynamicSignatureBuilder defaultBuilder = pureSignatureBuilder();
defaultBuilder
.addControl("A", 1)
.addControl("B", 1)
.addControl("C", 1)
.addControl("D", 1)
;
return defaultBuilder.create();
}

private ReactionRule<PureBigraph> createRR_A() throws InvalidReactionRuleException {
DefaultDynamicSignature sig = sig();
PureBigraphBuilder<DefaultDynamicSignature> bRedex = pureBuilder(sig);
PureBigraphBuilder<DefaultDynamicSignature> bReactum = pureBuilder(sig);

bRedex.createRoot()
.addChild("A").down()
/**/.addSite().top()
;
bReactum.createRoot()
.addChild("A").down()
/**/.addSite()
/**/.addChild("B")
;
PureBigraph redex = bRedex.createBigraph();
PureBigraph reactum = bReactum.createBigraph();
ParametricReactionRule<PureBigraph> rr = new ParametricReactionRule<>(redex, reactum);
rr.withLabel("RA");
TrackingMap map = new TrackingMap();
map.put("v0", "v0");
map.put("v1", "");
rr.withTrackingMap(map);
InstantiationMap iMap = InstantiationMap.create(1);
iMap.map(0, 0);
rr.withInstantiationMap(iMap);
return rr;
}

private ReactionRule<PureBigraph> createRR_B() throws InvalidReactionRuleException {
DefaultDynamicSignature sig = sig();
PureBigraphBuilder<DefaultDynamicSignature> bRedex = pureBuilder(sig);
PureBigraphBuilder<DefaultDynamicSignature> bReactum = pureBuilder(sig);

bRedex.createRoot()
.addChild("C").down()
/**/.addChild("B").down()
/**//**/.addSite().addChild("C")
;

bReactum.createRoot()
.addChild("C").down()
/**/.addChild("B").down()
/**//**/.addSite().addChild("C")
;

PureBigraph redex = bRedex.createBigraph();
PureBigraph reactum = bReactum.createBigraph();
ParametricReactionRule<PureBigraph> rr = new ParametricReactionRule<>(redex, reactum);
rr.withLabel("RB");
TrackingMap map = new TrackingMap();
map.put("v0", "v0");
map.put("v1", "v1");
map.put("v2", "v2");
rr.withTrackingMap(map);
InstantiationMap iMap = InstantiationMap.create(1);
iMap.map(0, 0);
rr.withInstantiationMap(iMap);
return rr;
}
note

Both rules have also an instantiation map and a tracking map assigned.

Rule ARule B
imgsimgs

Calling the Rule Composer​

After having defined the two rules, we can call the ReactionRuleComposer class:

ReactionRule<PureBigraph> rrA = createRR_A();
ReactionRule<PureBigraph> rrB = createRR_B();
ReactionRuleComposer<ParametricReactionRule<Bigraph<?>>> rComp = new ReactionRuleComposer<>();
ParametricReactionRule<Bigraph<?>> product = rComp.parallelProduct(rrA, rrB);

The result is shown below.

imgs

Note that the instantiation map and tracking map has changed as well:

System.out.println("Product label = " + product.getLabel());
assert product.getLabel().equals("RA_PP_RB");
System.out.println(product.getTrackingMap());
product.getInstantationMap().getMappings().forEach((k,v) -> {
System.out.println(k.getValue() + " -> " + v.getValue());
});

Output

Product label = RA_PP_RB
{v0=v0, v1=, v2=v1, v3=v2, v4=v3}
1 -> 1
0 -> 0
tip

The default string separator "_PP_" combines the two rule labels to form a new rule label. This separator string can be changed by calling ReactionRuleComposer#withSeparator(String).