Implemented rack-b algorithm

This commit is contained in:
Maximilian Kratz 2021-07-15 16:08:33 +02:00
parent 77c8ee395f
commit 4bf8c24171
27 changed files with 533 additions and 35 deletions

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>network.model.rules.rack.a</name>
<name>network.model.rules.racka</name>
<comment></comment>
<projects>
</projects>

View file

@ -1,10 +1,10 @@
Manifest-Version: 1.0
Automatic-Module-Name: network.model.rules.rack
Bundle-ManifestVersion: 2
Bundle-Name: network.model.rules.rack
Bundle-Name: network.model.rules.racka
Bundle-Vendor: My Company
Bundle-Version: 1.0.0.qualifier
Bundle-SymbolicName: network.model.rules.rack.a;singleton:=true
Bundle-SymbolicName: network.model.rules.racka;singleton:=true
Bundle-ActivationPolicy: lazy
Import-Package: org.apache.log4j,
org.apache.commons.logging
@ -15,6 +15,6 @@ Require-Bundle: org.emoflon.ibex.common,
org.emoflon.ibex.gt.democles,
org.emoflon.ibex.gt.hipe,
org.emoflon.ibex.gt.viatra
Export-Package: network.model.rules.rack.api,
network.model.rules.rack.api.matches,
network.model.rules.rack.api.rules
Export-Package: network.model.rules.racka.api,
network.model.rules.racka.api.matches,
network.model.rules.racka.api.rules

View file

