diff options
author | 20001LastOrder <boqi.chen@mail.mcgill.ca> | 2020-11-04 01:33:58 -0500 |
---|---|---|
committer | 20001LastOrder <boqi.chen@mail.mcgill.ca> | 2020-11-04 01:33:58 -0500 |
commit | a20af4d0dbf5eab84ee271d426528aabb5a8ac3b (patch) | |
tree | a9ab772ee313125aaf3a941d66e131b408d949ba /Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RelationConstraintCalculator.xtend | |
parent | changes in settings of measurements (diff) | |
parent | merge with current master, comment numerical solver related logging (diff) | |
download | VIATRA-Generator-a20af4d0dbf5eab84ee271d426528aabb5a8ac3b.tar.gz VIATRA-Generator-a20af4d0dbf5eab84ee271d426528aabb5a8ac3b.tar.zst VIATRA-Generator-a20af4d0dbf5eab84ee271d426528aabb5a8ac3b.zip |
fix merging issue
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RelationConstraintCalculator.xtend')
-rw-r--r-- | Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RelationConstraintCalculator.xtend | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RelationConstraintCalculator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RelationConstraintCalculator.xtend new file mode 100644 index 00000000..abf65be3 --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RelationConstraintCalculator.xtend | |||
@@ -0,0 +1,156 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality | ||
2 | |||
3 | import com.google.common.collect.ImmutableList | ||
4 | import com.google.common.collect.ImmutableSet | ||
5 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.InverseRelationAssertion | ||
6 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.LowerMultiplicityAssertion | ||
7 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.UpperMultiplicityAssertion | ||
8 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference | ||
9 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation | ||
10 | import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem | ||
11 | import java.util.HashMap | ||
12 | import java.util.List | ||
13 | import org.eclipse.xtend.lib.annotations.Data | ||
14 | |||
15 | @Data | ||
16 | class RelationConstraints { | ||
17 | val List<RelationMultiplicityConstraint> multiplicityConstraints | ||
18 | } | ||
19 | |||
20 | @Data | ||
21 | class RelationMultiplicityConstraint { | ||
22 | Relation relation | ||
23 | Relation inverseRelation | ||
24 | boolean containment | ||
25 | boolean container | ||
26 | int lowerBound | ||
27 | int upperBound | ||
28 | int inverseUpperBound | ||
29 | |||
30 | def isUpperBoundFinite() { | ||
31 | upperBound >= 0 | ||
32 | } | ||
33 | |||
34 | private def isInverseUpperBoundFinite() { | ||
35 | inverseUpperBound >= 0 | ||
36 | } | ||
37 | |||
38 | private def canHaveMultipleSourcesPerTarget() { | ||
39 | inverseUpperBound != 1 | ||
40 | } | ||
41 | |||
42 | def constrainsUnfinished() { | ||
43 | lowerBound >= 1 && (!container || lowerBound >= 2) | ||
44 | } | ||
45 | |||
46 | def constrainsUnrepairable() { | ||
47 | // TODO Optimize the unrepairable matches computation, | ||
48 | // or come up with a heuristic when does computing unrepairables worth the overhead. | ||
49 | false && constrainsUnfinished && canHaveMultipleSourcesPerTarget && reference | ||
50 | } | ||
51 | |||
52 | def constrainsRemainingInverse() { | ||
53 | lowerBound >= 1 && !containment && !container && inverseUpperBoundFinite && reference | ||
54 | } | ||
55 | |||
56 | def constrainsRemainingContents() { | ||
57 | containment | ||
58 | } | ||
59 | |||
60 | def isActive() { | ||
61 | constrainsUnfinished || constrainsUnrepairable || constrainsRemainingInverse || constrainsRemainingContents | ||
62 | } | ||
63 | |||
64 | def isSourceTypeComplex() { | ||
65 | getParamTypeReference(0) instanceof ComplexTypeReference | ||
66 | } | ||
67 | |||
68 | def isTargetTypeComplex() { | ||
69 | getParamTypeReference(1) instanceof ComplexTypeReference | ||
70 | } | ||
71 | |||
72 | def isReference() { | ||
73 | sourceTypeComplex && targetTypeComplex | ||
74 | } | ||
75 | |||
76 | def getSourceType() { | ||
77 | getParamType(0) | ||
78 | } | ||
79 | |||
80 | def getTargetType() { | ||
81 | getParamType(1) | ||
82 | } | ||
83 | |||
84 | private def getParamTypeReference(int i) { | ||
85 | val parameters = relation.parameters | ||
86 | if (i < parameters.size) { | ||
87 | return parameters.get(i) | ||
88 | } | ||
89 | throw new IllegalArgumentException("Argument index out of range") | ||
90 | } | ||
91 | |||
92 | private def getParamType(int i) { | ||
93 | val reference = getParamTypeReference(i) | ||
94 | if (reference instanceof ComplexTypeReference) { | ||
95 | return reference.referred | ||
96 | } | ||
97 | throw new IllegalArgumentException("Constraint with primitive type") | ||
98 | } | ||
99 | } | ||
100 | |||
101 | class RelationConstraintCalculator { | ||
102 | def calculateRelationConstraints(LogicProblem problem) { | ||
103 | val containmentRelations = switch (problem.containmentHierarchies.size) { | ||
104 | case 0: | ||
105 | <Relation>emptySet | ||
106 | case 1: | ||
107 | ImmutableSet.copyOf(problem.containmentHierarchies.head.containmentRelations) | ||
108 | default: | ||
109 | throw new IllegalArgumentException("Only a single containment hierarchy is supported") | ||
110 | } | ||
111 | val inverseRelations = new HashMap<Relation, Relation> | ||
112 | val lowerMultiplicities = new HashMap<Relation, Integer> | ||
113 | val upperMultiplicities = new HashMap<Relation, Integer> | ||
114 | for (relation : problem.relations) { | ||
115 | lowerMultiplicities.put(relation, 0) | ||
116 | upperMultiplicities.put(relation, -1) | ||
117 | } | ||
118 | for (annotation : problem.annotations) { | ||
119 | switch (annotation) { | ||
120 | InverseRelationAssertion: { | ||
121 | inverseRelations.put(annotation.inverseA, annotation.inverseB) | ||
122 | inverseRelations.put(annotation.inverseB, annotation.inverseA) | ||
123 | } | ||
124 | LowerMultiplicityAssertion: | ||
125 | lowerMultiplicities.put(annotation.relation, annotation.lower) | ||
126 | UpperMultiplicityAssertion: | ||
127 | upperMultiplicities.put(annotation.relation, annotation.upper) | ||
128 | } | ||
129 | } | ||
130 | val multiplicityConstraintsBuilder = ImmutableList.builder() | ||
131 | for (relation : problem.relations) { | ||
132 | val containment = containmentRelations.contains(relation) | ||
133 | val lowerMultiplicity = lowerMultiplicities.get(relation) | ||
134 | val upperMultiplicity = upperMultiplicities.get(relation) | ||
135 | var container = false | ||
136 | var inverseUpperMultiplicity = -1 | ||
137 | val inverseRelation = inverseRelations.get(relation) | ||
138 | if (inverseRelation !== null) { | ||
139 | inverseUpperMultiplicity = upperMultiplicities.get(inverseRelation) | ||
140 | container = containmentRelations.contains(inverseRelation) | ||
141 | } | ||
142 | if (containment) { | ||
143 | inverseUpperMultiplicity = 1 | ||
144 | } | ||
145 | val constraint = new RelationMultiplicityConstraint(relation, inverseRelation, containment, container, | ||
146 | lowerMultiplicity, upperMultiplicity, inverseUpperMultiplicity) | ||
147 | if (constraint.isActive) { | ||
148 | if (relation.parameters.size != 2) { | ||
149 | throw new IllegalArgumentException('''Relation «relation.name» has multiplicity or containment constraints, but it is not binary''') | ||
150 | } | ||
151 | multiplicityConstraintsBuilder.add(constraint) | ||
152 | } | ||
153 | } | ||
154 | new RelationConstraints(multiplicityConstraintsBuilder.build) | ||
155 | } | ||
156 | } | ||