aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/boundary/ReteBoundary.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/boundary/ReteBoundary.java')
-rw-r--r--subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/boundary/ReteBoundary.java551
1 files changed, 551 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/boundary/ReteBoundary.java b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/boundary/ReteBoundary.java
new file mode 100644
index 00000000..fe9c795e
--- /dev/null
+++ b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/boundary/ReteBoundary.java
@@ -0,0 +1,551 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2008 Gabor Bergmann and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.rete.boundary;
11
12import java.util.Collection;
13import java.util.Map;
14import java.util.Set;
15
16import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException;
17import tools.refinery.viatra.runtime.matchers.planning.SubPlan;
18import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
19import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
20import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory;
21import tools.refinery.viatra.runtime.matchers.util.Direction;
22import tools.refinery.viatra.runtime.rete.matcher.ReteEngine;
23import tools.refinery.viatra.runtime.rete.network.Network;
24import tools.refinery.viatra.runtime.rete.network.ProductionNode;
25import tools.refinery.viatra.runtime.rete.network.Receiver;
26import tools.refinery.viatra.runtime.rete.network.ReteContainer;
27import tools.refinery.viatra.runtime.rete.network.Supplier;
28import tools.refinery.viatra.runtime.rete.remote.Address;
29import tools.refinery.viatra.runtime.rete.traceability.CompiledQuery;
30import tools.refinery.viatra.runtime.rete.traceability.RecipeTraceInfo;
31
32/**
33 * Responsible for the storage, maintenance and communication of the nodes of the network that are accessible form the
34 * outside for various reasons.
35 *
36 * @author Gabor Bergmann
37 *
38 * <p> TODO: should eventually be merged into {@link InputConnector} and deleted
39 *
40 */
41public class ReteBoundary /*implements IPatternMatcherRuntimeContextListener*/ {
42
43 protected ReteEngine engine;
44 protected Network network;
45 protected ReteContainer headContainer;
46
47 public ReteContainer getHeadContainer() {
48 return headContainer;
49 }
50
51 protected final InputConnector inputConnector;
52
53
54 protected Map<SubPlan, Address<? extends Supplier>> subplanToAddressMapping;
55
56
57 /**
58 * SubPlans of parent nodes that have the key node as their child. For RETE --> SubPlan traceability, mainly at production
59 * nodes.
60 */
61 protected Map<Address<? extends Receiver>, Set<SubPlan>> parentPlansOfReceiver;
62
63 /**
64 * Prerequisite: engine has its network and framework fields initialized
65 */
66 public ReteBoundary(ReteEngine engine) {
67 super();
68 this.engine = engine;
69 this.network = engine.getReteNet();
70 this.headContainer = network.getHeadContainer();
71 inputConnector = network.getInputConnector();
72
73 this.parentPlansOfReceiver = CollectionsFactory.createMap();
74
75 // productionsScoped = new HashMap<GTPattern, Map<Map<Integer,Scope>,Address<? extends Production>>>();
76 subplanToAddressMapping = CollectionsFactory.createMap();
77
78 }
79
80 public Collection<? extends RecipeTraceInfo> getAllProductionNodes() {
81 return engine.getCompiler().getCachedCompiledQueries().values();
82 }
83
84// /**
85// * accesses the entity Root node under specified label; creates the node if it doesn't exist yet
86// */
87// public Address<? extends Tunnel> accessUnaryRoot(Object typeObject) {
88// Address<? extends Tunnel> tn;
89// tn = unaryRoots.get(typeObject);
90// if (tn == null) {
91// tn = headContainer.getProvisioner().newUniquenessEnforcerNode(1, typeObject);
92// unaryRoots.put(typeObject, tn);
93//
94// new EntityFeeder(tn, context, network, this, typeObject).feed();
95//
96// if (typeObject != null && generalizationQueryDirection == GeneralizationQueryDirection.BOTH) {
97// Collection<? extends Object> subTypes = context.enumerateDirectUnarySubtypes(typeObject);
98//
99// for (Object subType : subTypes) {
100// Address<? extends Tunnel> subRoot = accessUnaryRoot(subType);
101// network.connectRemoteNodes(subRoot, tn, true);
102// }
103// }
104//
105// }
106// return tn;
107// }
108//
109// /**
110// * accesses the relation Root node under specified label; creates the node if it doesn't exist yet
111// */
112// public Address<? extends Tunnel> accessTernaryEdgeRoot(Object typeObject) {
113// Address<? extends Tunnel> tn;
114// tn = ternaryEdgeRoots.get(typeObject);
115// if (tn == null) {
116// tn = headContainer.getProvisioner().newUniquenessEnforcerNode(3, typeObject);
117// ternaryEdgeRoots.put(typeObject, tn);
118//
119// new RelationFeeder(tn, context, network, this, typeObject).feed();
120//
121// if (typeObject != null && generalizationQueryDirection == GeneralizationQueryDirection.BOTH) {
122// Collection<? extends Object> subTypes = context.enumerateDirectTernaryEdgeSubtypes(typeObject);
123//
124// for (Object subType : subTypes) {
125// Address<? extends Tunnel> subRoot = accessTernaryEdgeRoot(subType);
126// network.connectRemoteNodes(subRoot, tn, true);
127// }
128// }
129// }
130// return tn;
131// }
132//
133// /**
134// * accesses the reference Root node under specified label; creates the node if it doesn't exist yet
135// */
136// public Address<? extends Tunnel> accessBinaryEdgeRoot(Object typeObject) {
137// Address<? extends Tunnel> tn;
138// tn = binaryEdgeRoots.get(typeObject);
139// if (tn == null) {
140// tn = headContainer.getProvisioner().newUniquenessEnforcerNode(2, typeObject);
141// binaryEdgeRoots.put(typeObject, tn);
142//
143// new ReferenceFeeder(tn, context, network, this, typeObject).feed();
144//
145// if (typeObject != null && generalizationQueryDirection == GeneralizationQueryDirection.BOTH) {
146// Collection<? extends Object> subTypes = context.enumerateDirectBinaryEdgeSubtypes(typeObject);
147//
148// for (Object subType : subTypes) {
149// Address<? extends Tunnel> subRoot = accessBinaryEdgeRoot(subType);
150// network.connectRemoteNodes(subRoot, tn, true);
151// }
152// }
153// }
154// return tn;
155// }
156//
157// /**
158// * accesses the special direct containment relation Root node; creates the node if it doesn't exist yet
159// */
160// public Address<? extends Tunnel> accessContainmentRoot() {
161// if (containmentRoot == null) {
162// // containment: relation quasi-type
163// containmentRoot = headContainer.getProvisioner().newUniquenessEnforcerNode(2, "$containment");
164//
165// new ContainmentFeeder(containmentRoot, context, network, this).feed();
166// }
167// return containmentRoot;
168// }
169//
170// /**
171// * accesses the special transitive containment relation Root node; creates the node if it doesn't exist yet
172// */
173// public Address<? extends Supplier> accessContainmentTransitiveRoot() {
174// if (containmentTransitiveRoot == null) {
175// // transitive containment: derived
176// Address<? extends Tunnel> containmentTransitiveRoot = headContainer.getProvisioner().newUniquenessEnforcerNode(
177// 2, "$containmentTransitive");
178// network.connectRemoteNodes(accessContainmentRoot(), containmentTransitiveRoot, true);
179//
180// final int[] actLI = { 1 };
181// final int arcLIw = 2;
182// final int[] actRI = { 0 };
183// final int arcRIw = 2;
184// Address<? extends IterableIndexer> jPrimarySlot = headContainer.getProvisioner().accessProjectionIndexer(
185// accessContainmentRoot(), new TupleMask(actLI, arcLIw));
186// Address<? extends IterableIndexer> jSecondarySlot = headContainer.getProvisioner().accessProjectionIndexer(
187// containmentTransitiveRoot, new TupleMask(actRI, arcRIw));
188//
189// final int[] actRIcomp = { 1 };
190// final int arcRIwcomp = 2;
191// TupleMask complementerMask = new TupleMask(actRIcomp, arcRIwcomp);
192//
193// Address<? extends Supplier> andCT = headContainer.getProvisioner().accessJoinNode(jPrimarySlot, jSecondarySlot,
194// complementerMask);
195//
196// final int[] mask = { 0, 2 };
197// final int maskw = 3;
198// Address<? extends Supplier> tr = headContainer.getProvisioner().accessTrimmerNode(andCT, new TupleMask(mask, maskw));
199// network.connectRemoteNodes(tr, containmentTransitiveRoot, true);
200//
201// this.containmentTransitiveRoot = containmentTransitiveRoot; // cast
202// // back
203// // to
204// // Supplier
205// }
206// return containmentTransitiveRoot;
207// }
208//
209// /**
210// * accesses the special instantiation relation Root node; creates the node if it doesn't exist yet
211// */
212// public Address<? extends Tunnel> accessInstantiationRoot() {
213// if (instantiationRoot == null) {
214// // instantiation: relation quasi-type
215// instantiationRoot = headContainer.getProvisioner().newUniquenessEnforcerNode(2, "$instantiation");
216//
217// new InstantiationFeeder(instantiationRoot, context, network, this).feed();
218// }
219// return instantiationRoot;
220// }
221//
222// /**
223// * accesses the special transitive instantiation relation Root node; creates the node if it doesn't exist yet
224// * InstantiationTransitive = Instantiation o (Generalization)^*
225// */
226// public Address<? extends Supplier> accessInstantiationTransitiveRoot() {
227// if (instantiationTransitiveRoot == null) {
228// // transitive instantiation: derived
229// Address<? extends Tunnel> instantiationTransitiveRoot = headContainer.getProvisioner()
230// .newUniquenessEnforcerNode(2, "$instantiationTransitive");
231// network.connectRemoteNodes(accessInstantiationRoot(), instantiationTransitiveRoot, true);
232//
233// final int[] actLI = { 1 };
234// final int arcLIw = 2;
235// final int[] actRI = { 0 };
236// final int arcRIw = 2;
237// Address<? extends IterableIndexer> jPrimarySlot = headContainer.getProvisioner().accessProjectionIndexer(
238// accessGeneralizationRoot(), new TupleMask(actLI, arcLIw));
239// Address<? extends Indexer> jSecondarySlot = headContainer.getProvisioner().accessProjectionIndexer(
240// instantiationTransitiveRoot, new TupleMask(actRI, arcRIw));
241//
242// final int[] actRIcomp = { 1 };
243// final int arcRIwcomp = 2;
244// TupleMask complementerMask = new TupleMask(actRIcomp, arcRIwcomp);
245//
246// Address<? extends Supplier> andCT = headContainer.getProvisioner().accessJoinNode(jPrimarySlot, jSecondarySlot,
247// complementerMask);
248//
249// final int[] mask = { 0, 2 };
250// final int maskw = 3;
251// Address<? extends Supplier> tr = headContainer.getProvisioner().accessTrimmerNode(andCT,
252// new TupleMask(mask, maskw));
253// network.connectRemoteNodes(tr, instantiationTransitiveRoot, true);
254//
255// this.instantiationTransitiveRoot = instantiationTransitiveRoot; // cast
256// // back
257// // to
258// // Supplier
259// }
260// return instantiationTransitiveRoot;
261// }
262//
263// /**
264// * accesses the special generalization relation Root node; creates the node if it doesn't exist yet
265// */
266// public Address<? extends Tunnel> accessGeneralizationRoot() {
267// if (generalizationRoot == null) {
268// // generalization: relation quasi-type
269// generalizationRoot = headContainer.getProvisioner().newUniquenessEnforcerNode(2, "$generalization");
270//
271// new GeneralizationFeeder(generalizationRoot, context, network, this).feed();
272// }
273// return generalizationRoot;
274// }
275//
276// /**
277// * accesses the special transitive containment relation Root node; creates the node if it doesn't exist yet
278// */
279// public Address<? extends Supplier> accessGeneralizationTransitiveRoot() {
280// if (generalizationTransitiveRoot == null) {
281// // transitive generalization: derived
282// Address<? extends Tunnel> generalizationTransitiveRoot = headContainer.getProvisioner()
283// .newUniquenessEnforcerNode(2, "$generalizationTransitive");
284// network.connectRemoteNodes(accessGeneralizationRoot(), generalizationTransitiveRoot, true);
285//
286// final int[] actLI = { 1 };
287// final int arcLIw = 2;
288// final int[] actRI = { 0 };
289// final int arcRIw = 2;
290// Address<? extends IterableIndexer> jPrimarySlot = headContainer.getProvisioner().accessProjectionIndexer(
291// accessGeneralizationRoot(), new TupleMask(actLI, arcLIw));
292// Address<? extends Indexer> jSecondarySlot = headContainer.getProvisioner().accessProjectionIndexer(
293// generalizationTransitiveRoot, new TupleMask(actRI, arcRIw));
294//
295// final int[] actRIcomp = { 1 };
296// final int arcRIwcomp = 2;
297// TupleMask complementerMask = new TupleMask(actRIcomp, arcRIwcomp);
298//
299// Address<? extends Supplier> andCT = headContainer.getProvisioner().accessJoinNode(jPrimarySlot, jSecondarySlot,
300// complementerMask);
301//
302// final int[] mask = { 0, 2 };
303// final int maskw = 3;
304// Address<? extends Supplier> tr = headContainer.getProvisioner().accessTrimmerNode(andCT, new TupleMask(mask, maskw));
305// network.connectRemoteNodes(tr, generalizationTransitiveRoot, true);
306//
307// this.generalizationTransitiveRoot = generalizationTransitiveRoot; // cast
308// // back
309// // to
310// // Supplier
311// }
312// return generalizationTransitiveRoot;
313// }
314
315 // /**
316 // * Registers and publishes a supplier under specified label.
317 // */
318 // public void publishSupplier(Supplier s, Object label)
319 // {
320 // publishedSuppliers.put(label, s);
321 // }
322 //
323 // /**
324 // * fetches the production node under specified label;
325 // * returns null if it doesn't exist yet
326 // */
327 // public Production getProductionNode(Object label)
328 // {
329 // return productions.get(label);
330 // }
331 //
332 // /**
333 // * fetches the published supplier under specified label;
334 // * returns null if it doesn't exist yet
335 // */
336 // public Supplier getPublishedSupplier(Object label)
337 // {
338 // return publishedSuppliers.get(label);
339 // }
340
341 /**
342 * accesses the production node for specified pattern; builds pattern matcher if it doesn't exist yet
343 * @throws ViatraQueryRuntimeException
344 */
345 public synchronized RecipeTraceInfo accessProductionTrace(PQuery query)
346 {
347 final CompiledQuery compiled = engine.getCompiler().getCompiledForm(query);
348 return compiled;
349// RecipeTraceInfo pn;
350// pn = queryPlans.get(query);
351// if (pn == null) {
352// pn = construct(query);
353// TODO handle recursion by reinterpret-RecipeTrace
354// queryPlans.put(query, pn);
355// if (pn == null) {
356// String[] args = { query.toString() };
357// throw new RetePatternBuildException("Unsuccessful planning of RETE construction recipe for query {1}",
358// args, "Could not create RETE recipe plan.", query);
359// }
360// }
361// return pn;
362 }
363 /**
364 * accesses the production node for specified pattern; builds pattern matcher if it doesn't exist yet
365 * @throws ViatraQueryRuntimeException
366 */
367 public synchronized Address<? extends ProductionNode> accessProductionNode(PQuery query) {
368 final RecipeTraceInfo productionTrace = accessProductionTrace(query);
369 return (Address<? extends ProductionNode>) headContainer.getProvisioner().getOrCreateNodeByRecipe(productionTrace);
370 }
371
372// /**
373// * creates the production node for the specified pattern Contract: only call from the builder (through Buildable)
374// * responsible for building this pattern
375// *
376// * @throws PatternMatcherCompileTimeException
377// * if production node is already created
378// */
379// public synchronized Address<? extends Production> createProductionInternal(PQuery gtPattern)
380// throws QueryPlannerException {
381// if (queryPlans.containsKey(gtPattern)) {
382// String[] args = { gtPattern.toString() };
383// throw new RetePatternBuildException("Multiple creation attempts of production node for {1}", args,
384// "Duplicate RETE production node.", gtPattern);
385// }
386//
387// Map<String, Integer> posMapping = engine.getBuilder().getPosMapping(gtPattern);
388// Address<? extends Production> pn = headContainer.getProvisioner().newProductionNode(posMapping, gtPattern);
389// queryPlans.put(gtPattern, pn);
390// context.reportPatternDependency(gtPattern);
391//
392// return pn;
393// }
394
395 // /**
396 // * accesses the production node for specified pattern and scope map; creates the node if
397 // * it doesn't exist yet
398 // */
399 // public synchronized Address<? extends Production> accessProductionScoped(
400 // GTPattern gtPattern, Map<Integer, Scope> additionalScopeMap) throws PatternMatcherCompileTimeException {
401 // if (additionalScopeMap.isEmpty()) return accessProduction(gtPattern);
402 //
403 // Address<? extends Production> pn;
404 //
405 // Map<Map<Integer, Scope>, Address<? extends Production>> scopes = productionsScoped.get(gtPattern);
406 // if (scopes == null) {
407 // scopes = new HashMap<Map<Integer, Scope>, Address<? extends Production>>();
408 // productionsScoped.put(gtPattern, scopes);
409 // }
410 //
411 // pn = scopes.get(additionalScopeMap);
412 // if (pn == null) {
413 // Address<? extends Production> unscopedProduction = accessProduction(gtPattern);
414 //
415 // HashMap<Object, Integer> posMapping = headContainer.resolveLocal(unscopedProduction).getPosMapping();
416 // pn = headContainer.getLibrary().newProductionNode(posMapping);
417 // scopes.put(additionalScopeMap, pn);
418 //
419 // constructScoper(unscopedProduction, additionalScopeMap, pn);
420 // }
421 // return pn;
422 // }
423
424 // protected void constructScoper(
425 // Address<? extends Production> unscopedProduction,
426 // Map<Integer, Scope> additionalScopeMap,
427 // Address<? extends Production> production)
428 // throws PatternMatcherCompileTimeException {
429 // engine.reteNet.waitForReteTermination();
430 // engine.builder.constructScoper(unscopedProduction, additionalScopeMap, production);
431 // }
432
433 // /**
434 // * Invalidates the subnet constructed for the recognition of a given
435 // pattern.
436 // * The pattern matcher will have to be rebuilt.
437 // * @param gtPattern the pattern whose matcher subnet should be invalidated
438 // */
439 // public void invalidatePattern(GTPattern gtPattern) {
440 // Production production = null;
441 // try {
442 // production = accessProduction(gtPattern);
443 // } catch (PatternMatcherCompileTimeException e) {
444 // // this should not occur here, since we already have a production node
445 // e.printStackTrace();
446 // }
447 //
448 // production.tearOff();
449 // //production.setDirty(true);
450 // }
451
452 // updaters for change notification
453 // if the corresponding rete input isn't created yet, call is ignored
454
455 private static Direction direction(boolean isInsertion) {
456 return isInsertion ? Direction.INSERT : Direction.DELETE;
457 }
458
459// @Override
460// public void updateUnary(boolean isInsertion, Object entity, Object typeObject) {
461// Address<? extends Tunnel> root = inputConnector.getUnaryRoot(typeObject);
462// if (root != null) {
463// network.sendExternalUpdate(root, direction(isInsertion), new FlatTuple(inputConnector.wrapElement(entity)));
464// if (!engine.isParallelExecutionEnabled())
465// network.waitForReteTermination();
466// }
467// if (typeObject != null && generalizationQueryDirection == GeneralizationQueryDirection.SUPERTYPE_ONLY) {
468// for (Object superType : context.enumerateDirectUnarySupertypes(typeObject)) {
469// updateUnary(isInsertion, entity, superType);
470// }
471// }
472// }
473//
474// @Override
475// public void updateTernaryEdge(boolean isInsertion, Object relation, Object from, Object to, Object typeObject) {
476// Address<? extends Tunnel> root = inputConnector.getTernaryEdgeRoot(typeObject);
477// if (root != null) {
478// network.sendExternalUpdate(root, direction(isInsertion), new FlatTuple(inputConnector.wrapElement(relation), inputConnector.wrapElement(from),
479// inputConnector.wrapElement(to)));
480// if (!engine.isParallelExecutionEnabled())
481// network.waitForReteTermination();
482// }
483// if (typeObject != null && generalizationQueryDirection == GeneralizationQueryDirection.SUPERTYPE_ONLY) {
484// for (Object superType : context.enumerateDirectTernaryEdgeSupertypes(typeObject)) {
485// updateTernaryEdge(isInsertion, relation, from, to, superType);
486// }
487// }
488// }
489// @Override
490// public void updateBinaryEdge(boolean isInsertion, Object from, Object to, Object typeObject) {
491// Address<? extends Tunnel> root = inputConnector.getBinaryEdgeRoot(typeObject);
492// if (root != null) {
493// network.sendExternalUpdate(root, direction(isInsertion), new FlatTuple(inputConnector.wrapElement(from), inputConnector.wrapElement(to)));
494// if (!engine.isParallelExecutionEnabled())
495// network.waitForReteTermination();
496// }
497// if (typeObject != null && generalizationQueryDirection == GeneralizationQueryDirection.SUPERTYPE_ONLY) {
498// for (Object superType : context.enumerateDirectBinaryEdgeSupertypes(typeObject)) {
499// updateBinaryEdge(isInsertion, from, to, superType);
500// }
501// }
502// }
503//
504// @Override
505// public void updateContainment(boolean isInsertion, Object container, Object element) {
506// final Address<? extends Tunnel> containmentRoot = inputConnector.getContainmentRoot();
507// if (containmentRoot != null) {
508// network.sendExternalUpdate(containmentRoot, direction(isInsertion), new FlatTuple(inputConnector.wrapElement(container),
509// inputConnector.wrapElement(element)));
510// if (!engine.isParallelExecutionEnabled())
511// network.waitForReteTermination();
512// }
513// }
514//
515// @Override
516// public void updateInstantiation(boolean isInsertion, Object parent, Object child) {
517// final Address<? extends Tunnel> instantiationRoot = inputConnector.getInstantiationRoot();
518// if (instantiationRoot != null) {
519// network.sendExternalUpdate(instantiationRoot, direction(isInsertion), new FlatTuple(inputConnector.wrapElement(parent),
520// inputConnector.wrapElement(child)));
521// if (!engine.isParallelExecutionEnabled())
522// network.waitForReteTermination();
523// }
524// }
525//
526// @Override
527// public void updateGeneralization(boolean isInsertion, Object parent, Object child) {
528// final Address<? extends Tunnel> generalizationRoot = inputConnector.getGeneralizationRoot();
529// if (generalizationRoot != null) {
530// network.sendExternalUpdate(generalizationRoot, direction(isInsertion), new FlatTuple(inputConnector.wrapElement(parent),
531// inputConnector.wrapElement(child)));
532// if (!engine.isParallelExecutionEnabled())
533// network.waitForReteTermination();
534// }
535// }
536
537 // no wrapping needed!
538 public void notifyEvaluator(Address<? extends Receiver> receiver, Tuple tuple) {
539 network.sendExternalUpdate(receiver, Direction.INSERT, tuple);
540 if (!engine.isParallelExecutionEnabled())
541 network.waitForReteTermination();
542 }
543
544 public void mapPlanToAddress(SubPlan plan, Address<? extends Supplier> handle) {
545 subplanToAddressMapping.put(plan, handle);
546 }
547
548 public Address<? extends Supplier> getAddress(SubPlan plan) {
549 return subplanToAddressMapping.get(plan);
550 }
551}