Skip to content
Snippets Groups Projects
Commit fe3ca9e8 authored by Gabor Szarnyas's avatar Gabor Szarnyas
Browse files

Inserted segments now have a default length

parent 78a41d74
No related branches found
No related tags found
No related merge requests found
Showing
with 157 additions and 24 deletions
......@@ -15,5 +15,6 @@ package hu.bme.mit.trainbenchmark.constants;
public class TrainBenchmarkConstants {
public static final long RANDOM_SEED = 19871053l;
public static final int DEFAULT_SEGMENT_LENGTH = 500;
}
......@@ -17,6 +17,7 @@ import java.util.Collection;
import hu.bme.mit.trainbenchmark.benchmark.emf.driver.EmfDriver;
import hu.bme.mit.trainbenchmark.benchmark.emf.matches.EmfConnectedSegmentsInjectMatch;
import hu.bme.mit.trainbenchmark.benchmark.emf.transformation.EmfTransformation;
import hu.bme.mit.trainbenchmark.constants.TrainBenchmarkConstants;
import hu.bme.mit.trainbenchmark.railway.RailwayFactory;
import hu.bme.mit.trainbenchmark.railway.Region;
import hu.bme.mit.trainbenchmark.railway.Segment;
......@@ -32,6 +33,7 @@ public class EmfTransformationInjectConnectedSegments<TDriver extends EmfDriver,
public void activate(final Collection<TConnectedSegmentsInjectMatch> matches) throws IOException {
for (final EmfConnectedSegmentsInjectMatch match : matches) {
final Segment segment2 = RailwayFactory.eINSTANCE.createSegment();
segment2.setLength(TrainBenchmarkConstants.DEFAULT_SEGMENT_LENGTH);
// delete (segment1)-[:connectsTo]->(segment3)
match.getSegment1().getConnectsTo().remove(match.getSegment3());
......
......@@ -30,6 +30,7 @@ public class EmfTransformationInjectPosLength<TDriver extends EmfDriver, TPosLen
for (final TPosLengthInjectMatch match : matches) {
match.getSegment().setLength(0);
}
System.out.println(matches.size());
}
}
......@@ -5,7 +5,9 @@ import ingraph.cypherparser.CypherParser
import ingraph.relalg2tex.RelalgTreeSerializer
import java.io.IOException
import org.junit.Test
import org.junit.Ignore
@Ignore
class RelalgBuilderTest {
val static RelalgTreeSerializer drawer = new RelalgTreeSerializer
......
......@@ -12,6 +12,8 @@
package hu.bme.mit.trainbenchmark.benchmark.ingraph.test;
import org.junit.Ignore;
import hu.bme.mit.trainbenchmark.benchmark.config.BenchmarkConfigBase;
import hu.bme.mit.trainbenchmark.benchmark.ingraph.IngraphBenchmarkScenario;
import hu.bme.mit.trainbenchmark.benchmark.ingraph.config.IngraphBenchmarkConfig;
......@@ -19,6 +21,7 @@ import hu.bme.mit.trainbenchmark.benchmark.ingraph.config.IngraphBenchmarkConfig
import hu.bme.mit.trainbenchmark.benchmark.runcomponents.BenchmarkResult;
import hu.bme.mit.trainbenchmark.benchmark.test.TrainBenchmarkTest;
@Ignore
public class IngraphTest extends TrainBenchmarkTest {
@Override
......
......@@ -25,6 +25,7 @@ import hu.bme.mit.trainbenchmark.benchmark.jena.driver.JenaDriver;
import hu.bme.mit.trainbenchmark.benchmark.jena.matches.JenaConnectedSegmentsInjectMatch;
import hu.bme.mit.trainbenchmark.benchmark.jena.transformations.JenaTransformation;
import hu.bme.mit.trainbenchmark.constants.ModelConstants;
import hu.bme.mit.trainbenchmark.constants.TrainBenchmarkConstants;
public class JenaTransformationInjectConnectedSegments extends JenaTransformation<JenaConnectedSegmentsInjectMatch> {
......@@ -36,6 +37,7 @@ public class JenaTransformationInjectConnectedSegments extends JenaTransformatio
public void activate(final Collection<JenaConnectedSegmentsInjectMatch> matches) throws Exception {
final Model model = driver.getModel();
final Property length = model.getProperty(BASE_PREFIX + ModelConstants.LENGTH);
final Property connectsTo = model.getProperty(BASE_PREFIX + ModelConstants.CONNECTS_TO);
final Property monitoredBy = model.getProperty(BASE_PREFIX + ModelConstants.MONITORED_BY);
final Property segmentType = model.getProperty(BASE_PREFIX + ModelConstants.SEGMENT);
......@@ -45,6 +47,7 @@ public class JenaTransformationInjectConnectedSegments extends JenaTransformatio
final Long newVertexId = driver.getNewVertexId();
final Resource segment2 = model.createResource(BASE_PREFIX + ID_PREFIX + newVertexId);
model.add(model.createStatement(segment2, RDF.type, segmentType));
model.add(model.createLiteralStatement(segment2, length, TrainBenchmarkConstants.DEFAULT_SEGMENT_LENGTH));
// (segment1)-[:connectsTo]->(segment2)
model.add(csim.getSegment1(), connectsTo, segment2);
......
......@@ -45,9 +45,6 @@ public class Neo4jCoreQueryPosLength extends Neo4jCoreQuery<Neo4jPosLengthMatch>
// (segment:Segment)
final Iterable<Node> segments = () -> graphDb.findNodes(Neo4jConstants.labelSegment);
for (final Node segment : segments) {
if (!segment.hasProperty(LENGTH)) {
continue;
}
final Integer length = (Integer) segment.getProperty(LENGTH);
// segment.length <= 0
......
......@@ -20,6 +20,8 @@ import org.neo4j.graphdb.Relationship;
import hu.bme.mit.trainbenchmark.benchmark.neo4j.driver.Neo4jDriver;
import hu.bme.mit.trainbenchmark.benchmark.neo4j.matches.Neo4jConnectedSegmentsInjectMatch;
import hu.bme.mit.trainbenchmark.benchmark.neo4j.transformations.Neo4jCoreTransformation;
import hu.bme.mit.trainbenchmark.constants.ModelConstants;
import hu.bme.mit.trainbenchmark.constants.TrainBenchmarkConstants;
import hu.bme.mit.trainbenchmark.neo4j.Neo4jConstants;
public class Neo4jCoreTransformationInjectConnectedSegments extends Neo4jCoreTransformation<Neo4jConnectedSegmentsInjectMatch> {
......@@ -33,6 +35,7 @@ public class Neo4jCoreTransformationInjectConnectedSegments extends Neo4jCoreTra
for (final Neo4jConnectedSegmentsInjectMatch match : matches) {
// create (segment2) node
final Node segment2 = driver.getGraphDb().createNode(Neo4jConstants.labelSegment);
segment2.setProperty(ModelConstants.LENGTH, TrainBenchmarkConstants.DEFAULT_SEGMENT_LENGTH);
// (segment2)-[:monitoredBy]->(sensor)
segment2.createRelationshipTo(match.getSensor(), Neo4jConstants.relationshipTypeMonitoredBy);
......
......@@ -22,6 +22,7 @@ import hu.bme.mit.trainbenchmark.benchmark.neo4j.matches.Neo4jConnectedSegmentsI
import hu.bme.mit.trainbenchmark.benchmark.neo4j.transformations.Neo4jCypherTransformation;
import hu.bme.mit.trainbenchmark.constants.QueryConstants;
import hu.bme.mit.trainbenchmark.constants.RailwayOperation;
import hu.bme.mit.trainbenchmark.constants.TrainBenchmarkConstants;
public class Neo4jCypherTransformationInjectConnectedSegments extends Neo4jCypherTransformation<Neo4jConnectedSegmentsInjectMatch> {
......@@ -35,7 +36,8 @@ public class Neo4jCypherTransformationInjectConnectedSegments extends Neo4jCyphe
final Map<String, Object> parameters = ImmutableMap.of( //
QueryConstants.VAR_SENSOR, match.getSensor().getId(), //
QueryConstants.VAR_SEGMENT1, match.getSegment1().getId(), //
QueryConstants.VAR_SEGMENT3, match.getSegment3().getId() //
QueryConstants.VAR_SEGMENT3, match.getSegment3().getId(), //
QueryConstants.VAR_LENGTH, TrainBenchmarkConstants.DEFAULT_SEGMENT_LENGTH //
);
driver.runTransformation(transformationDefinition, parameters);
}
......
......@@ -3,7 +3,7 @@ WHERE id(sensor) = { sensor }
AND id(segment1) = { segment1 }
AND id(segment3) = { segment3 }
CREATE
(segment2:Segment)-[:monitoredBy]->(sensor),
(segment2:Segment { length: { length } })-[:monitoredBy]->(sensor),
(segment1)-[:connectsTo]->(segment2),
(segment2)-[:connectsTo]->(segment3)
DELETE c
......@@ -12,6 +12,7 @@
package hu.bme.mit.trainbenchmark.benchmark.rdf4j.transformations.inject;
import static hu.bme.mit.trainbenchmark.constants.ModelConstants.CONNECTS_TO;
import static hu.bme.mit.trainbenchmark.constants.ModelConstants.LENGTH;
import static hu.bme.mit.trainbenchmark.constants.ModelConstants.MONITORED_BY;
import static hu.bme.mit.trainbenchmark.constants.ModelConstants.SEGMENT;
import static hu.bme.mit.trainbenchmark.rdf.RdfConstants.BASE_PREFIX;
......@@ -20,6 +21,7 @@ import static hu.bme.mit.trainbenchmark.rdf.RdfConstants.ID_PREFIX;
import java.util.Collection;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.repository.RepositoryConnection;
......@@ -27,6 +29,7 @@ import org.eclipse.rdf4j.repository.RepositoryConnection;
import hu.bme.mit.trainbenchmark.benchmark.rdf4j.driver.Rdf4jDriver;
import hu.bme.mit.trainbenchmark.benchmark.rdf4j.matches.Rdf4jConnectedSegmentsInjectMatch;
import hu.bme.mit.trainbenchmark.benchmark.rdf4j.transformations.Rdf4jTransformation;
import hu.bme.mit.trainbenchmark.constants.TrainBenchmarkConstants;
public class Rdf4jTransformationInjectConnectedSegments<TRdf4jDriver extends Rdf4jDriver> extends Rdf4jTransformation<Rdf4jConnectedSegmentsInjectMatch, TRdf4jDriver> {
......@@ -39,9 +42,11 @@ public class Rdf4jTransformationInjectConnectedSegments<TRdf4jDriver extends Rdf
final RepositoryConnection connection = driver.getConnection();
final ValueFactory vf = driver.getValueFactory();
final IRI length = vf.createIRI(BASE_PREFIX + LENGTH);
final IRI connectsTo = vf.createIRI(BASE_PREFIX + CONNECTS_TO);
final IRI monitoredBy = vf.createIRI(BASE_PREFIX + MONITORED_BY);
final IRI segmentType = vf.createIRI(BASE_PREFIX + SEGMENT);
final Literal lengthLiteral = vf.createLiteral(TrainBenchmarkConstants.DEFAULT_SEGMENT_LENGTH);
for (final Rdf4jConnectedSegmentsInjectMatch csim : matches) {
// create (segment2) node
......
......@@ -12,6 +12,7 @@
package hu.bme.mit.trainbenchmark.benchmark.sesame.transformations.inject;
import static hu.bme.mit.trainbenchmark.constants.ModelConstants.CONNECTS_TO;
import static hu.bme.mit.trainbenchmark.constants.ModelConstants.LENGTH;
import static hu.bme.mit.trainbenchmark.constants.ModelConstants.MONITORED_BY;
import static hu.bme.mit.trainbenchmark.constants.ModelConstants.SEGMENT;
import static hu.bme.mit.trainbenchmark.rdf.RdfConstants.BASE_PREFIX;
......@@ -19,6 +20,7 @@ import static hu.bme.mit.trainbenchmark.rdf.RdfConstants.ID_PREFIX;
import java.util.Collection;
import org.openrdf.model.Literal;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.vocabulary.RDF;
......@@ -27,6 +29,7 @@ import org.openrdf.repository.RepositoryConnection;
import hu.bme.mit.trainbenchmark.benchmark.sesame.driver.SesameDriver;
import hu.bme.mit.trainbenchmark.benchmark.sesame.matches.SesameConnectedSegmentsInjectMatch;
import hu.bme.mit.trainbenchmark.benchmark.sesame.transformations.SesameTransformation;
import hu.bme.mit.trainbenchmark.constants.TrainBenchmarkConstants;
public class SesameTransformationInjectConnectedSegments<TSesameDriver extends SesameDriver> extends SesameTransformation<SesameConnectedSegmentsInjectMatch, TSesameDriver> {
......@@ -39,15 +42,18 @@ public class SesameTransformationInjectConnectedSegments<TSesameDriver extends S
final RepositoryConnection connection = driver.getConnection();
final ValueFactory vf = driver.getValueFactory();
final URI length = vf.createURI(BASE_PREFIX + LENGTH);
final URI connectsTo = vf.createURI(BASE_PREFIX + CONNECTS_TO);
final URI monitoredBy = vf.createURI(BASE_PREFIX + MONITORED_BY);
final URI segmentType = vf.createURI(BASE_PREFIX + SEGMENT);
final Literal lengthLiteral = vf.createLiteral(TrainBenchmarkConstants.DEFAULT_SEGMENT_LENGTH);
for (final SesameConnectedSegmentsInjectMatch csim : matches) {
// create (segment2) node
final Long newVertexId = driver.getNewVertexId();
final URI segment2 = vf.createURI(BASE_PREFIX + ID_PREFIX + newVertexId);
connection.add(segment2, RDF.TYPE, segmentType);
connection.add(segment2, length, lengthLiteral);
// (segment1)-[:connectsTo]->(segment2)
connection.add(csim.getSegment1(), connectsTo, segment2);
......
......@@ -19,6 +19,7 @@ import hu.bme.mit.trainbenchmark.benchmark.sql.driver.SqlDriver;
import hu.bme.mit.trainbenchmark.benchmark.sql.matches.SqlConnectedSegmentsInjectMatch;
import hu.bme.mit.trainbenchmark.benchmark.sql.transformations.SqlTransformation;
import hu.bme.mit.trainbenchmark.constants.RailwayOperation;
import hu.bme.mit.trainbenchmark.constants.TrainBenchmarkConstants;
public class SqlTransformationInjectConnectedSegments<TSqlDriver extends SqlDriver> extends SqlTransformation<SqlConnectedSegmentsInjectMatch, TSqlDriver> {
......@@ -36,6 +37,7 @@ public class SqlTransformationInjectConnectedSegments<TSqlDriver extends SqlDriv
preparedUpdateStatement.setLong(1, match.getSensor());
preparedUpdateStatement.setLong(2, match.getSegment1());
preparedUpdateStatement.setLong(3, match.getSegment3());
preparedUpdateStatement.setLong(4, TrainBenchmarkConstants.DEFAULT_SEGMENT_LENGTH);
preparedUpdateStatement.executeUpdate();
}
}
......
SET @sensor := ?;
SET @segment1 := ?;
SET @segment3 := ?;
SET @length := ?;
-- get (region) node
SET @region :=
......@@ -18,8 +19,8 @@ INSERT INTO TrackElement (region) VALUES (@region);
SET @segment2 := (SELECT LAST_INSERT_ID());
-- insert (segment2) node as a Segment
INSERT INTO Segment (id)
VALUES (@segment2);
INSERT INTO Segment (id, length)
VALUES (@segment2, @length);
-- insert (segment1)-[:connectsTo]->(segment2) edge
INSERT INTO connectsTo
......
......@@ -19,12 +19,14 @@ import hu.bme.mit.trainbenchmark.benchmark.sql.matches.SqlConnectedSegmentsInjec
import hu.bme.mit.trainbenchmark.benchmark.sqlite.driver.SQLiteDriver;
import hu.bme.mit.trainbenchmark.benchmark.sqlite.transformation.SQLiteTransformation;
import hu.bme.mit.trainbenchmark.constants.RailwayOperation;
import hu.bme.mit.trainbenchmark.constants.TrainBenchmarkConstants;
public class SQLiteTransformationInjectConnectedSegments extends SQLiteTransformation<SqlConnectedSegmentsInjectMatch> {
final String setBindings = "INSERT OR REPLACE INTO Variables VALUES ('sensor', ?), ('segment1', ?), ('segment3', ?);";
final String setBindings = "INSERT OR REPLACE INTO Variables VALUES ('sensor', ?), ('segment1', ?), ('segment3', ?), ('length', ?);";
public SQLiteTransformationInjectConnectedSegments(final SQLiteDriver driver, final String workspaceDir) throws IOException {
public SQLiteTransformationInjectConnectedSegments(final SQLiteDriver driver, final String workspaceDir)
throws IOException {
super(driver, workspaceDir, RailwayOperation.CONNECTEDSEGMENTS_INJECT);
}
......@@ -38,6 +40,7 @@ public class SQLiteTransformationInjectConnectedSegments extends SQLiteTransform
preparedUpdateStatement.setLong(1, match.getSensor());
preparedUpdateStatement.setLong(2, match.getSegment1());
preparedUpdateStatement.setLong(3, match.getSegment3());
preparedUpdateStatement.setLong(4, TrainBenchmarkConstants.DEFAULT_SEGMENT_LENGTH);
preparedUpdateStatement.executeUpdate();
driver.getConnection().createStatement().executeUpdate(updateQuery);
......
......@@ -21,9 +21,10 @@ INSERT OR REPLACE INTO Variables VALUES ('segment2',
);
-- insert (segment2) node as a Segment
INSERT INTO Segment (id)
INSERT INTO Segment (id, length)
VALUES (
(SELECT Value FROM Variables WHERE Name = 'segment2')
(SELECT Value FROM Variables WHERE Name = 'segment2'),
(SELECT Value FROM Variables WHERE Name = 'length')
);
-- insert (segment1)-[:connectsTo]->(segment2) edge
......
......@@ -21,6 +21,7 @@ import hu.bme.mit.trainbenchmark.benchmark.tinkergraph.driver.TinkerGraphDriver;
import hu.bme.mit.trainbenchmark.benchmark.tinkergraph.matches.TinkerGraphConnectedSegmentsInjectMatch;
import hu.bme.mit.trainbenchmark.benchmark.tinkergraph.transformations.TinkerGraphTransformation;
import hu.bme.mit.trainbenchmark.constants.ModelConstants;
import hu.bme.mit.trainbenchmark.constants.TrainBenchmarkConstants;
public class TinkerGraphTransformationInjectConnectedSegments<TTinkerGraphDriver extends TinkerGraphDriver>
extends TinkerGraphTransformation<TinkerGraphConnectedSegmentsInjectMatch, TTinkerGraphDriver> {
......@@ -34,6 +35,7 @@ public class TinkerGraphTransformationInjectConnectedSegments<TTinkerGraphDriver
for (final TinkerGraphConnectedSegmentsInjectMatch match : matches) {
// create (segment2) node
final Vertex segment2 = driver.getGraph().addVertex(ModelConstants.SEGMENT);
segment2.property(ModelConstants.LENGTH, TrainBenchmarkConstants.DEFAULT_SEGMENT_LENGTH);
// (segment2)-[:monitoredBy]->(sensor)
segment2.addEdge(ModelConstants.MONITORED_BY, match.getSensor());
......
......@@ -17,6 +17,7 @@ import java.util.Collection;
import hu.bme.mit.trainbenchmark.benchmark.viatra.ConnectedSegmentsInjectMatch;
import hu.bme.mit.trainbenchmark.benchmark.viatra.driver.ViatraDriver;
import hu.bme.mit.trainbenchmark.benchmark.viatra.transformations.ViatraTransformation;
import hu.bme.mit.trainbenchmark.constants.TrainBenchmarkConstants;
import hu.bme.mit.trainbenchmark.railway.RailwayFactory;
import hu.bme.mit.trainbenchmark.railway.Region;
import hu.bme.mit.trainbenchmark.railway.Segment;
......@@ -32,6 +33,7 @@ public class ViatraTransformationInjectConnectedSegments extends ViatraTransform
for (final ConnectedSegmentsInjectMatch csim : matches) {
// create (segment2) node
final Segment segment2 = RailwayFactory.eINSTANCE.createSegment();
segment2.setLength(TrainBenchmarkConstants.DEFAULT_SEGMENT_LENGTH);
final Region region = (Region) csim.getSegment1().eContainer();
region.getElements().add(segment2);
......
......@@ -26,7 +26,7 @@ public abstract class TrainBenchmarkTest {
protected final int benchmarkId = 0;
protected ExecutionConfig executionConfig = ExecutionConfig.defaultExecutionConfig();
protected final long timeout = 120;
protected final int runs = 2;
protected final int runs = 1;
protected final int size = 1;
protected final TransformationChangeSetStrategy strategy = TransformationChangeSetStrategy.FIXED;
protected final int transformationConstant = 10;
......@@ -70,6 +70,51 @@ public abstract class TrainBenchmarkTest {
collector.checkThat(allMatches.get(RailwayQuery.SWITCHSET).get(0), Matchers.equalTo(0));
}
// inject
@Test
public void injectTest() throws Exception {
// Arrange
final String workload = "InjectTest";
final int queryTransformationCount = 1;
final String modelFilename = "railway-inject-" + size;
final List<RailwayOperation> operations = ImmutableList.of(//
RailwayOperation.CONNECTEDSEGMENTS, //
RailwayOperation.POSLENGTH, //
RailwayOperation.ROUTESENSOR, //
RailwayOperation.SEMAPHORENEIGHBOR, //
RailwayOperation.SWITCHSET, //
RailwayOperation.SWITCHMONITORED, //
RailwayOperation.CONNECTEDSEGMENTS_INJECT, //
RailwayOperation.POSLENGTH_INJECT, //
RailwayOperation.ROUTESENSOR_INJECT, //
RailwayOperation.SEMAPHORENEIGHBOR_INJECT, //
RailwayOperation.SWITCHSET_INJECT, //
RailwayOperation.SWITCHMONITORED_INJECT //
);
final BenchmarkConfigBase bcb = bcbb.setQueryTransformationCount(queryTransformationCount)
.setModelFilename(modelFilename).setOperations(operations).setWorkload(workload)
.createConfigBase();
// Act
final BenchmarkResult result = runTest(bcb);
// Assert
final ListMultimap<RailwayQuery, Integer> allMatches = result.getLastRunResult().getMatches();
collector.checkThat(allMatches.get(RailwayQuery.CONNECTEDSEGMENTS).get(0), Matchers.equalTo(3));
collector.checkThat(allMatches.get(RailwayQuery.CONNECTEDSEGMENTS).get(1), Matchers.equalTo(13));
collector.checkThat(allMatches.get(RailwayQuery.POSLENGTH).get(0), Matchers.equalTo(11));
collector.checkThat(allMatches.get(RailwayQuery.POSLENGTH).get(1), Matchers.equalTo(21));
collector.checkThat(allMatches.get(RailwayQuery.ROUTESENSOR).get(0), Matchers.equalTo(9));
collector.checkThat(allMatches.get(RailwayQuery.ROUTESENSOR).get(1), Matchers.equalTo(13));
collector.checkThat(allMatches.get(RailwayQuery.SEMAPHORENEIGHBOR).get(0), Matchers.equalTo(12));
collector.checkThat(allMatches.get(RailwayQuery.SEMAPHORENEIGHBOR).get(1), Matchers.equalTo(22));
collector.checkThat(allMatches.get(RailwayQuery.SWITCHMONITORED).get(0), Matchers.equalTo(0));
collector.checkThat(allMatches.get(RailwayQuery.SWITCHMONITORED).get(1), Matchers.equalTo(10));
collector.checkThat(allMatches.get(RailwayQuery.SWITCHSET).get(0), Matchers.equalTo(0));
collector.checkThat(allMatches.get(RailwayQuery.SWITCHSET).get(1), Matchers.equalTo(0));
}
// repair
@Test
......
\begin{forest} for tree={align=center}
[
{$\antijoin$
\\
\footnotesize
$\color{gray} \langle \var{route, swP, sw, sensor} \rangle$
}
[
{$\join$
\\
\footnotesize
$\color{gray} \langle \var{route, swP, sw, sensor} \rangle$
}
[
{$\join$
\\
\footnotesize
$\color{gray} \langle \var{route, swP, sw} \rangle$
}
[
{$\getedgesi{route}{Route}{swP}{SwitchPosition}$\\$\getedgesii{\_e3}{follows}$
\\
\footnotesize
$\color{gray} \langle \var{route, swP} \rangle$
},tier=input,for tree={blue,densely dashed}
]
[
{$\getedgesi{swP}{SwitchPosition}{sw}{Switch}$\\$\getedgesii{\_e1}{target}$
\\
\footnotesize
$\color{gray} \langle \var{swP, sw} \rangle$
},tier=input,for tree={blue,densely dashed}
]
]
[
{$\getedgesi{sw}{Switch}{sensor}{Sensor}$\\$\getedgesii{\_e2}{monitoredBy}$
\\
\footnotesize
$\color{gray} \langle \var{sw, sensor} \rangle$
},tier=input,for tree={blue,densely dashed}
]
]
[
{$\getedgesi{route}{Route}{sensor}{Sensor}$\\$\getedgesii{\_e4}{requires}$
\\
\footnotesize
$\color{gray} \langle \var{route, sensor} \rangle$
},tier=input,for tree={blue,densely dashed}
]
]
;
\end{forest}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment