aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.viatra.solver.language.parent/org.eclipse.viatra.solver.language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java
diff options
context:
space:
mode:
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.java218
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 @@
1package org.eclipse.viatra.solver.language.resource;
2
3import java.util.HashSet;
4import java.util.List;
5import java.util.Set;
6import java.util.regex.Pattern;
7
8import org.eclipse.emf.ecore.EObject;
9import org.eclipse.viatra.solver.language.model.problem.Assertion;
10import org.eclipse.viatra.solver.language.model.problem.Atom;
11import org.eclipse.viatra.solver.language.model.problem.ClassDeclaration;
12import org.eclipse.viatra.solver.language.model.problem.Conjunction;
13import org.eclipse.viatra.solver.language.model.problem.ExistentialQuantifier;
14import org.eclipse.viatra.solver.language.model.problem.ImplicitVariable;
15import org.eclipse.viatra.solver.language.model.problem.Literal;
16import org.eclipse.viatra.solver.language.model.problem.NegativeLiteral;
17import org.eclipse.viatra.solver.language.model.problem.Node;
18import org.eclipse.viatra.solver.language.model.problem.Parameter;
19import org.eclipse.viatra.solver.language.model.problem.PredicateDefinition;
20import org.eclipse.viatra.solver.language.model.problem.Problem;
21import org.eclipse.viatra.solver.language.model.problem.ProblemFactory;
22import org.eclipse.viatra.solver.language.model.problem.ProblemPackage;
23import org.eclipse.viatra.solver.language.model.problem.Statement;
24import org.eclipse.xtext.linking.impl.LinkingHelper;
25import org.eclipse.xtext.naming.IQualifiedNameConverter;
26import org.eclipse.xtext.naming.QualifiedName;
27import org.eclipse.xtext.nodemodel.INode;
28import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
29import org.eclipse.xtext.resource.DerivedStateAwareResource;
30import org.eclipse.xtext.resource.IDerivedStateComputer;
31import org.eclipse.xtext.scoping.IGlobalScopeProvider;
32import org.eclipse.xtext.scoping.IScope;
33
34import com.google.common.base.Predicates;
35import com.google.inject.Inject;
36import com.google.inject.Singleton;
37
38@Singleton
39public 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}