aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kris7topher@gmail.com>2019-06-15 20:56:47 -0400
committerLibravatar Kristóf Marussy <kris7topher@gmail.com>2019-06-15 20:56:47 -0400
commitc0c5a1644cc221352b8b9b370eea6a87677ba948 (patch)
tree4b1412577c568440b7098dc31691438ebc8e7e9d /Solvers
parentBump MDEOptimizer version (diff)
downloadVIATRA-Generator-c0c5a1644cc221352b8b9b370eea6a87677ba948.tar.gz
VIATRA-Generator-c0c5a1644cc221352b8b9b370eea6a87677ba948.tar.zst
VIATRA-Generator-c0c5a1644cc221352b8b9b370eea6a87677ba948.zip
Try fix statecode bug
Modified graph width calculation to not depend on order of nodes
Diffstat (limited to 'Solvers')
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/Descriptor.xtend188
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/NeighbourhoodOptions.xtend22
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2NeighbourhoodRepresentation.xtend456
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2PairwiseNeighbourhoodRepresentation.xtend68
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/AbstractNeighborhoodBasedStateCoderFactory.xtend137
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/IdentifierBasedStateCoderFactory.xtend4
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/NeighbourhoodBasedStateCoderFactory.xtend275
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/PairwiseNeighbourhoodBasedStateCoderFactory.xtend75
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend9
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend3
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java8
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend71
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend62
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend164
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend52
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java24
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend48
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend2
18 files changed, 1095 insertions, 573 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/Descriptor.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/Descriptor.xtend
index 41482b28..c7c1ad77 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/Descriptor.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/Descriptor.xtend
@@ -4,10 +4,21 @@ import java.util.HashMap
4import java.util.Map 4import java.util.Map
5import java.util.Set 5import java.util.Set
6import org.eclipse.xtend.lib.annotations.Data 6import org.eclipse.xtend.lib.annotations.Data
7import org.eclipse.xtend2.lib.StringConcatenationClient
7 8
8@Data abstract class AbstractNodeDescriptor { 9@Data abstract class AbstractNodeDescriptor {
9 long dataHash 10 long dataHash
10 11
12 protected def StringConcatenationClient prettyPrint() {
13 '''(«dataHash»)[«class.simpleName»]'''
14 }
15
16 override toString() {
17 '''
18 «prettyPrint»
19 '''
20 }
21
11// @Pure 22// @Pure
12// @Override 23// @Override
13// override public boolean equals(Object obj) { 24// override public boolean equals(Object obj) {
@@ -24,34 +35,41 @@ import org.eclipse.xtend.lib.annotations.Data
24// } 35// }
25} 36}
26 37
27@Data class LocalNodeDescriptor extends AbstractNodeDescriptor{ 38@Data class LocalNodeDescriptor extends AbstractNodeDescriptor {
28 Set<String> types 39 Set<String> types
29 String id; 40 String id;
41
30 new(String id, Set<String> types) { 42 new(String id, Set<String> types) {
31 super(calcualteDataHash(id,types)) 43 super(calcualteDataHash(id, types))
32 this.types = types 44 this.types = types
33 this.id = id 45 this.id = id
34 } 46 }
35 47
36 def private static calcualteDataHash(String id, Set<String> types) { 48 def private static calcualteDataHash(String id, Set<String> types) {
37 val int prime = 31; 49 val int prime = 31;
38 var result = 0 50 var result = 0
39 if(id !== null) 51 if (id !== null)
40 result = id.hashCode(); 52 result = id.hashCode();
41 if(types !== null) { 53 if (types !== null) {
42 result = prime * result + types.hashCode 54 result = prime * result + types.hashCode
43 } 55 }
44 return result 56 return result
45 } 57 }
46 58
47 override hashCode() { 59 override hashCode() {
48 return this.dataHash.hashCode 60 return this.dataHash.hashCode
49 } 61 }
50 62
63 override protected prettyPrint() {
64 '''(«dataHash»)[«IF id !== null»id = "«id»"«IF types === null || !types.empty», «ENDIF»«ENDIF»«IF types === null»TYPES = null«ELSE»«FOR type : types SEPARATOR ", "»«type»«ENDFOR»«ENDIF»]'''
65 }
66
51 override toString() { 67 override toString() {
52 return class.name + this.dataHash 68 '''
69 «prettyPrint»
70 '''
53 } 71 }
54 72
55// @Pure 73// @Pure
56// @Override 74// @Override
57// override public boolean equals(Object obj) { 75// override public boolean equals(Object obj) {
@@ -66,7 +84,6 @@ import org.eclipse.xtend.lib.annotations.Data
66// return false; 84// return false;
67// return true; 85// return true;
68// } 86// }
69
70// @Pure 87// @Pure
71// override public boolean equals(Object obj) { 88// override public boolean equals(Object obj) {
72// if (this === obj) 89// if (this === obj)
@@ -97,49 +114,70 @@ import org.eclipse.xtend.lib.annotations.Data
97 String type 114 String type
98} 115}
99 116
100@Data class FurtherNodeDescriptor<NodeRep> extends AbstractNodeDescriptor{ 117@Data class FurtherNodeDescriptor<NodeRep> extends AbstractNodeDescriptor {
101 118
102 NodeRep previousRepresentation 119 NodeRep previousRepresentation
103 Map<IncomingRelation<NodeRep>,Integer> incomingEdges 120 Map<IncomingRelation<NodeRep>, Integer> incomingEdges
104 Map<OutgoingRelation<NodeRep>,Integer> outgoingEdges 121 Map<OutgoingRelation<NodeRep>, Integer> outgoingEdges
105 122
106 new( 123 new(NodeRep previousRepresentation, Map<IncomingRelation<NodeRep>, Integer> incomingEdges,
107 NodeRep previousRepresentation, 124 Map<OutgoingRelation<NodeRep>, Integer> outgoingEdges) {
108 Map<IncomingRelation<NodeRep>,Integer> incomingEdges, 125 super(calculateDataHash(previousRepresentation, incomingEdges, outgoingEdges))
109 Map<OutgoingRelation<NodeRep>,Integer> outgoingEdges) 126 this.previousRepresentation = previousRepresentation
110 { 127 this.incomingEdges = new HashMap(incomingEdges)
111 super(calculateDataHash(previousRepresentation,incomingEdges,outgoingEdges)) 128 this.outgoingEdges = new HashMap(outgoingEdges)
112 this.previousRepresentation = previousRepresentation
113 this.incomingEdges = new HashMap(incomingEdges)
114 this.outgoingEdges = new HashMap(outgoingEdges)
115 }
116
117 static def private <NodeRep> int calculateDataHash(
118 NodeRep previousRepresentation,
119 Map<IncomingRelation<NodeRep>,Integer> incomingEdges,
120 Map<OutgoingRelation<NodeRep>,Integer> outgoingEdges)
121 {
122 val int prime = 31;
123 var int result = previousRepresentation.hashCode;
124 if(incomingEdges !== null)
125 result = prime * result + incomingEdges.hashCode();
126 if(outgoingEdges !== null)
127 result = prime * result + outgoingEdges.hashCode();
128 return result;
129 }
130
131 override hashCode() {
132 return this.dataHash.hashCode
133 } 129 }
134 130
131 static def private <NodeRep> int calculateDataHash(NodeRep previousRepresentation,
132 Map<IncomingRelation<NodeRep>, Integer> incomingEdges, Map<OutgoingRelation<NodeRep>, Integer> outgoingEdges) {
133 val int prime = 31;
134 var int result = previousRepresentation.hashCode;
135 if (incomingEdges !== null)
136 result = prime * result + incomingEdges.hashCode();
137 if (outgoingEdges !== null)
138 result = prime * result + outgoingEdges.hashCode();
139 return result;
140 }
141
142 override hashCode() {
143 return this.dataHash.hashCode
144 }
145
146 override prettyPrint() {
147 '''
148 («dataHash»)[
149 PREV = «previousRepresentation?.prettyPrint»
150 «IF incomingEdges === null»
151 IN null
152 «ELSE»
153 «FOR edge : incomingEdges.entrySet»
154 IN «edge.value» «edge.key.type» = «edge.key.from.prettyPrint»
155 «ENDFOR»
156 «ENDIF»
157 «IF outgoingEdges === null»
158 OUT null
159 «ELSE»
160 «FOR edge : outgoingEdges.entrySet»
161 OUT «edge.value» «edge.key.type» = «edge.key.to.prettyPrint»
162 «ENDFOR»
163 «ENDIF»
164 ]'''
165 }
166
167 private def StringConcatenationClient prettyPrint(NodeRep rep) {
168 if (rep instanceof AbstractNodeDescriptor) {
169 rep.prettyPrint
170 } else {
171 '''«rep»'''
172 }
173 }
174
135 override toString() { 175 override toString() {
136 return class.name + dataHash 176 '''
137// return '''[«previousRepresentation»,(«FOR 177 «prettyPrint»
138// in: incomingEdges.entrySet»(«in.key.type.name»=«in.key.from»,«in.value»)«ENDFOR»),(«FOR 178 '''
139// out: outgoingEdges.entrySet»(«out.key.type.name»=«out.key.to»,«out.value»)«ENDFOR»),«FOR
140// att: attributeValues»(«att.type.name»=«att.value»)«ENDFOR»]'''
141 } 179 }
142 180
143// @Pure 181// @Pure
144// @Override 182// @Override
145// override public boolean equals(Object obj) { 183// override public boolean equals(Object obj) {
@@ -154,7 +192,6 @@ import org.eclipse.xtend.lib.annotations.Data
154// return false; 192// return false;
155// return true; 193// return true;
156// } 194// }
157
158// @Pure 195// @Pure
159// override public boolean equals(Object obj) { 196// override public boolean equals(Object obj) {
160// if (this === obj) 197// if (this === obj)
@@ -191,24 +228,23 @@ import org.eclipse.xtend.lib.annotations.Data
191// return true; 228// return true;
192// } 229// }
193} 230}
194
195/* 231/*
196@Data 232 * @Data
197class ModelDescriptor { 233 * class ModelDescriptor {
198 int dataHash 234 * int dataHash
199 int unknownElements 235 * int unknownElements
200 Map<? extends AbstractNodeDescriptor,Integer> knownElements 236 * Map<? extends AbstractNodeDescriptor,Integer> knownElements
201 237 *
202 public new(Map<? extends AbstractNodeDescriptor,Integer> knownElements, int unknownElements) { 238 * public new(Map<? extends AbstractNodeDescriptor,Integer> knownElements, int unknownElements) {
203 this.dataHash = calculateDataHash(knownElements,unknownElements) 239 * this.dataHash = calculateDataHash(knownElements,unknownElements)
204 this.unknownElements = unknownElements 240 * this.unknownElements = unknownElements
205 this.knownElements = knownElements 241 * this.knownElements = knownElements
206 } 242 * }
207 243 *
208 def private static calculateDataHash(Map<? extends AbstractNodeDescriptor,Integer> knownElements, int unknownElements) 244 * def private static calculateDataHash(Map<? extends AbstractNodeDescriptor,Integer> knownElements, int unknownElements)
209 { 245 * {
210 val int prime = 31; 246 * val int prime = 31;
211 return knownElements.hashCode * prime + unknownElements.hashCode 247 * return knownElements.hashCode * prime + unknownElements.hashCode
212 } 248 * }
213} 249 * }
214*/ \ No newline at end of file 250 */
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/NeighbourhoodOptions.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/NeighbourhoodOptions.xtend
new file mode 100644
index 00000000..efc89803
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/NeighbourhoodOptions.xtend
@@ -0,0 +1,22 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood
2
3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration
5import java.util.Set
6import org.eclipse.xtend.lib.annotations.Data
7
8@Data
9class NeighbourhoodOptions {
10 public static val FixPointRage = -1
11 public static val GraphWidthRange = -2
12 public static val FullParallels = Integer.MAX_VALUE
13 public static val MaxNumbers = Integer.MAX_VALUE
14
15 public static val DEFAULT = new NeighbourhoodOptions(GraphWidthRange, FullParallels, MaxNumbers, null, null)
16
17 val int range
18 val int parallels
19 val int maxNumber
20 val Set<TypeDeclaration> relevantTypes
21 val Set<RelationDeclaration> relevantRelations
22}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2NeighbourhoodRepresentation.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2NeighbourhoodRepresentation.xtend
index 6dc40705..54b0f54a 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2NeighbourhoodRepresentation.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2NeighbourhoodRepresentation.xtend
@@ -4,32 +4,34 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration 4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration 5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink 6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation
10import java.util.ArrayList
8import java.util.HashMap 11import java.util.HashMap
9import java.util.HashSet 12import java.util.HashSet
10import java.util.LinkedList
11import java.util.List 13import java.util.List
12import java.util.Map 14import java.util.Map
13import java.util.Set 15import java.util.Set
14 16
15import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* 17import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
16import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation
17import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
18 18
19abstract class PartialInterpretation2NeighbourhoodRepresentation<ModelRepresentation,NodeRepresentation> { 19abstract class PartialInterpretation2NeighbourhoodRepresentation<ModelRepresentation, NodeRepresentation> {
20 private val boolean deepRepresentation 20 val boolean deepRepresentation
21 private val boolean mergeSimilarNeighbourhood 21 val boolean mergeSimilarNeighbourhood
22 22
23 protected new(boolean deeprepresentation, boolean mergeSimilarNeighbourhood) { 23 protected new(boolean deeprepresentation, boolean mergeSimilarNeighbourhood) {
24 this.deepRepresentation = deeprepresentation 24 this.deepRepresentation = deeprepresentation
25 this.mergeSimilarNeighbourhood = mergeSimilarNeighbourhood 25 this.mergeSimilarNeighbourhood = mergeSimilarNeighbourhood
26 } 26 }
27 27
28 public static val FixPointRage = -1 28 public static val FixPointRage = NeighbourhoodOptions.FixPointRage
29 public static val GraphWidthRange = -2 29 public static val GraphWidthRange = NeighbourhoodOptions.GraphWidthRange
30 public static val FullParallels = Integer.MAX_VALUE 30 public static val FullParallels = NeighbourhoodOptions.FullParallels
31 public static val MaxNumbers = Integer.MAX_VALUE 31 public static val MaxNumbers = NeighbourhoodOptions.MaxNumbers
32 32
33 static val FOCUSED_ELEMENT_NAME = "<<THIS>>"
34
33 /** 35 /**
34 * Creates a neighbourhood representation with traces 36 * Creates a neighbourhood representation with traces
35 * @param model The model to be represented. 37 * @param model The model to be represented.
@@ -37,10 +39,15 @@ abstract class PartialInterpretation2NeighbourhoodRepresentation<ModelRepresenta
37 * @param parallels The maximal number of parallel references to be differentiated. 39 * @param parallels The maximal number of parallel references to be differentiated.
38 * @param maxNumber The maximal number of elements in a equivalence class that chan be differentiated. 40 * @param maxNumber The maximal number of elements in a equivalence class that chan be differentiated.
39 */ 41 */
40 def public createRepresentation(PartialInterpretation model, int range, int parallels, int maxNumber) { 42 def createRepresentation(PartialInterpretation model, int range, int parallels, int maxNumber) {
41 return createRepresentation(model,range,parallels,maxNumber,null,null) 43 return createRepresentation(model, range, parallels, maxNumber, null, null)
44 }
45
46 def createRepresentation(PartialInterpretation model, NeighbourhoodOptions options) {
47 createRepresentation(model, options.range, options.parallels, options.maxNumber, options.relevantTypes,
48 options.relevantRelations)
42 } 49 }
43 50
44 /** 51 /**
45 * Creates a neighbourhood representation with traces 52 * Creates a neighbourhood representation with traces
46 * @param model The model to be represented. 53 * @param model The model to be represented.
@@ -48,72 +55,88 @@ abstract class PartialInterpretation2NeighbourhoodRepresentation<ModelRepresenta
48 * @param parallels The maximal number of parallel references to be differentiated. 55 * @param parallels The maximal number of parallel references to be differentiated.
49 * @param maxNumber The maximal number of elements in a equivalence class that chan be differentiated. 56 * @param maxNumber The maximal number of elements in a equivalence class that chan be differentiated.
50 */ 57 */
51 def public createRepresentation( 58 def createRepresentation(PartialInterpretation model, int range, int parallels, int maxNumber,
52 PartialInterpretation model, 59 Set<TypeDeclaration> relevantTypes, Set<RelationDeclaration> relevantRelations) {
53 int range, int parallels, int maxNumber, 60 createRepresentationWithFocus(model, range, parallels, maxNumber, relevantTypes, relevantRelations, null)
54 Set<TypeDeclaration> relevantTypes, Set<RelationDeclaration> relevantRelations) 61 }
55 { 62
63 def createRepresentationWithFocus(PartialInterpretation model, NeighbourhoodOptions options,
64 DefinedElement focusedElement) {
65 createRepresentationWithFocus(model, options.range, options.parallels, options.maxNumber, options.relevantTypes,
66 options.relevantRelations, focusedElement)
67 }
68
69 def createRepresentationWithFocus(PartialInterpretation model, int range, int parallels, int maxNumber,
70 Set<TypeDeclaration> relevantTypes, Set<RelationDeclaration> relevantRelations, DefinedElement focusedElement) {
56 val Map<DefinedElement, Set<String>> types = new HashMap 71 val Map<DefinedElement, Set<String>> types = new HashMap
57 fillTypes(model,types,relevantTypes) 72 fillTypes(model, types, relevantTypes)
58 val Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations = new HashMap; 73 val Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations = new HashMap;
59 val Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations = new HashMap; 74 val Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations = new HashMap;
60 fillReferences(model,IncomingRelations,OutgoingRelations,relevantRelations) 75 fillReferences(model, IncomingRelations, OutgoingRelations, relevantRelations)
61 76
62 val res = doRecursiveNeighbourCalculation(model,types,IncomingRelations,OutgoingRelations,range,parallels,maxNumber); 77 val res = doRecursiveNeighbourCalculation(model, types, IncomingRelations, OutgoingRelations, range, parallels,
63 78 maxNumber, focusedElement);
79
64 return res; 80 return res;
65 } 81 }
66 82
67 def private isRelevant(TypeDeclaration t, Set<TypeDeclaration> relevantTypes) { 83 def private isRelevant(TypeDeclaration t, Set<TypeDeclaration> relevantTypes) {
68 if(relevantTypes === null) { 84 if (relevantTypes === null) {
69 return true 85 return true
70 } else { 86 } else {
71 return relevantTypes.contains(t) 87 return relevantTypes.contains(t)
72 } 88 }
73 } 89 }
90
74 def private isRelevant(RelationDeclaration r, Set<RelationDeclaration> relevantRelations) { 91 def private isRelevant(RelationDeclaration r, Set<RelationDeclaration> relevantRelations) {
75 if(relevantRelations === null) { 92 if (relevantRelations === null) {
76 return true 93 return true
77 } else { 94 } else {
78 return relevantRelations.contains(r) 95 return relevantRelations.contains(r)
79 } 96 }
80 } 97 }
98
81 /** 99 /**
82 * Gets the largest 100 * Gets the minimal neighbourhood size such that every reachable node appears in the shape of every other at least once.
83 */ 101 */
84 def private getWidth(Map<DefinedElement, Set<String>> types, 102 def private getWidth(Map<DefinedElement, Set<String>> types,
85 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations, 103 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations,
86 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations) 104 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations) {
87 { 105 val elements = types.keySet
88 val elements = types.keySet 106 var Map<DefinedElement, Set<DefinedElement>> reachable = new HashMap
89 val Map<DefinedElement,Set<DefinedElement>> reachable = new HashMap 107 var Map<DefinedElement, Set<DefinedElement>> newReachable = new HashMap
90 for(element : elements) { 108 for (element : elements) {
91 val set = new HashSet 109 val set = new HashSet
92 set.add(element) 110 set.add(element)
93 reachable.put(element,set) 111 reachable.put(element, new HashSet)
112 newReachable.put(element, set)
94 } 113 }
95 114
96 var int width = 0 115 var int width = 0
97 var boolean newAdded 116 var boolean newAdded
98 do { 117 do {
118 var tmp = reachable
119 reachable = newReachable
120 newReachable = tmp
99 newAdded = false 121 newAdded = false
100 for(element : elements) { 122 for (element : elements) {
101 val elementNeigbours = element.lookup(reachable) 123 val elementNeigbours = element.lookup(reachable)
102 val size = elementNeigbours.size 124 val newElementNeigbours = element.lookup(newReachable)
103 for(incoming : element.lookup(IncomingRelations)) { 125 newElementNeigbours.addAll(elementNeigbours)
104 elementNeigbours.addAll(incoming.from.lookup(reachable)) 126 for (incoming : element.lookup(IncomingRelations)) {
127 newElementNeigbours.addAll(incoming.from.lookup(reachable))
105 } 128 }
106 for(outgoing : element.lookup(OutgoingRelations)) { 129 for (outgoing : element.lookup(OutgoingRelations)) {
107 elementNeigbours.addAll(outgoing.to.lookup(reachable)) 130 newElementNeigbours.addAll(outgoing.to.lookup(reachable))
108 } 131 }
109 newAdded = newAdded || (elementNeigbours.size > size) 132 newAdded = newAdded || (newElementNeigbours.size > elementNeigbours.size)
110 } 133 }
111 134
112 width +=1 135 width += 1
113 } while(newAdded) 136 } while (newAdded)
114 return width 137 return width
115 } 138 }
116 139
117 /** 140 /**
118 * Creates a neighbourhood representation with traces 141 * Creates a neighbourhood representation with traces
119 * @param model The model to be represented. 142 * @param model The model to be represented.
@@ -122,68 +145,71 @@ abstract class PartialInterpretation2NeighbourhoodRepresentation<ModelRepresenta
122 * @param range The range of the neighbourhood. 145 * @param range The range of the neighbourhood.
123 * @param parallels The maximal number of parallel references to be differentiated. 146 * @param parallels The maximal number of parallel references to be differentiated.
124 */ 147 */
125 def private NeighbourhoodWithTraces<ModelRepresentation,NodeRepresentation> doRecursiveNeighbourCalculation( 148 def private NeighbourhoodWithTraces<ModelRepresentation, NodeRepresentation> doRecursiveNeighbourCalculation(
126 PartialInterpretation model, 149 PartialInterpretation model, Map<DefinedElement, Set<String>> types,
127 Map<DefinedElement, Set<String>> types,
128 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations, 150 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations,
129 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations, 151 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations, int range, int parallels,
130 int range, int parallels, int maxNumber) 152 int maxNumber, DefinedElement focusedElement) {
131 { 153 if (range == 0) {
132 if(range == 0){ 154 val r = calculateLocalNodeDescriptors(model, types, maxNumber, focusedElement)
133 val r = calculateLocalNodeDescriptors(model,types,maxNumber) 155 val res = this.createLocalRepresentation(r.value, r.key)
134 val res = this.createLocalRepresentation(r.value,r.key) 156 if (res.modelRepresentation === null) {
135 if(res.modelRepresentation === null) {
136 throw new IllegalArgumentException('''Model representation is null''') 157 throw new IllegalArgumentException('''Model representation is null''')
137 } else if(res.nodeRepresentations === null || res.nodeRepresentations.empty) { 158 } else if (res.nodeRepresentations === null || res.nodeRepresentations.empty) {
138 throw new IllegalArgumentException('''No node representation''') 159 throw new IllegalArgumentException('''No node representation''')
139 } else if(res.previousRepresentation !== null) { 160 } else if (res.previousRepresentation !== null) {
140 throw new IllegalArgumentException('''The previous representation of the first neighbourhood have to be null''') 161 throw new IllegalArgumentException('''The previous representation of the first neighbourhood have to be null''')
141 } else return res 162 } else
142 } else if(range > 0) { 163 return res
143 val previous = doRecursiveNeighbourCalculation(model,types,IncomingRelations,OutgoingRelations,range-1,parallels,maxNumber) 164 } else if (range > 0) {
144 val r = calculateFurtherNodeDescriptors(model,previous,IncomingRelations,OutgoingRelations,parallels,maxNumber) 165 val previous = doRecursiveNeighbourCalculation(model, types, IncomingRelations, OutgoingRelations,
145 //println('''Level «range» finished.''') 166 range - 1, parallels, maxNumber, focusedElement)
146 val res = createFurtherRepresentation(r.key,r.value,previous,deepRepresentation) 167 val r = calculateFurtherNodeDescriptors(model, previous, IncomingRelations, OutgoingRelations, parallels,
147 if(res.modelRepresentation === null) { 168 maxNumber)
169 // println('''Level «range» finished.''')
170 val res = createFurtherRepresentation(r.key, r.value, previous, deepRepresentation)
171 if (res.modelRepresentation === null) {
148 throw new IllegalArgumentException('''Model representation is null''') 172 throw new IllegalArgumentException('''Model representation is null''')
149 } else if(res.nodeRepresentations === null || res.nodeRepresentations.empty) { 173 } else if (res.nodeRepresentations === null || res.nodeRepresentations.empty) {
150 throw new IllegalArgumentException('''No node representation''') 174 throw new IllegalArgumentException('''No node representation''')
151 } else if(res.previousRepresentation === null && deepRepresentation) { 175 } else if (res.previousRepresentation === null && deepRepresentation) {
152 throw new IllegalArgumentException('''Need previous representations''') 176 throw new IllegalArgumentException('''Need previous representations''')
153 } else return res 177 } else
178 return res
154 } else if (range == FixPointRage) { 179 } else if (range == FixPointRage) {
155 return refineUntilFixpoint(model,types,IncomingRelations,OutgoingRelations,parallels,maxNumber) 180 return refineUntilFixpoint(model, types, IncomingRelations, OutgoingRelations, parallels, maxNumber,
181 focusedElement)
156 } else if (range == GraphWidthRange) { 182 } else if (range == GraphWidthRange) {
157 val width = this.getWidth(types,IncomingRelations,OutgoingRelations) 183 val width = this.getWidth(types, IncomingRelations, OutgoingRelations)
158 //println(width) 184 // println(width)
159 return doRecursiveNeighbourCalculation(model,types,IncomingRelations,OutgoingRelations,width,parallels,maxNumber) 185 return doRecursiveNeighbourCalculation(model, types, IncomingRelations, OutgoingRelations, width, parallels,
186 maxNumber, focusedElement)
160 } 187 }
161 } 188 }
162 189
163 def private refineUntilFixpoint( 190 def private refineUntilFixpoint(PartialInterpretation model, Map<DefinedElement, Set<String>> types,
164 PartialInterpretation model,
165 Map<DefinedElement, Set<String>> types,
166 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations, 191 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations,
167 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations, 192 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations, int parallels, int maxNumbers,
168 int parallels, int maxNumbers) 193 DefinedElement focusedElement) {
169 {
170 var lastRange = 0 194 var lastRange = 0
171 val last = calculateLocalNodeDescriptors(model,types,maxNumbers) 195 val last = calculateLocalNodeDescriptors(model, types, maxNumbers, focusedElement)
172 var lastRepresentation = this.createLocalRepresentation(last.value,last.key) 196 var lastRepresentation = this.createLocalRepresentation(last.value, last.key)
173 //println('''Level 0 finished.''') 197 // println('''Level 0 finished.''')
174 var boolean hasRefined 198 var boolean hasRefined
175 do { 199 do {
176 val nextRange = lastRange+1 200 val nextRange = lastRange + 1
177 val next = calculateFurtherNodeDescriptors(model,lastRepresentation,IncomingRelations,OutgoingRelations,parallels,maxNumbers) 201 val next = calculateFurtherNodeDescriptors(model, lastRepresentation, IncomingRelations, OutgoingRelations,
178 val nextRepresentation = createFurtherRepresentation(next.key,next.value,lastRepresentation,deepRepresentation) 202 parallels, maxNumbers)
179 203 val nextRepresentation = createFurtherRepresentation(next.key, next.value, lastRepresentation,
180 val previousNumberOfTypes =lastRepresentation.nodeRepresentations.values.toSet.size 204 deepRepresentation)
205
206 val previousNumberOfTypes = lastRepresentation.nodeRepresentations.values.toSet.size
181 val nextNumberOfTypes = nextRepresentation.nodeRepresentations.values.toSet.size 207 val nextNumberOfTypes = nextRepresentation.nodeRepresentations.values.toSet.size
182 hasRefined = nextNumberOfTypes > previousNumberOfTypes 208 hasRefined = nextNumberOfTypes > previousNumberOfTypes
183 209
184 lastRange = nextRange 210 lastRange = nextRange
185 lastRepresentation = nextRepresentation 211 lastRepresentation = nextRepresentation
186 212
187// if(hasRefined) { 213// if(hasRefined) {
188// println('''Level «nextRange» is calculated, number of types is refined: «previousNumberOfTypes» -> «nextNumberOfTypes»''') 214// println('''Level «nextRange» is calculated, number of types is refined: «previousNumberOfTypes» -> «nextNumberOfTypes»''')
189// } else { 215// } else {
@@ -192,211 +218,219 @@ abstract class PartialInterpretation2NeighbourhoodRepresentation<ModelRepresenta
192 } while (hasRefined) 218 } while (hasRefined)
193 return lastRepresentation 219 return lastRepresentation
194 } 220 }
195 221
196 def private getElements(PartialInterpretation model) { 222 def private getElements(PartialInterpretation model) {
197 return 223 return model.problem.elements + model.newElements + model.openWorldElements
198 model.problem.elements +
199 model.newElements +
200 model.openWorldElements
201 } 224 }
202 225
203 def private fillTypes(PartialInterpretation model, Map<DefinedElement, Set<String>> node2Type, Set<TypeDeclaration> relevantTypes) { 226 def private fillTypes(PartialInterpretation model, Map<DefinedElement, Set<String>> node2Type,
204 for(element : model.elements) { 227 Set<TypeDeclaration> relevantTypes) {
228 for (element : model.elements) {
205 node2Type.put(element, new HashSet) 229 node2Type.put(element, new HashSet)
206 } 230 }
207 231
208// for(typeDefinition : model.problem.types.filter(TypeDefinition)) { 232// for(typeDefinition : model.problem.types.filter(TypeDefinition)) {
209// // Dont need 233// // Dont need
210// } 234// }
211 for(typeInterpretation : model.partialtypeinterpratation) { 235 for (typeInterpretation : model.partialtypeinterpratation) {
212 if(typeInterpretation instanceof PartialPrimitiveInterpretation) { 236 if (typeInterpretation instanceof PartialPrimitiveInterpretation) {
213 237 } else if (typeInterpretation instanceof PartialComplexTypeInterpretation) {
214 } else if(typeInterpretation instanceof PartialComplexTypeInterpretation) {
215 val type = typeInterpretation.interpretationOf 238 val type = typeInterpretation.interpretationOf
216 if(type.isRelevant(relevantTypes)) { 239 if (type.isRelevant(relevantTypes)) {
217 for(element : typeInterpretation.elements) { 240 for (element : typeInterpretation.elements) {
218 element.lookup(node2Type).add(type.name) 241 element.lookup(node2Type).add(type.name)
219 } 242 }
220 } 243 }
221 } 244 }
222 } 245 }
223 } 246 }
224 247
225 /** 248 /**
226 * Indexes the references 249 * Indexes the references
227 */ 250 */
228 def private fillReferences(PartialInterpretation model, 251 def private fillReferences(PartialInterpretation model,
229 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations, 252 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations,
230 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations, 253 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations,
231 Set<RelationDeclaration> relevantRelations) 254 Set<RelationDeclaration> relevantRelations) {
232 { 255 for (object : model.elements) {
233 for(object : model.elements) { 256 IncomingRelations.put(object, new ArrayList)
234 IncomingRelations.put(object,new LinkedList) 257 OutgoingRelations.put(object, new ArrayList)
235 OutgoingRelations.put(object,new LinkedList)
236 } 258 }
237 for(relationInterpretation : model.partialrelationinterpretation) { 259 for (relationInterpretation : model.partialrelationinterpretation) {
238 val type = relationInterpretation.interpretationOf 260 val type = relationInterpretation.interpretationOf
239 if(type.isRelevant(relevantRelations)) { 261 if (type.isRelevant(relevantRelations)) {
240 for(link : relationInterpretation.relationlinks) { 262 for (link : relationInterpretation.relationlinks) {
241 if(link instanceof BinaryElementRelationLink) { 263 if (link instanceof BinaryElementRelationLink) {
242 OutgoingRelations.get(link.param1) += new OutgoingRelation(link.param2,type.name) 264 OutgoingRelations.get(link.param1) += new OutgoingRelation(link.param2, type.name)
243 IncomingRelations.get(link.param2) += new IncomingRelation(link.param1,type.name) 265 IncomingRelations.get(link.param2) += new IncomingRelation(link.param1, type.name)
244 } else throw new UnsupportedOperationException 266 } else
267 throw new UnsupportedOperationException
245 } 268 }
246 } 269 }
247 } 270 }
248 } 271 }
249 272
250 /** 273 /**
251 * Creates a local representation of the objects (aka zero range neighbourhood) 274 * Creates a local representation of the objects (aka zero range neighbourhood)
252 */ 275 */
253 def abstract protected NeighbourhoodWithTraces<ModelRepresentation,NodeRepresentation> createLocalRepresentation( 276 def abstract protected NeighbourhoodWithTraces<ModelRepresentation, NodeRepresentation> createLocalRepresentation(
254 Map<DefinedElement, LocalNodeDescriptor> node2Representation, 277 Map<DefinedElement, LocalNodeDescriptor> node2Representation,
255 Map<LocalNodeDescriptor, Integer> representation2Amount 278 Map<LocalNodeDescriptor, Integer> representation2Amount
256 ) 279 )
257 280
258 /** 281 /**
259 * Creates a 282 * Creates a
260 */ 283 */
261 def abstract protected NeighbourhoodWithTraces<ModelRepresentation,NodeRepresentation> createFurtherRepresentation( 284 def abstract protected NeighbourhoodWithTraces<ModelRepresentation, NodeRepresentation> createFurtherRepresentation(
262 Map<FurtherNodeDescriptor<NodeRepresentation>, Integer> nodeDescriptors, 285 Map<FurtherNodeDescriptor<NodeRepresentation>, Integer> nodeDescriptors,
263 Map<DefinedElement, FurtherNodeDescriptor<NodeRepresentation>> node2Representation, 286 Map<DefinedElement, FurtherNodeDescriptor<NodeRepresentation>> node2Representation,
264 NeighbourhoodWithTraces<ModelRepresentation,NodeRepresentation> previous, 287 NeighbourhoodWithTraces<ModelRepresentation, NodeRepresentation> previous,
265 boolean deepRepresentation 288 boolean deepRepresentation
266 ) 289 )
267 290
268 def private addOne(int original, int max) { 291 def private addOne(int original, int max) {
269 if(original == Integer.MAX_VALUE) return Integer.MAX_VALUE 292 if(original == Integer.MAX_VALUE) return Integer.MAX_VALUE
270 if(original +1 > max) return Integer.MAX_VALUE 293 if(original + 1 > max) return Integer.MAX_VALUE else return original + 1
271 else return original+1
272 } 294 }
273 295
274 private def calculateIncomingEdges(Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations, 296 private def calculateIncomingEdges(Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations,
275 DefinedElement object, Map<DefinedElement, ? extends NodeRepresentation> previousNodeRepresentations, int parallel) 297 DefinedElement object, Map<DefinedElement, ? extends NodeRepresentation> previousNodeRepresentations,
276 { 298 int parallel) {
277 val Map<IncomingRelation<NodeRepresentation>, Integer> res = new HashMap 299 val Map<IncomingRelation<NodeRepresentation>, Integer> res = new HashMap
278 for (incomingConcreteEdge : IncomingRelations.get(object)) { 300 for (incomingConcreteEdge : IncomingRelations.get(object)) {
279 val IncomingRelation<NodeRepresentation> e = new IncomingRelation( 301 val IncomingRelation<NodeRepresentation> e = new IncomingRelation(
280 previousNodeRepresentations.get(incomingConcreteEdge.from), incomingConcreteEdge.type) 302 previousNodeRepresentations.get(incomingConcreteEdge.from), incomingConcreteEdge.type)
281 if (res.containsKey(e)) { 303 if (res.containsKey(e)) {
282 res.put(e, addOne(res.get(e),parallel)) 304 res.put(e, addOne(res.get(e), parallel))
283 } else { 305 } else {
284 res.put(e, 1) 306 res.put(e, 1)
285 } 307 }
286 } 308 }
287 return res 309 return res
288 } 310 }
289 311
290 private def calcuateOutgoingEdges(Map<DefinedElement,List<OutgoingRelation<DefinedElement>>> OutgoingRelations, 312 private def calcuateOutgoingEdges(Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations,
291 DefinedElement object, Map<DefinedElement, ? extends NodeRepresentation> previousNodeRepresentations, int parallel) 313 DefinedElement object, Map<DefinedElement, ? extends NodeRepresentation> previousNodeRepresentations,
292 { 314 int parallel) {
293 val Map<OutgoingRelation<NodeRepresentation>,Integer> res= new HashMap 315 val Map<OutgoingRelation<NodeRepresentation>, Integer> res = new HashMap
294 for(outgoingConcreteEdge : OutgoingRelations.get(object)) { 316 for (outgoingConcreteEdge : OutgoingRelations.get(object)) {
295 val OutgoingRelation<NodeRepresentation> e = 317 val OutgoingRelation<NodeRepresentation> e = new OutgoingRelation(
296 new OutgoingRelation( 318 previousNodeRepresentations.get(outgoingConcreteEdge.to), outgoingConcreteEdge.type)
297 previousNodeRepresentations.get(outgoingConcreteEdge.to), 319 if (res.containsKey(e)) {
298 outgoingConcreteEdge.type) 320 res.put(e, addOne(res.get(e), parallel))
299 if(res.containsKey(e)) {
300 res.put(e,addOne(res.get(e),parallel))
301 } else { 321 } else {
302 res.put(e,1) 322 res.put(e, 1)
303 } 323 }
304 } 324 }
305 return res; 325 return res;
306 } 326 }
307 327
308 /*def private <KEY,VALUE> void addOrCreate_Set(Map<KEY,Set<VALUE>> map, KEY key, VALUE value) { 328 /*def private <KEY,VALUE> void addOrCreate_Set(Map<KEY,Set<VALUE>> map, KEY key, VALUE value) {
309 var Set<VALUE> s; 329 * var Set<VALUE> s;
310 if(map.containsKey(key)) { 330 * if(map.containsKey(key)) {
311 s = map.get(key); 331 * s = map.get(key);
312 } else { 332 * } else {
313 s = new HashSet 333 * s = new HashSet
314 map.put(key,s) 334 * map.put(key,s)
315 } 335 * }
316 s.add(value) 336 * s.add(value)
317 }*/ 337 }*/
318 338 private def calculateFurtherNodeDescriptors(PartialInterpretation model,
319
320 private def calculateFurtherNodeDescriptors(
321 PartialInterpretation model,
322 NeighbourhoodWithTraces<ModelRepresentation, NodeRepresentation> previous, 339 NeighbourhoodWithTraces<ModelRepresentation, NodeRepresentation> previous,
323 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations, 340 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations,
324 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations, 341 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations, int parallels, int maxNumber) {
325 int parallels, int maxNumber)
326 {
327 val previousNodeRepresentations = previous.nodeRepresentations 342 val previousNodeRepresentations = previous.nodeRepresentations
328 val node2Representation = new HashMap<DefinedElement,FurtherNodeDescriptor<NodeRepresentation>> 343 val node2Representation = new HashMap<DefinedElement, FurtherNodeDescriptor<NodeRepresentation>>
329 val Map<FurtherNodeDescriptor<NodeRepresentation>,Integer> descriptor2Number = 344 val Map<FurtherNodeDescriptor<NodeRepresentation>, Integer> descriptor2Number = if (this.
330 if(this.mergeSimilarNeighbourhood){ new HashMap } else { null } 345 mergeSimilarNeighbourhood) {
331 val Map<FurtherNodeDescriptor<NodeRepresentation>,FurtherNodeDescriptor<NodeRepresentation>> uniqueDescription = 346 new HashMap
332 if(this.mergeSimilarNeighbourhood){ new HashMap } else { null } 347 } else {
333 348 null
334 for(object: model.elements) { 349 }
335 val incomingEdges = this.calculateIncomingEdges(IncomingRelations, object, previousNodeRepresentations,parallels) 350 val Map<FurtherNodeDescriptor<NodeRepresentation>, FurtherNodeDescriptor<NodeRepresentation>> uniqueDescription = if (this.
336 val outgoingEdges = this.calcuateOutgoingEdges(OutgoingRelations,object, previousNodeRepresentations,parallels) 351 mergeSimilarNeighbourhood) {
337 352 new HashMap
353 } else {
354 null
355 }
356
357 for (object : model.elements) {
358 val incomingEdges = this.calculateIncomingEdges(IncomingRelations, object, previousNodeRepresentations,
359 parallels)
360 val outgoingEdges = this.calcuateOutgoingEdges(OutgoingRelations, object, previousNodeRepresentations,
361 parallels)
362
338 val previousType = previousNodeRepresentations.get(object) 363 val previousType = previousNodeRepresentations.get(object)
339 364
340 if(previousType === null) { 365 if (previousType === null) {
341 println("Error in state coder") 366 println("Error in state coder")
342 } 367 }
343 368
344 val nodeDescriptor = new FurtherNodeDescriptor( 369 val nodeDescriptor = new FurtherNodeDescriptor(previousType, incomingEdges, outgoingEdges)
345 previousType, 370
346 incomingEdges, 371 if (this.mergeSimilarNeighbourhood) {
347 outgoingEdges) 372 if (descriptor2Number.containsKey(nodeDescriptor)) {
348
349 if(this.mergeSimilarNeighbourhood) {
350 if(descriptor2Number.containsKey(nodeDescriptor)) {
351 descriptor2Number.put( 373 descriptor2Number.put(
352 nodeDescriptor, 374 nodeDescriptor,
353 addOne(descriptor2Number.get(nodeDescriptor),maxNumber) 375 addOne(descriptor2Number.get(nodeDescriptor), maxNumber)
354 ) 376 )
355 node2Representation.put(object,uniqueDescription.get(nodeDescriptor)) 377 node2Representation.put(object, uniqueDescription.get(nodeDescriptor))
356 } else { 378 } else {
357 descriptor2Number.put(nodeDescriptor,if(1>maxNumber){Integer.MAX_VALUE}else{1}) 379 descriptor2Number.put(nodeDescriptor, if (1 > maxNumber) {
358 uniqueDescription.put(nodeDescriptor,nodeDescriptor) 380 Integer.MAX_VALUE
359 node2Representation.put(object,nodeDescriptor) 381 } else {
382 1
383 })
384 uniqueDescription.put(nodeDescriptor, nodeDescriptor)
385 node2Representation.put(object, nodeDescriptor)
360 } 386 }
361 } else { 387 } else {
362 node2Representation.put(object,nodeDescriptor) 388 node2Representation.put(object, nodeDescriptor)
363 } 389 }
364 } 390 }
365 391
366 return descriptor2Number -> node2Representation 392 return descriptor2Number -> node2Representation
367 } 393 }
368 394
369 private def calculateLocalNodeDescriptors( 395 private def calculateLocalNodeDescriptors(PartialInterpretation model, Map<DefinedElement, Set<String>> types,
370 PartialInterpretation model, 396 int maxNumber, DefinedElement focusedElement) {
371 Map<DefinedElement, Set<String>> types,
372 int maxNumber)
373 {
374 val Map<DefinedElement, LocalNodeDescriptor> node2Representation = new HashMap 397 val Map<DefinedElement, LocalNodeDescriptor> node2Representation = new HashMap
375 val Map<LocalNodeDescriptor, Integer> representation2Amount = 398 val Map<LocalNodeDescriptor, Integer> representation2Amount = if (mergeSimilarNeighbourhood) {
376 if(mergeSimilarNeighbourhood){ new HashMap } else { null } 399 new HashMap
377 val Map<LocalNodeDescriptor, LocalNodeDescriptor> uniqueRepresentation = 400 } else {
378 if(this.mergeSimilarNeighbourhood){ new HashMap } else { null } 401 null
379 402 }
380 for(element : model.elements) { 403 val Map<LocalNodeDescriptor, LocalNodeDescriptor> uniqueRepresentation = if (this.mergeSimilarNeighbourhood) {
381 var newDescriptor = new LocalNodeDescriptor(element.name,element.lookup(types)) 404 new HashMap
382 if(this.mergeSimilarNeighbourhood){ 405 } else {
383 if(uniqueRepresentation.containsKey(newDescriptor)) { 406 null
407 }
408
409 for (element : model.elements) {
410 val name = if(element == focusedElement) FOCUSED_ELEMENT_NAME else element.name
411 var newDescriptor = new LocalNodeDescriptor(name, element.lookup(types))
412 if (this.mergeSimilarNeighbourhood) {
413 if (uniqueRepresentation.containsKey(newDescriptor)) {
384 newDescriptor = newDescriptor.lookup(uniqueRepresentation) 414 newDescriptor = newDescriptor.lookup(uniqueRepresentation)
385 node2Representation.put(element,newDescriptor) 415 node2Representation.put(element, newDescriptor)
386 representation2Amount.put( 416 representation2Amount.put(
387 newDescriptor, 417 newDescriptor,
388 addOne(newDescriptor.lookup(representation2Amount),maxNumber) 418 addOne(newDescriptor.lookup(representation2Amount), maxNumber)
389 ) 419 )
390 } else { 420 } else {
391 uniqueRepresentation.put(newDescriptor,newDescriptor) 421 uniqueRepresentation.put(newDescriptor, newDescriptor)
392 node2Representation.put(element,newDescriptor) 422 node2Representation.put(element, newDescriptor)
393 representation2Amount.put(newDescriptor, if(1>maxNumber){Integer.MAX_VALUE}else{1}) 423 representation2Amount.put(newDescriptor, if (1 > maxNumber) {
424 Integer.MAX_VALUE
425 } else {
426 1
427 })
394 } 428 }
395 } else { 429 } else {
396 node2Representation.put(element,newDescriptor) 430 node2Representation.put(element, newDescriptor)
397 } 431 }
398 } 432 }
399 433
400 return representation2Amount -> node2Representation 434 return representation2Amount -> node2Representation
401 } 435 }
402} \ No newline at end of file 436}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2PairwiseNeighbourhoodRepresentation.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2PairwiseNeighbourhoodRepresentation.xtend
new file mode 100644
index 00000000..c10457b0
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2PairwiseNeighbourhoodRepresentation.xtend
@@ -0,0 +1,68 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood
2
3import com.google.common.collect.Maps
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
6import java.util.HashMap
7import java.util.Map
8import org.eclipse.xtend.lib.annotations.Data
9import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
10
11@Data
12class PairwiseNeighbourhoodRepresentation<BasicNodeRepresentation> {
13 val Map<?, Integer> modelRepresentation
14 val Map<DefinedElement, BasicNodeRepresentation> basicNodeRepresentations
15 val Map<DefinedElement, ? extends Map<DefinedElement, ? extends BasicNodeRepresentation>> pairwiseNodeRepresentations
16
17 def getBasicRepresentation(DefinedElement a) {
18 basicNodeRepresentations.get(a)
19 }
20
21 def getPairwiseRepresentation(DefinedElement a, DefinedElement b) {
22 pairwiseNodeRepresentations.get(a).get(b)
23 }
24}
25
26@FinalFieldsConstructor
27class PartialInterpretation2PairwiseNeighbourhoodRepresentation<BasicNodeRepresentation> {
28 val PartialInterpretation2NeighbourhoodRepresentation<? extends Map<? extends BasicNodeRepresentation, Integer>, BasicNodeRepresentation> basicNeighbourhoodRepresenter
29
30 def createRepresentation(PartialInterpretation model, NeighbourhoodOptions options) {
31 val basicRepresentation = basicNeighbourhoodRepresenter.createRepresentation(model, options)
32 val basicModelRepresentation = basicRepresentation.modelRepresentation
33 val basicNodeRepresentations = basicRepresentation.nodeRepresentations
34 val pairwiseNodeRepresentations = Maps.newHashMapWithExpectedSize(basicNodeRepresentations.size)
35 val modelRepresentation = new HashMap<Object, Integer>
36 for (nodeWithBasicRepresentation : basicNodeRepresentations.entrySet) {
37 val node = nodeWithBasicRepresentation.key
38 val basicNodeRepresentation = nodeWithBasicRepresentation.value
39 val count = basicModelRepresentation.get(basicNodeRepresentation)
40 if (count == 1) {
41 pairwiseNodeRepresentations.put(node, basicNodeRepresentations)
42 modelRepresentation.put(basicNodeRepresentation, count)
43 } else {
44 val neighbourhoodRepresentation = basicNeighbourhoodRepresenter.
45 createRepresentationWithFocus(model, options, node)
46 pairwiseNodeRepresentations.put(node, neighbourhoodRepresentation.nodeRepresentations)
47 modelRepresentation.compute(neighbourhoodRepresentation.modelRepresentation) [ key, value |
48 if (value === null) {
49 if (1 > options.maxNumber) {
50 Integer.MAX_VALUE
51 } else {
52 1
53 }
54 } else {
55 addOne(value, options.maxNumber)
56 }
57 ]
58 }
59 }
60 new PairwiseNeighbourhoodRepresentation(modelRepresentation, basicNodeRepresentations,
61 pairwiseNodeRepresentations)
62 }
63
64 def private addOne(int original, int max) {
65 if(original == Integer.MAX_VALUE) return Integer.MAX_VALUE
66 if(original + 1 > max) return Integer.MAX_VALUE else return original + 1
67 }
68}
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 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder
2
3import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodOptions
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage
10import java.util.LinkedList
11import java.util.List
12import org.eclipse.emf.common.notify.Notifier
13import org.eclipse.emf.ecore.EClass
14import org.eclipse.emf.ecore.EObject
15import org.eclipse.emf.ecore.EStructuralFeature
16import org.eclipse.viatra.dse.statecode.IStateCoder
17import org.eclipse.viatra.dse.statecode.IStateCoderFactory
18import org.eclipse.viatra.query.runtime.api.IPatternMatch
19import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
20import org.eclipse.viatra.query.runtime.base.api.FeatureListener
21import org.eclipse.viatra.query.runtime.base.api.IndexingLevel
22import org.eclipse.viatra.query.runtime.base.api.InstanceListener
23import org.eclipse.viatra.query.runtime.emf.EMFBaseIndexWrapper
24import org.eclipse.viatra.query.runtime.emf.EMFScope
25import org.eclipse.xtend.lib.annotations.Accessors
26
27abstract class AbstractNeighbourhoodBasedStateCoderFactory implements IStateCoderFactory {
28 val List<AbstractNeighbourhoodBasedPartialInterpretationStateCoder> statecoders = new LinkedList
29
30 val NeighbourhoodOptions options
31
32 protected new() {
33 this(NeighbourhoodOptions.DEFAULT)
34 }
35
36 protected new(NeighbourhoodOptions options) {
37 this.options = options
38 }
39
40 synchronized override createStateCoder() {
41 val res = doCreateStateCoder(options)
42 statecoders += res
43 return res
44 }
45
46 protected def AbstractNeighbourhoodBasedPartialInterpretationStateCoder doCreateStateCoder(
47 NeighbourhoodOptions options)
48
49 def getSumStatecoderRuntime() {
50 statecoders.map[statecoderRuntime].reduce[p1, p2|p1 + p2]
51 }
52}
53
54abstract class AbstractNeighbourhoodBasedPartialInterpretationStateCoder implements IStateCoder {
55 val NeighbourhoodOptions options
56
57 var PartialInterpretation target
58
59 protected new(NeighbourhoodOptions options) {
60 this.options = options
61 }
62
63 @Accessors(PUBLIC_GETTER) var long statecoderRuntime = 0
64
65 synchronized private def refreshStateCodes() {
66 if (refreshNeeded) {
67 val startTime = System.nanoTime
68 doRefreshStateCodes(target, options)
69 statecoderRuntime += (System.nanoTime - startTime)
70 }
71 }
72
73 protected def boolean isRefreshNeeded()
74
75 protected def void doRefreshStateCodes(PartialInterpretation target, NeighbourhoodOptions options)
76
77 synchronized override createActivationCode(IPatternMatch match) {
78 refreshStateCodes
79 val startTime = System.nanoTime
80 val code = doCreateActivationCode(match)
81 statecoderRuntime += (System.nanoTime - startTime)
82 code
83 }
84
85 protected def Object doCreateActivationCode(IPatternMatch match)
86
87 synchronized override createStateCode() {
88 refreshStateCodes
89 doCreateStateCode
90 }
91
92 protected def Object doCreateStateCode()
93
94 override init(Notifier notifier) {
95 this.target = notifier as PartialInterpretation
96 val queryEngine = ViatraQueryEngine.on(new EMFScope(notifier))
97 val baseIndex = queryEngine.getBaseIndex() as EMFBaseIndexWrapper
98 val navigationHelper = baseIndex.getNavigationHelper();
99
100 val classes = PartialinterpretationPackage.eINSTANCE.EClassifiers.filter(EClass).toSet
101 val features = classes.map[it.EAllStructuralFeatures].flatten.toSet
102 navigationHelper.registerObservedTypes(classes, null, features, IndexingLevel.FULL);
103
104 navigationHelper.addFeatureListener(features, new FeatureListener() {
105 override void featureInserted(EObject host, EStructuralFeature feature, Object value) { invalidate }
106
107 override void featureDeleted(EObject host, EStructuralFeature feature, Object value) { invalidate }
108 })
109 navigationHelper.addInstanceListener(classes, new InstanceListener() {
110 override void instanceInserted(EClass clazz, EObject instance) { invalidate }
111
112 override void instanceDeleted(EClass clazz, EObject instance) { invalidate }
113 })
114 }
115
116 synchronized def invalidate() {
117 doInvalidate
118 }
119
120 protected def void doInvalidate()
121
122 def protected getFallbackCode(Object o) {
123 switch (o) {
124 PartialInterpretation,
125 LogicProblem:
126 null
127 PartialRelationInterpretation:
128 o.interpretationOf.name
129 PartialPrimitiveInterpretation:
130 o.class.simpleName.hashCode
131 PartialComplexTypeInterpretation:
132 o.interpretationOf.name.hashCode
133 default:
134 throw new UnsupportedOperationException('''Unsupported type: «o.class.simpleName»''')
135 }
136 }
137}
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 {
62 int numberOfNewElement 62 int numberOfNewElement
63 SortedSet<RelationStatecoder> relationStatecoders 63 SortedSet<RelationStatecoder> relationStatecoders
64 64
65 private static val comparator = new Comparator<RelationStatecoder>() { 65 static val comparator = new Comparator<RelationStatecoder>() {
66 override compare(RelationStatecoder o1, RelationStatecoder o2) { 66 override compare(RelationStatecoder o1, RelationStatecoder o2) {
67 o1.relationName.compareTo(o2.relationName) 67 o1.relationName.compareTo(o2.relationName)
68 } 68 }
69 } 69 }
70 70
71 public new(int numberOfNewElements) { 71 new(int numberOfNewElements) {
72 this.numberOfNewElement = numberOfNewElements 72 this.numberOfNewElement = numberOfNewElements
73 this.relationStatecoders = new TreeSet(comparator) 73 this.relationStatecoders = new TreeSet(comparator)
74 } 74 }
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 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder 1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder
2 2
3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement
3import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.AbstractNodeDescriptor 4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.AbstractNodeDescriptor
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodOptions
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice 6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage
7import java.util.ArrayList 8import java.util.ArrayList
8import java.util.LinkedList
9import java.util.List
10import java.util.Map 9import java.util.Map
11import org.eclipse.emf.common.notify.Notifier
12import org.eclipse.emf.ecore.EClass
13import org.eclipse.emf.ecore.EObject
14import org.eclipse.emf.ecore.EStructuralFeature
15import org.eclipse.viatra.dse.statecode.IStateCoder
16import org.eclipse.viatra.dse.statecode.IStateCoderFactory
17import org.eclipse.viatra.query.runtime.api.IPatternMatch 10import org.eclipse.viatra.query.runtime.api.IPatternMatch
18import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine 11
19import org.eclipse.viatra.query.runtime.base.api.FeatureListener 12class NeighbourhoodBasedStateCoderFactory extends AbstractNeighbourhoodBasedStateCoderFactory {
20import org.eclipse.viatra.query.runtime.base.api.IndexingLevel 13 new() {
21import org.eclipse.viatra.query.runtime.base.api.InstanceListener
22import org.eclipse.viatra.query.runtime.emf.EMFBaseIndexWrapper
23import org.eclipse.viatra.query.runtime.emf.EMFScope
24import org.eclipse.xtend.lib.annotations.Accessors
25import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement
26import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
27import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation
28import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation
29import java.util.Set
30import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration
31import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
32import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2NeighbourhoodRepresentation
33import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
34import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation
35
36class NeighbourhoodBasedStateCoderFactory implements IStateCoderFactory {
37 val List<NeighbourhoodBasedPartialInterpretationStateCoder> statecoders = new LinkedList
38
39 val int range
40 val int parallels
41 val int maxNumber
42 val Set<TypeDeclaration> relevantTypes
43 val Set<RelationDeclaration> relevantRelations
44
45 public new() {
46 this.range = PartialInterpretation2NeighbourhoodRepresentation::GraphWidthRange
47 this.parallels = PartialInterpretation2NeighbourhoodRepresentation::FullParallels
48 this.maxNumber = PartialInterpretation2NeighbourhoodRepresentation::MaxNumbers
49 this.relevantTypes = null
50 this.relevantRelations = null
51 } 14 }
52 15
53 public new(int range, int parallels, int maxNumber, Set<TypeDeclaration> relevantTypes, Set<RelationDeclaration> relevantRelations) { 16 new(NeighbourhoodOptions options) {
54 this.range = range 17 super(options)
55 this.parallels = parallels 18 }
56 this.maxNumber = maxNumber 19
57 this.relevantTypes = relevantTypes 20 override protected doCreateStateCoder(NeighbourhoodOptions options) {
58 this.relevantRelations = relevantRelations 21 new NeighbourhoodBasedPartialInterpretationStateCoder(options)
59 } 22 }
60 23
61 synchronized override createStateCoder() {
62 val res = new NeighbourhoodBasedPartialInterpretationStateCoder(statecoders.size,
63 range,parallels,maxNumber,relevantTypes,relevantRelations)
64 statecoders += res
65 return res
66 }
67 def getSumStatecoderRuntime() {
68 statecoders.map[statecoderRuntime].reduce[p1, p2|p1+p2]
69 }
70} 24}
71 25
72class NeighbourhoodBasedPartialInterpretationStateCoder implements IStateCoder{ 26class NeighbourhoodBasedPartialInterpretationStateCoder extends AbstractNeighbourhoodBasedPartialInterpretationStateCoder {
73 val int id; 27 val calculator = new PartialInterpretation2ImmutableTypeLattice
74 val int range 28
75 val int parallels 29 var Map<DefinedElement, ? extends AbstractNodeDescriptor> nodeRepresentations = null
76 val int maxNumber 30 var Map<? extends AbstractNodeDescriptor, Integer> modelRepresentation = null
77 val Set<TypeDeclaration> relevantTypes 31
78 val Set<RelationDeclaration> relevantRelations 32 new(NeighbourhoodOptions options) {
79 33 super(options)
80 val calculator =
81 new PartialInterpretation2ImmutableTypeLattice
82 var PartialInterpretation target
83
84 private var Map<DefinedElement, ? extends AbstractNodeDescriptor> nodeRepresentations = null
85 private var Map<? extends AbstractNodeDescriptor, Integer> modelRepresentation = null
86
87 /*public new(int id) {
88 this.id = id
89 this.range = PartialInterpretation2NeighbourhoodRepresentation::FixPointRage
90 this.parallels = PartialInterpretation2NeighbourhoodRepresentation::FullParallels
91 this.maxNumber = maxNumber = PartialInterpretation2NeighbourhoodRepresentation::MaxNumbers
92 this.relevantTypes = relevantTypes
93 this.relevantRelations = relevantRelations
94 }*/
95
96 public new(int id, int range, int parallels, int maxNumber, Set<TypeDeclaration> relevantTypes, Set<RelationDeclaration> relevantRelations) {
97 this.id = id
98 this.range = range
99 this.parallels = parallels
100 this.maxNumber = maxNumber
101 this.relevantTypes = relevantTypes
102 this.relevantRelations = relevantRelations
103 } 34 }
104 35
105 @Accessors(PUBLIC_GETTER) var long statecoderRuntime = 0 36 override protected isRefreshNeeded() {
106 37 nodeRepresentations === null || modelRepresentation === null
107// val range = -1 38 }
108// val par = Integer.MAX_VALUE 39
109 //val deeprepresentation = false 40 override doRefreshStateCodes(PartialInterpretation target, NeighbourhoodOptions options) {
110 41 val code = calculator.createRepresentation(target, options)
111 ///////// 42 modelRepresentation = code.modelRepresentation
112 // Caching version 43 nodeRepresentations = code.nodeRepresentations
113 ///////// 44 }
114 synchronized private def refreshStateCodes() { 45
115 if(this.nodeRepresentations === null || this.modelRepresentation === null) { 46 override doCreateActivationCode(IPatternMatch match) {
116 val startTime = System.nanoTime 47 val size = match.specification.parameters.size
117 //relevantObjects.forEach[println(it)] 48 val res = new ArrayList(size)
118 val code = calculator.createRepresentation(target,range,parallels,maxNumber,relevantTypes,relevantRelations) 49 var int index = 0
119 this.modelRepresentation = code.modelRepresentation 50 var int equivalenceHash = 0
120 this.nodeRepresentations = code.nodeRepresentations 51 val prime = 31
121 statecoderRuntime += (System.nanoTime - startTime) 52
122 } 53 while (index < size) {
123 } 54 res.add(getCode(match.get(index)))
124 synchronized override createActivationCode(IPatternMatch match) { 55 index++
125 refreshStateCodes 56 for (var i = 0; i < index; i++) {
126 57 val number = if (match.get(index) === match.get(i)) {
127 val startTime = System.nanoTime 58 1
128 val size = match.specification.parameters.size 59 } else {
129 val res = new ArrayList(size) 60 0
130 var int index = 0 61 }
131 var int equivalenceHash = 0 62 equivalenceHash = prime * equivalenceHash + number
132 val prime = 31
133
134 while(index < size) {
135 res.add(getCode(match.get(index)))
136 index++
137 for(var i = 0; i<index; i++) {
138 val number = if(match.get(index) === match.get(i)){1}else{0}
139 equivalenceHash = prime * equivalenceHash + number
140 }
141 }
142
143 statecoderRuntime += (System.nanoTime - startTime)
144 return match.specification.fullyQualifiedName->(res->equivalenceHash).hashCode
145 }
146
147
148 def private getCode(Object o) {
149 if(o instanceof DefinedElement) {
150 this.nodeRepresentations.get(o)
151 } else if(o instanceof PartialInterpretation || o instanceof LogicProblem) {
152 return null
153 } else if(o instanceof PartialRelationInterpretation) {
154 return o.interpretationOf.name
155 } else if(o instanceof PartialTypeInterpratation) {
156 if(o instanceof PartialPrimitiveInterpretation) {
157 o.class.simpleName.hashCode
158 } else if (o instanceof PartialComplexTypeInterpretation){
159 return o.interpretationOf.name.hashCode
160 } else {
161 throw new UnsupportedOperationException('''Unsupported type: «o.class.simpleName»''')
162 } 63 }
163 } else {
164 throw new UnsupportedOperationException('''Unsupported type: «o.class.simpleName»''')
165 } 64 }
166 } 65
167 66 match.specification.fullyQualifiedName -> (res -> equivalenceHash).hashCode
168 synchronized override createStateCode() { 67 }
169 refreshStateCodes 68
170 return this.modelRepresentation.hashCode 69 def private getCode(Object o) {
171 } 70 switch (o) {
172 ///////// 71 DefinedElement:
173 // Caching version 72 nodeRepresentations.get(o)
174 ///////// 73 default:
175 74 getFallbackCode(o)
176 ///////// 75 }
177 // Recalculating version 76 }
178 ///////// 77
179// synchronized override createActivationCode(IPatternMatch match) { 78 override doCreateStateCode() {
180// val nodes = calculator.createRepresentation(getRelevantObjects().toList,range,par).nodeRepresentations 79 modelRepresentation.hashCode
181// val res = match.toArray.map[objectInMatch | 80 }
182// nodes.get(objectInMatch) 81
183// ] 82 override doInvalidate() {
184// return res 83 nodeRepresentations = null
185// } 84 modelRepresentation = null
186//
187// override createStateCode() {
188// return this.calculator.createRepresentation(getRelevantObjects().toList,range,par).modelRepresentation
189// }
190 /////////
191 // Recalculating version
192 /////////
193
194 override init(Notifier notifier) {
195 this.target = notifier as PartialInterpretation
196 val queryEngine = ViatraQueryEngine.on(new EMFScope(notifier))
197 val baseIndex = queryEngine.getBaseIndex() as EMFBaseIndexWrapper
198 val navigationHelper = baseIndex.getNavigationHelper();
199
200 val classes = PartialinterpretationPackage.eINSTANCE.EClassifiers.filter(EClass).toSet
201 val features = classes.map[it.EAllStructuralFeatures].flatten.toSet
202 navigationHelper.registerObservedTypes(
203 classes,
204 null,
205 features,
206 IndexingLevel.FULL);
207
208
209 navigationHelper.addFeatureListener(features, new FeatureListener() {
210 override public void featureInserted(EObject host, EStructuralFeature feature, Object value) { invalidate }
211 override public void featureDeleted(EObject host, EStructuralFeature feature, Object value) { invalidate }
212 });
213 navigationHelper.addInstanceListener(classes, new InstanceListener() {
214 override public void instanceInserted(EClass clazz, EObject instance) { invalidate }
215 override public void instanceDeleted(EClass clazz, EObject instance) { invalidate }
216 });
217 }
218
219 synchronized def public invalidate() {
220 this.nodeRepresentations = null
221 this.modelRepresentation = null
222 } 85 }
223} 86}
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 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder
2
3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.AbstractNodeDescriptor
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodOptions
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PairwiseNeighbourhoodRepresentation
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2PairwiseNeighbourhoodRepresentation
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
10import java.util.ArrayList
11import org.eclipse.viatra.query.runtime.api.IPatternMatch
12
13class PairwiseNeighbourhoodBasedStateCoderFactory extends AbstractNeighbourhoodBasedStateCoderFactory {
14 new() {
15 }
16
17 new(NeighbourhoodOptions options) {
18 super(options)
19 }
20
21 override protected doCreateStateCoder(NeighbourhoodOptions options) {
22 new PairwiseNeighbourhoodBasedPartialInterpretationStateCoder(options)
23 }
24}
25
26class PairwiseNeighbourhoodBasedPartialInterpretationStateCoder extends AbstractNeighbourhoodBasedPartialInterpretationStateCoder {
27 val calculator = new PartialInterpretation2PairwiseNeighbourhoodRepresentation(
28 new PartialInterpretation2ImmutableTypeLattice)
29 var PairwiseNeighbourhoodRepresentation<? extends AbstractNodeDescriptor> representation
30
31 new(NeighbourhoodOptions options) {
32 super(options)
33 }
34
35 override protected isRefreshNeeded() {
36 representation === null
37 }
38
39 override protected doRefreshStateCodes(PartialInterpretation target, NeighbourhoodOptions options) {
40 representation = calculator.createRepresentation(target, options)
41 }
42
43 override protected doCreateActivationCode(IPatternMatch match) {
44 val size = match.specification.parameters.size
45 val res = new ArrayList(size * size)
46 for (var int i = 0; i < size; i++) {
47 val a = match.get(i)
48 for (var int j = 0; j < size; j++) {
49 val b = match.get(j)
50 res.add(getPairwiseRepresentation(a, b))
51 }
52 }
53 match.specification.fullyQualifiedName -> res.hashCode
54 }
55
56 private def getPairwiseRepresentation(Object a, Object b) {
57 if (b instanceof DefinedElement) {
58 if (a instanceof DefinedElement) {
59 representation.getPairwiseRepresentation(a, b)
60 } else {
61 representation.getBasicRepresentation(b)
62 }
63 } else {
64 getFallbackCode(b)
65 }
66 }
67
68 override protected doCreateStateCode() {
69 representation.modelRepresentation.hashCode
70 }
71
72 override protected doInvalidate() {
73 representation = null
74 }
75}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend
index edcca676..701eb054 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend
@@ -16,8 +16,9 @@ import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator
16import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.PartialInterpretationInitialiser 16import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.PartialInterpretationInitialiser
17import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 17import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
18import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage 18import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage
19import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.AbstractNeighbourhoodBasedStateCoderFactory
19import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory 20import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory
20import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedStateCoderFactory 21import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.PairwiseNeighbourhoodBasedStateCoderFactory
21import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BestFirstStrategyForModelGeneration 22import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BestFirstStrategyForModelGeneration
22import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.DiversityChecker 23import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.DiversityChecker
23import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.LoggerSolutionFoundHandler 24import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.LoggerSolutionFoundHandler
@@ -49,7 +50,7 @@ class ViatraReasoner extends LogicReasoner {
49 ReasonerWorkspace workspace) throws LogicReasonerException { 50 ReasonerWorkspace workspace) throws LogicReasonerException {
50 val viatraConfig = configuration.asConfig 51 val viatraConfig = configuration.asConfig
51 52
52 if (viatraConfig.debugConfiguration.logging) { 53 if (viatraConfig.documentationLevel == DocumentationLevel.FULL) {
53 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.VERBOSE_FULL) 54 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.VERBOSE_FULL)
54 } else { 55 } else {
55 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.WARN) 56 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.WARN)
@@ -139,7 +140,7 @@ class ViatraReasoner extends LogicReasoner {
139 dse.setInitialModel(emptySolution, false) 140 dse.setInitialModel(emptySolution, false)
140 141
141 val IStateCoderFactory statecoder = if (viatraConfig.stateCoderStrategy == StateCoderStrategy.Neighbourhood) { 142 val IStateCoderFactory statecoder = if (viatraConfig.stateCoderStrategy == StateCoderStrategy.Neighbourhood) {
142 new NeighbourhoodBasedStateCoderFactory 143 new PairwiseNeighbourhoodBasedStateCoderFactory
143 } else { 144 } else {
144 new IdentifierBasedStateCoderFactory 145 new IdentifierBasedStateCoderFactory
145 } 146 }
@@ -239,7 +240,7 @@ class ViatraReasoner extends LogicReasoner {
239 } 240 }
240 } 241 }
241 242
242 private def dispatch long runtime(NeighbourhoodBasedStateCoderFactory sc) { 243 private def dispatch long runtime(AbstractNeighbourhoodBasedStateCoderFactory sc) {
243 sc.sumStatecoderRuntime 244 sc.sumStatecoderRuntime
244 } 245 }
245 246
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend
index e6aee20c..99decdd9 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend
@@ -64,8 +64,7 @@ class DiversityDescriptor {
64} 64}
65 65
66class DebugConfiguration { 66class DebugConfiguration {
67 public var logging = false 67 public var PartialInterpretationVisualiser partialInterpretatioVisualiser = null
68 public var PartialInterpretationVisualiser partialInterpretatioVisualiser = null;
69 public var partalInterpretationVisualisationFrequency = 1 68 public var partalInterpretationVisualisationFrequency = 1
70} 69}
71 70
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java
index 077fea21..144e7484 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java
@@ -20,8 +20,8 @@ import java.util.List;
20import java.util.PriorityQueue; 20import java.util.PriorityQueue;
21import java.util.Random; 21import java.util.Random;
22 22
23import org.apache.log4j.Level;
24import org.apache.log4j.Logger; 23import org.apache.log4j.Logger;
24import org.eclipse.emf.ecore.EObject;
25import org.eclipse.emf.ecore.util.EcoreUtil; 25import org.eclipse.emf.ecore.util.EcoreUtil;
26import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; 26import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
27import org.eclipse.viatra.dse.base.ThreadContext; 27import org.eclipse.viatra.dse.base.ThreadContext;
@@ -254,6 +254,7 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
254 activationIds = new ArrayList<Object>(context.getUntraversedActivationIds()); 254 activationIds = new ArrayList<Object>(context.getUntraversedActivationIds());
255 Collections.shuffle(activationIds); 255 Collections.shuffle(activationIds);
256 } catch (NullPointerException e) { 256 } catch (NullPointerException e) {
257 logger.warn("Unexpected state code: " + context.getDesignSpaceManager().getCurrentState());
257 numberOfStatecoderFail++; 258 numberOfStatecoderFail++;
258 activationIds = Collections.emptyList(); 259 activationIds = Collections.emptyList();
259 } 260 }
@@ -295,7 +296,10 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
295 int id = ++numberOfPrintedModel; 296 int id = ++numberOfPrintedModel;
296 if (id % configuration.debugConfiguration.partalInterpretationVisualisationFrequency == 0) { 297 if (id % configuration.debugConfiguration.partalInterpretationVisualisationFrequency == 0) {
297 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); 298 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p);
298 visualisation.writeToFile(workspace, String.format("state%09d.png", id)); 299 logger.debug("Visualizing state: " + id + " (" + context.getDesignSpaceManager().getCurrentState() + ")");
300 String name = String.format("state%09d", id);
301 visualisation.writeToFile(workspace, name + ".png");
302 workspace.writeModel((EObject) context.getModel(), name + ".xmi");
299 } 303 }
300 } 304 }
301 } 305 }
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend
index 241bef2a..cd911ab5 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend
@@ -1,60 +1,10 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2 2
3import java.util.Comparator
4import org.eclipse.viatra.dse.base.ThreadContext 3import org.eclipse.viatra.dse.base.ThreadContext
5import org.eclipse.xtend.lib.annotations.Accessors
6import org.eclipse.xtend.lib.annotations.Data
7
8abstract class ObjectiveThreshold {
9 public static val NO_THRESHOLD = new hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold {
10 override isHard() {
11 false
12 }
13
14 override satisfiesThreshold(double cost, Comparator<Double> comparator) {
15 true
16 }
17 }
18
19 private new() {
20 }
21
22 def boolean isHard() {
23 true
24 }
25
26 def boolean satisfiesThreshold(double cost, Comparator<Double> comparator)
27
28 @Data
29 static class Exclusive extends ObjectiveThreshold {
30 val double threshold
31
32 override satisfiesThreshold(double cost, Comparator<Double> comparator) {
33 comparator.compare(threshold, cost) > 0
34 }
35 }
36
37 @Data
38 static class Inclusive extends ObjectiveThreshold {
39 val double threshold
40
41 override satisfiesThreshold(double cost, Comparator<Double> comparator) {
42 comparator.compare(threshold, cost) >= 0
43 }
44 }
45}
46
47abstract class AbstractThreeValuedObjective implements IThreeValuedObjective {
48 @Accessors val String name
49 @Accessors ObjectiveKind kind
50 @Accessors ObjectiveThreshold threshold
51 @Accessors int level
52 4
5abstract class AbstractThreeValuedObjective extends DirectionalThresholdObjective implements IThreeValuedObjective {
53 protected new(String name, ObjectiveKind kind, ObjectiveThreshold threshold, int level) { 6 protected new(String name, ObjectiveKind kind, ObjectiveThreshold threshold, int level) {
54 this.name = name 7 super(name, kind, threshold, level)
55 this.kind = kind
56 this.threshold = threshold
57 this.level = level
58 } 8 }
59 9
60 abstract def double getLowestPossibleFitness(ThreadContext threadContext) 10 abstract def double getLowestPossibleFitness(ThreadContext threadContext)
@@ -82,21 +32,4 @@ abstract class AbstractThreeValuedObjective implements IThreeValuedObjective {
82 throw new IllegalStateException("Unknown three valued objective kind: " + kind) 32 throw new IllegalStateException("Unknown three valued objective kind: " + kind)
83 } 33 }
84 } 34 }
85
86 override isHardObjective() {
87 threshold.hard
88 }
89
90 override satisifiesHardObjective(Double fitness) {
91 threshold.satisfiesThreshold(fitness, comparator)
92 }
93
94 override getComparator() {
95 kind.comparator
96 }
97
98 override setComparator(Comparator<Double> comparator) {
99 kind = ObjectiveKind.fromComparator(comparator)
100 }
101
102} 35}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend
new file mode 100644
index 00000000..0aa442f5
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend
@@ -0,0 +1,62 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import com.google.common.collect.ImmutableList
4import java.util.Collection
5import org.eclipse.viatra.dse.base.ThreadContext
6
7class CompositeDirectionalThresholdObjective extends DirectionalThresholdObjective {
8 val Collection<DirectionalThresholdObjective> objectives
9
10 new(String name, Collection<DirectionalThresholdObjective> objectives) {
11 this(name, objectives, getKind(objectives), getThreshold(objectives), getLevel(objectives))
12 }
13
14 new(String name, DirectionalThresholdObjective... objectives) {
15 this(name, objectives as Collection<DirectionalThresholdObjective>)
16 }
17
18 protected new(String name, Iterable<DirectionalThresholdObjective> objectives, ObjectiveKind kind,
19 ObjectiveThreshold threshold, int level) {
20 super(name, kind, threshold, level)
21 this.objectives = ImmutableList.copyOf(objectives)
22 }
23
24 override createNew() {
25 new CompositeDirectionalThresholdObjective(name, objectives.map[createNew as DirectionalThresholdObjective],
26 kind, threshold, level)
27 }
28
29 override init(ThreadContext context) {
30 for (objective : objectives) {
31 objective.init(context)
32 }
33 }
34
35 override protected getRawFitness(ThreadContext context) {
36 var double fitness = 0
37 for (objective : objectives) {
38 fitness += objective.getFitness(context)
39 }
40 fitness
41 }
42
43 private static def getKind(Collection<DirectionalThresholdObjective> objectives) {
44 val kinds = objectives.map[kind].toSet
45 if (kinds.size != 1) {
46 throw new IllegalArgumentException("Passed objectives must have the same kind")
47 }
48 kinds.head
49 }
50
51 private static def getThreshold(Collection<DirectionalThresholdObjective> objectives) {
52 objectives.map[threshold].reduce[a, b|a.merge(b)]
53 }
54
55 private static def int getLevel(Collection<DirectionalThresholdObjective> objectives) {
56 val levels = objectives.map[level].toSet
57 if (levels.size != 1) {
58 throw new IllegalArgumentException("Passed objectives must have the same level")
59 }
60 levels.head
61 }
62}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend
new file mode 100644
index 00000000..376e3d1a
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend
@@ -0,0 +1,164 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import java.util.Comparator
4import org.eclipse.viatra.dse.base.ThreadContext
5import org.eclipse.viatra.dse.objectives.IObjective
6import org.eclipse.xtend.lib.annotations.Accessors
7import org.eclipse.xtend.lib.annotations.Data
8import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
9
10abstract class ObjectiveThreshold {
11 public static val NO_THRESHOLD = new ObjectiveThreshold {
12 override isHard() {
13 false
14 }
15
16 override satisfiesThreshold(double cost, Comparator<Double> comparator) {
17 true
18 }
19
20 override protected postProcessSatisfactoryCost(double cost, ObjectiveKind kind) {
21 cost
22 }
23
24 override ObjectiveThreshold merge(ObjectiveThreshold other) {
25 if (other == NO_THRESHOLD) {
26 NO_THRESHOLD
27 } else {
28 throw new IllegalArgumentException("Merged thresholds must have the same type")
29 }
30 }
31 }
32
33 private new() {
34 }
35
36 def boolean isHard() {
37 true
38 }
39
40 def boolean satisfiesThreshold(double cost, ObjectiveKind kind) {
41 satisfiesThreshold(cost, kind.comparator)
42 }
43
44 def boolean satisfiesThreshold(double cost, Comparator<Double> comparator)
45
46 def double postProcessCost(double cost, ObjectiveKind kind) {
47 if (satisfiesThreshold(cost, kind)) {
48 postProcessSatisfactoryCost(cost, kind)
49 } else {
50 cost
51 }
52 }
53
54 protected def double postProcessSatisfactoryCost(double cost, ObjectiveKind kind)
55
56 def ObjectiveThreshold merge(ObjectiveThreshold other)
57
58 @Data
59 static class Exclusive extends ObjectiveThreshold {
60 static val EPSILON = 0.1
61
62 val double threshold
63 val boolean clampToThreshold
64
65 @FinalFieldsConstructor
66 new() {
67 }
68
69 new(double threshold) {
70 this(threshold, true)
71 }
72
73 override satisfiesThreshold(double cost, Comparator<Double> comparator) {
74 comparator.compare(threshold, cost) < 0
75 }
76
77 override protected postProcessSatisfactoryCost(double cost, ObjectiveKind kind) {
78 if (clampToThreshold) {
79 threshold + Math.signum(kind.satisfiedValue) * EPSILON
80 } else {
81 cost
82 }
83 }
84
85 override ObjectiveThreshold merge(ObjectiveThreshold other) {
86 if (other instanceof Exclusive) {
87 new Exclusive(threshold + other.threshold)
88 } else {
89 throw new IllegalArgumentException("Merged thresholds must have the same type")
90 }
91 }
92 }
93
94 @Data
95 static class Inclusive extends ObjectiveThreshold {
96 val double threshold
97 val boolean clampToThreshold
98
99 @FinalFieldsConstructor
100 new() {
101 }
102
103 new(double threshold) {
104 this(threshold, true)
105 }
106
107 override satisfiesThreshold(double cost, Comparator<Double> comparator) {
108 comparator.compare(threshold, cost) <= 0
109 }
110
111 override protected postProcessSatisfactoryCost(double cost, ObjectiveKind kind) {
112 if (clampToThreshold) {
113 threshold
114 } else {
115 cost
116 }
117 }
118
119 override ObjectiveThreshold merge(ObjectiveThreshold other) {
120 if (other instanceof Inclusive) {
121 new Inclusive(threshold + other.threshold)
122 } else {
123 throw new IllegalArgumentException("Merged thresholds must have the same type")
124 }
125 }
126 }
127}
128
129abstract class DirectionalThresholdObjective implements IObjective {
130 @Accessors val String name
131 @Accessors ObjectiveKind kind
132 @Accessors ObjectiveThreshold threshold
133 @Accessors int level
134
135 protected new(String name, ObjectiveKind kind, ObjectiveThreshold threshold, int level) {
136 this.name = name
137 this.kind = kind
138 this.threshold = threshold
139 this.level = level
140 }
141
142 override isHardObjective() {
143 threshold.hard
144 }
145
146 override satisifiesHardObjective(Double fitness) {
147 threshold.satisfiesThreshold(fitness, comparator)
148 }
149
150 override getComparator() {
151 kind.comparator
152 }
153
154 override setComparator(Comparator<Double> comparator) {
155 kind = ObjectiveKind.fromComparator(comparator)
156 }
157
158 override getFitness(ThreadContext context) {
159 val fitness = getRawFitness(context)
160 threshold.postProcessCost(fitness, kind)
161 }
162
163 protected def double getRawFitness(ThreadContext context)
164}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend
new file mode 100644
index 00000000..a0c6a2c1
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend
@@ -0,0 +1,52 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import com.google.common.collect.ImmutableList
4import java.util.Collection
5import org.eclipse.viatra.dse.base.ThreadContext
6import org.eclipse.viatra.query.runtime.api.IPatternMatch
7import org.eclipse.viatra.query.runtime.api.IQuerySpecification
8import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
9import org.eclipse.xtend.lib.annotations.Data
10
11@Data
12class MatchCostElement {
13 val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification
14 val double weight
15}
16
17class MatchCostObjective extends DirectionalThresholdObjective {
18 val Collection<MatchCostElement> costElements
19 Collection<CostElementMatcher> matchers
20
21 new(String name, Collection<MatchCostElement> costElements, ObjectiveKind kind, ObjectiveThreshold threshold,
22 int level) {
23 super(name, kind, threshold, level)
24 this.costElements = costElements
25 }
26
27 override createNew() {
28 new MatchCostObjective(name, costElements, kind, threshold, level)
29 }
30
31 override init(ThreadContext context) {
32 val queryEngine = context.queryEngine
33 matchers = ImmutableList.copyOf(costElements.map [
34 val matcher = querySpecification.getMatcher(queryEngine)
35 new CostElementMatcher(matcher, weight)
36 ])
37 }
38
39 override protected getRawFitness(ThreadContext context) {
40 var double cost = 0
41 for (it : matchers) {
42 cost += weight * matcher.countMatches
43 }
44 cost
45 }
46
47 @Data
48 private static class CostElementMatcher {
49 val ViatraQueryMatcher<? extends IPatternMatch> matcher
50 val double weight
51 }
52}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java
index f65428fe..cbbaaafd 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java
@@ -12,6 +12,16 @@ public enum ObjectiveKind {
12 return Comparators.LOWER_IS_BETTER; 12 return Comparators.LOWER_IS_BETTER;
13 } 13 }
14 14
15 @Override
16 public double getInvalidValue() {
17 return Double.POSITIVE_INFINITY;
18 }
19
20 @Override
21 public double getSatisfiedValue() {
22 return Double.NEGATIVE_INFINITY;
23 }
24
15 }, 25 },
16 HIGHER_IS_BETTER { 26 HIGHER_IS_BETTER {
17 27
@@ -20,10 +30,24 @@ public enum ObjectiveKind {
20 return Comparators.HIGHER_IS_BETTER; 30 return Comparators.HIGHER_IS_BETTER;
21 } 31 }
22 32
33 @Override
34 public double getInvalidValue() {
35 return Double.NEGATIVE_INFINITY;
36 }
37
38 @Override
39 public double getSatisfiedValue() {
40 return Double.POSITIVE_INFINITY;
41 }
42
23 }; 43 };
24 44
25 public abstract Comparator<Double> getComparator(); 45 public abstract Comparator<Double> getComparator();
26 46
47 public abstract double getInvalidValue();
48
49 public abstract double getSatisfiedValue();
50
27 public static ObjectiveKind fromComparator(Comparator<Double> comparator) { 51 public static ObjectiveKind fromComparator(Comparator<Double> comparator) {
28 if (Comparators.LOWER_IS_BETTER.equals(comparator)) { 52 if (Comparators.LOWER_IS_BETTER.equals(comparator)) {
29 return ObjectiveKind.LOWER_IS_BETTER; 53 return ObjectiveKind.LOWER_IS_BETTER;
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend
new file mode 100644
index 00000000..d355f5be
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend
@@ -0,0 +1,48 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import org.eclipse.viatra.dse.base.ThreadContext
4import org.eclipse.viatra.query.runtime.api.IPatternMatch
5import org.eclipse.viatra.query.runtime.api.IQuerySpecification
6import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
7
8class QueryBasedObjective extends DirectionalThresholdObjective {
9 val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification
10 ViatraQueryMatcher<? extends IPatternMatch> matcher
11
12 new(IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification,
13 ObjectiveKind kind, ObjectiveThreshold threshold, int level) {
14 super(querySpecification.simpleName + " objective", kind, threshold, level)
15 if (querySpecification.parameters.size != 1) {
16 throw new IllegalArgumentException("Objective query must have a single parameter")
17 }
18 this.querySpecification = querySpecification
19 }
20
21 override createNew() {
22 new QueryBasedObjective(querySpecification, kind, threshold, level)
23 }
24
25 override init(ThreadContext context) {
26 matcher = querySpecification.getMatcher(context.queryEngine)
27 }
28
29 override protected getRawFitness(ThreadContext context) {
30 val iterator = matcher.allMatches.iterator
31 if (!iterator.hasNext) {
32 return invalidValue
33 }
34 val value = iterator.next.get(0)
35 if (iterator.hasNext) {
36 throw new IllegalStateException("Multiple matches for objective query")
37 }
38 if (value instanceof Number) {
39 value.doubleValue
40 } else {
41 throw new IllegalStateException("Objective value is not an instance of Number")
42 }
43 }
44
45 private def getInvalidValue() {
46 kind.invalidValue
47 }
48}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend
index e2585c83..0a6fd55b 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend
@@ -42,7 +42,7 @@ class ThreeValuedCostObjective extends AbstractThreeValuedObjective {
42 ]) 42 ])
43 } 43 }
44 44
45 override getFitness(ThreadContext context) { 45 override getRawFitness(ThreadContext context) {
46 var int cost = 0 46 var int cost = 0
47 for (matcher : matchers) { 47 for (matcher : matchers) {
48 cost += matcher.weight * matcher.currentMatcher.countMatches 48 cost += matcher.weight * matcher.currentMatcher.countMatches