From c0c5a1644cc221352b8b9b370eea6a87677ba948 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Sat, 15 Jun 2019 20:56:47 -0400 Subject: Try fix statecode bug Modified graph width calculation to not depend on order of nodes --- ...bstractNeighborhoodBasedStateCoderFactory.xtend | 137 ++++++++++ .../IdentifierBasedStateCoderFactory.xtend | 4 +- .../NeighbourhoodBasedStateCoderFactory.xtend | 275 ++++++--------------- ...irwiseNeighbourhoodBasedStateCoderFactory.xtend | 75 ++++++ 4 files changed, 283 insertions(+), 208 deletions(-) create mode 100644 Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/AbstractNeighborhoodBasedStateCoderFactory.xtend create mode 100644 Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/PairwiseNeighbourhoodBasedStateCoderFactory.xtend (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder') diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/AbstractNeighborhoodBasedStateCoderFactory.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/AbstractNeighborhoodBasedStateCoderFactory.xtend new file mode 100644 index 00000000..089880b1 --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/AbstractNeighborhoodBasedStateCoderFactory.xtend @@ -0,0 +1,137 @@ +package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder + +import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodOptions +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage +import java.util.LinkedList +import java.util.List +import org.eclipse.emf.common.notify.Notifier +import org.eclipse.emf.ecore.EClass +import org.eclipse.emf.ecore.EObject +import org.eclipse.emf.ecore.EStructuralFeature +import org.eclipse.viatra.dse.statecode.IStateCoder +import org.eclipse.viatra.dse.statecode.IStateCoderFactory +import org.eclipse.viatra.query.runtime.api.IPatternMatch +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine +import org.eclipse.viatra.query.runtime.base.api.FeatureListener +import org.eclipse.viatra.query.runtime.base.api.IndexingLevel +import org.eclipse.viatra.query.runtime.base.api.InstanceListener +import org.eclipse.viatra.query.runtime.emf.EMFBaseIndexWrapper +import org.eclipse.viatra.query.runtime.emf.EMFScope +import org.eclipse.xtend.lib.annotations.Accessors + +abstract class AbstractNeighbourhoodBasedStateCoderFactory implements IStateCoderFactory { + val List statecoders = new LinkedList + + val NeighbourhoodOptions options + + protected new() { + this(NeighbourhoodOptions.DEFAULT) + } + + protected new(NeighbourhoodOptions options) { + this.options = options + } + + synchronized override createStateCoder() { + val res = doCreateStateCoder(options) + statecoders += res + return res + } + + protected def AbstractNeighbourhoodBasedPartialInterpretationStateCoder doCreateStateCoder( + NeighbourhoodOptions options) + + def getSumStatecoderRuntime() { + statecoders.map[statecoderRuntime].reduce[p1, p2|p1 + p2] + } +} + +abstract class AbstractNeighbourhoodBasedPartialInterpretationStateCoder implements IStateCoder { + val NeighbourhoodOptions options + + var PartialInterpretation target + + protected new(NeighbourhoodOptions options) { + this.options = options + } + + @Accessors(PUBLIC_GETTER) var long statecoderRuntime = 0 + + synchronized private def refreshStateCodes() { + if (refreshNeeded) { + val startTime = System.nanoTime + doRefreshStateCodes(target, options) + statecoderRuntime += (System.nanoTime - startTime) + } + } + + protected def boolean isRefreshNeeded() + + protected def void doRefreshStateCodes(PartialInterpretation target, NeighbourhoodOptions options) + + synchronized override createActivationCode(IPatternMatch match) { + refreshStateCodes + val startTime = System.nanoTime + val code = doCreateActivationCode(match) + statecoderRuntime += (System.nanoTime - startTime) + code + } + + protected def Object doCreateActivationCode(IPatternMatch match) + + synchronized override createStateCode() { + refreshStateCodes + doCreateStateCode + } + + protected def Object doCreateStateCode() + + override init(Notifier notifier) { + this.target = notifier as PartialInterpretation + val queryEngine = ViatraQueryEngine.on(new EMFScope(notifier)) + val baseIndex = queryEngine.getBaseIndex() as EMFBaseIndexWrapper + val navigationHelper = baseIndex.getNavigationHelper(); + + val classes = PartialinterpretationPackage.eINSTANCE.EClassifiers.filter(EClass).toSet + val features = classes.map[it.EAllStructuralFeatures].flatten.toSet + navigationHelper.registerObservedTypes(classes, null, features, IndexingLevel.FULL); + + navigationHelper.addFeatureListener(features, new FeatureListener() { + override void featureInserted(EObject host, EStructuralFeature feature, Object value) { invalidate } + + override void featureDeleted(EObject host, EStructuralFeature feature, Object value) { invalidate } + }) + navigationHelper.addInstanceListener(classes, new InstanceListener() { + override void instanceInserted(EClass clazz, EObject instance) { invalidate } + + override void instanceDeleted(EClass clazz, EObject instance) { invalidate } + }) + } + + synchronized def invalidate() { + doInvalidate + } + + protected def void doInvalidate() + + def protected getFallbackCode(Object o) { + switch (o) { + PartialInterpretation, + LogicProblem: + null + PartialRelationInterpretation: + o.interpretationOf.name + PartialPrimitiveInterpretation: + o.class.simpleName.hashCode + PartialComplexTypeInterpretation: + o.interpretationOf.name.hashCode + default: + throw new UnsupportedOperationException('''Unsupported type: «o.class.simpleName»''') + } + } +} diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/IdentifierBasedStateCoderFactory.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/IdentifierBasedStateCoderFactory.xtend index f55a501a..c7b8ee37 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/IdentifierBasedStateCoderFactory.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/IdentifierBasedStateCoderFactory.xtend @@ -62,13 +62,13 @@ class IdentifierBasedStateCode { int numberOfNewElement SortedSet relationStatecoders - private static val comparator = new Comparator() { + static val comparator = new Comparator() { override compare(RelationStatecoder o1, RelationStatecoder o2) { o1.relationName.compareTo(o2.relationName) } } - public new(int numberOfNewElements) { + new(int numberOfNewElements) { this.numberOfNewElement = numberOfNewElements this.relationStatecoders = new TreeSet(comparator) } diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/NeighbourhoodBasedStateCoderFactory.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/NeighbourhoodBasedStateCoderFactory.xtend index a86bcd1f..4ff39999 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/NeighbourhoodBasedStateCoderFactory.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/NeighbourhoodBasedStateCoderFactory.xtend @@ -1,223 +1,86 @@ package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.AbstractNodeDescriptor +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodOptions import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation -import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage import java.util.ArrayList -import java.util.LinkedList -import java.util.List import java.util.Map -import org.eclipse.emf.common.notify.Notifier -import org.eclipse.emf.ecore.EClass -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.EStructuralFeature -import org.eclipse.viatra.dse.statecode.IStateCoder -import org.eclipse.viatra.dse.statecode.IStateCoderFactory import org.eclipse.viatra.query.runtime.api.IPatternMatch -import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine -import org.eclipse.viatra.query.runtime.base.api.FeatureListener -import org.eclipse.viatra.query.runtime.base.api.IndexingLevel -import org.eclipse.viatra.query.runtime.base.api.InstanceListener -import org.eclipse.viatra.query.runtime.emf.EMFBaseIndexWrapper -import org.eclipse.viatra.query.runtime.emf.EMFScope -import org.eclipse.xtend.lib.annotations.Accessors -import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement -import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem -import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation -import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation -import java.util.Set -import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration -import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration -import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2NeighbourhoodRepresentation -import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation -import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation - -class NeighbourhoodBasedStateCoderFactory implements IStateCoderFactory { - val List statecoders = new LinkedList - - val int range - val int parallels - val int maxNumber - val Set relevantTypes - val Set relevantRelations - - public new() { - this.range = PartialInterpretation2NeighbourhoodRepresentation::GraphWidthRange - this.parallels = PartialInterpretation2NeighbourhoodRepresentation::FullParallels - this.maxNumber = PartialInterpretation2NeighbourhoodRepresentation::MaxNumbers - this.relevantTypes = null - this.relevantRelations = null + +class NeighbourhoodBasedStateCoderFactory extends AbstractNeighbourhoodBasedStateCoderFactory { + new() { } - - public new(int range, int parallels, int maxNumber, Set relevantTypes, Set relevantRelations) { - this.range = range - this.parallels = parallels - this.maxNumber = maxNumber - this.relevantTypes = relevantTypes - this.relevantRelations = relevantRelations + + new(NeighbourhoodOptions options) { + super(options) + } + + override protected doCreateStateCoder(NeighbourhoodOptions options) { + new NeighbourhoodBasedPartialInterpretationStateCoder(options) } - - synchronized override createStateCoder() { - val res = new NeighbourhoodBasedPartialInterpretationStateCoder(statecoders.size, - range,parallels,maxNumber,relevantTypes,relevantRelations) - statecoders += res - return res - } - def getSumStatecoderRuntime() { - statecoders.map[statecoderRuntime].reduce[p1, p2|p1+p2] - } + } -class NeighbourhoodBasedPartialInterpretationStateCoder implements IStateCoder{ - val int id; - val int range - val int parallels - val int maxNumber - val Set relevantTypes - val Set relevantRelations - - val calculator = - new PartialInterpretation2ImmutableTypeLattice - var PartialInterpretation target - - private var Map nodeRepresentations = null - private var Map modelRepresentation = null - - /*public new(int id) { - this.id = id - this.range = PartialInterpretation2NeighbourhoodRepresentation::FixPointRage - this.parallels = PartialInterpretation2NeighbourhoodRepresentation::FullParallels - this.maxNumber = maxNumber = PartialInterpretation2NeighbourhoodRepresentation::MaxNumbers - this.relevantTypes = relevantTypes - this.relevantRelations = relevantRelations - }*/ - - public new(int id, int range, int parallels, int maxNumber, Set relevantTypes, Set relevantRelations) { - this.id = id - this.range = range - this.parallels = parallels - this.maxNumber = maxNumber - this.relevantTypes = relevantTypes - this.relevantRelations = relevantRelations +class NeighbourhoodBasedPartialInterpretationStateCoder extends AbstractNeighbourhoodBasedPartialInterpretationStateCoder { + val calculator = new PartialInterpretation2ImmutableTypeLattice + + var Map nodeRepresentations = null + var Map modelRepresentation = null + + new(NeighbourhoodOptions options) { + super(options) } - - @Accessors(PUBLIC_GETTER) var long statecoderRuntime = 0 - -// val range = -1 -// val par = Integer.MAX_VALUE - //val deeprepresentation = false - - ///////// - // Caching version - ///////// - synchronized private def refreshStateCodes() { - if(this.nodeRepresentations === null || this.modelRepresentation === null) { - val startTime = System.nanoTime - //relevantObjects.forEach[println(it)] - val code = calculator.createRepresentation(target,range,parallels,maxNumber,relevantTypes,relevantRelations) - this.modelRepresentation = code.modelRepresentation - this.nodeRepresentations = code.nodeRepresentations - statecoderRuntime += (System.nanoTime - startTime) - } - } - synchronized override createActivationCode(IPatternMatch match) { - refreshStateCodes - - val startTime = System.nanoTime - val size = match.specification.parameters.size - val res = new ArrayList(size) - var int index = 0 - var int equivalenceHash = 0 - val prime = 31 - - while(index < size) { - res.add(getCode(match.get(index))) - index++ - for(var i = 0; i(res->equivalenceHash).hashCode - } - - - def private getCode(Object o) { - if(o instanceof DefinedElement) { - this.nodeRepresentations.get(o) - } else if(o instanceof PartialInterpretation || o instanceof LogicProblem) { - return null - } else if(o instanceof PartialRelationInterpretation) { - return o.interpretationOf.name - } else if(o instanceof PartialTypeInterpratation) { - if(o instanceof PartialPrimitiveInterpretation) { - o.class.simpleName.hashCode - } else if (o instanceof PartialComplexTypeInterpretation){ - return o.interpretationOf.name.hashCode - } else { - throw new UnsupportedOperationException('''Unsupported type: «o.class.simpleName»''') + + override protected isRefreshNeeded() { + nodeRepresentations === null || modelRepresentation === null + } + + override doRefreshStateCodes(PartialInterpretation target, NeighbourhoodOptions options) { + val code = calculator.createRepresentation(target, options) + modelRepresentation = code.modelRepresentation + nodeRepresentations = code.nodeRepresentations + } + + override doCreateActivationCode(IPatternMatch match) { + val size = match.specification.parameters.size + val res = new ArrayList(size) + var int index = 0 + var int equivalenceHash = 0 + val prime = 31 + + while (index < size) { + res.add(getCode(match.get(index))) + index++ + for (var i = 0; i < index; i++) { + val number = if (match.get(index) === match.get(i)) { + 1 + } else { + 0 + } + equivalenceHash = prime * equivalenceHash + number } - } else { - throw new UnsupportedOperationException('''Unsupported type: «o.class.simpleName»''') } - } - - synchronized override createStateCode() { - refreshStateCodes - return this.modelRepresentation.hashCode - } - ///////// - // Caching version - ///////// - - ///////// - // Recalculating version - ///////// -// synchronized override createActivationCode(IPatternMatch match) { -// val nodes = calculator.createRepresentation(getRelevantObjects().toList,range,par).nodeRepresentations -// val res = match.toArray.map[objectInMatch | -// nodes.get(objectInMatch) -// ] -// return res -// } -// -// override createStateCode() { -// return this.calculator.createRepresentation(getRelevantObjects().toList,range,par).modelRepresentation -// } - ///////// - // Recalculating version - ///////// - - override init(Notifier notifier) { - this.target = notifier as PartialInterpretation - val queryEngine = ViatraQueryEngine.on(new EMFScope(notifier)) - val baseIndex = queryEngine.getBaseIndex() as EMFBaseIndexWrapper - val navigationHelper = baseIndex.getNavigationHelper(); - - val classes = PartialinterpretationPackage.eINSTANCE.EClassifiers.filter(EClass).toSet - val features = classes.map[it.EAllStructuralFeatures].flatten.toSet - navigationHelper.registerObservedTypes( - classes, - null, - features, - IndexingLevel.FULL); - - - navigationHelper.addFeatureListener(features, new FeatureListener() { - override public void featureInserted(EObject host, EStructuralFeature feature, Object value) { invalidate } - override public void featureDeleted(EObject host, EStructuralFeature feature, Object value) { invalidate } - }); - navigationHelper.addInstanceListener(classes, new InstanceListener() { - override public void instanceInserted(EClass clazz, EObject instance) { invalidate } - override public void instanceDeleted(EClass clazz, EObject instance) { invalidate } - }); - } - - synchronized def public invalidate() { - this.nodeRepresentations = null - this.modelRepresentation = null + + match.specification.fullyQualifiedName -> (res -> equivalenceHash).hashCode + } + + def private getCode(Object o) { + switch (o) { + DefinedElement: + nodeRepresentations.get(o) + default: + getFallbackCode(o) + } + } + + override doCreateStateCode() { + modelRepresentation.hashCode + } + + override doInvalidate() { + nodeRepresentations = null + modelRepresentation = null } } diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/PairwiseNeighbourhoodBasedStateCoderFactory.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/PairwiseNeighbourhoodBasedStateCoderFactory.xtend new file mode 100644 index 00000000..84e798f2 --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/PairwiseNeighbourhoodBasedStateCoderFactory.xtend @@ -0,0 +1,75 @@ +package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder + +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.AbstractNodeDescriptor +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodOptions +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PairwiseNeighbourhoodRepresentation +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2PairwiseNeighbourhoodRepresentation +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation +import java.util.ArrayList +import org.eclipse.viatra.query.runtime.api.IPatternMatch + +class PairwiseNeighbourhoodBasedStateCoderFactory extends AbstractNeighbourhoodBasedStateCoderFactory { + new() { + } + + new(NeighbourhoodOptions options) { + super(options) + } + + override protected doCreateStateCoder(NeighbourhoodOptions options) { + new PairwiseNeighbourhoodBasedPartialInterpretationStateCoder(options) + } +} + +class PairwiseNeighbourhoodBasedPartialInterpretationStateCoder extends AbstractNeighbourhoodBasedPartialInterpretationStateCoder { + val calculator = new PartialInterpretation2PairwiseNeighbourhoodRepresentation( + new PartialInterpretation2ImmutableTypeLattice) + var PairwiseNeighbourhoodRepresentation representation + + new(NeighbourhoodOptions options) { + super(options) + } + + override protected isRefreshNeeded() { + representation === null + } + + override protected doRefreshStateCodes(PartialInterpretation target, NeighbourhoodOptions options) { + representation = calculator.createRepresentation(target, options) + } + + override protected doCreateActivationCode(IPatternMatch match) { + val size = match.specification.parameters.size + val res = new ArrayList(size * size) + for (var int i = 0; i < size; i++) { + val a = match.get(i) + for (var int j = 0; j < size; j++) { + val b = match.get(j) + res.add(getPairwiseRepresentation(a, b)) + } + } + match.specification.fullyQualifiedName -> res.hashCode + } + + private def getPairwiseRepresentation(Object a, Object b) { + if (b instanceof DefinedElement) { + if (a instanceof DefinedElement) { + representation.getPairwiseRepresentation(a, b) + } else { + representation.getBasicRepresentation(b) + } + } else { + getFallbackCode(b) + } + } + + override protected doCreateStateCode() { + representation.modelRepresentation.hashCode + } + + override protected doInvalidate() { + representation = null + } +} -- cgit v1.2.3-70-g09d2