diff options
author | Kristóf Marussy <kris7topher@gmail.com> | 2019-06-15 20:56:47 -0400 |
---|---|---|
committer | Kristóf Marussy <kris7topher@gmail.com> | 2019-06-15 20:56:47 -0400 |
commit | c0c5a1644cc221352b8b9b370eea6a87677ba948 (patch) | |
tree | 4b1412577c568440b7098dc31691438ebc8e7e9d /Solvers | |
parent | Bump MDEOptimizer version (diff) | |
download | VIATRA-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')
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 | |||
4 | import java.util.Map | 4 | import java.util.Map |
5 | import java.util.Set | 5 | import java.util.Set |
6 | import org.eclipse.xtend.lib.annotations.Data | 6 | import org.eclipse.xtend.lib.annotations.Data |
7 | import 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 |
197 | class 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration | ||
4 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration | ||
5 | import java.util.Set | ||
6 | import org.eclipse.xtend.lib.annotations.Data | ||
7 | |||
8 | @Data | ||
9 | class 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 | |||
4 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration | 4 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration |
5 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration | 5 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration |
6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink | 6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink |
7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation | ||
7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | 8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation |
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation | ||
10 | import java.util.ArrayList | ||
8 | import java.util.HashMap | 11 | import java.util.HashMap |
9 | import java.util.HashSet | 12 | import java.util.HashSet |
10 | import java.util.LinkedList | ||
11 | import java.util.List | 13 | import java.util.List |
12 | import java.util.Map | 14 | import java.util.Map |
13 | import java.util.Set | 15 | import java.util.Set |
14 | 16 | ||
15 | import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* | 17 | import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* |
16 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation | ||
17 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation | ||
18 | 18 | ||
19 | abstract class PartialInterpretation2NeighbourhoodRepresentation<ModelRepresentation,NodeRepresentation> { | 19 | abstract 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood | ||
2 | |||
3 | import com.google.common.collect.Maps | ||
4 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement | ||
5 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | ||
6 | import java.util.HashMap | ||
7 | import java.util.Map | ||
8 | import org.eclipse.xtend.lib.annotations.Data | ||
9 | import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor | ||
10 | |||
11 | @Data | ||
12 | class 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 | ||
27 | class 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem | ||
4 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodOptions | ||
5 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation | ||
6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | ||
7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation | ||
8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation | ||
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage | ||
10 | import java.util.LinkedList | ||
11 | import java.util.List | ||
12 | import org.eclipse.emf.common.notify.Notifier | ||
13 | import org.eclipse.emf.ecore.EClass | ||
14 | import org.eclipse.emf.ecore.EObject | ||
15 | import org.eclipse.emf.ecore.EStructuralFeature | ||
16 | import org.eclipse.viatra.dse.statecode.IStateCoder | ||
17 | import org.eclipse.viatra.dse.statecode.IStateCoderFactory | ||
18 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
19 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine | ||
20 | import org.eclipse.viatra.query.runtime.base.api.FeatureListener | ||
21 | import org.eclipse.viatra.query.runtime.base.api.IndexingLevel | ||
22 | import org.eclipse.viatra.query.runtime.base.api.InstanceListener | ||
23 | import org.eclipse.viatra.query.runtime.emf.EMFBaseIndexWrapper | ||
24 | import org.eclipse.viatra.query.runtime.emf.EMFScope | ||
25 | import org.eclipse.xtend.lib.annotations.Accessors | ||
26 | |||
27 | abstract 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 | |||
54 | abstract 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder | 1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder |
2 | 2 | ||
3 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement | ||
3 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.AbstractNodeDescriptor | 4 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.AbstractNodeDescriptor |
5 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodOptions | ||
4 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice | 6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice |
5 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | 7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation |
6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage | ||
7 | import java.util.ArrayList | 8 | import java.util.ArrayList |
8 | import java.util.LinkedList | ||
9 | import java.util.List | ||
10 | import java.util.Map | 9 | import java.util.Map |
11 | import org.eclipse.emf.common.notify.Notifier | ||
12 | import org.eclipse.emf.ecore.EClass | ||
13 | import org.eclipse.emf.ecore.EObject | ||
14 | import org.eclipse.emf.ecore.EStructuralFeature | ||
15 | import org.eclipse.viatra.dse.statecode.IStateCoder | ||
16 | import org.eclipse.viatra.dse.statecode.IStateCoderFactory | ||
17 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | 10 | import org.eclipse.viatra.query.runtime.api.IPatternMatch |
18 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine | 11 | |
19 | import org.eclipse.viatra.query.runtime.base.api.FeatureListener | 12 | class NeighbourhoodBasedStateCoderFactory extends AbstractNeighbourhoodBasedStateCoderFactory { |
20 | import org.eclipse.viatra.query.runtime.base.api.IndexingLevel | 13 | new() { |
21 | import org.eclipse.viatra.query.runtime.base.api.InstanceListener | ||
22 | import org.eclipse.viatra.query.runtime.emf.EMFBaseIndexWrapper | ||
23 | import org.eclipse.viatra.query.runtime.emf.EMFScope | ||
24 | import org.eclipse.xtend.lib.annotations.Accessors | ||
25 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement | ||
26 | import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem | ||
27 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation | ||
28 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation | ||
29 | import java.util.Set | ||
30 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration | ||
31 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration | ||
32 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2NeighbourhoodRepresentation | ||
33 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation | ||
34 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation | ||
35 | |||
36 | class 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 | ||
72 | class NeighbourhoodBasedPartialInterpretationStateCoder implements IStateCoder{ | 26 | class 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement | ||
4 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.AbstractNodeDescriptor | ||
5 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodOptions | ||
6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PairwiseNeighbourhoodRepresentation | ||
7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice | ||
8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2PairwiseNeighbourhoodRepresentation | ||
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | ||
10 | import java.util.ArrayList | ||
11 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
12 | |||
13 | class 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 | |||
26 | class 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 | |||
16 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.PartialInterpretationInitialiser | 16 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.PartialInterpretationInitialiser |
17 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | 17 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation |
18 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage | 18 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage |
19 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.AbstractNeighbourhoodBasedStateCoderFactory | ||
19 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory | 20 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory |
20 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedStateCoderFactory | 21 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.PairwiseNeighbourhoodBasedStateCoderFactory |
21 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BestFirstStrategyForModelGeneration | 22 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BestFirstStrategyForModelGeneration |
22 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.DiversityChecker | 23 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.DiversityChecker |
23 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.LoggerSolutionFoundHandler | 24 | import 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 | ||
66 | class DebugConfiguration { | 66 | class 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; | |||
20 | import java.util.PriorityQueue; | 20 | import java.util.PriorityQueue; |
21 | import java.util.Random; | 21 | import java.util.Random; |
22 | 22 | ||
23 | import org.apache.log4j.Level; | ||
24 | import org.apache.log4j.Logger; | 23 | import org.apache.log4j.Logger; |
24 | import org.eclipse.emf.ecore.EObject; | ||
25 | import org.eclipse.emf.ecore.util.EcoreUtil; | 25 | import org.eclipse.emf.ecore.util.EcoreUtil; |
26 | import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; | 26 | import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; |
27 | import org.eclipse.viatra.dse.base.ThreadContext; | 27 | import 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | 1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization |
2 | 2 | ||
3 | import java.util.Comparator | ||
4 | import org.eclipse.viatra.dse.base.ThreadContext | 3 | import org.eclipse.viatra.dse.base.ThreadContext |
5 | import org.eclipse.xtend.lib.annotations.Accessors | ||
6 | import org.eclipse.xtend.lib.annotations.Data | ||
7 | |||
8 | abstract 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 | |||
47 | abstract class AbstractThreeValuedObjective implements IThreeValuedObjective { | ||
48 | @Accessors val String name | ||
49 | @Accessors ObjectiveKind kind | ||
50 | @Accessors ObjectiveThreshold threshold | ||
51 | @Accessors int level | ||
52 | 4 | ||
5 | abstract 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import com.google.common.collect.ImmutableList | ||
4 | import java.util.Collection | ||
5 | import org.eclipse.viatra.dse.base.ThreadContext | ||
6 | |||
7 | class 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import java.util.Comparator | ||
4 | import org.eclipse.viatra.dse.base.ThreadContext | ||
5 | import org.eclipse.viatra.dse.objectives.IObjective | ||
6 | import org.eclipse.xtend.lib.annotations.Accessors | ||
7 | import org.eclipse.xtend.lib.annotations.Data | ||
8 | import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor | ||
9 | |||
10 | abstract 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 | |||
129 | abstract 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import com.google.common.collect.ImmutableList | ||
4 | import java.util.Collection | ||
5 | import org.eclipse.viatra.dse.base.ThreadContext | ||
6 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
7 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification | ||
8 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | ||
9 | import org.eclipse.xtend.lib.annotations.Data | ||
10 | |||
11 | @Data | ||
12 | class MatchCostElement { | ||
13 | val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification | ||
14 | val double weight | ||
15 | } | ||
16 | |||
17 | class 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import org.eclipse.viatra.dse.base.ThreadContext | ||
4 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
5 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification | ||
6 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | ||
7 | |||
8 | class 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 |