diff options
Diffstat (limited to 'org.eclipse.viatra.solver.language.parent/org.eclipse.viatra.solver.language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java')
-rw-r--r-- | org.eclipse.viatra.solver.language.parent/org.eclipse.viatra.solver.language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/org.eclipse.viatra.solver.language.parent/org.eclipse.viatra.solver.language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java b/org.eclipse.viatra.solver.language.parent/org.eclipse.viatra.solver.language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java new file mode 100644 index 00000000..571b5745 --- /dev/null +++ b/org.eclipse.viatra.solver.language.parent/org.eclipse.viatra.solver.language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java | |||
@@ -0,0 +1,218 @@ | |||
1 | package org.eclipse.viatra.solver.language.resource; | ||
2 | |||
3 | import java.util.HashSet; | ||
4 | import java.util.List; | ||
5 | import java.util.Set; | ||
6 | import java.util.regex.Pattern; | ||
7 | |||
8 | import org.eclipse.emf.ecore.EObject; | ||
9 | import org.eclipse.viatra.solver.language.model.problem.Assertion; | ||
10 | import org.eclipse.viatra.solver.language.model.problem.Atom; | ||
11 | import org.eclipse.viatra.solver.language.model.problem.ClassDeclaration; | ||
12 | import org.eclipse.viatra.solver.language.model.problem.Conjunction; | ||
13 | import org.eclipse.viatra.solver.language.model.problem.ExistentialQuantifier; | ||
14 | import org.eclipse.viatra.solver.language.model.problem.ImplicitVariable; | ||
15 | import org.eclipse.viatra.solver.language.model.problem.Literal; | ||
16 | import org.eclipse.viatra.solver.language.model.problem.NegativeLiteral; | ||
17 | import org.eclipse.viatra.solver.language.model.problem.Node; | ||
18 | import org.eclipse.viatra.solver.language.model.problem.Parameter; | ||
19 | import org.eclipse.viatra.solver.language.model.problem.PredicateDefinition; | ||
20 | import org.eclipse.viatra.solver.language.model.problem.Problem; | ||
21 | import org.eclipse.viatra.solver.language.model.problem.ProblemFactory; | ||
22 | import org.eclipse.viatra.solver.language.model.problem.ProblemPackage; | ||
23 | import org.eclipse.viatra.solver.language.model.problem.Statement; | ||
24 | import org.eclipse.xtext.linking.impl.LinkingHelper; | ||
25 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | ||
26 | import org.eclipse.xtext.naming.QualifiedName; | ||
27 | import org.eclipse.xtext.nodemodel.INode; | ||
28 | import org.eclipse.xtext.nodemodel.util.NodeModelUtils; | ||
29 | import org.eclipse.xtext.resource.DerivedStateAwareResource; | ||
30 | import org.eclipse.xtext.resource.IDerivedStateComputer; | ||
31 | import org.eclipse.xtext.scoping.IGlobalScopeProvider; | ||
32 | import org.eclipse.xtext.scoping.IScope; | ||
33 | |||
34 | import com.google.common.base.Predicates; | ||
35 | import com.google.inject.Inject; | ||
36 | import com.google.inject.Singleton; | ||
37 | |||
38 | @Singleton | ||
39 | public class ProblemDerivedStateComputer implements IDerivedStateComputer { | ||
40 | public static final String NEW_NODE = "new"; | ||
41 | |||
42 | private static final String ID_REGEX_STRING = "[_a-zA-Z][_0-9a-zA-Z]*"; | ||
43 | |||
44 | private static final Pattern ID_REGEX = Pattern.compile(ID_REGEX_STRING); | ||
45 | |||
46 | private static final Pattern QUALIFIED_NAME_REGEX = Pattern | ||
47 | .compile(ID_REGEX_STRING + "(::" + ID_REGEX_STRING + ")*"); | ||
48 | |||
49 | @Inject | ||
50 | private LinkingHelper linkingHelper; | ||
51 | |||
52 | @Inject | ||
53 | private IQualifiedNameConverter qualifiedNameConverter; | ||
54 | |||
55 | @Inject | ||
56 | private IGlobalScopeProvider scopeProvider; | ||
57 | |||
58 | @Override | ||
59 | public void installDerivedState(DerivedStateAwareResource resource, boolean preLinkingPhase) { | ||
60 | for (EObject object : resource.getContents()) { | ||
61 | if (object instanceof Problem) { | ||
62 | installDerivedProblemState((Problem) object, preLinkingPhase); | ||
63 | } | ||
64 | } | ||
65 | } | ||
66 | |||
67 | protected void installDerivedProblemState(Problem problem, boolean preLinkingPhase) { | ||
68 | Set<String> nodeNames = new HashSet<>(); | ||
69 | if (!preLinkingPhase) { | ||
70 | installDerivedNodes(problem); | ||
71 | } | ||
72 | for (Statement statement : problem.getStatements()) { | ||
73 | if (statement instanceof PredicateDefinition) { | ||
74 | PredicateDefinition definition = (PredicateDefinition) statement; | ||
75 | installDerivedPredicateDefinitionState(definition); | ||
76 | } | ||
77 | } | ||
78 | List<Node> grapNodes = problem.getNodes(); | ||
79 | for (String nodeName : nodeNames) { | ||
80 | Node graphNode = ProblemFactory.eINSTANCE.createNode(); | ||
81 | graphNode.setName(nodeName); | ||
82 | grapNodes.add(graphNode); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | protected void installDerivedNodes(Problem problem) { | ||
87 | IScope nodeScope = scopeProvider.getScope(problem.eResource(), ProblemPackage.Literals.ASSERTION__ARGUMENTS, | ||
88 | Predicates.alwaysTrue()); | ||
89 | Set<String> nodeNames = new HashSet<>(); | ||
90 | for (Statement statement : problem.getStatements()) { | ||
91 | if (statement instanceof ClassDeclaration) { | ||
92 | ClassDeclaration declaration = (ClassDeclaration) statement; | ||
93 | if (!declaration.isAbstract()) { | ||
94 | String className = declaration.getName(); | ||
95 | if (validId(className)) { | ||
96 | QualifiedName qualifiedName = QualifiedName.create(className, NEW_NODE); | ||
97 | String nodeName = qualifiedNameConverter.toString(qualifiedName); | ||
98 | nodeNames.add(nodeName); | ||
99 | } | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | for (Statement statement : problem.getStatements()) { | ||
104 | if (statement instanceof Assertion) { | ||
105 | Assertion assertion = (Assertion) statement; | ||
106 | List<INode> nodes = NodeModelUtils.findNodesForFeature(assertion, | ||
107 | ProblemPackage.Literals.ASSERTION__ARGUMENTS); | ||
108 | for (INode node : nodes) { | ||
109 | String nodeName = linkingHelper.getCrossRefNodeAsString(node, true); | ||
110 | if (validQualifiedName(nodeName)) { | ||
111 | QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(nodeName); | ||
112 | if (nodeScope.getSingleElement(qualifiedName) == null) { | ||
113 | nodeNames.add(nodeName); | ||
114 | } | ||
115 | } | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | List<Node> grapNodes = problem.getNodes(); | ||
120 | for (String nodeName : nodeNames) { | ||
121 | Node graphNode = ProblemFactory.eINSTANCE.createNode(); | ||
122 | graphNode.setName(nodeName); | ||
123 | grapNodes.add(graphNode); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | protected void installDerivedPredicateDefinitionState(PredicateDefinition definition) { | ||
128 | Set<String> parameterNames = new HashSet<>(); | ||
129 | for (Parameter parameter : definition.getParameters()) { | ||
130 | String name = parameter.getName(); | ||
131 | if (name != null) { | ||
132 | parameterNames.add(name); | ||
133 | } | ||
134 | } | ||
135 | for (Conjunction body : definition.getBodies()) { | ||
136 | installDeriveConjunctionState(body, parameterNames); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | protected void installDeriveConjunctionState(Conjunction conjunction, Set<String> knownVariables) { | ||
141 | Set<String> newVariables = new HashSet<>(); | ||
142 | for (Literal literal : conjunction.getLiterals()) { | ||
143 | if (literal instanceof Atom) { | ||
144 | Atom atom = (Atom) literal; | ||
145 | collectVariables(atom, knownVariables, newVariables); | ||
146 | } | ||
147 | } | ||
148 | createVariables(conjunction, newVariables); | ||
149 | newVariables.addAll(knownVariables); | ||
150 | for (Literal literal : conjunction.getLiterals()) { | ||
151 | if (literal instanceof NegativeLiteral) { | ||
152 | NegativeLiteral negativeLiteral = (NegativeLiteral) literal; | ||
153 | installDeriveNegativeLiteralState(negativeLiteral, newVariables); | ||
154 | } | ||
155 | } | ||
156 | } | ||
157 | |||
158 | protected void installDeriveNegativeLiteralState(NegativeLiteral negativeLiteral, Set<String> knownVariables) { | ||
159 | Set<String> newVariables = new HashSet<>(); | ||
160 | collectVariables(negativeLiteral.getAtom(), knownVariables, newVariables); | ||
161 | createVariables(negativeLiteral, newVariables); | ||
162 | } | ||
163 | |||
164 | protected void collectVariables(Atom atom, Set<String> knownVariables, Set<String> newVariables) { | ||
165 | List<INode> nodes = NodeModelUtils.findNodesForFeature(atom, ProblemPackage.Literals.ATOM__ARGUMENTS); | ||
166 | for (INode node : nodes) { | ||
167 | String variableName = linkingHelper.getCrossRefNodeAsString(node, true); | ||
168 | if (!knownVariables.contains(variableName)) { | ||
169 | newVariables.add(variableName); | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | |||
174 | protected void createVariables(ExistentialQuantifier quantifier, Set<String> newVariables) { | ||
175 | for (String variableName : newVariables) { | ||
176 | if (validId(variableName)) { | ||
177 | ImplicitVariable variable = ProblemFactory.eINSTANCE.createImplicitVariable(); | ||
178 | variable.setName(variableName); | ||
179 | quantifier.getImplicitVariables().add(variable); | ||
180 | } | ||
181 | } | ||
182 | } | ||
183 | |||
184 | @Override | ||
185 | public void discardDerivedState(DerivedStateAwareResource resource) { | ||
186 | for (EObject object : resource.getContents()) { | ||
187 | if (object instanceof Problem) { | ||
188 | discardDerivedProblemState((Problem) object); | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | |||
193 | protected void discardDerivedProblemState(Problem problem) { | ||
194 | problem.getNodes().clear(); | ||
195 | for (Statement statement : problem.getStatements()) { | ||
196 | if (statement instanceof PredicateDefinition) { | ||
197 | PredicateDefinition definition = (PredicateDefinition) statement; | ||
198 | for (Conjunction body : definition.getBodies()) { | ||
199 | body.getImplicitVariables().clear(); | ||
200 | for (Literal literal : body.getLiterals()) { | ||
201 | if (literal instanceof NegativeLiteral) { | ||
202 | NegativeLiteral negativeLiteral = (NegativeLiteral) literal; | ||
203 | negativeLiteral.getImplicitVariables().clear(); | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | } | ||
208 | } | ||
209 | } | ||
210 | |||
211 | protected static boolean validId(String name) { | ||
212 | return name != null && ID_REGEX.matcher(name).matches(); | ||
213 | } | ||
214 | |||
215 | protected static boolean validQualifiedName(String name) { | ||
216 | return name != null && QUALIFIED_NAME_REGEX.matcher(name).matches(); | ||
217 | } | ||
218 | } | ||