diff options
20 files changed, 339 insertions, 315 deletions
@@ -1,6 +1,6 @@ | |||
1 | # Refinery | 1 | # Refinery |
2 | 2 | ||
3 | [![Build](https://github.com/graphs4value/refinery/actions/workflows/build.yml/badge.svg)](https://github.com/graphs4value/refinery/actions/workflows/build.yml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=graphs4value_refinery&metric=alert_status)](https://sonarcloud.io/dashboard?id=graphs4value_refinery) | 3 | [![Build](https://github.com/graphs4value/refinery/actions/workflows/build.yml/badge.svg)](https://github.com/graphs4value/refinery/actions/workflows/build.yml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=graphs4value_refinery&metric=alert_status)](https://sonarcloud.io/dashboard?id=graphs4value_refinery) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=graphs4value_refinery&metric=coverage)](https://sonarcloud.io/dashboard?id=graphs4value_refinery) |
4 | 4 | ||
5 | ## How to contribute | 5 | ## How to contribute |
6 | 6 | ||
diff --git a/language-ide/src/main/java/org/eclipse/viatra/solver/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java b/language-ide/src/main/java/org/eclipse/viatra/solver/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java index f9a1fb7b..1de73912 100644 --- a/language-ide/src/main/java/org/eclipse/viatra/solver/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java +++ b/language-ide/src/main/java/org/eclipse/viatra/solver/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java | |||
@@ -105,9 +105,8 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli | |||
105 | return new String[] { BUILTIN_CLASS }; | 105 | return new String[] { BUILTIN_CLASS }; |
106 | } | 106 | } |
107 | ImmutableList.Builder<String> classesBuilder = ImmutableList.builder(); | 107 | ImmutableList.Builder<String> classesBuilder = ImmutableList.builder(); |
108 | if (eObject instanceof ClassDeclaration) { | 108 | if (eObject instanceof ClassDeclaration classDeclaration) { |
109 | classesBuilder.add(CLASS_CLASS); | 109 | classesBuilder.add(CLASS_CLASS); |
110 | var classDeclaration = (ClassDeclaration) eObject; | ||
111 | if (classDeclaration.isAbstract()) { | 110 | if (classDeclaration.isAbstract()) { |
112 | classesBuilder.add(ABSTRACT_CLASS); | 111 | classesBuilder.add(ABSTRACT_CLASS); |
113 | } | 112 | } |
@@ -115,23 +114,20 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli | |||
115 | if (eObject instanceof EnumDeclaration) { | 114 | if (eObject instanceof EnumDeclaration) { |
116 | classesBuilder.add(ENUM_CLASS); | 115 | classesBuilder.add(ENUM_CLASS); |
117 | } | 116 | } |
118 | if (eObject instanceof ReferenceDeclaration) { | 117 | if (eObject instanceof ReferenceDeclaration referenceDeclaration) { |
119 | classesBuilder.add(REFERENCE_CLASS); | 118 | classesBuilder.add(REFERENCE_CLASS); |
120 | var referenceDeclaration = (ReferenceDeclaration) eObject; | ||
121 | if (referenceDeclaration.isContainment()) { | 119 | if (referenceDeclaration.isContainment()) { |
122 | classesBuilder.add(CONTAINMENT_CLASS); | 120 | classesBuilder.add(CONTAINMENT_CLASS); |
123 | } | 121 | } |
124 | } | 122 | } |
125 | if (eObject instanceof PredicateDefinition) { | 123 | if (eObject instanceof PredicateDefinition predicateDefinition) { |
126 | classesBuilder.add(PREDICATE_CLASS); | 124 | classesBuilder.add(PREDICATE_CLASS); |
127 | var predicateDefinition = (PredicateDefinition) eObject; | ||
128 | if (predicateDefinition.isError()) { | 125 | if (predicateDefinition.isError()) { |
129 | classesBuilder.add(ERROR_CLASS); | 126 | classesBuilder.add(ERROR_CLASS); |
130 | } | 127 | } |
131 | } | 128 | } |
132 | if (eObject instanceof Node) { | 129 | if (eObject instanceof Node node) { |
133 | classesBuilder.add(NODE_CLASS); | 130 | classesBuilder.add(NODE_CLASS); |
134 | var node = (Node) eObject; | ||
135 | if (ProblemUtil.isUniqueNode(node)) { | 131 | if (ProblemUtil.isUniqueNode(node)) { |
136 | classesBuilder.add(UNIQUE_NODE_CLASS); | 132 | classesBuilder.add(UNIQUE_NODE_CLASS); |
137 | } | 133 | } |
@@ -142,9 +138,8 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli | |||
142 | if (eObject instanceof Parameter) { | 138 | if (eObject instanceof Parameter) { |
143 | classesBuilder.add(PARAMETER_CLASS); | 139 | classesBuilder.add(PARAMETER_CLASS); |
144 | } | 140 | } |
145 | if (eObject instanceof Variable) { | 141 | if (eObject instanceof Variable variable) { |
146 | classesBuilder.add(VARIABLE_CLASS); | 142 | classesBuilder.add(VARIABLE_CLASS); |
147 | var variable = (Variable) eObject; | ||
148 | if (ProblemUtil.isSingletonVariable(variable)) { | 143 | if (ProblemUtil.isSingletonVariable(variable)) { |
149 | classesBuilder.add(SINGLETON_VARIABLE_CLASS); | 144 | classesBuilder.add(SINGLETON_VARIABLE_CLASS); |
150 | } | 145 | } |
diff --git a/language-web/src/main/java/org/eclipse/viatra/solver/language/web/CacheControlFilter.java b/language-web/src/main/java/org/eclipse/viatra/solver/language/web/CacheControlFilter.java index 41b8e5bf..a1d086c4 100644 --- a/language-web/src/main/java/org/eclipse/viatra/solver/language/web/CacheControlFilter.java +++ b/language-web/src/main/java/org/eclipse/viatra/solver/language/web/CacheControlFilter.java | |||
@@ -34,9 +34,7 @@ public class CacheControlFilter implements Filter { | |||
34 | @Override | 34 | @Override |
35 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) | 35 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) |
36 | throws IOException, ServletException { | 36 | throws IOException, ServletException { |
37 | if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) { | 37 | if (request instanceof HttpServletRequest httpRequest && response instanceof HttpServletResponse httpResponse) { |
38 | var httpRequest = (HttpServletRequest) request; | ||
39 | var httpResponse = (HttpServletResponse) response; | ||
40 | if (CACHE_URI_PATTERN.matcher(httpRequest.getRequestURI()).matches()) { | 38 | if (CACHE_URI_PATTERN.matcher(httpRequest.getRequestURI()).matches()) { |
41 | httpResponse.setHeader(CACHE_CONTROL_HEADER, CACHE_CONTROL_CACHE_VALUE); | 39 | httpResponse.setHeader(CACHE_CONTROL_HEADER, CACHE_CONTROL_CACHE_VALUE); |
42 | httpResponse.setDateHeader(EXPIRES_HEADER, System.currentTimeMillis() + EXPIRY * 1000L); | 40 | httpResponse.setDateHeader(EXPIRES_HEADER, System.currentTimeMillis() + EXPIRY * 1000L); |
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java b/language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java index 1581186c..a2938274 100644 --- a/language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java +++ b/language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java | |||
@@ -74,8 +74,8 @@ public final class ProblemUtil { | |||
74 | if (!found.contains(current)) { | 74 | if (!found.contains(current)) { |
75 | found.add(current); | 75 | found.add(current); |
76 | for (Relation superType : current.getSuperTypes()) { | 76 | for (Relation superType : current.getSuperTypes()) { |
77 | if (superType instanceof ClassDeclaration) { | 77 | if (superType instanceof ClassDeclaration superDeclaration) { |
78 | queue.addLast((ClassDeclaration) superType); | 78 | queue.addLast(superDeclaration); |
79 | } | 79 | } |
80 | } | 80 | } |
81 | } | 81 | } |
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/resource/DerivedVariableComputer.java b/language/src/main/java/org/eclipse/viatra/solver/language/resource/DerivedVariableComputer.java index 1b0146b6..2789f590 100644 --- a/language/src/main/java/org/eclipse/viatra/solver/language/resource/DerivedVariableComputer.java +++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/DerivedVariableComputer.java | |||
@@ -45,8 +45,7 @@ public class DerivedVariableComputer { | |||
45 | 45 | ||
46 | public void installDerivedVariables(Problem problem, Set<String> nodeNames) { | 46 | public void installDerivedVariables(Problem problem, Set<String> nodeNames) { |
47 | for (Statement statement : problem.getStatements()) { | 47 | for (Statement statement : problem.getStatements()) { |
48 | if (statement instanceof PredicateDefinition) { | 48 | if (statement instanceof PredicateDefinition definition) { |
49 | PredicateDefinition definition = (PredicateDefinition) statement; | ||
50 | installDerivedPredicateDefinitionState(definition, nodeNames); | 49 | installDerivedPredicateDefinitionState(definition, nodeNames); |
51 | } | 50 | } |
52 | } | 51 | } |
@@ -69,16 +68,14 @@ public class DerivedVariableComputer { | |||
69 | protected void installDeriveConjunctionState(Conjunction conjunction, Set<String> knownVariables) { | 68 | protected void installDeriveConjunctionState(Conjunction conjunction, Set<String> knownVariables) { |
70 | Set<String> newVariables = new HashSet<>(); | 69 | Set<String> newVariables = new HashSet<>(); |
71 | for (Literal literal : conjunction.getLiterals()) { | 70 | for (Literal literal : conjunction.getLiterals()) { |
72 | if (literal instanceof Atom) { | 71 | if (literal instanceof Atom atom) { |
73 | var atom = (Atom) literal; | ||
74 | createSigletonVariablesAndCollectVariables(atom, knownVariables, newVariables); | 72 | createSigletonVariablesAndCollectVariables(atom, knownVariables, newVariables); |
75 | } | 73 | } |
76 | } | 74 | } |
77 | createVariables(conjunction, newVariables); | 75 | createVariables(conjunction, newVariables); |
78 | newVariables.addAll(knownVariables); | 76 | newVariables.addAll(knownVariables); |
79 | for (Literal literal : conjunction.getLiterals()) { | 77 | for (Literal literal : conjunction.getLiterals()) { |
80 | if (literal instanceof NegativeLiteral) { | 78 | if (literal instanceof NegativeLiteral negativeLiteral) { |
81 | var negativeLiteral = (NegativeLiteral) literal; | ||
82 | installDeriveNegativeLiteralState(negativeLiteral, newVariables); | 79 | installDeriveNegativeLiteralState(negativeLiteral, newVariables); |
83 | } | 80 | } |
84 | } | 81 | } |
@@ -93,8 +90,7 @@ public class DerivedVariableComputer { | |||
93 | protected void createSigletonVariablesAndCollectVariables(Atom atom, Set<String> knownVariables, | 90 | protected void createSigletonVariablesAndCollectVariables(Atom atom, Set<String> knownVariables, |
94 | Set<String> newVariables) { | 91 | Set<String> newVariables) { |
95 | for (Argument argument : atom.getArguments()) { | 92 | for (Argument argument : atom.getArguments()) { |
96 | if (argument instanceof VariableOrNodeArgument) { | 93 | if (argument instanceof VariableOrNodeArgument variableOrNodeArgument) { |
97 | var variableOrNodeArgument = (VariableOrNodeArgument) argument; | ||
98 | IScope scope = scopeProvider.getScope(variableOrNodeArgument, | 94 | IScope scope = scopeProvider.getScope(variableOrNodeArgument, |
99 | ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE); | 95 | ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE); |
100 | List<INode> nodes = NodeModelUtils.findNodesForFeature(variableOrNodeArgument, | 96 | List<INode> nodes = NodeModelUtils.findNodesForFeature(variableOrNodeArgument, |
@@ -159,8 +155,8 @@ public class DerivedVariableComputer { | |||
159 | 155 | ||
160 | public void discardDerivedVariables(Problem problem) { | 156 | public void discardDerivedVariables(Problem problem) { |
161 | for (Statement statement : problem.getStatements()) { | 157 | for (Statement statement : problem.getStatements()) { |
162 | if (statement instanceof PredicateDefinition) { | 158 | if (statement instanceof PredicateDefinition predicateDefinition) { |
163 | discardPredicateDefinitionState((PredicateDefinition) statement); | 159 | discardPredicateDefinitionState(predicateDefinition); |
164 | } | 160 | } |
165 | } | 161 | } |
166 | } | 162 | } |
@@ -169,11 +165,10 @@ public class DerivedVariableComputer { | |||
169 | for (Conjunction body : definition.getBodies()) { | 165 | for (Conjunction body : definition.getBodies()) { |
170 | body.getImplicitVariables().clear(); | 166 | body.getImplicitVariables().clear(); |
171 | for (Literal literal : body.getLiterals()) { | 167 | for (Literal literal : body.getLiterals()) { |
172 | if (literal instanceof Atom) { | 168 | if (literal instanceof Atom atom) { |
173 | discardDerivedAtomState((Atom) literal); | 169 | discardDerivedAtomState(atom); |
174 | } | 170 | } |
175 | if (literal instanceof NegativeLiteral) { | 171 | if (literal instanceof NegativeLiteral negativeLiteral) { |
176 | var negativeLiteral = (NegativeLiteral) literal; | ||
177 | negativeLiteral.getImplicitVariables().clear(); | 172 | negativeLiteral.getImplicitVariables().clear(); |
178 | discardDerivedAtomState(negativeLiteral.getAtom()); | 173 | discardDerivedAtomState(negativeLiteral.getAtom()); |
179 | } | 174 | } |
@@ -186,8 +181,7 @@ public class DerivedVariableComputer { | |||
186 | return; | 181 | return; |
187 | } | 182 | } |
188 | for (Argument argument : atom.getArguments()) { | 183 | for (Argument argument : atom.getArguments()) { |
189 | if (argument instanceof VariableOrNodeArgument) { | 184 | if (argument instanceof VariableOrNodeArgument variableOrNodeArgument) { |
190 | var variableOrNodeArgument = (VariableOrNodeArgument) argument; | ||
191 | variableOrNodeArgument.setSingletonVariable(null); | 185 | variableOrNodeArgument.setSingletonVariable(null); |
192 | } | 186 | } |
193 | } | 187 | } |
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/resource/NodeNameCollector.java b/language/src/main/java/org/eclipse/viatra/solver/language/resource/NodeNameCollector.java index e9533c25..415db9a9 100644 --- a/language/src/main/java/org/eclipse/viatra/solver/language/resource/NodeNameCollector.java +++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/NodeNameCollector.java | |||
@@ -52,10 +52,10 @@ public class NodeNameCollector { | |||
52 | } | 52 | } |
53 | 53 | ||
54 | protected void collectStatementNodeNames(Statement statement) { | 54 | protected void collectStatementNodeNames(Statement statement) { |
55 | if (statement instanceof Assertion) { | 55 | if (statement instanceof Assertion assertion) { |
56 | collectAssertionNodeNames((Assertion) statement); | 56 | collectAssertionNodeNames(assertion); |
57 | } else if (statement instanceof NodeValueAssertion) { | 57 | } else if (statement instanceof NodeValueAssertion nodeValueAssertion) { |
58 | collectNodeValueAssertionNodeNames((NodeValueAssertion) statement); | 58 | collectNodeValueAssertionNodeNames(nodeValueAssertion); |
59 | } | 59 | } |
60 | } | 60 | } |
61 | 61 | ||
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java index a2d0eef6..3c6c8273 100644 --- a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java +++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java | |||
@@ -62,8 +62,8 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
62 | return null; | 62 | return null; |
63 | } | 63 | } |
64 | EObject object = contents.get(0); | 64 | EObject object = contents.get(0); |
65 | if (object instanceof Problem) { | 65 | if (object instanceof Problem problem) { |
66 | return (Problem) object; | 66 | return problem; |
67 | } | 67 | } |
68 | return null; | 68 | return null; |
69 | } | 69 | } |
@@ -79,12 +79,10 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
79 | 79 | ||
80 | protected void installNewNodes(Problem problem, Adapter adapter) { | 80 | protected void installNewNodes(Problem problem, Adapter adapter) { |
81 | for (Statement statement : problem.getStatements()) { | 81 | for (Statement statement : problem.getStatements()) { |
82 | if (statement instanceof ClassDeclaration) { | 82 | if (statement instanceof ClassDeclaration declaration && !declaration.isAbstract() |
83 | var declaration = (ClassDeclaration) statement; | 83 | && declaration.getNewNode() == null) { |
84 | if (!declaration.isAbstract() && declaration.getNewNode() == null) { | 84 | var newNode = adapter.createNodeIfAbsent(declaration, key -> createNode(NEW_NODE)); |
85 | var newNode = adapter.createNodeIfAbsent(declaration, key -> createNode(NEW_NODE)); | 85 | declaration.setNewNode(newNode); |
86 | declaration.setNewNode(newNode); | ||
87 | } | ||
88 | } | 86 | } |
89 | } | 87 | } |
90 | } | 88 | } |
@@ -120,8 +118,7 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
120 | Set<ClassDeclaration> classDeclarations = new HashSet<>(); | 118 | Set<ClassDeclaration> classDeclarations = new HashSet<>(); |
121 | problem.getNodes().clear(); | 119 | problem.getNodes().clear(); |
122 | for (Statement statement : problem.getStatements()) { | 120 | for (Statement statement : problem.getStatements()) { |
123 | if (statement instanceof ClassDeclaration) { | 121 | if (statement instanceof ClassDeclaration classDeclaration) { |
124 | var classDeclaration = (ClassDeclaration) statement; | ||
125 | classDeclaration.setNewNode(null); | 122 | classDeclaration.setNewNode(null); |
126 | classDeclarations.add(classDeclaration); | 123 | classDeclarations.add(classDeclaration); |
127 | } | 124 | } |
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemLocationInFileProvider.java b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemLocationInFileProvider.java index 80bbdb0f..bd05e8cf 100644 --- a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemLocationInFileProvider.java +++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemLocationInFileProvider.java | |||
@@ -10,8 +10,8 @@ import org.eclipse.xtext.util.ITextRegion; | |||
10 | public class ProblemLocationInFileProvider extends DefaultLocationInFileProvider { | 10 | public class ProblemLocationInFileProvider extends DefaultLocationInFileProvider { |
11 | @Override | 11 | @Override |
12 | protected ITextRegion doGetTextRegion(EObject obj, RegionDescription query) { | 12 | protected ITextRegion doGetTextRegion(EObject obj, RegionDescription query) { |
13 | if (obj instanceof Node) { | 13 | if (obj instanceof Node node) { |
14 | return getNodeTextRegion((Node) obj, query); | 14 | return getNodeTextRegion(node, query); |
15 | } | 15 | } |
16 | if (obj instanceof ImplicitVariable) { | 16 | if (obj instanceof ImplicitVariable) { |
17 | return ITextRegion.EMPTY_REGION; | 17 | return ITextRegion.EMPTY_REGION; |
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java index 012606d6..cd5020e7 100644 --- a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java +++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java | |||
@@ -80,8 +80,7 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti | |||
80 | // Variables are always private to the containing predicate definition. | 80 | // Variables are always private to the containing predicate definition. |
81 | return false; | 81 | return false; |
82 | } | 82 | } |
83 | if (eObject instanceof Node) { | 83 | if (eObject instanceof Node node) { |
84 | var node = (Node) eObject; | ||
85 | // Only enum literals and new nodes are visible across problem files. | 84 | // Only enum literals and new nodes are visible across problem files. |
86 | return ProblemUtil.isUniqueNode(node) || ProblemUtil.isNewNode(node); | 85 | return ProblemUtil.isUniqueNode(node) || ProblemUtil.isNewNode(node); |
87 | } | 86 | } |
@@ -89,8 +88,8 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti | |||
89 | } | 88 | } |
90 | 89 | ||
91 | protected boolean shouldExportSimpleName(EObject eObject) { | 90 | protected boolean shouldExportSimpleName(EObject eObject) { |
92 | if (eObject instanceof Node) { | 91 | if (eObject instanceof Node node) { |
93 | return !ProblemUtil.isNewNode((Node) eObject); | 92 | return !ProblemUtil.isNewNode(node); |
94 | } | 93 | } |
95 | return true; | 94 | return true; |
96 | } | 95 | } |
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java b/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java index 33f8c50f..56de6b1b 100644 --- a/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java +++ b/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java | |||
@@ -57,16 +57,14 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider { | |||
57 | protected IScope getVariableScope(EObject context, IScope delegateScope) { | 57 | protected IScope getVariableScope(EObject context, IScope delegateScope) { |
58 | List<Variable> variables = new ArrayList<>(); | 58 | List<Variable> variables = new ArrayList<>(); |
59 | EObject currentContext = context; | 59 | EObject currentContext = context; |
60 | if (context instanceof VariableOrNodeArgument) { | 60 | if (context instanceof VariableOrNodeArgument argument) { |
61 | VariableOrNodeArgument argument = (VariableOrNodeArgument) context; | ||
62 | Variable singletonVariable = argument.getSingletonVariable(); | 61 | Variable singletonVariable = argument.getSingletonVariable(); |
63 | if (singletonVariable != null) { | 62 | if (singletonVariable != null) { |
64 | variables.add(singletonVariable); | 63 | variables.add(singletonVariable); |
65 | } | 64 | } |
66 | } | 65 | } |
67 | while (currentContext != null && !(currentContext instanceof PredicateDefinition)) { | 66 | while (currentContext != null && !(currentContext instanceof PredicateDefinition)) { |
68 | if (currentContext instanceof ExistentialQuantifier) { | 67 | if (currentContext instanceof ExistentialQuantifier quantifier) { |
69 | ExistentialQuantifier quantifier = (ExistentialQuantifier) currentContext; | ||
70 | variables.addAll(quantifier.getImplicitVariables()); | 68 | variables.addAll(quantifier.getImplicitVariables()); |
71 | } | 69 | } |
72 | currentContext = currentContext.eContainer(); | 70 | currentContext = currentContext.eContainer(); |
diff --git a/store/src/main/java/org/eclipse/viatra/solver/data/map/internal/HashClash.java b/store/src/main/java/org/eclipse/viatra/solver/data/map/internal/HashClash.java new file mode 100644 index 00000000..c70fb8b8 --- /dev/null +++ b/store/src/main/java/org/eclipse/viatra/solver/data/map/internal/HashClash.java | |||
@@ -0,0 +1,18 @@ | |||
1 | package org.eclipse.viatra.solver.data.map.internal; | ||
2 | |||
3 | enum HashClash { | ||
4 | /** | ||
5 | * Not stuck. | ||
6 | */ | ||
7 | NONE, | ||
8 | |||
9 | /** | ||
10 | * Clashed, next we should return the key of cursor 1. | ||
11 | */ | ||
12 | STUCK_CURSOR_1, | ||
13 | |||
14 | /** | ||
15 | * Clashed, next we should return the key of cursor 2. | ||
16 | */ | ||
17 | STUCK_CURSOR_2 | ||
18 | } | ||
diff --git a/store/src/main/java/org/eclipse/viatra/solver/data/map/internal/ImmutableNode.java b/store/src/main/java/org/eclipse/viatra/solver/data/map/internal/ImmutableNode.java index 04a9b19a..b507763f 100644 --- a/store/src/main/java/org/eclipse/viatra/solver/data/map/internal/ImmutableNode.java +++ b/store/src/main/java/org/eclipse/viatra/solver/data/map/internal/ImmutableNode.java | |||
@@ -15,15 +15,16 @@ public class ImmutableNode<K, V> extends Node<K, V> { | |||
15 | */ | 15 | */ |
16 | final int nodeMap; | 16 | final int nodeMap; |
17 | /** | 17 | /** |
18 | * Stores Keys, Values, and subnodes. Structure: (K,V)*,NODE; NODES are stored backwards. | 18 | * Stores Keys, Values, and subnodes. Structure: (K,V)*,NODE; NODES are stored |
19 | * backwards. | ||
19 | */ | 20 | */ |
20 | final Object[] content; | 21 | final Object[] content; |
21 | 22 | ||
22 | /** | 23 | /** |
23 | * Hash code derived from immutable hash code | 24 | * Hash code derived from immutable hash code |
24 | */ | 25 | */ |
25 | final int precalculatedHash; | 26 | final int precalculatedHash; |
26 | 27 | ||
27 | private ImmutableNode(int dataMap, int nodeMap, Object[] content, int precalculatedHash) { | 28 | private ImmutableNode(int dataMap, int nodeMap, Object[] content, int precalculatedHash) { |
28 | super(); | 29 | super(); |
29 | this.dataMap = dataMap; | 30 | this.dataMap = dataMap; |
@@ -41,83 +42,87 @@ public class ImmutableNode<K, V> extends Node<K, V> { | |||
41 | * available. | 42 | * available. |
42 | * @return an immutable version of the input node. | 43 | * @return an immutable version of the input node. |
43 | */ | 44 | */ |
44 | @SuppressWarnings("unchecked") | 45 | static <K, V> ImmutableNode<K, V> constructImmutable(MutableNode<K, V> node, |
45 | static <K,V> ImmutableNode<K,V> constructImmutable(MutableNode<K,V> node, Map<Node<K, V>, ImmutableNode<K, V>> cache) { | 46 | Map<Node<K, V>, ImmutableNode<K, V>> cache) { |
46 | // 1. try to return from cache | 47 | // 1. try to return from cache |
47 | if(cache != null) { | 48 | if (cache != null) { |
48 | ImmutableNode<K, V> cachedResult = cache.get(node); | 49 | ImmutableNode<K, V> cachedResult = cache.get(node); |
49 | if(cachedResult != null) { | 50 | if (cachedResult != null) { |
50 | // 1.1 Already cached, return from cache. | 51 | // 1.1 Already cached, return from cache. |
51 | return cachedResult; | 52 | return cachedResult; |
52 | } | 53 | } |
53 | } | 54 | } |
54 | 55 | ||
55 | // 2. otherwise construct a new ImmutableNode | 56 | // 2. otherwise construct a new ImmutableNode |
56 | int size = 0; | 57 | int size = 0; |
57 | for(int i = 0; i<node.content.length; i++) { | 58 | for (int i = 0; i < node.content.length; i++) { |
58 | if(node.content[i]!=null) { | 59 | if (node.content[i] != null) { |
59 | size++; | 60 | size++; |
60 | } | 61 | } |
61 | } | 62 | } |
62 | 63 | ||
63 | int datas = 0; | 64 | int datas = 0; |
64 | int nodes = 0; | 65 | int nodes = 0; |
65 | int resultDataMap = 0; | 66 | int resultDataMap = 0; |
66 | int resultNodeMap = 0; | 67 | int resultNodeMap = 0; |
67 | final Object[] resultContent = new Object[size]; | 68 | final Object[] resultContent = new Object[size]; |
68 | int bitposition = 1; | 69 | int bitposition = 1; |
69 | for(int i = 0; i<FACTOR; i++) { | 70 | for (int i = 0; i < FACTOR; i++) { |
70 | Object key = node.content[i*2]; | 71 | Object key = node.content[i * 2]; |
71 | if(key != null) { | 72 | if (key != null) { |
72 | resultDataMap |= bitposition; | 73 | resultDataMap |= bitposition; |
73 | resultContent[datas*2] = key; | 74 | resultContent[datas * 2] = key; |
74 | resultContent[datas*2+1] = node.content[i*2+1]; | 75 | resultContent[datas * 2 + 1] = node.content[i * 2 + 1]; |
75 | datas++; | 76 | datas++; |
76 | } else { | 77 | } else { |
77 | Node<K,V> subnode = (Node<K, V>) node.content[i*2+1]; | 78 | @SuppressWarnings("unchecked") |
78 | if(subnode != null) { | 79 | var subnode = (Node<K, V>) node.content[i * 2 + 1]; |
80 | if (subnode != null) { | ||
79 | ImmutableNode<K, V> immutableSubnode = subnode.toImmutable(cache); | 81 | ImmutableNode<K, V> immutableSubnode = subnode.toImmutable(cache); |
80 | resultNodeMap |=bitposition; | 82 | resultNodeMap |= bitposition; |
81 | resultContent[size-1-nodes] = immutableSubnode; | 83 | resultContent[size - 1 - nodes] = immutableSubnode; |
82 | nodes++; | 84 | nodes++; |
83 | } | 85 | } |
84 | } | 86 | } |
85 | bitposition<<=1; | 87 | bitposition <<= 1; |
86 | } | 88 | } |
87 | final int resultHash = node.hashCode(); | 89 | final int resultHash = node.hashCode(); |
88 | ImmutableNode<K,V> newImmutable = new ImmutableNode<>(resultDataMap, resultNodeMap, resultContent, resultHash); | 90 | var newImmutable = new ImmutableNode<K, V>(resultDataMap, resultNodeMap, resultContent, resultHash); |
89 | 91 | ||
90 | // 3. save new immutable. | 92 | // 3. save new immutable. |
91 | if(cache != null) { | 93 | if (cache != null) { |
92 | cache.put(newImmutable, newImmutable); | 94 | cache.put(newImmutable, newImmutable); |
93 | } | 95 | } |
94 | return newImmutable; | 96 | return newImmutable; |
95 | } | 97 | } |
96 | 98 | ||
97 | private int index(int bitmap, int bitpos) { | 99 | private int index(int bitmap, int bitpos) { |
98 | return Integer.bitCount(bitmap & (bitpos-1)); | 100 | return Integer.bitCount(bitmap & (bitpos - 1)); |
99 | } | 101 | } |
100 | 102 | ||
101 | @SuppressWarnings("unchecked") | ||
102 | @Override | 103 | @Override |
103 | public V getValue(K key, ContinousHashProvider<? super K> hashProvider, V defaultValue, int hash, int depth) { | 104 | public V getValue(K key, ContinousHashProvider<? super K> hashProvider, V defaultValue, int hash, int depth) { |
104 | int selectedHashFragment = hashFragment(hash,shiftDepth(depth)); | 105 | int selectedHashFragment = hashFragment(hash, shiftDepth(depth)); |
105 | int bitposition = 1 << selectedHashFragment; | 106 | int bitposition = 1 << selectedHashFragment; |
106 | // If the key is stored as a data | 107 | // If the key is stored as a data |
107 | if((dataMap & bitposition) != 0) { | 108 | if ((dataMap & bitposition) != 0) { |
108 | int keyIndex = 2*index(dataMap, bitposition); | 109 | int keyIndex = 2 * index(dataMap, bitposition); |
110 | @SuppressWarnings("unchecked") | ||
109 | K keyCandidate = (K) content[keyIndex]; | 111 | K keyCandidate = (K) content[keyIndex]; |
110 | if(keyCandidate.equals(key)) { | 112 | if (keyCandidate.equals(key)) { |
111 | return (V) content[keyIndex+1]; | 113 | @SuppressWarnings("unchecked") |
114 | V value = (V) content[keyIndex + 1]; | ||
115 | return value; | ||
112 | } else { | 116 | } else { |
113 | return defaultValue; | 117 | return defaultValue; |
114 | } | 118 | } |
115 | } | 119 | } |
116 | // the key is stored as a node | 120 | // the key is stored as a node |
117 | else if((nodeMap & bitposition) != 0) { | 121 | else if ((nodeMap & bitposition) != 0) { |
118 | int keyIndex = content.length-1-index(nodeMap, bitposition); | 122 | int keyIndex = content.length - 1 - index(nodeMap, bitposition); |
119 | ImmutableNode<K,V> subNode = (ImmutableNode<K,V>) content[keyIndex]; | 123 | @SuppressWarnings("unchecked") |
120 | int newDepth = depth+1; | 124 | var subNode = (ImmutableNode<K, V>) content[keyIndex]; |
125 | int newDepth = depth + 1; | ||
121 | int newHash = newHash(hashProvider, key, hash, newDepth); | 126 | int newHash = newHash(hashProvider, key, hash, newDepth); |
122 | return subNode.getValue(key, hashProvider, defaultValue, newHash, newDepth); | 127 | return subNode.getValue(key, hashProvider, defaultValue, newHash, newDepth); |
123 | } | 128 | } |
@@ -126,21 +131,22 @@ public class ImmutableNode<K, V> extends Node<K, V> { | |||
126 | return defaultValue; | 131 | return defaultValue; |
127 | } | 132 | } |
128 | } | 133 | } |
129 | 134 | ||
130 | @SuppressWarnings("unchecked") | ||
131 | @Override | 135 | @Override |
132 | public Node<K,V> putValue(K key, V value, OldValueBox<V> oldValue, ContinousHashProvider<? super K> hashProvider, V defaultValue, int hash, int depth) { | 136 | public Node<K, V> putValue(K key, V value, OldValueBox<V> oldValue, ContinousHashProvider<? super K> hashProvider, |
133 | int selectedHashFragment = hashFragment(hash,shiftDepth(depth)); | 137 | V defaultValue, int hash, int depth) { |
138 | int selectedHashFragment = hashFragment(hash, shiftDepth(depth)); | ||
134 | int bitposition = 1 << selectedHashFragment; | 139 | int bitposition = 1 << selectedHashFragment; |
135 | if((dataMap & bitposition) != 0) { | 140 | if ((dataMap & bitposition) != 0) { |
136 | int keyIndex = 2*index(dataMap, bitposition); | 141 | int keyIndex = 2 * index(dataMap, bitposition); |
142 | @SuppressWarnings("unchecked") | ||
137 | K keyCandidate = (K) content[keyIndex]; | 143 | K keyCandidate = (K) content[keyIndex]; |
138 | if(keyCandidate.equals(key)) { | 144 | if (keyCandidate.equals(key)) { |
139 | if(value == defaultValue) { | 145 | if (value == defaultValue) { |
140 | // delete | 146 | // delete |
141 | MutableNode<K, V> mutable = this.toMutable(); | 147 | MutableNode<K, V> mutable = this.toMutable(); |
142 | return mutable.removeEntry(selectedHashFragment,oldValue); | 148 | return mutable.removeEntry(selectedHashFragment, oldValue); |
143 | } else if(value == content[keyIndex+1]) { | 149 | } else if (value == content[keyIndex + 1]) { |
144 | // dont change | 150 | // dont change |
145 | oldValue.setOldValue(value); | 151 | oldValue.setOldValue(value); |
146 | return this; | 152 | return this; |
@@ -150,7 +156,7 @@ public class ImmutableNode<K, V> extends Node<K, V> { | |||
150 | return mutable.updateValue(value, oldValue, selectedHashFragment); | 156 | return mutable.updateValue(value, oldValue, selectedHashFragment); |
151 | } | 157 | } |
152 | } else { | 158 | } else { |
153 | if(value == defaultValue) { | 159 | if (value == defaultValue) { |
154 | // dont change | 160 | // dont change |
155 | oldValue.setOldValue(defaultValue); | 161 | oldValue.setOldValue(defaultValue); |
156 | return this; | 162 | return this; |
@@ -160,19 +166,19 @@ public class ImmutableNode<K, V> extends Node<K, V> { | |||
160 | return mutable.putValue(key, value, oldValue, hashProvider, defaultValue, hash, depth); | 166 | return mutable.putValue(key, value, oldValue, hashProvider, defaultValue, hash, depth); |
161 | } | 167 | } |
162 | } | 168 | } |
163 | } else if((nodeMap & bitposition)!=0) { | 169 | } else if ((nodeMap & bitposition) != 0) { |
164 | 170 | int keyIndex = content.length - 1 - index(nodeMap, bitposition); | |
165 | int keyIndex = content.length-1-index(nodeMap, bitposition); | 171 | @SuppressWarnings("unchecked") |
166 | ImmutableNode<K,V> subNode = (ImmutableNode<K,V>) content[keyIndex]; | 172 | var subNode = (ImmutableNode<K, V>) content[keyIndex]; |
167 | int newDepth = depth+1; | 173 | int newDepth = depth + 1; |
168 | int newHash = newHash(hashProvider, key, hash, newDepth); | 174 | int newHash = newHash(hashProvider, key, hash, newDepth); |
169 | Node<K,V> newsubNode = subNode.putValue(key, value, oldValue, hashProvider, defaultValue, newHash, newDepth); | 175 | var newsubNode = subNode.putValue(key, value, oldValue, hashProvider, defaultValue, newHash, newDepth); |
170 | 176 | ||
171 | if(subNode == newsubNode) { | 177 | if (subNode == newsubNode) { |
172 | // nothing changed | 178 | // nothing changed |
173 | return this; | 179 | return this; |
174 | } else { | 180 | } else { |
175 | MutableNode<K, V> mutable = toMutable(); | 181 | MutableNode<K, V> mutable = toMutable(); |
176 | return mutable.updateWithSubNode(selectedHashFragment, newsubNode, value.equals(defaultValue)); | 182 | return mutable.updateWithSubNode(selectedHashFragment, newsubNode, value.equals(defaultValue)); |
177 | } | 183 | } |
178 | } else { | 184 | } else { |
@@ -181,59 +187,56 @@ public class ImmutableNode<K, V> extends Node<K, V> { | |||
181 | return mutable.putValue(key, value, oldValue, hashProvider, defaultValue, hash, depth); | 187 | return mutable.putValue(key, value, oldValue, hashProvider, defaultValue, hash, depth); |
182 | } | 188 | } |
183 | } | 189 | } |
184 | 190 | ||
185 | |||
186 | @SuppressWarnings("unchecked") | ||
187 | @Override | 191 | @Override |
188 | public long getSize() { | 192 | public long getSize() { |
189 | int result = Integer.bitCount(this.dataMap); | 193 | int result = Integer.bitCount(this.dataMap); |
190 | for(int subnodeIndex = 0; subnodeIndex < Integer.bitCount(this.nodeMap); subnodeIndex++) { | 194 | for (int subnodeIndex = 0; subnodeIndex < Integer.bitCount(this.nodeMap); subnodeIndex++) { |
191 | ImmutableNode<K,V> subnode = | 195 | @SuppressWarnings("unchecked") |
192 | (ImmutableNode<K, V>) this.content[this.content.length-1-subnodeIndex]; | 196 | var subnode = (ImmutableNode<K, V>) this.content[this.content.length - 1 - subnodeIndex]; |
193 | result += subnode.getSize(); | 197 | result += subnode.getSize(); |
194 | } | 198 | } |
195 | return result; | 199 | return result; |
196 | } | 200 | } |
197 | 201 | ||
198 | @Override | 202 | @Override |
199 | protected MutableNode<K,V> toMutable() { | 203 | protected MutableNode<K, V> toMutable() { |
200 | return new MutableNode<>(this); | 204 | return new MutableNode<>(this); |
201 | } | 205 | } |
202 | 206 | ||
203 | @Override | 207 | @Override |
204 | public ImmutableNode<K, V> toImmutable( | 208 | public ImmutableNode<K, V> toImmutable(Map<Node<K, V>, ImmutableNode<K, V>> cache) { |
205 | Map<Node<K, V>, ImmutableNode<K, V>> cache) { | ||
206 | return this; | 209 | return this; |
207 | } | 210 | } |
208 | 211 | ||
209 | @Override | 212 | @Override |
210 | protected MutableNode<K, V> isMutable() { | 213 | protected MutableNode<K, V> isMutable() { |
211 | return null; | 214 | return null; |
212 | } | 215 | } |
213 | 216 | ||
214 | @SuppressWarnings("unchecked") | 217 | @SuppressWarnings("unchecked") |
215 | @Override | 218 | @Override |
216 | boolean moveToNext(MapCursor<K, V> cursor) { | 219 | boolean moveToNext(MapCursor<K, V> cursor) { |
217 | // 1. try to move to data | 220 | // 1. try to move to data |
218 | int datas = Integer.bitCount(this.dataMap); | 221 | int datas = Integer.bitCount(this.dataMap); |
219 | if(cursor.dataIndex != MapCursor.INDEX_FINISH) { | 222 | if (cursor.dataIndex != MapCursor.INDEX_FINISH) { |
220 | int newDataIndex = cursor.dataIndex + 1; | 223 | int newDataIndex = cursor.dataIndex + 1; |
221 | if(newDataIndex < datas) { | 224 | if (newDataIndex < datas) { |
222 | cursor.dataIndex = newDataIndex; | 225 | cursor.dataIndex = newDataIndex; |
223 | cursor.key = (K) this.content[newDataIndex*2]; | 226 | cursor.key = (K) this.content[newDataIndex * 2]; |
224 | cursor.value = (V) this.content[newDataIndex*2+1]; | 227 | cursor.value = (V) this.content[newDataIndex * 2 + 1]; |
225 | return true; | 228 | return true; |
226 | } else { | 229 | } else { |
227 | cursor.dataIndex = MapCursor.INDEX_FINISH; | 230 | cursor.dataIndex = MapCursor.INDEX_FINISH; |
228 | } | 231 | } |
229 | } | 232 | } |
230 | 233 | ||
231 | // 2. look inside the subnodes | 234 | // 2. look inside the subnodes |
232 | int nodes = Integer.bitCount(this.nodeMap); | 235 | int nodes = Integer.bitCount(this.nodeMap); |
233 | int newNodeIndex = cursor.nodeIndexStack.peek() + 1; | 236 | int newNodeIndex = cursor.nodeIndexStack.peek() + 1; |
234 | if(newNodeIndex < nodes) { | 237 | if (newNodeIndex < nodes) { |
235 | // 2.1 found next subnode, move down to the subnode | 238 | // 2.1 found next subnode, move down to the subnode |
236 | Node<K, V> subnode = (Node<K, V>) this.content[this.content.length-1-newNodeIndex]; | 239 | Node<K, V> subnode = (Node<K, V>) this.content[this.content.length - 1 - newNodeIndex]; |
237 | cursor.dataIndex = MapCursor.INDEX_START; | 240 | cursor.dataIndex = MapCursor.INDEX_START; |
238 | cursor.nodeIndexStack.pop(); | 241 | cursor.nodeIndexStack.pop(); |
239 | cursor.nodeIndexStack.push(newNodeIndex); | 242 | cursor.nodeIndexStack.push(newNodeIndex); |
@@ -244,7 +247,7 @@ public class ImmutableNode<K, V> extends Node<K, V> { | |||
244 | // 3. no subnode found, move up | 247 | // 3. no subnode found, move up |
245 | cursor.nodeStack.pop(); | 248 | cursor.nodeStack.pop(); |
246 | cursor.nodeIndexStack.pop(); | 249 | cursor.nodeIndexStack.pop(); |
247 | if(!cursor.nodeStack.isEmpty()) { | 250 | if (!cursor.nodeStack.isEmpty()) { |
248 | Node<K, V> supernode = cursor.nodeStack.peek(); | 251 | Node<K, V> supernode = cursor.nodeStack.peek(); |
249 | return supernode.moveToNext(cursor); | 252 | return supernode.moveToNext(cursor); |
250 | } else { | 253 | } else { |
@@ -254,69 +257,69 @@ public class ImmutableNode<K, V> extends Node<K, V> { | |||
254 | } | 257 | } |
255 | } | 258 | } |
256 | } | 259 | } |
257 | 260 | ||
258 | @Override | 261 | @Override |
259 | public void prettyPrint(StringBuilder builder, int depth, int code) { | 262 | public void prettyPrint(StringBuilder builder, int depth, int code) { |
260 | for(int i = 0; i<depth; i++) { | 263 | for (int i = 0; i < depth; i++) { |
261 | builder.append("\t"); | 264 | builder.append("\t"); |
262 | } | 265 | } |
263 | if(code>=0) { | 266 | if (code >= 0) { |
264 | builder.append(code); | 267 | builder.append(code); |
265 | builder.append(":"); | 268 | builder.append(":"); |
266 | } | 269 | } |
267 | builder.append("Immutable("); | 270 | builder.append("Immutable("); |
268 | boolean hadContent = false; | 271 | boolean hadContent = false; |
269 | int dataMask = 1; | 272 | int dataMask = 1; |
270 | for(int i = 0; i<FACTOR; i++) { | 273 | for (int i = 0; i < FACTOR; i++) { |
271 | if((dataMask & dataMap) != 0) { | 274 | if ((dataMask & dataMap) != 0) { |
272 | if(hadContent) { | 275 | if (hadContent) { |
273 | builder.append(","); | 276 | builder.append(","); |
274 | } | 277 | } |
275 | builder.append(i); | 278 | builder.append(i); |
276 | builder.append(":["); | 279 | builder.append(":["); |
277 | builder.append(content[2*index(dataMap, dataMask)].toString()); | 280 | builder.append(content[2 * index(dataMap, dataMask)].toString()); |
278 | builder.append("]->["); | 281 | builder.append("]->["); |
279 | builder.append(content[2*index(dataMap, dataMask)+1].toString()); | 282 | builder.append(content[2 * index(dataMap, dataMask) + 1].toString()); |
280 | builder.append("]"); | 283 | builder.append("]"); |
281 | hadContent = true; | 284 | hadContent = true; |
282 | } | 285 | } |
283 | dataMask<<=1; | 286 | dataMask <<= 1; |
284 | } | 287 | } |
285 | builder.append(")"); | 288 | builder.append(")"); |
286 | int nodeMask = 1; | 289 | int nodeMask = 1; |
287 | for(int i = 0; i<FACTOR; i++) { | 290 | for (int i = 0; i < FACTOR; i++) { |
288 | if((nodeMask & nodeMap)!=0) { | 291 | if ((nodeMask & nodeMap) != 0) { |
289 | @SuppressWarnings("unchecked") | 292 | @SuppressWarnings("unchecked") |
290 | Node<K,V> subNode = (Node<K, V>) content[content.length-1-index(nodeMap, nodeMask)]; | 293 | Node<K, V> subNode = (Node<K, V>) content[content.length - 1 - index(nodeMap, nodeMask)]; |
291 | builder.append("\n"); | 294 | builder.append("\n"); |
292 | subNode.prettyPrint(builder, depth+1, i); | 295 | subNode.prettyPrint(builder, depth + 1, i); |
293 | } | 296 | } |
294 | nodeMask<<=1; | 297 | nodeMask <<= 1; |
295 | } | 298 | } |
296 | } | 299 | } |
297 | 300 | ||
298 | @SuppressWarnings("unchecked") | ||
299 | @Override | 301 | @Override |
300 | public void checkIntegrity(ContinousHashProvider<? super K> hashProvider, V defaultValue, int depth) { | 302 | public void checkIntegrity(ContinousHashProvider<? super K> hashProvider, V defaultValue, int depth) { |
301 | if(depth>0) { | 303 | if (depth > 0) { |
302 | boolean orphaned = Integer.bitCount(dataMap) == 1 && nodeMap == 0; | 304 | boolean orphaned = Integer.bitCount(dataMap) == 1 && nodeMap == 0; |
303 | if(orphaned) { | 305 | if (orphaned) { |
304 | throw new IllegalStateException("Orphaned node! " + dataMap + ": " + content[0]); | 306 | throw new IllegalStateException("Orphaned node! " + dataMap + ": " + content[0]); |
305 | } | 307 | } |
306 | } | 308 | } |
307 | // check the place of data | 309 | // check the place of data |
308 | 310 | ||
309 | // check subnodes | 311 | // check subnodes |
310 | for(int i = 0; i<Integer.bitCount(nodeMap); i++) { | 312 | for (int i = 0; i < Integer.bitCount(nodeMap); i++) { |
311 | Node<K,V> subnode = (Node<K, V>) this.content[this.content.length-1-i]; | 313 | @SuppressWarnings("unchecked") |
312 | if(! (subnode instanceof ImmutableNode<?,?>)) { | 314 | var subnode = (Node<K, V>) this.content[this.content.length - 1 - i]; |
315 | if (!(subnode instanceof ImmutableNode<?, ?>)) { | ||
313 | throw new IllegalStateException("Immutable node contains mutable subnodes!"); | 316 | throw new IllegalStateException("Immutable node contains mutable subnodes!"); |
314 | } else { | 317 | } else { |
315 | subnode.checkIntegrity(hashProvider, defaultValue, depth+1); | 318 | subnode.checkIntegrity(hashProvider, defaultValue, depth + 1); |
316 | } | 319 | } |
317 | } | 320 | } |
318 | } | 321 | } |
319 | 322 | ||
320 | @Override | 323 | @Override |
321 | public int hashCode() { | 324 | public int hashCode() { |
322 | return this.precalculatedHash; | 325 | return this.precalculatedHash; |
@@ -328,43 +331,39 @@ public class ImmutableNode<K, V> extends Node<K, V> { | |||
328 | return true; | 331 | return true; |
329 | if (obj == null) | 332 | if (obj == null) |
330 | return false; | 333 | return false; |
331 | if (obj instanceof ImmutableNode<?,?>) { | 334 | if (obj instanceof ImmutableNode<?, ?> other) { |
332 | ImmutableNode<?,?> other = (ImmutableNode<?,?>) obj; | 335 | return precalculatedHash == other.precalculatedHash && dataMap == other.dataMap && nodeMap == other.nodeMap |
333 | if (precalculatedHash != other.precalculatedHash || dataMap != other.dataMap || nodeMap != other.nodeMap || !Arrays.deepEquals(content, other.content)) | 336 | && Arrays.deepEquals(content, other.content); |
334 | return false; | 337 | } else if (obj instanceof MutableNode<?, ?> mutableObj) { |
335 | else return true; | 338 | return ImmutableNode.compareImmutableMutable(this, mutableObj); |
336 | } else if(obj instanceof MutableNode<?,?>) { | ||
337 | return ImmutableNode.compareImmutableMutable(this, (MutableNode<?, ?>) obj); | ||
338 | } else { | 339 | } else { |
339 | return false; | 340 | return false; |
340 | } | 341 | } |
341 | } | 342 | } |
342 | public static boolean compareImmutableMutable( | 343 | |
343 | ImmutableNode<?, ?> immutable, | 344 | public static boolean compareImmutableMutable(ImmutableNode<?, ?> immutable, MutableNode<?, ?> mutable) { |
344 | MutableNode<?, ?> mutable) | ||
345 | { | ||
346 | int datas = 0; | 345 | int datas = 0; |
347 | int nodes = 0; | 346 | int nodes = 0; |
348 | final int immutableLength = immutable.content.length; | 347 | final int immutableLength = immutable.content.length; |
349 | for(int i = 0; i<FACTOR; i++) { | 348 | for (int i = 0; i < FACTOR; i++) { |
350 | Object key = mutable.content[i*2]; | 349 | Object key = mutable.content[i * 2]; |
351 | // For each key candidate | 350 | // For each key candidate |
352 | if(key != null) { | 351 | if (key != null) { |
353 | // Check whether a new Key-Value pair can fit into the immutable container | 352 | // Check whether a new Key-Value pair can fit into the immutable container |
354 | if(datas*2+nodes+2 <= immutableLength) { | 353 | if (datas * 2 + nodes + 2 <= immutableLength) { |
355 | if( !immutable.content[datas*2].equals(key) || | 354 | if (!immutable.content[datas * 2].equals(key) |
356 | !immutable.content[datas*2+1].equals(mutable.content[i*2+1])) | 355 | || !immutable.content[datas * 2 + 1].equals(mutable.content[i * 2 + 1])) { |
357 | { | ||
358 | return false; | 356 | return false; |
359 | } | 357 | } |
360 | } else return false; | 358 | } else |
359 | return false; | ||
361 | datas++; | 360 | datas++; |
362 | } else { | 361 | } else { |
363 | Node<?,?> mutableSubnode = (Node<?, ?>) mutable.content[i*2+1]; | 362 | var mutableSubnode = (Node<?, ?>) mutable.content[i * 2 + 1]; |
364 | if(mutableSubnode != null) { | 363 | if (mutableSubnode != null) { |
365 | if(datas*2+nodes+1 <= immutableLength) { | 364 | if (datas * 2 + nodes + 1 <= immutableLength) { |
366 | Object immutableSubnode = immutable.content[immutableLength-1-nodes]; | 365 | Object immutableSubnode = immutable.content[immutableLength - 1 - nodes]; |
367 | if(!mutableSubnode.equals(immutableSubnode)) { | 366 | if (!mutableSubnode.equals(immutableSubnode)) { |
368 | return false; | 367 | return false; |
369 | } | 368 | } |
370 | nodes++; | 369 | nodes++; |
diff --git a/store/src/main/java/org/eclipse/viatra/solver/data/map/internal/MapDiffCursor.java b/store/src/main/java/org/eclipse/viatra/solver/data/map/internal/MapDiffCursor.java index e97e4aa1..35d20539 100644 --- a/store/src/main/java/org/eclipse/viatra/solver/data/map/internal/MapDiffCursor.java +++ b/store/src/main/java/org/eclipse/viatra/solver/data/map/internal/MapDiffCursor.java | |||
@@ -1,7 +1,6 @@ | |||
1 | package org.eclipse.viatra.solver.data.map.internal; | 1 | package org.eclipse.viatra.solver.data.map.internal; |
2 | 2 | ||
3 | import java.util.List; | 3 | import java.util.List; |
4 | import java.util.stream.Collectors; | ||
5 | import java.util.stream.Stream; | 4 | import java.util.stream.Stream; |
6 | 5 | ||
7 | import org.eclipse.viatra.solver.data.map.ContinousHashProvider; | 6 | import org.eclipse.viatra.solver.data.map.ContinousHashProvider; |
@@ -11,110 +10,109 @@ import org.eclipse.viatra.solver.data.map.VersionedMap; | |||
11 | 10 | ||
12 | /** | 11 | /** |
13 | * A cursor representing the difference between two states of a map. | 12 | * A cursor representing the difference between two states of a map. |
13 | * | ||
14 | * @author Oszkar Semerath | 14 | * @author Oszkar Semerath |
15 | * | 15 | * |
16 | */ | 16 | */ |
17 | public class MapDiffCursor<K,V> implements DiffCursor<K, V>, Cursor<K,V>{ | 17 | public class MapDiffCursor<K, V> implements DiffCursor<K, V>, Cursor<K, V> { |
18 | /** | 18 | /** |
19 | * Default value representing missing elements. | 19 | * Default value representing missing elements. |
20 | */ | 20 | */ |
21 | private V defaultValue; | 21 | private V defaultValue; |
22 | private MapCursor<K,V> cursor1; | 22 | private MapCursor<K, V> cursor1; |
23 | private MapCursor<K,V> cursor2; | 23 | private MapCursor<K, V> cursor2; |
24 | private ContinousHashProvider<? super K> hashProvider; | 24 | private ContinousHashProvider<? super K> hashProvider; |
25 | 25 | ||
26 | // Values | 26 | // Values |
27 | private K key; | 27 | private K key; |
28 | private V fromValue; | 28 | private V fromValue; |
29 | private V toValue; | 29 | private V toValue; |
30 | 30 | ||
31 | // State | 31 | // State |
32 | /** | 32 | /** |
33 | * Positive number if cursor 1 is behind, negative number if cursor 2 is behind, and 0 if they are at the same position. | 33 | * Positive number if cursor 1 is behind, negative number if cursor 2 is behind, |
34 | * and 0 if they are at the same position. | ||
34 | */ | 35 | */ |
35 | private int cursorRelation; | 36 | private int cursorRelation; |
36 | /** | 37 | private HashClash hashClash = HashClash.NONE; |
37 | * Denotes a state when two cursors are in the same position, but they contain different keys. | 38 | |
38 | * Possible values: | 39 | public MapDiffCursor(ContinousHashProvider<? super K> hashProvider, V defaultValue, Cursor<K, V> cursor1, |
39 | * <ul> | 40 | Cursor<K, V> cursor2) { |
40 | * <li>0: not stuck</li> | ||
41 | * <li>1: hashClash, next it should return the key of cursor 1.</li> | ||
42 | * <li>2: hashClash, next it should return the key of cursor 2.</li> | ||
43 | * </ul> | ||
44 | */ | ||
45 | private int hashClash=0; | ||
46 | |||
47 | public MapDiffCursor(ContinousHashProvider<? super K> hashProvider, V defaultValue, Cursor<K, V> cursor1, Cursor<K, V> cursor2) { | ||
48 | super(); | 41 | super(); |
49 | this.hashProvider = hashProvider; | 42 | this.hashProvider = hashProvider; |
50 | this.defaultValue = defaultValue; | 43 | this.defaultValue = defaultValue; |
51 | this.cursor1 = (MapCursor<K, V>) cursor1; | 44 | this.cursor1 = (MapCursor<K, V>) cursor1; |
52 | this.cursor2 = (MapCursor<K, V>) cursor2; | 45 | this.cursor2 = (MapCursor<K, V>) cursor2; |
53 | } | 46 | } |
47 | |||
54 | @Override | 48 | @Override |
55 | public K getKey() { | 49 | public K getKey() { |
56 | return key; | 50 | return key; |
57 | } | 51 | } |
52 | |||
58 | @Override | 53 | @Override |
59 | public V getFromValue() { | 54 | public V getFromValue() { |
60 | return fromValue; | 55 | return fromValue; |
61 | } | 56 | } |
57 | |||
62 | @Override | 58 | @Override |
63 | public V getToValue() { | 59 | public V getToValue() { |
64 | return toValue; | 60 | return toValue; |
65 | } | 61 | } |
62 | |||
66 | @Override | 63 | @Override |
67 | public V getValue() { | 64 | public V getValue() { |
68 | return getToValue(); | 65 | return getToValue(); |
69 | } | 66 | } |
67 | |||
70 | public boolean isTerminated() { | 68 | public boolean isTerminated() { |
71 | return cursor1.isTerminated() && cursor2.isTerminated(); | 69 | return cursor1.isTerminated() && cursor2.isTerminated(); |
72 | } | 70 | } |
71 | |||
73 | @Override | 72 | @Override |
74 | public boolean isDirty() { | 73 | public boolean isDirty() { |
75 | return this.cursor1.isDirty() || this.cursor2.isDirty(); | 74 | return this.cursor1.isDirty() || this.cursor2.isDirty(); |
76 | } | 75 | } |
76 | |||
77 | @Override | 77 | @Override |
78 | public List<VersionedMap<?, ?>> getDependingMaps() { | 78 | public List<VersionedMap<?, ?>> getDependingMaps() { |
79 | return Stream.concat( | 79 | return Stream.concat(cursor1.getDependingMaps().stream(), cursor2.getDependingMaps().stream()).toList(); |
80 | cursor1.getDependingMaps().stream(), | ||
81 | cursor2.getDependingMaps().stream() | ||
82 | ).collect(Collectors.toList()); | ||
83 | } | 80 | } |
84 | 81 | ||
85 | protected void updateState() { | 82 | protected void updateState() { |
86 | if(!isTerminated()) { | 83 | if (!isTerminated()) { |
87 | this.cursorRelation = MapCursor.compare(cursor1, cursor2); | 84 | this.cursorRelation = MapCursor.compare(cursor1, cursor2); |
88 | if(cursorRelation > 0 || cursor2.isTerminated()) { | 85 | if (cursorRelation > 0 || cursor2.isTerminated()) { |
89 | this.key = cursor1.getKey(); | 86 | this.key = cursor1.getKey(); |
90 | this.fromValue = cursor1.getValue(); | 87 | this.fromValue = cursor1.getValue(); |
91 | this.toValue = defaultValue; | 88 | this.toValue = defaultValue; |
92 | } else if(cursorRelation < 0 || cursor1.isTerminated()){ | 89 | } else if (cursorRelation < 0 || cursor1.isTerminated()) { |
93 | this.key = cursor2.getKey(); | 90 | this.key = cursor2.getKey(); |
94 | this.fromValue = defaultValue; | 91 | this.fromValue = defaultValue; |
95 | this.toValue = cursor1.getValue(); | 92 | this.toValue = cursor1.getValue(); |
96 | } else { | 93 | } else { |
97 | // cursor1 = cursor2 | 94 | // cursor1 = cursor2 |
98 | if(cursor1.getKey().equals(cursor2.getKey())) { | 95 | if (cursor1.getKey().equals(cursor2.getKey())) { |
99 | this.key = cursor1.getKey(); | 96 | this.key = cursor1.getKey(); |
100 | this.fromValue = cursor1.getValue(); | 97 | this.fromValue = cursor1.getValue(); |
101 | this.toValue = defaultValue; | 98 | this.toValue = defaultValue; |
102 | } else { | 99 | } else { |
103 | resolveHashClash1(); | 100 | resolveHashClashWithFirstEntry(); |
104 | } | 101 | } |
105 | } | 102 | } |
106 | } | 103 | } |
107 | } | 104 | } |
108 | protected void resolveHashClash1() { | 105 | |
106 | protected void resolveHashClashWithFirstEntry() { | ||
109 | int compareResult = this.hashProvider.compare(cursor1.key, cursor2.key); | 107 | int compareResult = this.hashProvider.compare(cursor1.key, cursor2.key); |
110 | if(compareResult<0) { | 108 | if (compareResult < 0) { |
111 | this.hashClash = 2; | 109 | this.hashClash = HashClash.STUCK_CURSOR_2; |
112 | this.cursorRelation = 0; | 110 | this.cursorRelation = 0; |
113 | this.key = cursor1.key; | 111 | this.key = cursor1.key; |
114 | this.fromValue = cursor1.value; | 112 | this.fromValue = cursor1.value; |
115 | this.toValue = defaultValue; | 113 | this.toValue = defaultValue; |
116 | } else if(compareResult>0) { | 114 | } else if (compareResult > 0) { |
117 | this.hashClash = 1; | 115 | this.hashClash = HashClash.STUCK_CURSOR_1; |
118 | this.cursorRelation = 0; | 116 | this.cursorRelation = 0; |
119 | this.key = cursor2.key; | 117 | this.key = cursor2.key; |
120 | this.fromValue = defaultValue; | 118 | this.fromValue = defaultValue; |
@@ -123,40 +121,47 @@ public class MapDiffCursor<K,V> implements DiffCursor<K, V>, Cursor<K,V>{ | |||
123 | throw new IllegalArgumentException("Inconsistent compare result for diffcursor"); | 121 | throw new IllegalArgumentException("Inconsistent compare result for diffcursor"); |
124 | } | 122 | } |
125 | } | 123 | } |
124 | |||
126 | protected boolean isInHashClash() { | 125 | protected boolean isInHashClash() { |
127 | return this.hashClash != 0; | 126 | return this.hashClash != HashClash.NONE; |
128 | } | 127 | } |
129 | protected void resolveHashClash2() { | 128 | |
130 | if(hashClash == 1) { | 129 | protected void resolveHashClashWithSecondEntry() { |
131 | this.hashClash = 0; | 130 | switch (this.hashClash) { |
131 | case STUCK_CURSOR_1: | ||
132 | this.hashClash = HashClash.NONE; | ||
132 | this.cursorRelation = 0; | 133 | this.cursorRelation = 0; |
133 | this.key = cursor1.key; | 134 | this.key = cursor1.key; |
134 | this.fromValue = cursor1.value; | 135 | this.fromValue = cursor1.value; |
135 | this.toValue = defaultValue; | 136 | this.toValue = defaultValue; |
136 | } else if(hashClash == 2) { | 137 | break; |
137 | this.hashClash = 0; | 138 | case STUCK_CURSOR_2: |
139 | this.hashClash = HashClash.NONE; | ||
138 | this.cursorRelation = 0; | 140 | this.cursorRelation = 0; |
139 | this.key = cursor2.key; | 141 | this.key = cursor2.key; |
140 | this.fromValue = defaultValue; | 142 | this.fromValue = defaultValue; |
141 | this.toValue = cursor2.value; | 143 | this.toValue = cursor2.value; |
142 | } else throw new IllegalArgumentException("Inconsistent compare result for diffcursor"); | 144 | break; |
145 | default: | ||
146 | throw new IllegalArgumentException("Inconsistent compare result for diffcursor"); | ||
147 | } | ||
143 | } | 148 | } |
144 | 149 | ||
145 | |||
146 | protected boolean sameValues() { | 150 | protected boolean sameValues() { |
147 | if(this.fromValue == null) { | 151 | if (this.fromValue == null) { |
148 | return this.toValue == null; | 152 | return this.toValue == null; |
149 | } else { | 153 | } else { |
150 | return this.fromValue.equals(this.toValue); | 154 | return this.fromValue.equals(this.toValue); |
151 | } | 155 | } |
152 | } | 156 | } |
157 | |||
153 | protected boolean moveOne() { | 158 | protected boolean moveOne() { |
154 | if(isTerminated()) { | 159 | if (isTerminated()) { |
155 | return false; | 160 | return false; |
156 | } | 161 | } |
157 | if(this.cursorRelation > 0 || cursor2.isTerminated()) { | 162 | if (this.cursorRelation > 0 || cursor2.isTerminated()) { |
158 | return cursor1.move(); | 163 | return cursor1.move(); |
159 | } else if(this.cursorRelation < 0 || cursor1.isTerminated()) { | 164 | } else if (this.cursorRelation < 0 || cursor1.isTerminated()) { |
160 | return cursor2.move(); | 165 | return cursor2.move(); |
161 | } else { | 166 | } else { |
162 | boolean moved1 = cursor1.move(); | 167 | boolean moved1 = cursor1.move(); |
@@ -164,8 +169,9 @@ public class MapDiffCursor<K,V> implements DiffCursor<K, V>, Cursor<K,V>{ | |||
164 | return moved1 && moved2; | 169 | return moved1 && moved2; |
165 | } | 170 | } |
166 | } | 171 | } |
172 | |||
167 | private boolean skipNode() { | 173 | private boolean skipNode() { |
168 | if(isTerminated()) { | 174 | if (isTerminated()) { |
169 | throw new IllegalStateException("DiffCursor tries to skip when terminated!"); | 175 | throw new IllegalStateException("DiffCursor tries to skip when terminated!"); |
170 | } | 176 | } |
171 | boolean update1 = cursor1.skipCurrentNode(); | 177 | boolean update1 = cursor1.skipCurrentNode(); |
@@ -173,42 +179,43 @@ public class MapDiffCursor<K,V> implements DiffCursor<K, V>, Cursor<K,V>{ | |||
173 | updateState(); | 179 | updateState(); |
174 | return update1 && update2; | 180 | return update1 && update2; |
175 | } | 181 | } |
176 | 182 | ||
177 | protected boolean moveToConsistentState() { | 183 | protected boolean moveToConsistentState() { |
178 | if(!isTerminated()) { | 184 | if (!isTerminated()) { |
179 | boolean changed; | 185 | boolean changed; |
180 | boolean lastResult = true; | 186 | boolean lastResult = true; |
181 | do { | 187 | do { |
182 | changed = false; | 188 | changed = false; |
183 | if(MapCursor.sameSubnode(cursor1, cursor2)) { | 189 | if (MapCursor.sameSubnode(cursor1, cursor2)) { |
184 | lastResult = skipNode(); | 190 | lastResult = skipNode(); |
185 | changed = true; | 191 | changed = true; |
186 | } | 192 | } |
187 | if(sameValues()) { | 193 | if (sameValues()) { |
188 | lastResult = moveOne(); | 194 | lastResult = moveOne(); |
189 | changed = true; | 195 | changed = true; |
190 | } | 196 | } |
191 | updateState(); | 197 | updateState(); |
192 | } while(changed && !isTerminated()); | 198 | } while (changed && !isTerminated()); |
193 | return lastResult; | 199 | return lastResult; |
194 | } else { | 200 | } else { |
195 | return false; | 201 | return false; |
196 | } | 202 | } |
197 | } | 203 | } |
198 | 204 | ||
199 | public boolean move() { | 205 | public boolean move() { |
200 | if(!isTerminated()) { | 206 | if (!isTerminated()) { |
201 | if(isInHashClash()) { | 207 | if (isInHashClash()) { |
202 | this.resolveHashClash2(); | 208 | this.resolveHashClashWithSecondEntry(); |
203 | return true; | 209 | return true; |
204 | } else { | 210 | } else { |
205 | if(moveOne()) { | 211 | if (moveOne()) { |
206 | return moveToConsistentState(); | 212 | return moveToConsistentState(); |
207 | } else { | 213 | } else { |
208 | return false; | 214 | return false; |
209 | } | 215 | } |
210 | } | 216 | } |
211 | 217 | ||
212 | } else return false; | 218 | } else |
219 | return false; | ||
213 | } | 220 | } |
214 | } | 221 | } |
diff --git a/store/src/main/java/org/eclipse/viatra/solver/data/map/internal/MutableNode.java b/store/src/main/java/org/eclipse/viatra/solver/data/map/internal/MutableNode.java index 9e63b941..b5fee673 100644 --- a/store/src/main/java/org/eclipse/viatra/solver/data/map/internal/MutableNode.java +++ b/store/src/main/java/org/eclipse/viatra/solver/data/map/internal/MutableNode.java | |||
@@ -52,19 +52,22 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
52 | this.cachedHash = node.hashCode(); | 52 | this.cachedHash = node.hashCode(); |
53 | } | 53 | } |
54 | 54 | ||
55 | @SuppressWarnings("unchecked") | ||
56 | @Override | 55 | @Override |
57 | public V getValue(K key, ContinousHashProvider<? super K> hashProvider, V defaultValue, int hash, int depth) { | 56 | public V getValue(K key, ContinousHashProvider<? super K> hashProvider, V defaultValue, int hash, int depth) { |
58 | int selectedHashFragment = hashFragment(hash, shiftDepth(depth)); | 57 | int selectedHashFragment = hashFragment(hash, shiftDepth(depth)); |
58 | @SuppressWarnings("unchecked") | ||
59 | K keyCandidate = (K) this.content[2 * selectedHashFragment]; | 59 | K keyCandidate = (K) this.content[2 * selectedHashFragment]; |
60 | if (keyCandidate != null) { | 60 | if (keyCandidate != null) { |
61 | if (keyCandidate.equals(key)) { | 61 | if (keyCandidate.equals(key)) { |
62 | return (V) this.content[2 * selectedHashFragment + 1]; | 62 | @SuppressWarnings("unchecked") |
63 | V value = (V) this.content[2 * selectedHashFragment + 1]; | ||
64 | return value; | ||
63 | } else { | 65 | } else { |
64 | return defaultValue; | 66 | return defaultValue; |
65 | } | 67 | } |
66 | } else { | 68 | } else { |
67 | Node<K, V> nodeCandidate = (Node<K, V>) content[2 * selectedHashFragment + 1]; | 69 | @SuppressWarnings("unchecked") |
70 | var nodeCandidate = (Node<K, V>) content[2 * selectedHashFragment + 1]; | ||
68 | if (nodeCandidate != null) { | 71 | if (nodeCandidate != null) { |
69 | int newDepth = depth + 1; | 72 | int newDepth = depth + 1; |
70 | int newHash = newHash(hashProvider, key, hash, newDepth); | 73 | int newHash = newHash(hashProvider, key, hash, newDepth); |
@@ -75,11 +78,11 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
75 | } | 78 | } |
76 | } | 79 | } |
77 | 80 | ||
78 | @SuppressWarnings("unchecked") | ||
79 | @Override | 81 | @Override |
80 | public Node<K, V> putValue(K key, V value, OldValueBox<V> oldValue, ContinousHashProvider<? super K> hashProvider, V defaultValue, int hash, | 82 | public Node<K, V> putValue(K key, V value, OldValueBox<V> oldValue, ContinousHashProvider<? super K> hashProvider, |
81 | int depth) { | 83 | V defaultValue, int hash, int depth) { |
82 | int selectedHashFragment = hashFragment(hash, shiftDepth(depth)); | 84 | int selectedHashFragment = hashFragment(hash, shiftDepth(depth)); |
85 | @SuppressWarnings("unchecked") | ||
83 | K keyCandidate = (K) content[2 * selectedHashFragment]; | 86 | K keyCandidate = (K) content[2 * selectedHashFragment]; |
84 | if (keyCandidate != null) { | 87 | if (keyCandidate != null) { |
85 | // If has key | 88 | // If has key |
@@ -105,10 +108,11 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
105 | } | 108 | } |
106 | } else { | 109 | } else { |
107 | // If it does not have key, check for value | 110 | // If it does not have key, check for value |
108 | Node<K, V> nodeCandidate = (Node<K, V>) content[2 * selectedHashFragment + 1]; | 111 | @SuppressWarnings("unchecked") |
112 | var nodeCandidate = (Node<K, V>) content[2 * selectedHashFragment + 1]; | ||
109 | if (nodeCandidate != null) { | 113 | if (nodeCandidate != null) { |
110 | // If it has value, it is a subnode -> upate that | 114 | // If it has value, it is a subnode -> upate that |
111 | Node<K, V> newNode = nodeCandidate.putValue(key, value, oldValue, hashProvider, defaultValue, | 115 | var newNode = nodeCandidate.putValue(key, value, oldValue, hashProvider, defaultValue, |
112 | newHash(hashProvider, key, hash, depth + 1), depth + 1); | 116 | newHash(hashProvider, key, hash, depth + 1), depth + 1); |
113 | return updateWithSubNode(selectedHashFragment, newNode, value.equals(defaultValue)); | 117 | return updateWithSubNode(selectedHashFragment, newNode, value.equals(defaultValue)); |
114 | } else { | 118 | } else { |
@@ -125,10 +129,11 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
125 | } | 129 | } |
126 | } | 130 | } |
127 | 131 | ||
128 | @SuppressWarnings("unchecked") | 132 | private Node<K, V> addEntry(K key, V value, OldValueBox<V> oldValueBox, int selectedHashFragment) { |
129 | private Node<K, V> addEntry(K key, V value, OldValueBox<V> oldValue, int selectedHashFragment) { | ||
130 | content[2 * selectedHashFragment] = key; | 133 | content[2 * selectedHashFragment] = key; |
131 | oldValue.setOldValue((V) content[2 * selectedHashFragment + 1]); | 134 | @SuppressWarnings("unchecked") |
135 | V oldValue = (V) content[2 * selectedHashFragment + 1]; | ||
136 | oldValueBox.setOldValue(oldValue); | ||
132 | content[2 * selectedHashFragment + 1] = value; | 137 | content[2 * selectedHashFragment + 1] = value; |
133 | updateHash(); | 138 | updateHash(); |
134 | return this; | 139 | return this; |
@@ -231,6 +236,8 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
231 | return this; | 236 | return this; |
232 | } | 237 | } |
233 | 238 | ||
239 | // Pass everything as parameters for performance. | ||
240 | @SuppressWarnings("squid:S107") | ||
234 | private MutableNode<K, V> newNodeWithTwoEntries(ContinousHashProvider<? super K> hashProvider, K key1, V value1, | 241 | private MutableNode<K, V> newNodeWithTwoEntries(ContinousHashProvider<? super K> hashProvider, K key1, V value1, |
235 | int oldHash1, K key2, V value2, int oldHash2, int newdepth) { | 242 | int oldHash1, K key2, V value2, int oldHash2, int newdepth) { |
236 | int newHash1 = newHash(hashProvider, key1, oldHash1, newdepth); | 243 | int newHash1 = newHash(hashProvider, key1, oldHash1, newdepth); |
@@ -377,7 +384,6 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
377 | } | 384 | } |
378 | } | 385 | } |
379 | 386 | ||
380 | @SuppressWarnings({ "unchecked" }) | ||
381 | @Override | 387 | @Override |
382 | public void checkIntegrity(ContinousHashProvider<? super K> hashProvider, V defaultValue, int depth) { | 388 | public void checkIntegrity(ContinousHashProvider<? super K> hashProvider, V defaultValue, int depth) { |
383 | // check for orphan nodes | 389 | // check for orphan nodes |
@@ -390,7 +396,9 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
390 | // check the place of data | 396 | // check the place of data |
391 | for (int i = 0; i < FACTOR; i++) { | 397 | for (int i = 0; i < FACTOR; i++) { |
392 | if (this.content[2 * i] != null) { | 398 | if (this.content[2 * i] != null) { |
399 | @SuppressWarnings("unchecked") | ||
393 | K key = (K) this.content[2 * i]; | 400 | K key = (K) this.content[2 * i]; |
401 | @SuppressWarnings("unchecked") | ||
394 | V value = (V) this.content[2 * i + 1]; | 402 | V value = (V) this.content[2 * i + 1]; |
395 | 403 | ||
396 | if (value == defaultValue) { | 404 | if (value == defaultValue) { |
@@ -408,7 +416,8 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
408 | // check subnodes | 416 | // check subnodes |
409 | for (int i = 0; i < FACTOR; i++) { | 417 | for (int i = 0; i < FACTOR; i++) { |
410 | if (this.content[2 * i + 1] != null && this.content[2 * i] == null) { | 418 | if (this.content[2 * i + 1] != null && this.content[2 * i] == null) { |
411 | Node<K, V> subNode = (Node<K, V>) this.content[2 * i + 1]; | 419 | @SuppressWarnings("unchecked") |
420 | var subNode = (Node<K, V>) this.content[2 * i + 1]; | ||
412 | subNode.checkIntegrity(hashProvider, defaultValue, depth + 1); | 421 | subNode.checkIntegrity(hashProvider, defaultValue, depth + 1); |
413 | } | 422 | } |
414 | } | 423 | } |
@@ -436,12 +445,10 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
436 | return true; | 445 | return true; |
437 | if (obj == null) | 446 | if (obj == null) |
438 | return false; | 447 | return false; |
439 | if (obj instanceof MutableNode<?, ?>) { | 448 | if (obj instanceof MutableNode<?, ?> mutableObj) { |
440 | MutableNode<?, ?> other = (MutableNode<?, ?>) obj; | 449 | return Arrays.deepEquals(this.content, mutableObj.content); |
441 | return Arrays.deepEquals(this.content, other.content); | 450 | } else if (obj instanceof ImmutableNode<?, ?> immutableObj) { |
442 | } else if (obj instanceof ImmutableNode<?, ?>) { | 451 | return ImmutableNode.compareImmutableMutable(immutableObj, this); |
443 | ImmutableNode<?, ?> other = (ImmutableNode<?, ?>) obj; | ||
444 | return ImmutableNode.compareImmutableMutable(other, this); | ||
445 | } else { | 452 | } else { |
446 | return false; | 453 | return false; |
447 | } | 454 | } |
diff --git a/store/src/main/java/org/eclipse/viatra/solver/data/model/ModelStoreImpl.java b/store/src/main/java/org/eclipse/viatra/solver/data/model/ModelStoreImpl.java index f5e3b141..a97fb27a 100644 --- a/store/src/main/java/org/eclipse/viatra/solver/data/model/ModelStoreImpl.java +++ b/store/src/main/java/org/eclipse/viatra/solver/data/model/ModelStoreImpl.java | |||
@@ -1,7 +1,6 @@ | |||
1 | package org.eclipse.viatra.solver.data.model; | 1 | package org.eclipse.viatra.solver.data.model; |
2 | 2 | ||
3 | import java.util.HashMap; | 3 | import java.util.HashMap; |
4 | import java.util.HashSet; | ||
5 | import java.util.LinkedList; | 4 | import java.util.LinkedList; |
6 | import java.util.List; | 5 | import java.util.List; |
7 | import java.util.Map; | 6 | import java.util.Map; |
@@ -34,8 +33,7 @@ public class ModelStoreImpl implements ModelStore { | |||
34 | Map<SimilarRelationEquivalenceClass, List<Relation<?>>> symbolRepresentationsPerHashPerArity = new HashMap<>(); | 33 | Map<SimilarRelationEquivalenceClass, List<Relation<?>>> symbolRepresentationsPerHashPerArity = new HashMap<>(); |
35 | 34 | ||
36 | for (DataRepresentation<?, ?> dataRepresentation : dataRepresentations) { | 35 | for (DataRepresentation<?, ?> dataRepresentation : dataRepresentations) { |
37 | if (dataRepresentation instanceof Relation<?>) { | 36 | if (dataRepresentation instanceof Relation<?> symbolRepresentation) { |
38 | Relation<?> symbolRepresentation = (Relation<?>) dataRepresentation; | ||
39 | addOrCreate(symbolRepresentationsPerHashPerArity, | 37 | addOrCreate(symbolRepresentationsPerHashPerArity, |
40 | new SimilarRelationEquivalenceClass(symbolRepresentation), symbolRepresentation); | 38 | new SimilarRelationEquivalenceClass(symbolRepresentation), symbolRepresentation); |
41 | } else if (dataRepresentation instanceof AuxilaryData<?, ?>) { | 39 | } else if (dataRepresentation instanceof AuxilaryData<?, ?>) { |
@@ -58,10 +56,10 @@ public class ModelStoreImpl implements ModelStore { | |||
58 | List<Relation<?>> symbolGroup) { | 56 | List<Relation<?>> symbolGroup) { |
59 | final ContinousHashProvider<Tuple> hashProvider = symbolGroup.get(0).getHashProvider(); | 57 | final ContinousHashProvider<Tuple> hashProvider = symbolGroup.get(0).getHashProvider(); |
60 | final Object defaultValue = symbolGroup.get(0).getDefaultValue(); | 58 | final Object defaultValue = symbolGroup.get(0).getDefaultValue(); |
61 | 59 | ||
62 | List<VersionedMapStore<Tuple, Object>> maps = VersionedMapStoreImpl | 60 | List<VersionedMapStore<Tuple, Object>> maps = VersionedMapStoreImpl |
63 | .createSharedVersionedMapStores(symbolGroup.size(), hashProvider, defaultValue); | 61 | .createSharedVersionedMapStores(symbolGroup.size(), hashProvider, defaultValue); |
64 | 62 | ||
65 | for (int i = 0; i < symbolGroup.size(); i++) { | 63 | for (int i = 0; i < symbolGroup.size(); i++) { |
66 | result.put(symbolGroup.get(i), maps.get(i)); | 64 | result.put(symbolGroup.get(i), maps.get(i)); |
67 | } | 65 | } |
@@ -100,24 +98,20 @@ public class ModelStoreImpl implements ModelStore { | |||
100 | } | 98 | } |
101 | return new ModelImpl(this, maps); | 99 | return new ModelImpl(this, maps); |
102 | } | 100 | } |
103 | 101 | ||
104 | @Override | 102 | @Override |
105 | @SuppressWarnings("squid:S1751") | ||
106 | public synchronized Set<Long> getStates() { | 103 | public synchronized Set<Long> getStates() { |
107 | // if not empty, return first | 104 | var iterator = stores.values().iterator(); |
108 | for(VersionedMapStore<?, ?> store : stores.values()) { | 105 | if (iterator.hasNext()) { |
109 | return new HashSet<>(store.getStates()); | 106 | return Set.copyOf(iterator.next().getStates()); |
110 | } | 107 | } |
111 | // if empty | 108 | return Set.of(0l); |
112 | Set<Long> result = new HashSet<>(); | ||
113 | result.add(0l); | ||
114 | return result; | ||
115 | } | 109 | } |
116 | 110 | ||
117 | @Override | 111 | @Override |
118 | public synchronized ModelDiffCursor getDiffCursor(long from, long to) { | 112 | public synchronized ModelDiffCursor getDiffCursor(long from, long to) { |
119 | Map<DataRepresentation<?, ?>,DiffCursor<?,?>> diffcursors = new HashMap<>(); | 113 | Map<DataRepresentation<?, ?>, DiffCursor<?, ?>> diffcursors = new HashMap<>(); |
120 | for(Entry<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> entry : stores.entrySet()) { | 114 | for (Entry<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> entry : stores.entrySet()) { |
121 | DataRepresentation<?, ?> representation = entry.getKey(); | 115 | DataRepresentation<?, ?> representation = entry.getKey(); |
122 | DiffCursor<?, ?> diffCursor = entry.getValue().getDiffCursor(from, to); | 116 | DiffCursor<?, ?> diffCursor = entry.getValue().getDiffCursor(from, to); |
123 | diffcursors.put(representation, diffCursor); | 117 | diffcursors.put(representation, diffCursor); |
diff --git a/store/src/main/java/org/eclipse/viatra/solver/data/model/representation/TruthValue.java b/store/src/main/java/org/eclipse/viatra/solver/data/model/representation/TruthValue.java index aeccde9e..049c7eac 100644 --- a/store/src/main/java/org/eclipse/viatra/solver/data/model/representation/TruthValue.java +++ b/store/src/main/java/org/eclipse/viatra/solver/data/model/representation/TruthValue.java | |||
@@ -1,42 +1,49 @@ | |||
1 | package org.eclipse.viatra.solver.data.model.representation; | 1 | package org.eclipse.viatra.solver.data.model.representation; |
2 | 2 | ||
3 | public class TruthValue { | 3 | public enum TruthValue { |
4 | public static final TruthValue True = new TruthValue("true"); | 4 | TRUE("true"), |
5 | public static final TruthValue False = new TruthValue("false"); | 5 | |
6 | public static final TruthValue Unknown = new TruthValue("unknown"); | 6 | FALSE("false"), |
7 | public static final TruthValue Error = new TruthValue("error"); | 7 | |
8 | 8 | UNKNOWN("unknown"), | |
9 | |||
10 | ERROR("error"); | ||
11 | |||
9 | private final String name; | 12 | private final String name; |
10 | protected TruthValue(String name) { | 13 | |
14 | private TruthValue(String name) { | ||
11 | this.name = name; | 15 | this.name = name; |
12 | } | 16 | } |
13 | 17 | ||
14 | public String getName() { | 18 | public String getName() { |
15 | return name; | 19 | return name; |
16 | } | 20 | } |
17 | 21 | ||
18 | public static TruthValue toTruthValue(boolean value) { | 22 | public static TruthValue toTruthValue(boolean value) { |
19 | if(value) return True; | 23 | return value ? TRUE : FALSE; |
20 | else return False; | ||
21 | } | 24 | } |
25 | |||
22 | public boolean isConsistent() { | 26 | public boolean isConsistent() { |
23 | return this != Error; | 27 | return this != ERROR; |
24 | } | 28 | } |
29 | |||
25 | public boolean isComplete() { | 30 | public boolean isComplete() { |
26 | return this != Unknown; | 31 | return this != UNKNOWN; |
27 | } | 32 | } |
33 | |||
28 | public boolean must() { | 34 | public boolean must() { |
29 | return this == True || this == Error; | 35 | return this == TRUE || this == ERROR; |
30 | } | 36 | } |
37 | |||
31 | public boolean may() { | 38 | public boolean may() { |
32 | return this == True || this == Unknown; | 39 | return this == TRUE || this == UNKNOWN; |
33 | } | 40 | } |
34 | 41 | ||
35 | public TruthValue not() { | 42 | public TruthValue not() { |
36 | if(this == True) { | 43 | if (this == TRUE) { |
37 | return False; | 44 | return FALSE; |
38 | } else if(this == False) { | 45 | } else if (this == FALSE) { |
39 | return True; | 46 | return TRUE; |
40 | } else { | 47 | } else { |
41 | return this; | 48 | return this; |
42 | } | 49 | } |
diff --git a/store/src/main/java/org/eclipse/viatra/solver/data/query/building/PredicateAtom.java b/store/src/main/java/org/eclipse/viatra/solver/data/query/building/PredicateAtom.java index 3e5ef88e..439298d0 100644 --- a/store/src/main/java/org/eclipse/viatra/solver/data/query/building/PredicateAtom.java +++ b/store/src/main/java/org/eclipse/viatra/solver/data/query/building/PredicateAtom.java | |||
@@ -4,52 +4,61 @@ import java.util.List; | |||
4 | import java.util.Map; | 4 | import java.util.Map; |
5 | import java.util.Set; | 5 | import java.util.Set; |
6 | 6 | ||
7 | public class PredicateAtom implements DNFAtom{ | 7 | public class PredicateAtom implements DNFAtom { |
8 | private DNFPredicate referred; | 8 | private DNFPredicate referred; |
9 | private List<Variable> substitution; | 9 | private List<Variable> substitution; |
10 | private boolean positive; | 10 | private boolean positive; |
11 | private boolean transitive; | 11 | private boolean transitive; |
12 | 12 | ||
13 | public PredicateAtom(boolean positive, boolean transitive, DNFPredicate referred, List<Variable> substitution) { | 13 | public PredicateAtom(boolean positive, boolean transitive, DNFPredicate referred, List<Variable> substitution) { |
14 | this.positive = positive; | 14 | this.positive = positive; |
15 | this.referred = referred; | 15 | this.referred = referred; |
16 | this.substitution = substitution; | 16 | this.substitution = substitution; |
17 | this.transitive = transitive; | 17 | this.transitive = transitive; |
18 | } | 18 | } |
19 | |||
19 | public DNFPredicate getReferred() { | 20 | public DNFPredicate getReferred() { |
20 | return referred; | 21 | return referred; |
21 | } | 22 | } |
23 | |||
22 | public void setReferred(DNFPredicate referred) { | 24 | public void setReferred(DNFPredicate referred) { |
23 | this.referred = referred; | 25 | this.referred = referred; |
24 | } | 26 | } |
27 | |||
25 | public List<Variable> getSubstitution() { | 28 | public List<Variable> getSubstitution() { |
26 | return substitution; | 29 | return substitution; |
27 | } | 30 | } |
31 | |||
28 | public void setSubstitution(List<Variable> substitution) { | 32 | public void setSubstitution(List<Variable> substitution) { |
29 | this.substitution = substitution; | 33 | this.substitution = substitution; |
30 | } | 34 | } |
35 | |||
31 | public boolean isPositive() { | 36 | public boolean isPositive() { |
32 | return positive; | 37 | return positive; |
33 | } | 38 | } |
39 | |||
34 | public void setPositive(boolean positive) { | 40 | public void setPositive(boolean positive) { |
35 | this.positive = positive; | 41 | this.positive = positive; |
36 | } | 42 | } |
43 | |||
37 | public boolean isTransitive() { | 44 | public boolean isTransitive() { |
38 | return transitive; | 45 | return transitive; |
39 | } | 46 | } |
47 | |||
40 | public void setTransitive(boolean transitive) { | 48 | public void setTransitive(boolean transitive) { |
41 | this.transitive = transitive; | 49 | this.transitive = transitive; |
42 | } | 50 | } |
51 | |||
43 | @Override | 52 | @Override |
44 | public void unifyVariables(Map<String, Variable> variables) { | 53 | public void unifyVariables(Map<String, Variable> variables) { |
45 | for(int i = 0; i<this.substitution.size(); i++) { | 54 | for (int i = 0; i < this.substitution.size(); i++) { |
46 | final Object term = this.substitution.get(i); | 55 | final Object term = this.substitution.get(i); |
47 | if(term instanceof Variable) { | 56 | if (term instanceof Variable variableReference) { |
48 | Variable variableReference = (Variable) term; | ||
49 | this.substitution.set(i, DNFAtom.unifyVariables(variables, variableReference)); | 57 | this.substitution.set(i, DNFAtom.unifyVariables(variables, variableReference)); |
50 | } | 58 | } |
51 | } | 59 | } |
52 | } | 60 | } |
61 | |||
53 | @Override | 62 | @Override |
54 | public void collectAllVariables(Set<Variable> variables) { | 63 | public void collectAllVariables(Set<Variable> variables) { |
55 | DNFAtom.addToCollection(variables, substitution); | 64 | DNFAtom.addToCollection(variables, substitution); |
diff --git a/store/src/main/java/org/eclipse/viatra/solver/data/query/building/RelationAtom.java b/store/src/main/java/org/eclipse/viatra/solver/data/query/building/RelationAtom.java index f7152bba..adf2f8c7 100644 --- a/store/src/main/java/org/eclipse/viatra/solver/data/query/building/RelationAtom.java +++ b/store/src/main/java/org/eclipse/viatra/solver/data/query/building/RelationAtom.java | |||
@@ -7,37 +7,41 @@ import java.util.Set; | |||
7 | import org.eclipse.viatra.solver.data.query.view.FilteredRelationView; | 7 | import org.eclipse.viatra.solver.data.query.view.FilteredRelationView; |
8 | import org.eclipse.viatra.solver.data.query.view.RelationView; | 8 | import org.eclipse.viatra.solver.data.query.view.RelationView; |
9 | 9 | ||
10 | public class RelationAtom implements DNFAtom{ | 10 | public class RelationAtom implements DNFAtom { |
11 | RelationView<?> view; | 11 | RelationView<?> view; |
12 | List<Variable> substitution; | 12 | List<Variable> substitution; |
13 | 13 | ||
14 | public RelationAtom(RelationView<?> view, List<Variable> substitution) { | 14 | public RelationAtom(RelationView<?> view, List<Variable> substitution) { |
15 | this.view = view; | 15 | this.view = view; |
16 | this.substitution = substitution; | 16 | this.substitution = substitution; |
17 | } | 17 | } |
18 | |||
18 | public RelationView<?> getView() { | 19 | public RelationView<?> getView() { |
19 | return view; | 20 | return view; |
20 | } | 21 | } |
22 | |||
21 | public void setView(FilteredRelationView<?> view) { | 23 | public void setView(FilteredRelationView<?> view) { |
22 | this.view = view; | 24 | this.view = view; |
23 | } | 25 | } |
26 | |||
24 | public List<Variable> getSubstitution() { | 27 | public List<Variable> getSubstitution() { |
25 | return substitution; | 28 | return substitution; |
26 | } | 29 | } |
30 | |||
27 | public void setSubstitution(List<Variable> substitution) { | 31 | public void setSubstitution(List<Variable> substitution) { |
28 | this.substitution = substitution; | 32 | this.substitution = substitution; |
29 | } | 33 | } |
30 | 34 | ||
31 | @Override | 35 | @Override |
32 | public void unifyVariables(Map<String, Variable> variables) { | 36 | public void unifyVariables(Map<String, Variable> variables) { |
33 | for(int i = 0; i<this.substitution.size(); i++) { | 37 | for (int i = 0; i < this.substitution.size(); i++) { |
34 | final Object term = this.substitution.get(i); | 38 | final Object term = this.substitution.get(i); |
35 | if(term instanceof Variable) { | 39 | if (term instanceof Variable variableReference) { |
36 | Variable variableReference = (Variable) term; | ||
37 | this.substitution.set(i, DNFAtom.unifyVariables(variables, variableReference)); | 40 | this.substitution.set(i, DNFAtom.unifyVariables(variables, variableReference)); |
38 | } | 41 | } |
39 | } | 42 | } |
40 | } | 43 | } |
44 | |||
41 | @Override | 45 | @Override |
42 | public void collectAllVariables(Set<Variable> variables) { | 46 | public void collectAllVariables(Set<Variable> variables) { |
43 | DNFAtom.addToCollection(variables, substitution); | 47 | DNFAtom.addToCollection(variables, substitution); |
diff --git a/store/src/main/java/org/eclipse/viatra/solver/data/query/internal/RelationalRuntimeContext.java b/store/src/main/java/org/eclipse/viatra/solver/data/query/internal/RelationalRuntimeContext.java index 7d1682b2..fa6a59ab 100644 --- a/store/src/main/java/org/eclipse/viatra/solver/data/query/internal/RelationalRuntimeContext.java +++ b/store/src/main/java/org/eclipse/viatra/solver/data/query/internal/RelationalRuntimeContext.java | |||
@@ -37,7 +37,6 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext { | |||
37 | return metaContext; | 37 | return metaContext; |
38 | } | 38 | } |
39 | 39 | ||
40 | // | ||
41 | /** | 40 | /** |
42 | * TODO: check {@link NavigationHelperImpl#coalesceTraversals(Callable)} | 41 | * TODO: check {@link NavigationHelperImpl#coalesceTraversals(Callable)} |
43 | */ | 42 | */ |
@@ -57,8 +56,7 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext { | |||
57 | 56 | ||
58 | @Override | 57 | @Override |
59 | public boolean isIndexed(IInputKey key, IndexingService service) { | 58 | public boolean isIndexed(IInputKey key, IndexingService service) { |
60 | if(key instanceof RelationView<?>) { | 59 | if(key instanceof RelationView<?> relationalKey) { |
61 | RelationView<?> relationalKey = (RelationView<?>) key; | ||
62 | return this.relationUpdateListener.containsRelationalView(relationalKey); | 60 | return this.relationUpdateListener.containsRelationalView(relationalKey); |
63 | } else { | 61 | } else { |
64 | return false; | 62 | return false; |
diff --git a/store/src/test/java/org/eclipse/viatra/solver/data/query/test/QueryTest.java b/store/src/test/java/org/eclipse/viatra/solver/data/query/test/QueryTest.java index 182f6c94..1500f77c 100644 --- a/store/src/test/java/org/eclipse/viatra/solver/data/query/test/QueryTest.java +++ b/store/src/test/java/org/eclipse/viatra/solver/data/query/test/QueryTest.java | |||
@@ -52,7 +52,7 @@ class QueryTest { | |||
52 | void modelBuildingTest() { | 52 | void modelBuildingTest() { |
53 | Relation<Boolean> person = new Relation<>("Person", 1, false); | 53 | Relation<Boolean> person = new Relation<>("Person", 1, false); |
54 | Relation<Integer> age = new Relation<Integer>("age", 1, null); | 54 | Relation<Integer> age = new Relation<Integer>("age", 1, null); |
55 | Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.False); | 55 | Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE); |
56 | 56 | ||
57 | ModelStore store = new ModelStoreImpl(Set.of(person, age, friend)); | 57 | ModelStore store = new ModelStoreImpl(Set.of(person, age, friend)); |
58 | Model model = store.createModel(); | 58 | Model model = store.createModel(); |
@@ -61,8 +61,8 @@ class QueryTest { | |||
61 | model.put(person, Tuple.of(1), true); | 61 | model.put(person, Tuple.of(1), true); |
62 | model.put(age, Tuple.of(0), 3); | 62 | model.put(age, Tuple.of(0), 3); |
63 | model.put(age, Tuple.of(1), 1); | 63 | model.put(age, Tuple.of(1), 1); |
64 | model.put(friend, Tuple.of(0, 1), TruthValue.True); | 64 | model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); |
65 | model.put(friend, Tuple.of(1, 0), TruthValue.Unknown); | 65 | model.put(friend, Tuple.of(1, 0), TruthValue.UNKNOWN); |
66 | 66 | ||
67 | // Sanity check | 67 | // Sanity check |
68 | assertTrue(model.get(person, Tuple.of(0))); | 68 | assertTrue(model.get(person, Tuple.of(0))); |