@ -14,12 +14,12 @@ import model.Element;
import model.Root;
import model.SubstrateElement;
import model.VirtualElement;
import network.model.rules.rack.api.RackAPI;
import network.model.rules.rack.api.RackApp;
import network.model.rules.rack.api.matches.LinkPathMatchPositiveMatch;
import network.model.rules.rack.api.matches.LinkServerMatchPositiveMatch;
import network.model.rules.rack.api.matches.ServerMatchPositiveMatch;
import network.model.rules.rack.api.matches.SwitchMatchPositiveMatch;
import network.model.rules.racka.api.RackaAPI;
import network.model.rules.racka.api.RackaApp;
import network.model.rules.racka.api.matches.LinkPathMatchPositiveMatch;
import network.model.rules.racka.api.matches.LinkServerMatchPositiveMatch;
import network.model.rules.racka.api.matches.ServerMatchPositiveMatch;
import network.model.rules.racka.api.matches.SwitchMatchPositiveMatch;
/**
* Implementation of the {@link IncrementalPatternMatcher} for eMoflon.
@ -31,12 +31,12 @@ public class EmoflonGtRackA implements IncrementalPatternMatcher {
/**
* Rack Rules API object generated from graph transformation patterns.
*/
private final RackAPI api;
private final RackaAPI api;
/**
* Wrapper that initializes the API object.
*/
private final RackApp emoflonPatternMatcherApp;
private final RackaApp emoflonPatternMatcherApp;
/**
* Current state of the delta. Must be updated in every iteration.

View file

@ -1,14 +1,14 @@
package gt.emoflon.apps;
import model.Root;
import network.model.rules.rack.api.RackHiPEApp;
import network.model.rules.racka.api.RackaHiPEApp;
/**
* Wrapper class for initializing the rack A rules HiPe App pattern matcher.
*
* @author Maximilian Kratz {@literal <maximilian.kratz@stud.tu-darmstadt.de>}
*/
public class EmoflonGtRackAHiPEApp extends RackHiPEApp {
public class EmoflonGtRackAHiPEApp extends RackaHiPEApp {
/**
* Constructor that initializes the model resources for a given root node.

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>network.model.rules.rack.b</name>
<name>network.model.rules.rackb</name>
<comment></comment>
<projects>
</projects>

View file

@ -1,10 +1,10 @@
Manifest-Version: 1.0
Automatic-Module-Name: network.model.rules.rack
Automatic-Module-Name: network.model.rules.rackb
Bundle-ManifestVersion: 2
Bundle-Name: network.model.rules.rack
Bundle-Name: network.model.rules.rackb
Bundle-Vendor: My Company
Bundle-Version: 1.0.0.qualifier
Bundle-SymbolicName: network.model.rules.rack; singleton:=true
Bundle-SymbolicName: network.model.rules.rackb;singleton:=true
Bundle-ActivationPolicy: lazy
Import-Package: org.apache.log4j,
org.apache.commons.logging
@ -15,6 +15,6 @@ Require-Bundle: org.emoflon.ibex.common,
org.emoflon.ibex.gt.democles,
org.emoflon.ibex.gt.hipe,
org.emoflon.ibex.gt.viatra
Export-Package: network.model.rules.rack.api,
network.model.rules.rack.api.matches,
network.model.rules.rack.api.rules
Export-Package: network.model.rules.rackb.api,
network.model.rules.rackb.api.matches,
network.model.rules.rackb.api.rules

View file

@ -14,13 +14,13 @@ import model.Element;
import model.Root;
import model.SubstrateElement;
import model.VirtualElement;
import network.model.rules.rack.api.RackAPI;
import network.model.rules.rack.api.RackApp;
import network.model.rules.rack.api.matches.LinkPathMatchPositiveMatch;
import network.model.rules.rack.api.matches.LinkPathMatchServerServerMatch;
import network.model.rules.rack.api.matches.LinkServerMatchPositiveMatch;
import network.model.rules.rack.api.matches.ServerMatchPositiveMatch;
import network.model.rules.rack.api.matches.SwitchMatchPositiveMatch;
import network.model.rules.rackb.api.RackbAPI;
import network.model.rules.rackb.api.RackbApp;
import network.model.rules.rackb.api.matches.LinkPathMatchPositiveMatch;
import network.model.rules.rackb.api.matches.LinkPathMatchServerServerMatch;
import network.model.rules.rackb.api.matches.LinkServerMatchPositiveMatch;
import network.model.rules.rackb.api.matches.ServerMatchPositiveMatch;
import network.model.rules.rackb.api.matches.SwitchMatchPositiveMatch;
/**
* Implementation of the {@link IncrementalPatternMatcher} for eMoflon.
@ -32,12 +32,12 @@ public class EmoflonGtRackB implements IncrementalPatternMatcher {
/**
* Rack Rules API object generated from graph transformation patterns.
*/
private final RackAPI api;
private final RackbAPI api;
/**
* Wrapper that initializes the API object.
*/
private final RackApp emoflonPatternMatcherApp;
private final RackbApp emoflonPatternMatcherApp;
/**
* Current state of the delta. Must be updated in every iteration.

View file

@ -1,14 +1,14 @@
package gt.emoflon.apps;
import model.Root;
import network.model.rules.rack.api.RackHiPEApp;
import network.model.rules.rackb.api.RackbHiPEApp;
/**
* Wrapper class for initializing the rack B rules HiPe App pattern matcher.
*
* @author Maximilian Kratz {@literal <maximilian.kratz@stud.tu-darmstadt.de>}
*/
public class EmoflonGtRackBHiPEApp extends RackHiPEApp {
public class EmoflonGtRackBHiPEApp extends RackbHiPEApp {
/**
* Constructor that initializes the model resources for a given root node.

View file

@ -0,0 +1,24 @@
package test.algorithms.pm.pipeline;
import java.util.Set;
import algorithms.pm.VnePmMdvneAlgorithmPipelineThreeStagesB;
import model.SubstrateNetwork;
import model.VirtualNetwork;
import test.algorithms.pm.VnePmMdvneAlgorithmRepairModelNetworkTest;
/**
* Test class for the VNE pattern matching algorithm pipeline implementation for repairing a removed
* virtual network in the model. This test should trigger the algorithm to repair the substrate
* network information after a ungraceful removal of a previously embedded virtual network.
*
* @author Maximilian Kratz {@literal <maximilian.kratz@stud.tu-darmstadt.de>}
*/
public class VnePmMdvneAlgorithmPipelineThreeStagesBRepairModelNetworkTest
extends VnePmMdvneAlgorithmRepairModelNetworkTest {
@Override
public void initAlgo(final SubstrateNetwork sNet, final Set<VirtualNetwork> vNets) {
algo = VnePmMdvneAlgorithmPipelineThreeStagesB.prepare(sNet, vNets);
}
}

View file

@ -0,0 +1,25 @@
package test.algorithms.pm.pipeline;
import java.util.Set;
import algorithms.pm.VnePmMdvneAlgorithmPipelineThreeStagesB;
import model.SubstrateNetwork;
import model.VirtualNetwork;
import test.algorithms.pm.VnePmMdvneAlgorithmRepairModelServerTest;
/**
* Test class for the VNE pattern matching algorithm pipeline implementation for repairing a removed
* substrate server in the model. This test should trigger the algorithm to re-embed all virtual
* networks that had elements placed on the substrate server removed.
*
* @author Maximilian Kratz {@literal <maximilian.kratz@stud.tu-darmstadt.de>}
*/
public class VnePmMdvneAlgorithmPipelineThreeStagesBRepairModelServerTest
extends VnePmMdvneAlgorithmRepairModelServerTest {
@Override
public void initAlgo(final SubstrateNetwork sNet, final Set<VirtualNetwork> vNets) {
algo = VnePmMdvneAlgorithmPipelineThreeStagesB.prepare(sNet, vNets);
}
}

View file

@ -0,0 +1,26 @@
package test.algorithms.pm.pipeline;
import java.util.Set;
import algorithms.AlgorithmConfig;
import algorithms.AlgorithmConfig.Objective;
import algorithms.pm.VnePmMdvneAlgorithmPipelineThreeStagesB;
import model.SubstrateNetwork;
import model.VirtualNetwork;
import test.algorithms.pm.VnePmMdvneAlgorithmTotalCommunicationCostATest;
/**
* Test class for the VNE PM MdVNE algorithm implementation for minimizing the total communication
* cost metric A including the pipeline functionality.
*
* @author Maximilian Kratz {@literal <maximilian.kratz@stud.tu-darmstadt.de>}
*/
public class VnePmMdvneAlgorithmPipelineThreeStagesBTotalCommunicationCostATest
extends VnePmMdvneAlgorithmTotalCommunicationCostATest {
@Override
public void initAlgo(final SubstrateNetwork sNet, final Set<VirtualNetwork> vNets) {
AlgorithmConfig.obj = Objective.TOTAL_COMMUNICATION_COST_A;
algo = VnePmMdvneAlgorithmPipelineThreeStagesB.prepare(sNet, vNets);
}
}

View file

@ -0,0 +1,26 @@
package test.algorithms.pm.pipeline;
import java.util.Set;
import algorithms.AlgorithmConfig;
import algorithms.AlgorithmConfig.Objective;
import algorithms.pm.VnePmMdvneAlgorithmPipelineThreeStagesB;
import model.SubstrateNetwork;
import model.VirtualNetwork;
import test.algorithms.pm.VnePmMdvneAlgorithmTotalCommunicationCostBTest;
/**
* Test class for the VNE PM MdVNE algorithm implementation for minimizing the total communication
* cost metric B including the pipeline functionality.
*
* @author Maximilian Kratz {@literal <maximilian.kratz@stud.tu-darmstadt.de>}
*/
public class VnePmMdvneAlgorithmPipelineThreeStagesBTotalCommunicationCostBTest
extends VnePmMdvneAlgorithmTotalCommunicationCostBTest {
@Override
public void initAlgo(final SubstrateNetwork sNet, final Set<VirtualNetwork> vNets) {
AlgorithmConfig.obj = Objective.TOTAL_COMMUNICATION_COST_B;
algo = VnePmMdvneAlgorithmPipelineThreeStagesB.prepare(sNet, vNets);
}
}

View file

@ -0,0 +1,26 @@
package test.algorithms.pm.pipeline;
import java.util.Set;
import algorithms.AlgorithmConfig;
import algorithms.AlgorithmConfig.Objective;
import algorithms.pm.VnePmMdvneAlgorithmPipelineThreeStagesB;
import model.SubstrateNetwork;
import model.VirtualNetwork;
import test.algorithms.pm.VnePmMdvneAlgorithmTotalCommunicationCostCTest;
/**
* Test class for the VNE PM MdVNE algorithm implementation for minimizing the total communication
* cost metric C including the pipeline functionality.
*
* @author Maximilian Kratz {@literal <maximilian.kratz@stud.tu-darmstadt.de>}
*/
public class VnePmMdvneAlgorithmPipelineThreeStagesBTotalCommunicationCostCTest
extends VnePmMdvneAlgorithmTotalCommunicationCostCTest {
@Override
public void initAlgo(final SubstrateNetwork sNet, final Set<VirtualNetwork> vNets) {
AlgorithmConfig.obj = Objective.TOTAL_COMMUNICATION_COST_C;
algo = VnePmMdvneAlgorithmPipelineThreeStagesB.prepare(sNet, vNets);
}
}

View file

@ -0,0 +1,26 @@
package test.algorithms.pm.pipeline;
import java.util.Set;
import algorithms.AlgorithmConfig;
import algorithms.AlgorithmConfig.Objective;
import algorithms.pm.VnePmMdvneAlgorithmPipelineThreeStagesB;
import model.SubstrateNetwork;
import model.VirtualNetwork;
import test.algorithms.pm.VnePmMdvneAlgorithmTotalPathCostTest;
/**
* Test class for the VNE pattern matching algorithm implementation for minimizing the total path
* cost metric including the pipeline functionality.
*
* @author Maximilian Kratz {@literal <maximilian.kratz@stud.tu-darmstadt.de>}
*/
public class VnePmMdvneAlgorithmPipelineThreeStagesBTotalPathCostTest
extends VnePmMdvneAlgorithmTotalPathCostTest {
@Override
public void initAlgo(final SubstrateNetwork sNet, final Set<VirtualNetwork> vNets) {
AlgorithmConfig.obj = Objective.TOTAL_PATH_COST;
algo = VnePmMdvneAlgorithmPipelineThreeStagesB.prepare(sNet, vNets);
}
}

View file

@ -17,7 +17,8 @@
<classpathentry combineaccessrules="false" kind="src" path="/ilp"/>
<classpathentry combineaccessrules="false" kind="src" path="/network.model.rules"/>
<classpathentry combineaccessrules="false" kind="src" path="/network.model.rules.vnet"/>
<classpathentry combineaccessrules="false" kind="src" path="/network.model.rules.rack.a"/>
<classpathentry combineaccessrules="false" kind="src" path="/network.model.rules.racka"/>
<classpathentry combineaccessrules="false" kind="src" path="/network.model.rules.rackb"/>
<classpathentry combineaccessrules="false" kind="src" path="/network.metrics"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,133 @@
package algorithms.pm;
import java.util.HashSet;
import java.util.Set;
import algorithms.AbstractAlgorithm;
import algorithms.pm.stages.VnePmMdvneAlgorithmPipelineStageRackB;
import algorithms.pm.stages.VnePmMdvneAlgorithmPipelineStageVnet;
import metrics.manager.GlobalMetricsManager;
import model.SubstrateNetwork;
import model.VirtualNetwork;
/**
* Implementation of the model-driven virtual network algorithm that uses pattern matching as a way
* to reduce the search space of the ILP solver. This implementation uses a three-stage pipeline
* approach with rack B implementation
*
* @author Maximilian Kratz {@literal <maximilian.kratz@stud.tu-darmstadt.de>}
*/
public class VnePmMdvneAlgorithmPipelineThreeStagesB extends VnePmMdvneAlgorithm {
/**
* Algorithm instance (singleton).
*/
protected static VnePmMdvneAlgorithmPipelineThreeStagesB instance;
/**
* Constructor that gets the substrate as well as the virtual network.
*
* @param sNet Substrate network to work with.
* @param vNets Set of virtual networks to work with.
*/
protected VnePmMdvneAlgorithmPipelineThreeStagesB(final SubstrateNetwork sNet,
final Set<VirtualNetwork> vNets) {
super(sNet, vNets);
}
/**
* Initializes a new instance of the VNE pattern matching algorithm.
*
* @param sNet Substrate network to work with.
* @param vNets Set of virtual networks to work with.
* @return Instance of this algorithm implementation.
*/
public static VnePmMdvneAlgorithmPipelineThreeStagesB prepare(final SubstrateNetwork sNet,
final Set<VirtualNetwork> vNets) {
if (sNet == null || vNets == null) {
throw new IllegalArgumentException("One of the provided network objects was null.");
}
if (vNets.size() == 0) {
throw new IllegalArgumentException("Provided set of virtual networks was empty.");
}
if (instance == null) {
instance = new VnePmMdvneAlgorithmPipelineThreeStagesB(sNet, vNets);
}
instance.sNet = sNet;
instance.vNets = new HashSet<VirtualNetwork>();
instance.vNets.addAll(vNets);
instance.checkPreConditions();
return instance;
}
/**
* Resets the ILP solver and the pattern matcher.
*/
@Override
public void dispose() {
if (instance == null) {
return;
}
super.dispose();
instance = null;
}
@Override
public boolean execute() {
GlobalMetricsManager.measureMemory();
init();
// Check overall embedding possibility
checkOverallResources();
// Repair model consistency: Substrate network
repairSubstrateNetwork();
// Repair model consistency: Virtual network(s)
final Set<VirtualNetwork> repairedVnets = repairVirtualNetworks();
// if (!repairedVnets.isEmpty()) {
// this.patternMatcher = new EmoflonGtFactory().create();
// this.patternMatcherVnet = new EmoflonGtVnetFactory().create();
// }
vNets.addAll(repairedVnets);
//
// Stage 1: Virtual network -> Substrate server
//
System.out.println("=> Starting pipeline stage #1");
AbstractAlgorithm algo = VnePmMdvneAlgorithmPipelineStageVnet.prepare(sNet, vNets);
if (algo.execute()) {
return true;
}
//
// Stage 2: Virtual network -> Substrate Rack
//
// Remove embedding of all already embedded networks
PmAlgorithmUtils.unembedAll(sNet, vNets);
System.out.println("=> Starting pipeline stage #2");
dispose();
algo = VnePmMdvneAlgorithmPipelineStageRackB.prepare(sNet, vNets);
if (algo.execute()) {
return true;
}
//
// Stage 3: Normal PM-based embedding
//
// Remove embedding of all already embedded networks
PmAlgorithmUtils.unembedAll(sNet, vNets);
System.out.println("=> Starting pipeline stage #3");
dispose();
algo = VnePmMdvneAlgorithm.prepare(sNet, vNets);
return algo.execute();
}
}

View file

@ -0,0 +1,211 @@
package algorithms.pm.stages;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import algorithms.AlgorithmConfig;
import algorithms.pm.VnePmMdvneAlgorithm;
import gt.IncrementalPatternMatcher;
import gt.PatternMatchingDelta;
import gt.PatternMatchingDelta.Match;
import gt.emoflon.EmoflonGtFactory;
import gt.emoflon.EmoflonGtRackB;
import gt.emoflon.EmoflonGtRackBFactory;
import ilp.wrapper.config.IlpSolverConfig;
import ilp.wrapper.impl.IncrementalGurobiSolver;
import metrics.manager.GlobalMetricsManager;
import model.SubstrateElement;
import model.SubstrateNetwork;
import model.VirtualElement;
import model.VirtualNetwork;
/**
* Implementation of the model-driven virtual network algorithm that uses pattern matching as a way
* to reduce the search space of the ILP solver. This implementation embeds virtual networks onto
* racks B.
*
* @author Maximilian Kratz {@literal <maximilian.kratz@stud.tu-darmstadt.de>}
*/
public class VnePmMdvneAlgorithmPipelineStageRackB extends VnePmMdvneAlgorithm {
/**
* Algorithm instance (singleton).
*/
protected static VnePmMdvneAlgorithmPipelineStageRackB instance;
/**
* Incremental pattern matcher to use for the second pipeline stage.
*/
protected IncrementalPatternMatcher patternMatcherRack;
/**
* Constructor that gets the substrate as well as the virtual network.
*
* @param sNet Substrate network to work with.
* @param vNets Set of virtual networks to work with.
*/
protected VnePmMdvneAlgorithmPipelineStageRackB(final SubstrateNetwork sNet,
final Set<VirtualNetwork> vNets) {
super(sNet, vNets);
}
/**
* Initializes a new instance of the VNE pattern matching algorithm.
*
* @param sNet Substrate network to work with.
* @param vNets Set of virtual networks to work with.
* @return Instance of this algorithm implementation.
*/
public static VnePmMdvneAlgorithmPipelineStageRackB prepare(final SubstrateNetwork sNet,
final Set<VirtualNetwork> vNets) {
if (sNet == null || vNets == null) {
throw new IllegalArgumentException("One of the provided network objects was null.");
}
if (vNets.size() == 0) {
throw new IllegalArgumentException("Provided set of virtual networks was empty.");
}
if (instance == null) {
instance = new VnePmMdvneAlgorithmPipelineStageRackB(sNet, vNets);
}
instance.sNet = sNet;
instance.vNets = new HashSet<VirtualNetwork>();
instance.vNets.addAll(vNets);
instance.checkPreConditions();
return instance;
}
/**
* Resets the ILP solver and the pattern matcher.
*/
@Override
public void dispose() {
if (instance == null) {
return;
}
if (this.ilpSolver != null) {
this.ilpSolver.dispose();
}
if (this.patternMatcher != null) {
this.patternMatcher.dispose();
}
if (this.patternMatcherRack != null) {
this.patternMatcherRack.dispose();
}
super.dispose();
instance = null;
}
@Override
public boolean execute() {
GlobalMetricsManager.measureMemory();
init();
// // Check overall embedding possibility
// checkOverallResources();
//
// // Repair model consistency: Substrate network
// repairSubstrateNetwork();
//
// // Repair model consistency: Virtual network(s)
// final Set<VirtualNetwork> repairedVnets = repairVirtualNetworks();
// if (!repairedVnets.isEmpty()) {
// this.patternMatcher = new EmoflonGtFactory().create();
// this.patternMatcherRack = new EmoflonGtRackFactory().create();
// }
// vNets.addAll(repairedVnets);
//
// Stage 2: Virtual network -> Rack
//
// // Remove embedding of all already embedded networks
// PmAlgorithmUtils.unembedAll(sNet, vNets);
// System.out.println("=> Starting pipeline stage #2");
GlobalMetricsManager.startPmTime();
final PatternMatchingDelta deltaTwo = patternMatcherRack.run();
GlobalMetricsManager.endPmTime();
// Uses the "normal" delta to ILP translator of the super class
delta2Ilp(deltaTwo);
GlobalMetricsManager.measureMemory();
final Set<VirtualNetwork> rejectedNetworksTwo = solveIlp();
rejectedNetworksTwo.addAll(ignoredVnets);
embedNetworks(rejectedNetworksTwo);
GlobalMetricsManager.endDeployTime();
GlobalMetricsManager.measureMemory();
return rejectedNetworksTwo.isEmpty();
}
/*
* Helper methods.
*/
/**
* Initializes the algorithm by creating a new incremental solver object and a new pattern matcher
* object.
*/
@Override
public void init() {
// Create new ILP solver object on every method call.
ilpSolver = new IncrementalGurobiSolver(IlpSolverConfig.TIME_OUT, IlpSolverConfig.RANDOM_SEED);
if (patternMatcher == null) {
patternMatcher = new EmoflonGtFactory().create();
}
if (patternMatcherRack == null) {
patternMatcherRack = new EmoflonGtRackBFactory().create();
}
}
/**
* Updates and embeds the actual mappings for a given map of names (strings) and booleans.
*
* @param mappings Map of strings and booleans. The keys are mapping names and the values define
* if the mapping was chosen.
* @return Returns a set of all virtual networks that could not be embedded.
*/
@Override
protected Set<VirtualNetwork> updateMappingsAndEmbed(final Map<String, Boolean> mappings) {
// Embed elements
final Set<VirtualNetwork> rejectedNetworks = new HashSet<VirtualNetwork>();
final EmoflonGtRackB engine = (EmoflonGtRackB) patternMatcherRack;
// for (final String s : newMappings) {
for (final String s : mappings.keySet()) {
if (!mappings.get(s)) {
continue;
}
final Match m = variablesToMatch.get(s);
// Network -> Network (rejected)
if (m.getVirtual() instanceof VirtualNetwork) {
rejectedNetworks.add((VirtualNetwork) m.getVirtual());
continue;
}
// Embed element: Either use emoflon/GT or use manual mode.
switch (AlgorithmConfig.emb) {
case EMOFLON:
// Create embedding via matches and graph transformation
engine.apply((VirtualElement) m.getVirtual(), (SubstrateElement) m.getSubstrate(), true);
break;
case EMOFLON_WO_UPDATE:
// Create embedding via matches and graph transformation
engine.apply((VirtualElement) m.getVirtual(), (SubstrateElement) m.getSubstrate(), false);
break;
default:
throw new UnsupportedOperationException();
}
}
return rejectedNetworks;
}
}