diff --git a/buildSrc/src/main/kotlin/tools/refinery/gradle/internal/java-conventions.gradle.kts b/buildSrc/src/main/kotlin/tools/refinery/gradle/internal/java-conventions.gradle.kts index 3df17d677..b149a4839 100644 --- a/buildSrc/src/main/kotlin/tools/refinery/gradle/internal/java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/tools/refinery/gradle/internal/java-conventions.gradle.kts @@ -101,6 +101,14 @@ tasks { publishing.publications { create("mavenJava") { from(components["java"]) + pom { + licenses { + license { + name = "Eclipse Public License - v 2.0" + url = "https://www.eclipse.org/legal/epl-2.0/" + } + } + } } } diff --git a/buildSrc/src/main/kotlin/tools/refinery/gradle/interpreter-library.gradle.kts b/buildSrc/src/main/kotlin/tools/refinery/gradle/interpreter-library.gradle.kts index ae30ff1bf..8bafa1a5f 100644 --- a/buildSrc/src/main/kotlin/tools/refinery/gradle/interpreter-library.gradle.kts +++ b/buildSrc/src/main/kotlin/tools/refinery/gradle/interpreter-library.gradle.kts @@ -8,7 +8,6 @@ package tools.refinery.gradle import tools.refinery.gradle.utils.SonarPropertiesUtils plugins { - id("maven-publish") id("tools.refinery.gradle.java-library") id("tools.refinery.gradle.sonarqube") } diff --git a/gradle.properties b/gradle.properties index bcdef8244..9c20dde8f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021-2023 The Refinery Authors +# SPDX-FileCopyrightText: 2021-2024 The Refinery Authors # # SPDX-License-Identifier: EPL-2.0 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5f9dde6e8..9c4d686aa 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -41,6 +41,7 @@ mwe-utils = { group = "org.eclipse.emf", name = "org.eclipse.emf.mwe.utils", ver mwe2-launch = { group = "org.eclipse.emf", name = "org.eclipse.emf.mwe2.launch", version.ref = "mwe2" } mwe2-lib = { group = "org.eclipse.emf", name = "org.eclipse.emf.mwe2.lib", version.ref = "mwe2" } ortools = { group = "com.google.ortools", name = "ortools-java", version = "9.9.3963" } +refinery-z3 = { group = "tools.refinery.z3", name = "refinery-z3-solver", version = "4.12.6" } slf4j-api = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4j" } slf4j-simple = { group = "org.slf4j", name = "slf4j-simple", version.ref = "slf4j" } slf4j-log4j = { group = "org.slf4j", name = "log4j-over-slf4j", version.ref = "slf4j" } diff --git a/settings.gradle.kts b/settings.gradle.kts index 6e5a72e9b..50ca1f242 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -19,6 +19,7 @@ include( "language-model", "language-semantics", "language-web", + "logic", "store", "store-dse", "store-dse-visualization", @@ -26,6 +27,7 @@ include( "store-query-interpreter", "store-reasoning", "store-reasoning-scope", + "store-reasoning-smt", ) for (project in rootProject.children) { @@ -33,3 +35,5 @@ for (project in rootProject.children) { project.name = "${rootProject.name}-$projectName" project.projectDir = file("subprojects/$projectName") } + +includeBuild("z3") diff --git a/subprojects/frontend/src/editor/EditorTheme.ts b/subprojects/frontend/src/editor/EditorTheme.ts index 6deda0806..1f8152d3f 100644 --- a/subprojects/frontend/src/editor/EditorTheme.ts +++ b/subprojects/frontend/src/editor/EditorTheme.ts @@ -166,6 +166,11 @@ export default styled('div', { '.tok-problem-abstract': { fontStyle: 'italic', }, + '.tok-problem-datatype, .tok-problem-aggregator': { + '&, & .tok-typeName': { + color: theme.palette.primary.main, + }, + }, '.tok-problem-containment': { fontWeight: theme.typography.fontWeightEditorBold, textDecorationSkipInk: 'none', diff --git a/subprojects/frontend/src/language/problem.grammar b/subprojects/frontend/src/language/problem.grammar index b69ee73f1..7949f90cd 100644 --- a/subprojects/frontend/src/language/problem.grammar +++ b/subprojects/frontend/src/language/problem.grammar @@ -9,13 +9,16 @@ @external prop implicitCompletion from './props' @precedence { + cast, prefix, + range @left, exponential @right, multiplicative @left, additive @left, - range @left, lattice @left, comparison @left, + boolean @left, + assignment, feature @cut } @@ -42,6 +45,12 @@ statement { kw<"enum"> RelationName (EnumBody { "{" sep<",", AtomNodeName> "}" } | ".") } | + DatatypeDeclaration { + kw<"extern"> ckw<"datatype"> DatatypeName "." + } | + AggregatorDeclaration { + kw<"extern"> ckw<"aggregator"> AggregatorName "." + } | PredicateDefinition { ( (kw<"error"> | ckw<"contained"> | kw<"containment">)? kw<"pred"> | @@ -50,10 +59,10 @@ statement { RelationName ParameterList? PredicateBody { ("<->" sep)? "." } } | - FunctionDefinition { - kw<"fn"> PrimitiveType RelationName ParameterList? - FunctionBody { ("=" sep)? "." } - } | + // FunctionDefinition { + // kw<"fn"> RelationName RelationName ParameterList? + // FunctionBody { ("=" sep)? "." } + // } | //RuleDefinition { // kw<"rule"> // RuleName ParameterList? @@ -77,7 +86,7 @@ FeatureDeclaration { ReferenceKind !feature ~featureHead } | FeatureDeclarationHeadWithoutKind { - (PrimitiveType | kw<"bool">)? ~featureHead + ~featureHead } ) RelationName @@ -87,36 +96,42 @@ FeatureDeclaration { ";"? } -Parameter { Modality? RelationName? VariableName } +Parameter { RelationName? VariableName } // Use @dynamicPrecedence to prevent a(b) from being parsed as Expr { a } Expr { b } // instead of Atom { a(b) } // Being looser with token sequencing enables more consistent syntactic highlighting. Conjunction { ("," | NextConjunction[@dynamicPrecedence=-10] { Expr })+ } -Case { Conjunction ("->" Expr)? } +// Case { Conjunction ("->" Expr)? } OrOp { ";" } Expr { - UnaryExpr | BinaryExpr | Aggregation | VariableName | Atom | Constant | "(" Expr ")" + AssignmentExpr | UnaryExpr | BinaryExpr | CastExpr | Aggregation | + VariableName | Atom | Constant | "(" Expr ")" } +AssignmentExpr { !assignment VariableName kw<"is"> Expr } + BinaryExpr { + Expr !boolean ("&&" | "||" | "^^") Expr | Expr !comparison ComparisonOp Expr | Expr !lattice (LatticeMeet | "\\/") Expr | - Expr !range ".." Expr | Expr !additive ("+" | "-") Expr | - Expr !multiplicative (StarMult | Divide) Expr | - Expr !exponential "**" Expr + Expr !multiplicative (Star | Divide) Expr | + Expr !exponential "**" Expr | + Expr !range ".." Expr } UnaryExpr { - !prefix ("+" | "-" | "!" | kw<"count"> | Modality) Expr + !prefix ("+" | "-" | "!" | kw<"count">) Expr } +CastExpr { !cast Expr kw<"as"> DatatypeName } + Aggregation { - AggregationOp "{" Expr "|" Expr "}" + AggregatorName "{" Expr "|" Expr "}" } Atom { RelationName "+"? ParameterList } @@ -137,22 +152,10 @@ ReferenceKind { kw<"refers"> | ckw<"contains"> | kw<"container"> } -PrimitiveType { - kw<"int"> | kw<"real"> | kw<"string"> -} - LogicValue { kw<"true"> | kw<"false"> | kw<"unknown"> | kw<"error"> } -Modality { - kw<"must"> | kw<"may"> | kw<"current"> -} - -AggregationOp { - ckw<"sum"> | ckw<"prod"> | ckw<"min"> | ckw<"max"> -} - ComparisonOp { SymbolicComparisonOp | kw<"in"> } ScopeElement { RelationName ("=" | "+=") Multiplicity } @@ -165,6 +168,8 @@ Multiplicity { (IntMult "..")? (IntMult | StarMult)} // but will go with the transtive closure (and highlight `a` as a relation) if forced. RelationName { QualifiedName ~name } +DatatypeName { QualifiedName } + //RuleName { QualifiedName } AtomNodeName { QualifiedName } @@ -175,8 +180,12 @@ NodeName { QualifiedName } ModuleName { QualifiedName } +AggregatorName { QualifiedName } + QualifiedName[implicitCompletion=true] { "::"? identifier (QualifiedNameSeparator "::" identifier)* } +StarMult { Star } + kw { @specialize[@name={term},implicitCompletion=true] } ckw { @extend[@name={term},implicitCompletion=true] } @@ -216,7 +225,7 @@ sep1 { content (separator content)* } IntMult { int } - StarMult { "*" } + Star { "*" } Real { (exponential | int ("." (int | exponential))?) } @@ -229,7 +238,7 @@ sep1 { content (separator content)* } SymbolicComparisonOp { ">" | ">=" | "<" | "<=" | "==" | "!=" | - "<:" | ":>" | "===" | "!==" + "===" | "!==" } NotOp { "!" } diff --git a/subprojects/frontend/src/language/problemLanguageSupport.ts b/subprojects/frontend/src/language/problemLanguageSupport.ts index 148263635..dd5d63477 100644 --- a/subprojects/frontend/src/language/problemLanguageSupport.ts +++ b/subprojects/frontend/src/language/problemLanguageSupport.ts @@ -29,21 +29,22 @@ const parserWithMetadata = parser.configure({ BlockComment: t.blockComment, 'module problem class enum pred fn scope': t.definitionKeyword, 'import as declare atom multi': t.definitionKeyword, + 'extern datatype aggregator': t.definitionKeyword, 'abstract extends refers contains container opposite': t.modifier, - 'default error contained containment': t.modifier, + default: t.modifier, 'true false unknown error': t.keyword, - 'int real string bool': t.keyword, - 'may must current count': t.operatorKeyword, - 'sum prod min max in': t.operatorKeyword, + 'count in is': t.operatorKeyword, // 'new delete': t.keyword, NotOp: t.operator, UnknownOp: t.operator, OrOp: t.separator, StarArgument: t.keyword, - 'IntMult StarMult Real': t.number, - StarMult: t.number, + 'IntMult Real': t.number, + 'StarMult/Star': t.number, String: t.string, 'RelationName/QualifiedName': t.typeName, + 'DatatypeName/QualifiedName': t.keyword, + 'AggregatorName/QualifiedName': t.operatorKeyword, // 'RuleName/QualifiedName': t.typeName, 'AtomNodeName/QualifiedName': t.atom, 'VariableName/QualifiedName': t.variableName, @@ -60,7 +61,7 @@ const parserWithMetadata = parser.configure({ NodeDeclaration: indentDeclaration, ScopeDeclaration: indentDeclaration, PredicateBody: indentPredicateOrRule, - FunctionBody: indentPredicateOrRule, + // FunctionBody: indentPredicateOrRule, // RuleBody: indentPredicateOrRule, BlockComment: indentBlockComment, }), @@ -69,7 +70,7 @@ const parserWithMetadata = parser.configure({ EnumBody: foldInside, ParameterList: foldInside, PredicateBody: foldInside, - FunctionBody: foldInside, + // FunctionBody: foldInside, // RuleBody: foldInside, Conjunction: foldConjunction, // Consequent: foldWholeNode, diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelFacade.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelFacade.java index a00ddc46c..eaf60082c 100644 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ModelFacade.java +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelFacade.java @@ -6,6 +6,7 @@ package tools.refinery.generator; import tools.refinery.language.semantics.ProblemTrace; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.model.Model; import tools.refinery.store.model.ModelStore; import tools.refinery.store.reasoning.ReasoningAdapter; @@ -52,7 +53,8 @@ public Concreteness getConcreteness() { return concreteness; } - public PartialInterpretation getPartialInterpretation(PartialSymbol partialSymbol) { + public , C> PartialInterpretation getPartialInterpretation( + PartialSymbol partialSymbol) { return reasoningAdapter.getPartialInterpretation(concreteness, partialSymbol); } } diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java index 1515dceb6..36190b766 100644 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java @@ -9,6 +9,7 @@ import tools.refinery.language.model.problem.Problem; import tools.refinery.language.semantics.ProblemTrace; import tools.refinery.language.semantics.SolutionSerializer; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.dse.strategy.BestFirstStoreManager; import tools.refinery.store.map.Version; import tools.refinery.store.model.ModelStore; @@ -24,7 +25,7 @@ public class ModelGenerator extends ModelFacade { private boolean lastGenerationSuccessful; ModelGenerator(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed, - Provider solutionSerializerProvider) { + Provider solutionSerializerProvider) { super(problemTrace, store, modelSeed, Concreteness.CANDIDATE); this.solutionSerializerProvider = solutionSerializerProvider; initialVersion = getModel().commit(); @@ -66,7 +67,8 @@ public void generate() { } @Override - public PartialInterpretation getPartialInterpretation(PartialSymbol partialSymbol) { + public , C> PartialInterpretation getPartialInterpretation( + PartialSymbol partialSymbol) { checkSuccessfulGeneration(); return super.getPartialInterpretation(partialSymbol); } diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java b/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java index 580a87b62..c76fb7aaa 100644 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java @@ -12,7 +12,10 @@ import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.xtext.diagnostics.Severity; import org.eclipse.xtext.naming.IQualifiedNameConverter; -import org.eclipse.xtext.resource.*; +import org.eclipse.xtext.resource.FileExtensionProvider; +import org.eclipse.xtext.resource.IEObjectDescription; +import org.eclipse.xtext.resource.IResourceFactory; +import org.eclipse.xtext.resource.XtextResourceSet; import org.eclipse.xtext.scoping.impl.GlobalResourceDescriptionProvider; import org.eclipse.xtext.util.CancelIndicator; import org.eclipse.xtext.util.LazyStringInputStream; @@ -25,7 +28,7 @@ import tools.refinery.language.naming.NamingUtil; import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; import tools.refinery.language.resource.ProblemResourceDescriptionStrategy.ShadowingKey; -import tools.refinery.language.scoping.imports.ImportAdapter; +import tools.refinery.language.scoping.imports.ImportAdapterProvider; import tools.refinery.language.scoping.imports.ImportCollector; import tools.refinery.store.util.CancellationToken; @@ -61,6 +64,9 @@ public class ProblemLoader { @Inject private IQualifiedNameConverter qualifiedNameConverter; + @Inject + private ImportAdapterProvider importAdapterProvider; + private CancellationToken cancellationToken = CancellationToken.NONE; private final List extraPaths = new ArrayList<>(); @@ -125,7 +131,7 @@ public Problem loadUri(URI uri) throws IOException { private XtextResourceSet createResourceSet() { var resourceSet = resourceSetProvider.get(); - var adapter = ImportAdapter.getOrInstall(resourceSet); + var adapter = importAdapterProvider.getOrInstall(resourceSet); adapter.getLibraryPaths().addAll(0, extraPaths); return resourceSet; } diff --git a/subprojects/interpreter-rete-recipes/src/main/resources/model/recipes.ecore b/subprojects/interpreter-rete-recipes/src/main/resources/model/recipes.ecore index 6b8f10ea7..23ee5a77c 100644 --- a/subprojects/interpreter-rete-recipes/src/main/resources/model/recipes.ecore +++ b/subprojects/interpreter-rete-recipes/src/main/resources/model/recipes.ecore @@ -399,4 +399,15 @@ + + + +
+ + + + + + diff --git a/subprojects/interpreter-rete-recipes/src/main/resources/model/recipes.ecore.license b/subprojects/interpreter-rete-recipes/src/main/resources/model/recipes.ecore.license index 03d1d42b1..22023c2c2 100644 --- a/subprojects/interpreter-rete-recipes/src/main/resources/model/recipes.ecore.license +++ b/subprojects/interpreter-rete-recipes/src/main/resources/model/recipes.ecore.license @@ -1,4 +1,4 @@ Copyright (c) 2004-2014 Gabor Bergmann and Daniel Varro -Copyright (c) 2023 The Refinery Authors +Copyright (c) 2023-2024 The Refinery Authors SPDX-License-Identifier: EPL-2.0 diff --git a/subprojects/interpreter-rete-recipes/src/main/resources/model/rete-recipes.genmodel b/subprojects/interpreter-rete-recipes/src/main/resources/model/rete-recipes.genmodel index f7dc7a4e6..f156b1a24 100644 --- a/subprojects/interpreter-rete-recipes/src/main/resources/model/rete-recipes.genmodel +++ b/subprojects/interpreter-rete-recipes/src/main/resources/model/rete-recipes.genmodel @@ -1,6 +1,6 @@ + + + + + + diff --git a/subprojects/interpreter-rete-recipes/src/main/resources/model/rete-recipes.genmodel.license b/subprojects/interpreter-rete-recipes/src/main/resources/model/rete-recipes.genmodel.license index 03d1d42b1..22023c2c2 100644 --- a/subprojects/interpreter-rete-recipes/src/main/resources/model/rete-recipes.genmodel.license +++ b/subprojects/interpreter-rete-recipes/src/main/resources/model/rete-recipes.genmodel.license @@ -1,4 +1,4 @@ Copyright (c) 2004-2014 Gabor Bergmann and Daniel Varro -Copyright (c) 2023 The Refinery Authors +Copyright (c) 2023-2024 The Refinery Authors SPDX-License-Identifier: EPL-2.0 diff --git a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/aggregation/LeftJoinNode.java b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/aggregation/LeftJoinNode.java new file mode 100644 index 000000000..9871e3bc1 --- /dev/null +++ b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/aggregation/LeftJoinNode.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright (c) 2004-2009 Gabor Bergmann and Daniel Varro + * Copyright (c) 2024 The Refinery Authors + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package tools.refinery.interpreter.rete.aggregation; + +import tools.refinery.interpreter.matchers.tuple.ITuple; +import tools.refinery.interpreter.matchers.tuple.Tuple; +import tools.refinery.interpreter.matchers.tuple.TupleMask; +import tools.refinery.interpreter.matchers.tuple.Tuples; +import tools.refinery.interpreter.matchers.util.Direction; +import tools.refinery.interpreter.matchers.util.timeline.Timeline; +import tools.refinery.interpreter.rete.index.DefaultIndexerListener; +import tools.refinery.interpreter.rete.index.Indexer; +import tools.refinery.interpreter.rete.index.ProjectionIndexer; +import tools.refinery.interpreter.rete.index.StandardIndexer; +import tools.refinery.interpreter.rete.network.Node; +import tools.refinery.interpreter.rete.network.ReteContainer; +import tools.refinery.interpreter.rete.network.StandardNode; +import tools.refinery.interpreter.rete.network.communication.Timestamp; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class LeftJoinNode extends StandardNode { + private final Object defaultValue; + private ProjectionIndexer projectionIndexer; + private TupleMask projectionMask; + private boolean leftInheritanceOutputMask; + private OuterIndexer outerIndexer = null; + + public LeftJoinNode(ReteContainer reteContainer, Object defaultValue) { + super(reteContainer); + this.defaultValue = defaultValue; + } + + @Override + public void networkStructureChanged() { + if (reteContainer.isTimelyEvaluation() && reteContainer.getCommunicationTracker().isInRecursiveGroup(this)) { + throw new IllegalStateException(this + " cannot be used in recursive differential dataflow evaluation!"); + } + super.networkStructureChanged(); + } + + public void initializeWith(ProjectionIndexer projectionIndexer) { + this.projectionIndexer = projectionIndexer; + projectionMask = projectionIndexer.getMask(); + leftInheritanceOutputMask = isLeftInheritanceOutputMask(projectionMask); + projectionIndexer.attachListener(new DefaultIndexerListener(this) { + @Override + public void notifyIndexerUpdate(Direction direction, Tuple updateElement, Tuple signature, boolean change, + Timestamp timestamp) { + update(direction, updateElement, signature, change, timestamp); + } + }); + } + + private static boolean isLeftInheritanceOutputMask(TupleMask mask) { + int size = mask.getSize(); + int sourceWidth = mask.getSourceWidth(); + if (size != sourceWidth - 1) { + throw new IllegalArgumentException("projectionMask should omit a single index, got " + mask); + } + int[] repetitions = new int[sourceWidth]; + for (int i = 0; i < size; i++) { + int index = mask.indices[i]; + int repetition = repetitions[index] + 1; + if (repetition >= 2) { + throw new IllegalArgumentException("Repeated index %d in projectionMask %s".formatted(index, mask)); + } + repetitions[index] = repetition; + } + for (int i = 0; i < size; i++) { + int index = mask.indices[i]; + if (index != i) { + return false; + } + } + return true; + } + + protected void update(Direction direction, Tuple updateElement, Tuple signature, boolean change, + Timestamp timestamp) { + propagateUpdate(direction, updateElement, timestamp); + if (outerIndexer != null) { + outerIndexer.update(direction, updateElement, signature, change, timestamp); + } + } + + protected Tuple getDefaultTuple(ITuple key) { + if (leftInheritanceOutputMask) { + return Tuples.staticArityFlatTupleOf(key, defaultValue); + } + var objects = new Object[projectionMask.sourceWidth]; + int targetLength = projectionMask.indices.length; + for (int i = 0; i < targetLength; i++) { + int j = projectionMask.indices[i]; + objects[j] = key.get(j); + } + return Tuples.flatTupleOf(objects); + } + + @Override + public void pullInto(Collection collector, boolean flush) { + projectionIndexer.getParent().pullInto(collector, flush); + } + + @Override + public void pullIntoWithTimeline(Map> collector, boolean flush) { + projectionIndexer.getParent().pullIntoWithTimeline(collector, flush); + } + + @Override + public Set getPulledContents(boolean flush) { + return projectionIndexer.getParent().getPulledContents(flush); + } + + public Indexer getOuterIndexer() { + if (outerIndexer == null) { + outerIndexer = new OuterIndexer(); + getCommunicationTracker().registerDependency(this, outerIndexer); + } + return outerIndexer; + } + + /** + * A special non-iterable index that retrieves the aggregated, packed result (signature+aggregate) for the original + * signature. + * + * @author Gabor Bergmann + */ + class OuterIndexer extends StandardIndexer { + public OuterIndexer() { + super(LeftJoinNode.this.reteContainer, LeftJoinNode.this.projectionMask); + this.parent = LeftJoinNode.this; + } + + @Override + public Collection get(Tuple signature) { + var collection = projectionIndexer.get(signature); + if (collection == null || collection.isEmpty()) { + return List.of(getDefaultTuple(signature)); + } + return collection; + } + + public void update(Direction direction, Tuple updateElement, Tuple signature, boolean change, + Timestamp timestamp) { + propagate(direction, updateElement, signature, false, timestamp); + if (change) { + var defaultTuple = getDefaultTuple(signature); + propagate(direction.opposite(), defaultTuple, signature, false, timestamp); + } + } + + @Override + public Node getActiveNode() { + return projectionIndexer.getActiveNode(); + } + } +} diff --git a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/construction/plancompiler/ReteRecipeCompiler.java b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/construction/plancompiler/ReteRecipeCompiler.java index f84eae0ab..52a4de41b 100644 --- a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/construction/plancompiler/ReteRecipeCompiler.java +++ b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/construction/plancompiler/ReteRecipeCompiler.java @@ -10,6 +10,7 @@ package tools.refinery.interpreter.rete.construction.plancompiler; import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.util.EcoreUtil; import tools.refinery.interpreter.matchers.InterpreterRuntimeException; import tools.refinery.interpreter.matchers.backend.CommonQueryHintOptions; import tools.refinery.interpreter.matchers.backend.IQueryBackendHintProvider; @@ -53,782 +54,843 @@ * {@link CompiledSubPlan}. * * @author Bergmann Gabor - * */ public class ReteRecipeCompiler { - private final IQueryPlannerStrategy plannerStrategy; - private final IQueryMetaContext metaContext; - private final IQueryBackendHintProvider hintProvider; - private final PDisjunctionRewriter normalizer; - private final QueryAnalyzer queryAnalyzer; - private final Logger logger; - - /** - * @since 2.2 - */ - protected final boolean deleteAndRederiveEvaluation; - /** - * @since 2.4 - */ - protected final TimelyConfiguration timelyEvaluation; - - /** - * @since 1.5 - */ - public ReteRecipeCompiler(IQueryPlannerStrategy plannerStrategy, Logger logger, IQueryMetaContext metaContext, - IQueryCacheContext queryCacheContext, IQueryBackendHintProvider hintProvider, QueryAnalyzer queryAnalyzer) { - this(plannerStrategy, logger, metaContext, queryCacheContext, hintProvider, queryAnalyzer, false, null); - } - - /** - * @since 2.4 - */ - public ReteRecipeCompiler(IQueryPlannerStrategy plannerStrategy, Logger logger, IQueryMetaContext metaContext, - IQueryCacheContext queryCacheContext, IQueryBackendHintProvider hintProvider, QueryAnalyzer queryAnalyzer, - boolean deleteAndRederiveEvaluation, TimelyConfiguration timelyEvaluation) { - super(); - this.deleteAndRederiveEvaluation = deleteAndRederiveEvaluation; - this.timelyEvaluation = timelyEvaluation; - this.plannerStrategy = plannerStrategy; - this.logger = logger; - this.metaContext = metaContext; - this.queryAnalyzer = queryAnalyzer; - this.normalizer = new PDisjunctionRewriterCacher(new SurrogateQueryRewriter(), - new PBodyNormalizer(metaContext) { - - @Override - protected boolean shouldExpandWeakenedAlternatives(PQuery query) { - QueryEvaluationHint hint = ReteRecipeCompiler.this.hintProvider.getQueryEvaluationHint(query); - Boolean expandWeakenedAlternativeConstraints = ReteHintOptions.expandWeakenedAlternativeConstraints - .getValueOrDefault(hint); - return expandWeakenedAlternativeConstraints; - } - - }); - this.hintProvider = hintProvider; - } - - static final RecipesFactory FACTORY = RecipesFactory.eINSTANCE; - - // INTERNALLY CACHED - private Map plannerCache = new HashMap(); - private Set planningInProgress = new HashSet(); - - private Map queryCompilerCache = new HashMap(); - private Set compilationInProgress = new HashSet(); - private IMultiLookup recursionCutoffPoints = CollectionsFactory.createMultiLookup(Object.class, MemoryType.SETS, Object.class); - private Map subPlanCompilerCache = new HashMap(); - private Map compilerBackTrace = new HashMap(); - - /** - * Clears internal state - */ - public void reset() { - plannerCache.clear(); - planningInProgress.clear(); - queryCompilerCache.clear(); - subPlanCompilerCache.clear(); - compilerBackTrace.clear(); - } - - /** - * Returns a {@link CompiledQuery} compiled from a query - * @throws InterpreterRuntimeException - */ - public CompiledQuery getCompiledForm(PQuery query) { - CompiledQuery compiled = queryCompilerCache.get(query); - if (compiled == null) { - - IRewriterTraceCollector traceCollector = CommonQueryHintOptions.normalizationTraceCollector - .getValueOrDefault(hintProvider.getQueryEvaluationHint(query)); - if (traceCollector != null) { - traceCollector.addTrace(query, query); - } - - boolean reentrant = !compilationInProgress.add(query); - if (reentrant) { // oops, recursion into body in progress - RecursionCutoffPoint cutoffPoint = new RecursionCutoffPoint(query, getHints(query), metaContext, - deleteAndRederiveEvaluation, timelyEvaluation); - recursionCutoffPoints.addPair(query, cutoffPoint); - return cutoffPoint.getCompiledQuery(); - } else { // not reentrant, therefore no recursion, do the compilation - try { - compiled = compileProduction(query); - queryCompilerCache.put(query, compiled); - // backTrace.put(compiled.getRecipe(), plan); - - // if this was a recursive query, mend all points where recursion was cut off - for (RecursionCutoffPoint cutoffPoint : recursionCutoffPoints.lookupOrEmpty(query)) { - cutoffPoint.mend(compiled); - } - } finally { - compilationInProgress.remove(query); - } - } - } - return compiled; - } - - /** - * Returns a {@link CompiledSubPlan} compiled from a query plan - * @throws InterpreterRuntimeException - */ - public CompiledSubPlan getCompiledForm(SubPlan plan) { - CompiledSubPlan compiled = subPlanCompilerCache.get(plan); - if (compiled == null) { - compiled = doCompileDispatch(plan); - subPlanCompilerCache.put(plan, compiled); - compilerBackTrace.put(compiled.getRecipe(), plan); - } - return compiled; - } - - /** - * @throws InterpreterRuntimeException - */ - public SubPlan getPlan(PBody pBody) { - // if the query is not marked as being compiled, initiate compilation - // (this is useful in case of recursion if getPlan() is the entry point) - PQuery pQuery = pBody.getPattern(); - if (!compilationInProgress.contains(pQuery)) - getCompiledForm(pQuery); - - // Is the plan already cached? - SubPlan plan = plannerCache.get(pBody); - if (plan == null) { - boolean reentrant = !planningInProgress.add(pBody); - if (reentrant) { // oops, recursion into body in progress - throw new IllegalArgumentException( - "Planning-level recursion unsupported: " + pBody.getPattern().getFullyQualifiedName()); - } else { // not reentrant, therefore no recursion, do the planning - try { - plan = plannerStrategy.plan(pBody, logger, metaContext); - plannerCache.put(pBody, plan); - } finally { - planningInProgress.remove(pBody); - } - } - } - return plan; - } - - private CompiledQuery compileProduction(PQuery query) { - Collection bodyPlans = new ArrayList(); - normalizer.setTraceCollector(CommonQueryHintOptions.normalizationTraceCollector - .getValueOrDefault(hintProvider.getQueryEvaluationHint(query))); - for (PBody pBody : normalizer.rewrite(query).getBodies()) { - SubPlan bodyPlan = getPlan(pBody); - bodyPlans.add(bodyPlan); - } - return doCompileProduction(query, bodyPlans); - } - - private CompiledQuery doCompileProduction(PQuery query, Collection bodies) { - // TODO skip production node if there is just one body and no projection needed? - Map bodyFinalTraces = new HashMap(); - Collection bodyFinalRecipes = new HashSet(); - - for (SubPlan bodyFinalPlan : bodies) { - // skip over any projections at the end - bodyFinalPlan = BuildHelper.eliminateTrailingProjections(bodyFinalPlan); - - // TODO checkAndTrimEqualVariables may introduce superfluous trim, - // but whatever (no uniqueness enforcer needed) - - // compile body - final CompiledSubPlan compiledBody = getCompiledForm(bodyFinalPlan); - - // project to parameter list - RecipeTraceInfo finalTrace = projectBodyFinalToParameters(compiledBody, false); - - bodyFinalTraces.put(bodyFinalPlan.getBody(), finalTrace); - bodyFinalRecipes.add(finalTrace.getRecipe()); - } - - CompiledQuery compiled = CompilerHelper.makeQueryTrace(query, bodyFinalTraces, bodyFinalRecipes, - getHints(query), metaContext, deleteAndRederiveEvaluation, timelyEvaluation); - - return compiled; - } - - private CompiledSubPlan doCompileDispatch(SubPlan plan) { - final POperation operation = plan.getOperation(); - if (operation instanceof PEnumerate) { - return doCompileEnumerate(((PEnumerate) operation).getEnumerablePConstraint(), plan); - } else if (operation instanceof PApply) { - final PConstraint pConstraint = ((PApply) operation).getPConstraint(); - if (pConstraint instanceof EnumerablePConstraint) { - CompiledSubPlan primaryParent = getCompiledForm(plan.getParentPlans().get(0)); - PlanningTrace secondaryParent = doEnumerateDispatch(plan, (EnumerablePConstraint) pConstraint); - return compileToNaturalJoin(plan, primaryParent, secondaryParent); - } else if (pConstraint instanceof DeferredPConstraint) { - return doDeferredDispatch((DeferredPConstraint) pConstraint, plan); - } else { - throw new IllegalArgumentException("Unsupported PConstraint in query plan: " + plan.toShortString()); - } - } else if (operation instanceof PJoin) { - return doCompileJoin((PJoin) operation, plan); - } else if (operation instanceof PProject) { - return doCompileProject((PProject) operation, plan); - } else if (operation instanceof PStart) { - return doCompileStart((PStart) operation, plan); - } else { - throw new IllegalArgumentException("Unsupported POperation in query plan: " + plan.toShortString()); - } - } - - private CompiledSubPlan doDeferredDispatch(DeferredPConstraint constraint, SubPlan plan) { - final SubPlan parentPlan = plan.getParentPlans().get(0); - final CompiledSubPlan parentCompiled = getCompiledForm(parentPlan); - if (constraint instanceof Equality) { - return compileDeferred((Equality) constraint, plan, parentPlan, parentCompiled); - } else if (constraint instanceof ExportedParameter) { - return compileDeferred((ExportedParameter) constraint, plan, parentPlan, parentCompiled); - } else if (constraint instanceof Inequality) { - return compileDeferred((Inequality) constraint, plan, parentPlan, parentCompiled); - } else if (constraint instanceof NegativePatternCall) { - return compileDeferred((NegativePatternCall) constraint, plan, parentPlan, parentCompiled); - } else if (constraint instanceof PatternMatchCounter) { - return compileDeferred((PatternMatchCounter) constraint, plan, parentPlan, parentCompiled); - } else if (constraint instanceof AggregatorConstraint) { - return compileDeferred((AggregatorConstraint) constraint, plan, parentPlan, parentCompiled); - } else if (constraint instanceof ExpressionEvaluation) { - return compileDeferred((ExpressionEvaluation) constraint, plan, parentPlan, parentCompiled); - } else if (constraint instanceof TypeFilterConstraint) { - return compileDeferred((TypeFilterConstraint) constraint, plan, parentPlan, parentCompiled); - } - throw new UnsupportedOperationException("Unknown deferred constraint " + constraint); - } - - private CompiledSubPlan compileDeferred(Equality constraint, SubPlan plan, SubPlan parentPlan, - CompiledSubPlan parentCompiled) { - if (constraint.isMoot()) - return parentCompiled.cloneFor(plan); - - Integer index1 = parentCompiled.getPosMapping().get(constraint.getWho()); - Integer index2 = parentCompiled.getPosMapping().get(constraint.getWithWhom()); - - if (index1 != null && index2 != null && index1.intValue() != index2.intValue()) { - Integer indexLower = Math.min(index1, index2); - Integer indexHigher = Math.max(index1, index2); - - EqualityFilterRecipe equalityFilterRecipe = FACTORY.createEqualityFilterRecipe(); - equalityFilterRecipe.setParent(parentCompiled.getRecipe()); - equalityFilterRecipe.getIndices().add(indexLower); - equalityFilterRecipe.getIndices().add(indexHigher); - - return new CompiledSubPlan(plan, parentCompiled.getVariablesTuple(), equalityFilterRecipe, parentCompiled); - } else { - throw new IllegalArgumentException(String.format("Unable to interpret %s after compiled parent %s", - plan.toShortString(), parentCompiled.toString())); - } - } - - /** - * Precondition: constantTrace must map to a ConstantRecipe, and all of its variables must be contained in - * toFilterTrace. - */ - private CompiledSubPlan compileConstantFiltering(SubPlan plan, PlanningTrace toFilterTrace, - ConstantRecipe constantRecipe, List filteredVariables) { - PlanningTrace resultTrace = toFilterTrace; - - int constantVariablesSize = filteredVariables.size(); - for (int i = 0; i < constantVariablesSize; ++i) { - Object constantValue = constantRecipe.getConstantValues().get(i); - PVariable filteredVariable = filteredVariables.get(i); - int filteredColumn = resultTrace.getVariablesTuple().indexOf(filteredVariable); - - DiscriminatorDispatcherRecipe dispatcherRecipe = FACTORY.createDiscriminatorDispatcherRecipe(); - dispatcherRecipe.setDiscriminationColumnIndex(filteredColumn); - dispatcherRecipe.setParent(resultTrace.getRecipe()); - - PlanningTrace dispatcherTrace = new PlanningTrace(plan, resultTrace.getVariablesTuple(), dispatcherRecipe, - resultTrace); - - DiscriminatorBucketRecipe bucketRecipe = FACTORY.createDiscriminatorBucketRecipe(); - bucketRecipe.setBucketKey(constantValue); - bucketRecipe.setParent(dispatcherRecipe); - - PlanningTrace bucketTrace = new PlanningTrace(plan, dispatcherTrace.getVariablesTuple(), bucketRecipe, - dispatcherTrace); - - resultTrace = bucketTrace; - } - - return resultTrace.cloneFor(plan); - } - - private CompiledSubPlan compileDeferred(ExportedParameter constraint, SubPlan plan, SubPlan parentPlan, - CompiledSubPlan parentCompiled) { - return parentCompiled.cloneFor(plan); - } - - private CompiledSubPlan compileDeferred(Inequality constraint, SubPlan plan, SubPlan parentPlan, - CompiledSubPlan parentCompiled) { - if (constraint.isEliminable()) - return parentCompiled.cloneFor(plan); - - Integer index1 = parentCompiled.getPosMapping().get(constraint.getWho()); - Integer index2 = parentCompiled.getPosMapping().get(constraint.getWithWhom()); - - if (index1 != null && index2 != null && index1.intValue() != index2.intValue()) { - Integer indexLower = Math.min(index1, index2); - Integer indexHigher = Math.max(index1, index2); - - InequalityFilterRecipe inequalityFilterRecipe = FACTORY.createInequalityFilterRecipe(); - inequalityFilterRecipe.setParent(parentCompiled.getRecipe()); - inequalityFilterRecipe.setSubject(indexLower); - inequalityFilterRecipe.getInequals().add(indexHigher); - - return new CompiledSubPlan(plan, parentCompiled.getVariablesTuple(), inequalityFilterRecipe, - parentCompiled); - } else { - throw new IllegalArgumentException(String.format("Unable to interpret %s after compiled parent %s", - plan.toShortString(), parentCompiled.toString())); - } - } - - private CompiledSubPlan compileDeferred(TypeFilterConstraint constraint, SubPlan plan, SubPlan parentPlan, - CompiledSubPlan parentCompiled) { - final IInputKey inputKey = constraint.getInputKey(); - if (!metaContext.isStateless(inputKey)) - throw new UnsupportedOperationException( - "Non-enumerable input keys are currently supported in Rete only if they are stateless, unlike " - + inputKey); - - final Tuple constraintVariables = constraint.getVariablesTuple(); - final List parentVariables = parentCompiled.getVariablesTuple(); - - Mask mask; // select elements of the tuple to check against extensional relation - if (Tuples.flatTupleOf(parentVariables.toArray()).equals(constraintVariables)) { - mask = null; // lucky case, parent signature equals that of input key - } else { - List variables = new ArrayList(); - for (Object variable : constraintVariables.getElements()) { - variables.add((PVariable) variable); - } - mask = CompilerHelper.makeProjectionMask(parentCompiled, variables); - } - InputFilterRecipe inputFilterRecipe = RecipesHelper.inputFilterRecipe(parentCompiled.getRecipe(), inputKey, - inputKey.getStringID(), mask); - return new CompiledSubPlan(plan, parentVariables, inputFilterRecipe, parentCompiled); - } - - private CompiledSubPlan compileDeferred(NegativePatternCall constraint, SubPlan plan, SubPlan parentPlan, - CompiledSubPlan parentCompiled) { - final PlanningTrace callTrace = referQuery(constraint.getReferredQuery(), plan, - constraint.getActualParametersTuple()); - - CompilerHelper.JoinHelper joinHelper = new CompilerHelper.JoinHelper(plan, parentCompiled, callTrace); - final RecipeTraceInfo primaryIndexer = joinHelper.getPrimaryIndexer(); - final RecipeTraceInfo secondaryIndexer = joinHelper.getSecondaryIndexer(); - - AntiJoinRecipe antiJoinRecipe = FACTORY.createAntiJoinRecipe(); - antiJoinRecipe.setLeftParent((ProjectionIndexerRecipe) primaryIndexer.getRecipe()); - antiJoinRecipe.setRightParent((IndexerRecipe) secondaryIndexer.getRecipe()); - - return new CompiledSubPlan(plan, parentCompiled.getVariablesTuple(), antiJoinRecipe, primaryIndexer, - secondaryIndexer); - } - - private CompiledSubPlan compileDeferred(PatternMatchCounter constraint, SubPlan plan, SubPlan parentPlan, - CompiledSubPlan parentCompiled) { - final PlanningTrace callTrace = referQuery(constraint.getReferredQuery(), plan, - constraint.getActualParametersTuple()); - - // hack: use some mask computations (+ the indexers) from a fake natural join against the called query - CompilerHelper.JoinHelper fakeJoinHelper = new CompilerHelper.JoinHelper(plan, parentCompiled, callTrace); - final RecipeTraceInfo primaryIndexer = fakeJoinHelper.getPrimaryIndexer(); - final RecipeTraceInfo callProjectionIndexer = fakeJoinHelper.getSecondaryIndexer(); - - final List sideVariablesTuple = new ArrayList( - fakeJoinHelper.getSecondaryMask().transform(callTrace.getVariablesTuple())); - /* if (!booleanCheck) */ sideVariablesTuple.add(constraint.getResultVariable()); - - CountAggregatorRecipe aggregatorRecipe = FACTORY.createCountAggregatorRecipe(); - aggregatorRecipe.setParent((ProjectionIndexerRecipe) callProjectionIndexer.getRecipe()); - PlanningTrace aggregatorTrace = new PlanningTrace(plan, sideVariablesTuple, aggregatorRecipe, - callProjectionIndexer); - - IndexerRecipe aggregatorIndexerRecipe = FACTORY.createAggregatorIndexerRecipe(); - aggregatorIndexerRecipe.setParent(aggregatorRecipe); - // aggregatorIndexerRecipe.setMask(RecipesHelper.mask( - // sideVariablesTuple.size(), - // //use same indices as in the projection indexer - // // EVEN if result variable already visible in left parent - // fakeJoinHelper.getSecondaryMask().indices - // )); - - int aggregatorWidth = sideVariablesTuple.size(); - int aggregateResultIndex = aggregatorWidth - 1; - - aggregatorIndexerRecipe.setMask(CompilerHelper.toRecipeMask(TupleMask.omit( - // aggregate according all but the last index - aggregateResultIndex, aggregatorWidth))); - PlanningTrace aggregatorIndexerTrace = new PlanningTrace(plan, sideVariablesTuple, aggregatorIndexerRecipe, - aggregatorTrace); - - JoinRecipe naturalJoinRecipe = FACTORY.createJoinRecipe(); - naturalJoinRecipe.setLeftParent((ProjectionIndexerRecipe) primaryIndexer.getRecipe()); - naturalJoinRecipe.setRightParent(aggregatorIndexerRecipe); - naturalJoinRecipe.setRightParentComplementaryMask(RecipesHelper.mask(aggregatorWidth, - // extend with last element only - the computation value - aggregateResultIndex)); - - // what if the new variable already has a value? - // even if already known, we add the new result variable, so that it can be filtered at the end - // boolean alreadyKnown = parentPlan.getVisibleVariables().contains(constraint.getResultVariable()); - - final List aggregatedVariablesTuple = new ArrayList(parentCompiled.getVariablesTuple()); - aggregatedVariablesTuple.add(constraint.getResultVariable()); - - PlanningTrace joinTrace = new PlanningTrace(plan, aggregatedVariablesTuple, naturalJoinRecipe, primaryIndexer, - aggregatorIndexerTrace); - - return CompilerHelper.checkAndTrimEqualVariables(plan, joinTrace).cloneFor(plan); - // if (!alreadyKnown) { - // return joinTrace.cloneFor(plan); - // } else { - // //final Integer equalsWithIndex = parentCompiled.getPosMapping().get(parentCompiled.getVariablesTuple()); - // } - } - - private CompiledSubPlan compileDeferred(AggregatorConstraint constraint, SubPlan plan, SubPlan parentPlan, - CompiledSubPlan parentCompiled) { - final PlanningTrace callTrace = referQuery(constraint.getReferredQuery(), plan, - constraint.getActualParametersTuple()); - - // hack: use some mask computations (+ the indexers) from a fake natural join against the called query - CompilerHelper.JoinHelper fakeJoinHelper = new CompilerHelper.JoinHelper(plan, parentCompiled, callTrace); - final RecipeTraceInfo primaryIndexer = fakeJoinHelper.getPrimaryIndexer(); - TupleMask callGroupMask = fakeJoinHelper.getSecondaryMask(); - - final List sideVariablesTuple = new ArrayList( - callGroupMask.transform(callTrace.getVariablesTuple())); - /* if (!booleanCheck) */ sideVariablesTuple.add(constraint.getResultVariable()); - - IMultisetAggregationOperator operator = constraint.getAggregator().getOperator(); - - SingleColumnAggregatorRecipe columnAggregatorRecipe = FACTORY.createSingleColumnAggregatorRecipe(); - columnAggregatorRecipe.setParent(callTrace.getRecipe()); - columnAggregatorRecipe.setMultisetAggregationOperator(operator); - - int columnIndex = constraint.getAggregatedColumn(); - IPosetComparator posetComparator = null; - Mask groupMask = CompilerHelper.toRecipeMask(callGroupMask); - - // temporary solution to support the deprecated option for now - final boolean deleteAndRederiveEvaluationDep = this.deleteAndRederiveEvaluation || ReteHintOptions.deleteRederiveEvaluation.getValueOrDefault(getHints(plan)); - - columnAggregatorRecipe.setDeleteRederiveEvaluation(deleteAndRederiveEvaluationDep); - if (deleteAndRederiveEvaluationDep || (this.timelyEvaluation != null)) { - List parameters = constraint.getReferredQuery().getParameters(); - IInputKey key = parameters.get(columnIndex).getDeclaredUnaryType(); - if (key != null && metaContext.isPosetKey(key)) { - posetComparator = metaContext.getPosetComparator(Collections.singleton(key)); - } - } - - if (posetComparator == null) { - columnAggregatorRecipe.setGroupByMask(groupMask); - columnAggregatorRecipe.setAggregableIndex(columnIndex); - } else { - MonotonicityInfo monotonicityInfo = FACTORY.createMonotonicityInfo(); - monotonicityInfo.setCoreMask(groupMask); - monotonicityInfo.setPosetMask(CompilerHelper.toRecipeMask( - TupleMask.selectSingle(columnIndex, constraint.getActualParametersTuple().getSize()))); - monotonicityInfo.setPosetComparator(posetComparator); - columnAggregatorRecipe.setOptionalMonotonicityInfo(monotonicityInfo); - } - - ReteNodeRecipe aggregatorRecipe = columnAggregatorRecipe; - PlanningTrace aggregatorTrace = new PlanningTrace(plan, sideVariablesTuple, aggregatorRecipe, callTrace); - - IndexerRecipe aggregatorIndexerRecipe = FACTORY.createAggregatorIndexerRecipe(); - aggregatorIndexerRecipe.setParent(aggregatorRecipe); - - int aggregatorWidth = sideVariablesTuple.size(); - int aggregateResultIndex = aggregatorWidth - 1; - - aggregatorIndexerRecipe.setMask(CompilerHelper.toRecipeMask(TupleMask.omit( - // aggregate according all but the last index - aggregateResultIndex, aggregatorWidth))); - PlanningTrace aggregatorIndexerTrace = new PlanningTrace(plan, sideVariablesTuple, aggregatorIndexerRecipe, - aggregatorTrace); - - JoinRecipe naturalJoinRecipe = FACTORY.createJoinRecipe(); - naturalJoinRecipe.setLeftParent((ProjectionIndexerRecipe) primaryIndexer.getRecipe()); - naturalJoinRecipe.setRightParent(aggregatorIndexerRecipe); - naturalJoinRecipe.setRightParentComplementaryMask(RecipesHelper.mask(aggregatorWidth, - // extend with last element only - the computation value - aggregateResultIndex)); - - // what if the new variable already has a value? - // even if already known, we add the new result variable, so that it can be filtered at the end - // boolean alreadyKnown = parentPlan.getVisibleVariables().contains(constraint.getResultVariable()); - - final List finalVariablesTuple = new ArrayList(parentCompiled.getVariablesTuple()); - finalVariablesTuple.add(constraint.getResultVariable()); - - PlanningTrace joinTrace = new PlanningTrace(plan, finalVariablesTuple, naturalJoinRecipe, primaryIndexer, - aggregatorIndexerTrace); - - return CompilerHelper.checkAndTrimEqualVariables(plan, joinTrace).cloneFor(plan); - // if (!alreadyKnown) { - // return joinTrace.cloneFor(plan); - // } else { - // //final Integer equalsWithIndex = parentCompiled.getPosMapping().get(parentCompiled.getVariablesTuple()); - // } - } - - private CompiledSubPlan compileDeferred(ExpressionEvaluation constraint, SubPlan plan, SubPlan parentPlan, - CompiledSubPlan parentCompiled) { - Map tupleNameMap = new HashMap(); - for (String name : constraint.getEvaluator().getInputParameterNames()) { - Map index = parentCompiled.getPosMapping(); - PVariable variable = constraint.getPSystem().getVariableByNameChecked(name); - Integer position = index.get(variable); - tupleNameMap.put(name, position); - } - - final PVariable outputVariable = constraint.getOutputVariable(); - final boolean booleanCheck = outputVariable == null; - - // TODO determine whether expression is costly - boolean cacheOutput = ReteHintOptions.cacheOutputOfEvaluatorsByDefault.getValueOrDefault(getHints(plan)); - // for (PAnnotation pAnnotation : - // plan.getBody().getPattern().getAnnotationsByName(EXPRESSION_EVALUATION_ANNOTATION"")) { - // for (Object value : pAnnotation.getAllValues("expensive")) { - // if (value instanceof Boolean) - // cacheOutput = (boolean) value; - // } - // } - - ExpressionEnforcerRecipe enforcerRecipe = booleanCheck ? FACTORY.createCheckRecipe() - : FACTORY.createEvalRecipe(); - enforcerRecipe.setParent(parentCompiled.getRecipe()); - enforcerRecipe.setExpression(RecipesHelper.expressionDefinition(constraint.getEvaluator())); - enforcerRecipe.setCacheOutput(cacheOutput); - if (enforcerRecipe instanceof EvalRecipe) { - ((EvalRecipe) enforcerRecipe).setUnwinding(constraint.isUnwinding()); - } - for (Entry entry : tupleNameMap.entrySet()) { - enforcerRecipe.getMappedIndices().put(entry.getKey(), entry.getValue()); - } - - final List enforcerVariablesTuple = new ArrayList(parentCompiled.getVariablesTuple()); - if (!booleanCheck) - enforcerVariablesTuple.add(outputVariable); - PlanningTrace enforcerTrace = new PlanningTrace(plan, enforcerVariablesTuple, enforcerRecipe, parentCompiled); - - return CompilerHelper.checkAndTrimEqualVariables(plan, enforcerTrace).cloneFor(plan); - } - - private CompiledSubPlan doCompileJoin(PJoin operation, SubPlan plan) { - final List compiledParents = getCompiledFormOfParents(plan); - final CompiledSubPlan leftCompiled = compiledParents.get(0); - final CompiledSubPlan rightCompiled = compiledParents.get(1); - - return compileToNaturalJoin(plan, leftCompiled, rightCompiled); - } - - private CompiledSubPlan compileToNaturalJoin(SubPlan plan, final PlanningTrace leftCompiled, - final PlanningTrace rightCompiled) { - // CHECK IF SPECIAL CASE - - // Is constant filtering applicable? - if (ReteHintOptions.useDiscriminatorDispatchersForConstantFiltering.getValueOrDefault(getHints(plan))) { - if (leftCompiled.getRecipe() instanceof ConstantRecipe - && rightCompiled.getVariablesTuple().containsAll(leftCompiled.getVariablesTuple())) { - return compileConstantFiltering(plan, rightCompiled, (ConstantRecipe) leftCompiled.getRecipe(), - leftCompiled.getVariablesTuple()); - } - if (rightCompiled.getRecipe() instanceof ConstantRecipe - && leftCompiled.getVariablesTuple().containsAll(rightCompiled.getVariablesTuple())) { - return compileConstantFiltering(plan, leftCompiled, (ConstantRecipe) rightCompiled.getRecipe(), - rightCompiled.getVariablesTuple()); - } - } - - // ELSE: ACTUAL JOIN - CompilerHelper.JoinHelper joinHelper = new CompilerHelper.JoinHelper(plan, leftCompiled, rightCompiled); - return new CompiledSubPlan(plan, joinHelper.getNaturalJoinVariablesTuple(), joinHelper.getNaturalJoinRecipe(), - joinHelper.getPrimaryIndexer(), joinHelper.getSecondaryIndexer()); - } - - private CompiledSubPlan doCompileProject(PProject operation, SubPlan plan) { - final List compiledParents = getCompiledFormOfParents(plan); - final CompiledSubPlan compiledParent = compiledParents.get(0); - - List projectedVariables = new ArrayList(operation.getToVariables()); - // Determinizing projection: try to keep original order (hopefully facilitates node reuse) - Map parentPosMapping = compiledParent.getPosMapping(); - Collections.sort(projectedVariables, Comparator.comparing(parentPosMapping::get)); - - return doProjectPlan(compiledParent, projectedVariables, true, - parentTrace -> parentTrace.cloneFor(plan), - (recipe, parentTrace) -> new PlanningTrace(plan, projectedVariables, recipe, parentTrace), - (recipe, parentTrace) -> new CompiledSubPlan(plan, projectedVariables, recipe, parentTrace) - ); - } - - /** - * Projects a subplan onto the specified variable tuple - * @param compiledParentPlan the compiled form of the subplan - * @param targetVariables list of variables to project to - * @param enforceUniqueness whether distinctness shall be enforced after the projection. - * Specify false only if directly connecting to a production node. - * @param reinterpretTraceFactory constructs a reinterpreted trace that simply relabels the compiled parent plan, in case it is sufficient - * @param intermediateTraceFactory constructs a recipe trace for an intermediate node, given the recipe of the node and its parent trace - * @param finalTraceFactory constructs a recipe trace for the final resulting node, given the recipe of the node and its parent trace - * @since 2.1 - */ - ResultTrace doProjectPlan( - final CompiledSubPlan compiledParentPlan, - final List targetVariables, - boolean enforceUniqueness, - Function reinterpretTraceFactory, - BiFunction intermediateTraceFactory, - BiFunction finalTraceFactory) - { - if (targetVariables.equals(compiledParentPlan.getVariablesTuple())) // no projection needed - return reinterpretTraceFactory.apply(compiledParentPlan); - - // otherwise, we need at least a trimmer - TrimmerRecipe trimmerRecipe = CompilerHelper.makeTrimmerRecipe(compiledParentPlan, targetVariables); - - // do we need to eliminate duplicates? - SubPlan parentPlan = compiledParentPlan.getSubPlan(); - if (!enforceUniqueness || BuildHelper.areAllVariablesDetermined( - parentPlan, - targetVariables, - queryAnalyzer, - true)) - { - // if uniqueness enforcess is unwanted or unneeeded, skip it - return finalTraceFactory.apply(trimmerRecipe, compiledParentPlan); - } else { - // add a uniqueness enforcer - UniquenessEnforcerRecipe recipe = FACTORY.createUniquenessEnforcerRecipe(); - recipe.getParents().add(trimmerRecipe); - - // temporary solution to support the deprecated option for now - final boolean deleteAndRederiveEvaluationDep = this.deleteAndRederiveEvaluation || ReteHintOptions.deleteRederiveEvaluation.getValueOrDefault(getHints(parentPlan)); - - recipe.setDeleteRederiveEvaluation(deleteAndRederiveEvaluationDep); - if (deleteAndRederiveEvaluationDep || (this.timelyEvaluation != null)) { - CompilerHelper.PosetTriplet triplet = CompilerHelper.computePosetInfo(targetVariables, parentPlan.getBody(), metaContext); - - if (triplet.comparator != null) { - MonotonicityInfo info = FACTORY.createMonotonicityInfo(); - info.setCoreMask(triplet.coreMask); - info.setPosetMask(triplet.posetMask); - info.setPosetComparator(triplet.comparator); - recipe.setOptionalMonotonicityInfo(info); - } - } - - RecipeTraceInfo trimmerTrace = intermediateTraceFactory.apply(trimmerRecipe, compiledParentPlan); - return finalTraceFactory.apply(recipe, trimmerTrace); - } - } - - /** - * Projects the final compiled form of a PBody onto the parameter tuple - * @param compiledBody the compiled form of the body, with all constraints enforced, not yet projected to query parameters - * @param enforceUniqueness whether distinctness shall be enforced after the projection. - * Specify false only if directly connecting to a production node. - * @since 2.1 - */ - RecipeTraceInfo projectBodyFinalToParameters( - final CompiledSubPlan compiledBody, - boolean enforceUniqueness) - { - final PBody body = compiledBody.getSubPlan().getBody(); - final List parameterList = body.getSymbolicParameterVariables(); - - return doProjectPlan(compiledBody, parameterList, enforceUniqueness, - parentTrace -> parentTrace, - (recipe, parentTrace) -> new ParameterProjectionTrace(body, recipe, parentTrace), - (recipe, parentTrace) -> new ParameterProjectionTrace(body, recipe, parentTrace) - ); - } - - private CompiledSubPlan doCompileStart(PStart operation, SubPlan plan) { - if (!operation.getAPrioriVariables().isEmpty()) { - throw new IllegalArgumentException("Input variables unsupported by Rete: " + plan.toShortString()); - } - final ConstantRecipe recipe = FACTORY.createConstantRecipe(); - recipe.getConstantValues().clear(); - - return new CompiledSubPlan(plan, new ArrayList(), recipe); - } - - private CompiledSubPlan doCompileEnumerate(EnumerablePConstraint constraint, SubPlan plan) { - final PlanningTrace trimmedTrace = doEnumerateAndDeduplicate(constraint, plan); - - return trimmedTrace.cloneFor(plan); - } - - private PlanningTrace doEnumerateAndDeduplicate(EnumerablePConstraint constraint, SubPlan plan) { - final PlanningTrace coreTrace = doEnumerateDispatch(plan, constraint); - final PlanningTrace trimmedTrace = CompilerHelper.checkAndTrimEqualVariables(plan, coreTrace); - return trimmedTrace; - } - - private PlanningTrace doEnumerateDispatch(SubPlan plan, EnumerablePConstraint constraint) { - if (constraint instanceof RelationEvaluation) { - return compileEnumerable(plan, (RelationEvaluation) constraint); - } else if (constraint instanceof BinaryTransitiveClosure) { - return compileEnumerable(plan, (BinaryTransitiveClosure) constraint); - } else if (constraint instanceof BinaryReflexiveTransitiveClosure) { - return compileEnumerable(plan, (BinaryReflexiveTransitiveClosure) constraint); + private final IQueryPlannerStrategy plannerStrategy; + private final IQueryMetaContext metaContext; + private final IQueryBackendHintProvider hintProvider; + private final PDisjunctionRewriter normalizer; + private final QueryAnalyzer queryAnalyzer; + private final Logger logger; + + /** + * @since 2.2 + */ + protected final boolean deleteAndRederiveEvaluation; + /** + * @since 2.4 + */ + protected final TimelyConfiguration timelyEvaluation; + + /** + * @since 1.5 + */ + public ReteRecipeCompiler(IQueryPlannerStrategy plannerStrategy, Logger logger, IQueryMetaContext metaContext, + IQueryCacheContext queryCacheContext, IQueryBackendHintProvider hintProvider, + QueryAnalyzer queryAnalyzer) { + this(plannerStrategy, logger, metaContext, queryCacheContext, hintProvider, queryAnalyzer, false, null); + } + + /** + * @since 2.4 + */ + public ReteRecipeCompiler(IQueryPlannerStrategy plannerStrategy, Logger logger, IQueryMetaContext metaContext, + IQueryCacheContext queryCacheContext, IQueryBackendHintProvider hintProvider, + QueryAnalyzer queryAnalyzer, + boolean deleteAndRederiveEvaluation, TimelyConfiguration timelyEvaluation) { + super(); + this.deleteAndRederiveEvaluation = deleteAndRederiveEvaluation; + this.timelyEvaluation = timelyEvaluation; + this.plannerStrategy = plannerStrategy; + this.logger = logger; + this.metaContext = metaContext; + this.queryAnalyzer = queryAnalyzer; + this.normalizer = new PDisjunctionRewriterCacher(new SurrogateQueryRewriter(), + new PBodyNormalizer(metaContext) { + + @Override + protected boolean shouldExpandWeakenedAlternatives(PQuery query) { + QueryEvaluationHint hint = ReteRecipeCompiler.this.hintProvider.getQueryEvaluationHint(query); + Boolean expandWeakenedAlternativeConstraints = + ReteHintOptions.expandWeakenedAlternativeConstraints + .getValueOrDefault(hint); + return expandWeakenedAlternativeConstraints; + } + + }); + this.hintProvider = hintProvider; + } + + static final RecipesFactory FACTORY = RecipesFactory.eINSTANCE; + + // INTERNALLY CACHED + private Map plannerCache = new HashMap(); + private Set planningInProgress = new HashSet(); + + private Map queryCompilerCache = new HashMap(); + private Set compilationInProgress = new HashSet(); + private IMultiLookup recursionCutoffPoints = + CollectionsFactory.createMultiLookup(Object.class, MemoryType.SETS, Object.class); + private Map subPlanCompilerCache = new HashMap(); + private Map compilerBackTrace = new HashMap(); + + /** + * Clears internal state + */ + public void reset() { + plannerCache.clear(); + planningInProgress.clear(); + queryCompilerCache.clear(); + subPlanCompilerCache.clear(); + compilerBackTrace.clear(); + } + + /** + * Returns a {@link CompiledQuery} compiled from a query + * + * @throws InterpreterRuntimeException + */ + public CompiledQuery getCompiledForm(PQuery query) { + CompiledQuery compiled = queryCompilerCache.get(query); + if (compiled == null) { + + IRewriterTraceCollector traceCollector = CommonQueryHintOptions.normalizationTraceCollector + .getValueOrDefault(hintProvider.getQueryEvaluationHint(query)); + if (traceCollector != null) { + traceCollector.addTrace(query, query); + } + + boolean reentrant = !compilationInProgress.add(query); + if (reentrant) { // oops, recursion into body in progress + RecursionCutoffPoint cutoffPoint = new RecursionCutoffPoint(query, getHints(query), metaContext, + deleteAndRederiveEvaluation, timelyEvaluation); + recursionCutoffPoints.addPair(query, cutoffPoint); + return cutoffPoint.getCompiledQuery(); + } else { // not reentrant, therefore no recursion, do the compilation + try { + compiled = compileProduction(query); + queryCompilerCache.put(query, compiled); + // backTrace.put(compiled.getRecipe(), plan); + + // if this was a recursive query, mend all points where recursion was cut off + for (RecursionCutoffPoint cutoffPoint : recursionCutoffPoints.lookupOrEmpty(query)) { + cutoffPoint.mend(compiled); + } + } finally { + compilationInProgress.remove(query); + } + } + } + return compiled; + } + + /** + * Returns a {@link CompiledSubPlan} compiled from a query plan + * + * @throws InterpreterRuntimeException + */ + public CompiledSubPlan getCompiledForm(SubPlan plan) { + CompiledSubPlan compiled = subPlanCompilerCache.get(plan); + if (compiled == null) { + compiled = doCompileDispatch(plan); + subPlanCompilerCache.put(plan, compiled); + compilerBackTrace.put(compiled.getRecipe(), plan); + } + return compiled; + } + + /** + * @throws InterpreterRuntimeException + */ + public SubPlan getPlan(PBody pBody) { + // if the query is not marked as being compiled, initiate compilation + // (this is useful in case of recursion if getPlan() is the entry point) + PQuery pQuery = pBody.getPattern(); + if (!compilationInProgress.contains(pQuery)) + getCompiledForm(pQuery); + + // Is the plan already cached? + SubPlan plan = plannerCache.get(pBody); + if (plan == null) { + boolean reentrant = !planningInProgress.add(pBody); + if (reentrant) { // oops, recursion into body in progress + throw new IllegalArgumentException( + "Planning-level recursion unsupported: " + pBody.getPattern().getFullyQualifiedName()); + } else { // not reentrant, therefore no recursion, do the planning + try { + plan = plannerStrategy.plan(pBody, logger, metaContext); + plannerCache.put(pBody, plan); + } finally { + planningInProgress.remove(pBody); + } + } + } + return plan; + } + + private CompiledQuery compileProduction(PQuery query) { + Collection bodyPlans = new ArrayList(); + normalizer.setTraceCollector(CommonQueryHintOptions.normalizationTraceCollector + .getValueOrDefault(hintProvider.getQueryEvaluationHint(query))); + for (PBody pBody : normalizer.rewrite(query).getBodies()) { + SubPlan bodyPlan = getPlan(pBody); + bodyPlans.add(bodyPlan); + } + return doCompileProduction(query, bodyPlans); + } + + private CompiledQuery doCompileProduction(PQuery query, Collection bodies) { + // TODO skip production node if there is just one body and no projection needed? + Map bodyFinalTraces = new HashMap(); + Collection bodyFinalRecipes = new HashSet(); + + for (SubPlan bodyFinalPlan : bodies) { + // skip over any projections at the end + bodyFinalPlan = BuildHelper.eliminateTrailingProjections(bodyFinalPlan); + + // TODO checkAndTrimEqualVariables may introduce superfluous trim, + // but whatever (no uniqueness enforcer needed) + + // compile body + final CompiledSubPlan compiledBody = getCompiledForm(bodyFinalPlan); + + // project to parameter list + RecipeTraceInfo finalTrace = projectBodyFinalToParameters(compiledBody, false); + + bodyFinalTraces.put(bodyFinalPlan.getBody(), finalTrace); + bodyFinalRecipes.add(finalTrace.getRecipe()); + } + + CompiledQuery compiled = CompilerHelper.makeQueryTrace(query, bodyFinalTraces, bodyFinalRecipes, + getHints(query), metaContext, deleteAndRederiveEvaluation, timelyEvaluation); + + return compiled; + } + + private CompiledSubPlan doCompileDispatch(SubPlan plan) { + final POperation operation = plan.getOperation(); + if (operation instanceof PEnumerate) { + return doCompileEnumerate(((PEnumerate) operation).getEnumerablePConstraint(), plan); + } else if (operation instanceof PApply) { + final PConstraint pConstraint = ((PApply) operation).getPConstraint(); + if (pConstraint instanceof EnumerablePConstraint) { + CompiledSubPlan primaryParent = getCompiledForm(plan.getParentPlans().get(0)); + PlanningTrace secondaryParent = doEnumerateDispatch(plan, (EnumerablePConstraint) pConstraint); + return compileToNaturalJoin(plan, primaryParent, secondaryParent); + } else if (pConstraint instanceof DeferredPConstraint) { + return doDeferredDispatch((DeferredPConstraint) pConstraint, plan); + } else { + throw new IllegalArgumentException("Unsupported PConstraint in query plan: " + plan.toShortString()); + } + } else if (operation instanceof PJoin) { + return doCompileJoin((PJoin) operation, plan); + } else if (operation instanceof PProject) { + return doCompileProject((PProject) operation, plan); + } else if (operation instanceof PStart) { + return doCompileStart((PStart) operation, plan); + } else { + throw new IllegalArgumentException("Unsupported POperation in query plan: " + plan.toShortString()); + } + } + + private CompiledSubPlan doDeferredDispatch(DeferredPConstraint constraint, SubPlan plan) { + final SubPlan parentPlan = plan.getParentPlans().get(0); + final CompiledSubPlan parentCompiled = getCompiledForm(parentPlan); + if (constraint instanceof Equality) { + return compileDeferred((Equality) constraint, plan, parentPlan, parentCompiled); + } else if (constraint instanceof ExportedParameter) { + return compileDeferred((ExportedParameter) constraint, plan, parentPlan, parentCompiled); + } else if (constraint instanceof Inequality) { + return compileDeferred((Inequality) constraint, plan, parentPlan, parentCompiled); + } else if (constraint instanceof NegativePatternCall) { + return compileDeferred((NegativePatternCall) constraint, plan, parentPlan, parentCompiled); + } else if (constraint instanceof PatternMatchCounter) { + return compileDeferred((PatternMatchCounter) constraint, plan, parentPlan, parentCompiled); + } else if (constraint instanceof AggregatorConstraint) { + return compileDeferred((AggregatorConstraint) constraint, plan, parentPlan, parentCompiled); + } else if (constraint instanceof LeftJoinConstraint leftJoinConstraint) { + return compileDeferred(leftJoinConstraint, plan, parentCompiled); + } else if (constraint instanceof ExpressionEvaluation) { + return compileDeferred((ExpressionEvaluation) constraint, plan, parentPlan, parentCompiled); + } else if (constraint instanceof TypeFilterConstraint) { + return compileDeferred((TypeFilterConstraint) constraint, plan, parentPlan, parentCompiled); + } + throw new UnsupportedOperationException("Unknown deferred constraint " + constraint); + } + + private CompiledSubPlan compileDeferred(Equality constraint, SubPlan plan, SubPlan parentPlan, + CompiledSubPlan parentCompiled) { + if (constraint.isMoot()) + return parentCompiled.cloneFor(plan); + + Integer index1 = parentCompiled.getPosMapping().get(constraint.getWho()); + Integer index2 = parentCompiled.getPosMapping().get(constraint.getWithWhom()); + + if (index1 != null && index2 != null && index1.intValue() != index2.intValue()) { + Integer indexLower = Math.min(index1, index2); + Integer indexHigher = Math.max(index1, index2); + + EqualityFilterRecipe equalityFilterRecipe = FACTORY.createEqualityFilterRecipe(); + equalityFilterRecipe.setParent(parentCompiled.getRecipe()); + equalityFilterRecipe.getIndices().add(indexLower); + equalityFilterRecipe.getIndices().add(indexHigher); + + return new CompiledSubPlan(plan, parentCompiled.getVariablesTuple(), equalityFilterRecipe, parentCompiled); + } else { + throw new IllegalArgumentException(String.format("Unable to interpret %s after compiled parent %s", + plan.toShortString(), parentCompiled.toString())); + } + } + + /** + * Precondition: constantTrace must map to a ConstantRecipe, and all of its variables must be contained in + * toFilterTrace. + */ + private CompiledSubPlan compileConstantFiltering(SubPlan plan, PlanningTrace toFilterTrace, + ConstantRecipe constantRecipe, List filteredVariables) { + PlanningTrace resultTrace = toFilterTrace; + + int constantVariablesSize = filteredVariables.size(); + for (int i = 0; i < constantVariablesSize; ++i) { + Object constantValue = constantRecipe.getConstantValues().get(i); + PVariable filteredVariable = filteredVariables.get(i); + int filteredColumn = resultTrace.getVariablesTuple().indexOf(filteredVariable); + + DiscriminatorDispatcherRecipe dispatcherRecipe = FACTORY.createDiscriminatorDispatcherRecipe(); + dispatcherRecipe.setDiscriminationColumnIndex(filteredColumn); + dispatcherRecipe.setParent(resultTrace.getRecipe()); + + PlanningTrace dispatcherTrace = new PlanningTrace(plan, resultTrace.getVariablesTuple(), dispatcherRecipe, + resultTrace); + + DiscriminatorBucketRecipe bucketRecipe = FACTORY.createDiscriminatorBucketRecipe(); + bucketRecipe.setBucketKey(constantValue); + bucketRecipe.setParent(dispatcherRecipe); + + PlanningTrace bucketTrace = new PlanningTrace(plan, dispatcherTrace.getVariablesTuple(), bucketRecipe, + dispatcherTrace); + + resultTrace = bucketTrace; + } + + return resultTrace.cloneFor(plan); + } + + private CompiledSubPlan compileDeferred(ExportedParameter constraint, SubPlan plan, SubPlan parentPlan, + CompiledSubPlan parentCompiled) { + return parentCompiled.cloneFor(plan); + } + + private CompiledSubPlan compileDeferred(Inequality constraint, SubPlan plan, SubPlan parentPlan, + CompiledSubPlan parentCompiled) { + if (constraint.isEliminable()) + return parentCompiled.cloneFor(plan); + + Integer index1 = parentCompiled.getPosMapping().get(constraint.getWho()); + Integer index2 = parentCompiled.getPosMapping().get(constraint.getWithWhom()); + + if (index1 != null && index2 != null && index1.intValue() != index2.intValue()) { + Integer indexLower = Math.min(index1, index2); + Integer indexHigher = Math.max(index1, index2); + + InequalityFilterRecipe inequalityFilterRecipe = FACTORY.createInequalityFilterRecipe(); + inequalityFilterRecipe.setParent(parentCompiled.getRecipe()); + inequalityFilterRecipe.setSubject(indexLower); + inequalityFilterRecipe.getInequals().add(indexHigher); + + return new CompiledSubPlan(plan, parentCompiled.getVariablesTuple(), inequalityFilterRecipe, + parentCompiled); + } else { + throw new IllegalArgumentException(String.format("Unable to interpret %s after compiled parent %s", + plan.toShortString(), parentCompiled.toString())); + } + } + + private CompiledSubPlan compileDeferred(TypeFilterConstraint constraint, SubPlan plan, SubPlan parentPlan, + CompiledSubPlan parentCompiled) { + final IInputKey inputKey = constraint.getInputKey(); + if (!metaContext.isStateless(inputKey)) + throw new UnsupportedOperationException( + "Non-enumerable input keys are currently supported in Rete only if they are stateless, unlike " + + inputKey); + + final Tuple constraintVariables = constraint.getVariablesTuple(); + final List parentVariables = parentCompiled.getVariablesTuple(); + + Mask mask; // select elements of the tuple to check against extensional relation + if (Tuples.flatTupleOf(parentVariables.toArray()).equals(constraintVariables)) { + mask = null; // lucky case, parent signature equals that of input key + } else { + List variables = new ArrayList(); + for (Object variable : constraintVariables.getElements()) { + variables.add((PVariable) variable); + } + mask = CompilerHelper.makeProjectionMask(parentCompiled, variables); + } + InputFilterRecipe inputFilterRecipe = RecipesHelper.inputFilterRecipe(parentCompiled.getRecipe(), inputKey, + inputKey.getStringID(), mask); + return new CompiledSubPlan(plan, parentVariables, inputFilterRecipe, parentCompiled); + } + + private CompiledSubPlan compileDeferred(NegativePatternCall constraint, SubPlan plan, SubPlan parentPlan, + CompiledSubPlan parentCompiled) { + final PlanningTrace callTrace = referQuery(constraint.getReferredQuery(), plan, + constraint.getActualParametersTuple()); + + CompilerHelper.JoinHelper joinHelper = new CompilerHelper.JoinHelper(plan, parentCompiled, callTrace); + final RecipeTraceInfo primaryIndexer = joinHelper.getPrimaryIndexer(); + final RecipeTraceInfo secondaryIndexer = joinHelper.getSecondaryIndexer(); + + AntiJoinRecipe antiJoinRecipe = FACTORY.createAntiJoinRecipe(); + antiJoinRecipe.setLeftParent((ProjectionIndexerRecipe) primaryIndexer.getRecipe()); + antiJoinRecipe.setRightParent((IndexerRecipe) secondaryIndexer.getRecipe()); + + return new CompiledSubPlan(plan, parentCompiled.getVariablesTuple(), antiJoinRecipe, primaryIndexer, + secondaryIndexer); + } + + private CompiledSubPlan compileDeferred(PatternMatchCounter constraint, SubPlan plan, SubPlan parentPlan, + CompiledSubPlan parentCompiled) { + final PlanningTrace callTrace = referQuery(constraint.getReferredQuery(), plan, + constraint.getActualParametersTuple()); + + // hack: use some mask computations (+ the indexers) from a fake natural join against the called query + CompilerHelper.JoinHelper fakeJoinHelper = new CompilerHelper.JoinHelper(plan, parentCompiled, callTrace); + final RecipeTraceInfo primaryIndexer = fakeJoinHelper.getPrimaryIndexer(); + final RecipeTraceInfo callProjectionIndexer = fakeJoinHelper.getSecondaryIndexer(); + + final List sideVariablesTuple = new ArrayList( + fakeJoinHelper.getSecondaryMask().transform(callTrace.getVariablesTuple())); + /* if (!booleanCheck) */ + sideVariablesTuple.add(constraint.getResultVariable()); + + CountAggregatorRecipe aggregatorRecipe = FACTORY.createCountAggregatorRecipe(); + aggregatorRecipe.setParent((ProjectionIndexerRecipe) callProjectionIndexer.getRecipe()); + PlanningTrace aggregatorTrace = new PlanningTrace(plan, sideVariablesTuple, aggregatorRecipe, + callProjectionIndexer); + + IndexerRecipe aggregatorIndexerRecipe = FACTORY.createAggregatorIndexerRecipe(); + aggregatorIndexerRecipe.setParent(aggregatorRecipe); + // aggregatorIndexerRecipe.setMask(RecipesHelper.mask( + // sideVariablesTuple.size(), + // //use same indices as in the projection indexer + // // EVEN if result variable already visible in left parent + // fakeJoinHelper.getSecondaryMask().indices + // )); + + int aggregatorWidth = sideVariablesTuple.size(); + int aggregateResultIndex = aggregatorWidth - 1; + + aggregatorIndexerRecipe.setMask(CompilerHelper.toRecipeMask(TupleMask.omit( + // aggregate according all but the last index + aggregateResultIndex, aggregatorWidth))); + PlanningTrace aggregatorIndexerTrace = new PlanningTrace(plan, sideVariablesTuple, aggregatorIndexerRecipe, + aggregatorTrace); + + JoinRecipe naturalJoinRecipe = FACTORY.createJoinRecipe(); + naturalJoinRecipe.setLeftParent((ProjectionIndexerRecipe) primaryIndexer.getRecipe()); + naturalJoinRecipe.setRightParent(aggregatorIndexerRecipe); + naturalJoinRecipe.setRightParentComplementaryMask(RecipesHelper.mask(aggregatorWidth, + // extend with last element only - the computation value + aggregateResultIndex)); + + // what if the new variable already has a value? + // even if already known, we add the new result variable, so that it can be filtered at the end + // boolean alreadyKnown = parentPlan.getVisibleVariables().contains(constraint.getResultVariable()); + + final List aggregatedVariablesTuple = new ArrayList(parentCompiled.getVariablesTuple()); + aggregatedVariablesTuple.add(constraint.getResultVariable()); + + PlanningTrace joinTrace = new PlanningTrace(plan, aggregatedVariablesTuple, naturalJoinRecipe, primaryIndexer, + aggregatorIndexerTrace); + + return CompilerHelper.checkAndTrimEqualVariables(plan, joinTrace).cloneFor(plan); + // if (!alreadyKnown) { + // return joinTrace.cloneFor(plan); + // } else { + // //final Integer equalsWithIndex = parentCompiled.getPosMapping().get(parentCompiled.getVariablesTuple()); + // } + } + + private CompiledSubPlan compileDeferred(AggregatorConstraint constraint, SubPlan plan, SubPlan parentPlan, + CompiledSubPlan parentCompiled) { + final PlanningTrace callTrace = referQuery(constraint.getReferredQuery(), plan, + constraint.getActualParametersTuple()); + + // hack: use some mask computations (+ the indexers) from a fake natural join against the called query + CompilerHelper.JoinHelper fakeJoinHelper = new CompilerHelper.JoinHelper(plan, parentCompiled, callTrace); + final RecipeTraceInfo primaryIndexer = fakeJoinHelper.getPrimaryIndexer(); + TupleMask callGroupMask = fakeJoinHelper.getSecondaryMask(); + + final List sideVariablesTuple = new ArrayList( + callGroupMask.transform(callTrace.getVariablesTuple())); + /* if (!booleanCheck) */ + sideVariablesTuple.add(constraint.getResultVariable()); + + IMultisetAggregationOperator operator = constraint.getAggregator().getOperator(); + + SingleColumnAggregatorRecipe columnAggregatorRecipe = FACTORY.createSingleColumnAggregatorRecipe(); + columnAggregatorRecipe.setParent(callTrace.getRecipe()); + columnAggregatorRecipe.setMultisetAggregationOperator(operator); + + int columnIndex = constraint.getAggregatedColumn(); + IPosetComparator posetComparator = null; + Mask groupMask = CompilerHelper.toRecipeMask(callGroupMask); + + // temporary solution to support the deprecated option for now + final boolean deleteAndRederiveEvaluationDep = + this.deleteAndRederiveEvaluation || ReteHintOptions.deleteRederiveEvaluation.getValueOrDefault(getHints(plan)); + + columnAggregatorRecipe.setDeleteRederiveEvaluation(deleteAndRederiveEvaluationDep); + if (deleteAndRederiveEvaluationDep || (this.timelyEvaluation != null)) { + List parameters = constraint.getReferredQuery().getParameters(); + IInputKey key = parameters.get(columnIndex).getDeclaredUnaryType(); + if (key != null && metaContext.isPosetKey(key)) { + posetComparator = metaContext.getPosetComparator(Collections.singleton(key)); + } + } + + if (posetComparator == null) { + columnAggregatorRecipe.setGroupByMask(groupMask); + columnAggregatorRecipe.setAggregableIndex(columnIndex); + } else { + MonotonicityInfo monotonicityInfo = FACTORY.createMonotonicityInfo(); + monotonicityInfo.setCoreMask(groupMask); + monotonicityInfo.setPosetMask(CompilerHelper.toRecipeMask( + TupleMask.selectSingle(columnIndex, constraint.getActualParametersTuple().getSize()))); + monotonicityInfo.setPosetComparator(posetComparator); + columnAggregatorRecipe.setOptionalMonotonicityInfo(monotonicityInfo); + } + + ReteNodeRecipe aggregatorRecipe = columnAggregatorRecipe; + PlanningTrace aggregatorTrace = new PlanningTrace(plan, sideVariablesTuple, aggregatorRecipe, callTrace); + + IndexerRecipe aggregatorIndexerRecipe = FACTORY.createAggregatorIndexerRecipe(); + aggregatorIndexerRecipe.setParent(aggregatorRecipe); + + int aggregatorWidth = sideVariablesTuple.size(); + int aggregateResultIndex = aggregatorWidth - 1; + + aggregatorIndexerRecipe.setMask(CompilerHelper.toRecipeMask(TupleMask.omit( + // aggregate according all but the last index + aggregateResultIndex, aggregatorWidth))); + PlanningTrace aggregatorIndexerTrace = new PlanningTrace(plan, sideVariablesTuple, aggregatorIndexerRecipe, + aggregatorTrace); + + JoinRecipe naturalJoinRecipe = FACTORY.createJoinRecipe(); + naturalJoinRecipe.setLeftParent((ProjectionIndexerRecipe) primaryIndexer.getRecipe()); + naturalJoinRecipe.setRightParent(aggregatorIndexerRecipe); + naturalJoinRecipe.setRightParentComplementaryMask(RecipesHelper.mask(aggregatorWidth, + // extend with last element only - the computation value + aggregateResultIndex)); + + // what if the new variable already has a value? + // even if already known, we add the new result variable, so that it can be filtered at the end + // boolean alreadyKnown = parentPlan.getVisibleVariables().contains(constraint.getResultVariable()); + + final List finalVariablesTuple = new ArrayList(parentCompiled.getVariablesTuple()); + finalVariablesTuple.add(constraint.getResultVariable()); + + PlanningTrace joinTrace = new PlanningTrace(plan, finalVariablesTuple, naturalJoinRecipe, primaryIndexer, + aggregatorIndexerTrace); + + return CompilerHelper.checkAndTrimEqualVariables(plan, joinTrace).cloneFor(plan); + // if (!alreadyKnown) { + // return joinTrace.cloneFor(plan); + // } else { + // //final Integer equalsWithIndex = parentCompiled.getPosMapping().get(parentCompiled.getVariablesTuple()); + // } + } + + private CompiledSubPlan compileDeferred(LeftJoinConstraint constraint, SubPlan plan, + CompiledSubPlan parentCompiled) { + var callTrace = referQuery(constraint.getReferredQuery(), plan, constraint.getActualParametersTuple()); + var fakeJoinHelper = new CompilerHelper.JoinHelper(plan, parentCompiled, callTrace); + var primaryIndexer = fakeJoinHelper.getPrimaryIndexer(); + var secondaryIndexer = fakeJoinHelper.getSecondaryIndexer(); + + var sideVariablesTuple = CompilerHelper.convertVariablesTuple(constraint.getActualParametersTuple()); + var resultVariable = constraint.getResultVariable(); + sideVariablesTuple.set(constraint.getOptionalColumn(), resultVariable); + + var leftNodeRecipe = FACTORY.createOuterJoinNodeRecipe(); + var secondaryIndexerRecipe = (ProjectionIndexerRecipe) secondaryIndexer.getRecipe(); + leftNodeRecipe.setParent(secondaryIndexerRecipe); + leftNodeRecipe.setDefaultValue(constraint.getDefaultValue()); + var leftNodeTrace = new PlanningTrace(plan, sideVariablesTuple, leftNodeRecipe, secondaryIndexer); + + var leftIndexerRecipe = FACTORY.createOuterJoinIndexerRecipe(); + leftIndexerRecipe.setParent(leftIndexerRecipe); + // Must make a copy of the mask here, because we are already using secondaryIndexerRecipe in the plan an mask + // is a containment reference. + var copyOfMask = EcoreUtil.copy(secondaryIndexerRecipe.getMask()); + leftIndexerRecipe.setMask(copyOfMask); + var leftIndexerTrace = new PlanningTrace(plan, sideVariablesTuple, leftIndexerRecipe, leftNodeTrace); + + var naturalJoinRecipe = FACTORY.createJoinRecipe(); + naturalJoinRecipe.setLeftParent((ProjectionIndexerRecipe) primaryIndexer.getRecipe()); + naturalJoinRecipe.setRightParent(leftIndexerRecipe); + var complementaryMask = fakeJoinHelper.getNaturalJoinRecipe().getRightParentComplementaryMask(); + naturalJoinRecipe.setRightParentComplementaryMask(complementaryMask); + + var primaryVariablesTuple = parentCompiled.getVariablesTuple(); + var joinedVariablesTuple = new ArrayList(primaryVariablesTuple.size() + 1); + joinedVariablesTuple.addAll(primaryVariablesTuple); + joinedVariablesTuple.add(resultVariable); + var joinTrace = new PlanningTrace(plan, joinedVariablesTuple, naturalJoinRecipe, primaryIndexer, + leftIndexerTrace); + + return CompilerHelper.checkAndTrimEqualVariables(plan, joinTrace).cloneFor(plan); + } + + private CompiledSubPlan compileDeferred(ExpressionEvaluation constraint, SubPlan plan, SubPlan parentPlan, + CompiledSubPlan parentCompiled) { + Map tupleNameMap = new HashMap(); + for (String name : constraint.getEvaluator().getInputParameterNames()) { + Map index = parentCompiled.getPosMapping(); + PVariable variable = constraint.getPSystem().getVariableByNameChecked(name); + Integer position = index.get(variable); + tupleNameMap.put(name, position); + } + + final PVariable outputVariable = constraint.getOutputVariable(); + final boolean booleanCheck = outputVariable == null; + + // TODO determine whether expression is costly + boolean cacheOutput = ReteHintOptions.cacheOutputOfEvaluatorsByDefault.getValueOrDefault(getHints(plan)); + // for (PAnnotation pAnnotation : + // plan.getBody().getPattern().getAnnotationsByName(EXPRESSION_EVALUATION_ANNOTATION"")) { + // for (Object value : pAnnotation.getAllValues("expensive")) { + // if (value instanceof Boolean) + // cacheOutput = (boolean) value; + // } + // } + + ExpressionEnforcerRecipe enforcerRecipe = booleanCheck ? FACTORY.createCheckRecipe() + : FACTORY.createEvalRecipe(); + enforcerRecipe.setParent(parentCompiled.getRecipe()); + enforcerRecipe.setExpression(RecipesHelper.expressionDefinition(constraint.getEvaluator())); + enforcerRecipe.setCacheOutput(cacheOutput); + if (enforcerRecipe instanceof EvalRecipe) { + ((EvalRecipe) enforcerRecipe).setUnwinding(constraint.isUnwinding()); + } + for (Entry entry : tupleNameMap.entrySet()) { + enforcerRecipe.getMappedIndices().put(entry.getKey(), entry.getValue()); + } + + final List enforcerVariablesTuple = new ArrayList(parentCompiled.getVariablesTuple()); + if (!booleanCheck) + enforcerVariablesTuple.add(outputVariable); + PlanningTrace enforcerTrace = new PlanningTrace(plan, enforcerVariablesTuple, enforcerRecipe, parentCompiled); + + return CompilerHelper.checkAndTrimEqualVariables(plan, enforcerTrace).cloneFor(plan); + } + + private CompiledSubPlan doCompileJoin(PJoin operation, SubPlan plan) { + final List compiledParents = getCompiledFormOfParents(plan); + final CompiledSubPlan leftCompiled = compiledParents.get(0); + final CompiledSubPlan rightCompiled = compiledParents.get(1); + + return compileToNaturalJoin(plan, leftCompiled, rightCompiled); + } + + private CompiledSubPlan compileToNaturalJoin(SubPlan plan, final PlanningTrace leftCompiled, + final PlanningTrace rightCompiled) { + // CHECK IF SPECIAL CASE + + // Is constant filtering applicable? + if (ReteHintOptions.useDiscriminatorDispatchersForConstantFiltering.getValueOrDefault(getHints(plan))) { + if (leftCompiled.getRecipe() instanceof ConstantRecipe + && rightCompiled.getVariablesTuple().containsAll(leftCompiled.getVariablesTuple())) { + return compileConstantFiltering(plan, rightCompiled, (ConstantRecipe) leftCompiled.getRecipe(), + leftCompiled.getVariablesTuple()); + } + if (rightCompiled.getRecipe() instanceof ConstantRecipe + && leftCompiled.getVariablesTuple().containsAll(rightCompiled.getVariablesTuple())) { + return compileConstantFiltering(plan, leftCompiled, (ConstantRecipe) rightCompiled.getRecipe(), + rightCompiled.getVariablesTuple()); + } + } + + // ELSE: ACTUAL JOIN + CompilerHelper.JoinHelper joinHelper = new CompilerHelper.JoinHelper(plan, leftCompiled, rightCompiled); + return new CompiledSubPlan(plan, joinHelper.getNaturalJoinVariablesTuple(), joinHelper.getNaturalJoinRecipe(), + joinHelper.getPrimaryIndexer(), joinHelper.getSecondaryIndexer()); + } + + private CompiledSubPlan doCompileProject(PProject operation, SubPlan plan) { + final List compiledParents = getCompiledFormOfParents(plan); + final CompiledSubPlan compiledParent = compiledParents.get(0); + + List projectedVariables = new ArrayList(operation.getToVariables()); + // Determinizing projection: try to keep original order (hopefully facilitates node reuse) + Map parentPosMapping = compiledParent.getPosMapping(); + Collections.sort(projectedVariables, Comparator.comparing(parentPosMapping::get)); + + return doProjectPlan(compiledParent, projectedVariables, true, + parentTrace -> parentTrace.cloneFor(plan), + (recipe, parentTrace) -> new PlanningTrace(plan, projectedVariables, recipe, parentTrace), + (recipe, parentTrace) -> new CompiledSubPlan(plan, projectedVariables, recipe, parentTrace) + ); + } + + /** + * Projects a subplan onto the specified variable tuple + * + * @param compiledParentPlan the compiled form of the subplan + * @param targetVariables list of variables to project to + * @param enforceUniqueness whether distinctness shall be enforced after the projection. + * Specify false only if directly connecting to a production node. + * @param reinterpretTraceFactory constructs a reinterpreted trace that simply relabels the compiled parent plan, + * in case it is sufficient + * @param intermediateTraceFactory constructs a recipe trace for an intermediate node, given the recipe of the + * node and its parent trace + * @param finalTraceFactory constructs a recipe trace for the final resulting node, given the recipe of the + * node and its parent trace + * @since 2.1 + */ + ResultTrace doProjectPlan( + final CompiledSubPlan compiledParentPlan, + final List targetVariables, + boolean enforceUniqueness, + Function reinterpretTraceFactory, + BiFunction intermediateTraceFactory, + BiFunction finalTraceFactory) { + if (targetVariables.equals(compiledParentPlan.getVariablesTuple())) // no projection needed + return reinterpretTraceFactory.apply(compiledParentPlan); + + // otherwise, we need at least a trimmer + TrimmerRecipe trimmerRecipe = CompilerHelper.makeTrimmerRecipe(compiledParentPlan, targetVariables); + + // do we need to eliminate duplicates? + SubPlan parentPlan = compiledParentPlan.getSubPlan(); + if (!enforceUniqueness || BuildHelper.areAllVariablesDetermined( + parentPlan, + targetVariables, + queryAnalyzer, + true)) { + // if uniqueness enforcess is unwanted or unneeeded, skip it + return finalTraceFactory.apply(trimmerRecipe, compiledParentPlan); + } else { + // add a uniqueness enforcer + UniquenessEnforcerRecipe recipe = FACTORY.createUniquenessEnforcerRecipe(); + recipe.getParents().add(trimmerRecipe); + + // temporary solution to support the deprecated option for now + final boolean deleteAndRederiveEvaluationDep = + this.deleteAndRederiveEvaluation || ReteHintOptions.deleteRederiveEvaluation.getValueOrDefault(getHints(parentPlan)); + + recipe.setDeleteRederiveEvaluation(deleteAndRederiveEvaluationDep); + if (deleteAndRederiveEvaluationDep || (this.timelyEvaluation != null)) { + CompilerHelper.PosetTriplet triplet = CompilerHelper.computePosetInfo(targetVariables, + parentPlan.getBody(), metaContext); + + if (triplet.comparator != null) { + MonotonicityInfo info = FACTORY.createMonotonicityInfo(); + info.setCoreMask(triplet.coreMask); + info.setPosetMask(triplet.posetMask); + info.setPosetComparator(triplet.comparator); + recipe.setOptionalMonotonicityInfo(info); + } + } + + RecipeTraceInfo trimmerTrace = intermediateTraceFactory.apply(trimmerRecipe, compiledParentPlan); + return finalTraceFactory.apply(recipe, trimmerTrace); + } + } + + /** + * Projects the final compiled form of a PBody onto the parameter tuple + * + * @param compiledBody the compiled form of the body, with all constraints enforced, not yet projected to + * query parameters + * @param enforceUniqueness whether distinctness shall be enforced after the projection. + * Specify false only if directly connecting to a production node. + * @since 2.1 + */ + RecipeTraceInfo projectBodyFinalToParameters( + final CompiledSubPlan compiledBody, + boolean enforceUniqueness) { + final PBody body = compiledBody.getSubPlan().getBody(); + final List parameterList = body.getSymbolicParameterVariables(); + + return doProjectPlan(compiledBody, parameterList, enforceUniqueness, + parentTrace -> parentTrace, + (recipe, parentTrace) -> new ParameterProjectionTrace(body, recipe, parentTrace), + (recipe, parentTrace) -> new ParameterProjectionTrace(body, recipe, parentTrace) + ); + } + + private CompiledSubPlan doCompileStart(PStart operation, SubPlan plan) { + if (!operation.getAPrioriVariables().isEmpty()) { + throw new IllegalArgumentException("Input variables unsupported by Rete: " + plan.toShortString()); + } + final ConstantRecipe recipe = FACTORY.createConstantRecipe(); + recipe.getConstantValues().clear(); + + return new CompiledSubPlan(plan, new ArrayList(), recipe); + } + + private CompiledSubPlan doCompileEnumerate(EnumerablePConstraint constraint, SubPlan plan) { + final PlanningTrace trimmedTrace = doEnumerateAndDeduplicate(constraint, plan); + + return trimmedTrace.cloneFor(plan); + } + + private PlanningTrace doEnumerateAndDeduplicate(EnumerablePConstraint constraint, SubPlan plan) { + final PlanningTrace coreTrace = doEnumerateDispatch(plan, constraint); + final PlanningTrace trimmedTrace = CompilerHelper.checkAndTrimEqualVariables(plan, coreTrace); + return trimmedTrace; + } + + private PlanningTrace doEnumerateDispatch(SubPlan plan, EnumerablePConstraint constraint) { + if (constraint instanceof RelationEvaluation) { + return compileEnumerable(plan, (RelationEvaluation) constraint); + } else if (constraint instanceof BinaryTransitiveClosure) { + return compileEnumerable(plan, (BinaryTransitiveClosure) constraint); + } else if (constraint instanceof BinaryReflexiveTransitiveClosure) { + return compileEnumerable(plan, (BinaryReflexiveTransitiveClosure) constraint); } else if (constraint instanceof RepresentativeElectionConstraint) { return compileEnumerable(plan, (RepresentativeElectionConstraint) constraint); - } else if (constraint instanceof ConstantValue) { - return compileEnumerable(plan, (ConstantValue) constraint); - } else if (constraint instanceof PositivePatternCall) { - return compileEnumerable(plan, (PositivePatternCall) constraint); - } else if (constraint instanceof TypeConstraint) { - return compileEnumerable(plan, (TypeConstraint) constraint); - } - throw new UnsupportedOperationException("Unknown enumerable constraint " + constraint); - } - - private PlanningTrace compileEnumerable(SubPlan plan, BinaryReflexiveTransitiveClosure constraint) { - // TODO the implementation would perform better if an inequality check would be used after tcRecipe and - // uniqueness enforcer be replaced by a transparent node with multiple parents, but such a node is not available - // in recipe metamodel in VIATRA 2.0 - - // Find called query - final PQuery referredQuery = constraint.getSupplierKey(); - final PlanningTrace callTrace = referQuery(referredQuery, plan, constraint.getVariablesTuple()); - - // Calculate irreflexive transitive closure - final TransitiveClosureRecipe tcRecipe = FACTORY.createTransitiveClosureRecipe(); - tcRecipe.setParent(callTrace.getRecipe()); - final PlanningTrace tcTrace = new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(constraint), tcRecipe, callTrace); - - // Enumerate universe type - final IInputKey inputKey = constraint.getUniverseType(); - final InputRecipe universeTypeRecipe = RecipesHelper.inputRecipe(inputKey, inputKey.getStringID(), inputKey.getArity()); - final PlanningTrace universeTypeTrace = new PlanningTrace(plan, CompilerHelper.convertVariablesTuple( - Tuples.staticArityFlatTupleOf(constraint.getVariablesTuple().get(0))), universeTypeRecipe); - - // Calculate reflexive access by duplicating universe type column - final TrimmerRecipe reflexiveRecipe = FACTORY.createTrimmerRecipe(); - reflexiveRecipe.setMask(RecipesHelper.mask(1, 0, 0)); - reflexiveRecipe.setParent(universeTypeRecipe); - final PlanningTrace reflexiveTrace = new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(constraint), reflexiveRecipe, universeTypeTrace); - - // Finally, reduce duplicates after a join - final UniquenessEnforcerRecipe brtcRecipe = FACTORY.createUniquenessEnforcerRecipe(); - brtcRecipe.getParents().add(tcRecipe); - brtcRecipe.getParents().add(reflexiveRecipe); - - return new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(constraint), brtcRecipe, reflexiveTrace, tcTrace); - } + } else if (constraint instanceof ConstantValue) { + return compileEnumerable(plan, (ConstantValue) constraint); + } else if (constraint instanceof PositivePatternCall) { + return compileEnumerable(plan, (PositivePatternCall) constraint); + } else if (constraint instanceof TypeConstraint) { + return compileEnumerable(plan, (TypeConstraint) constraint); + } + throw new UnsupportedOperationException("Unknown enumerable constraint " + constraint); + } + + private PlanningTrace compileEnumerable(SubPlan plan, BinaryReflexiveTransitiveClosure constraint) { + // TODO the implementation would perform better if an inequality check would be used after tcRecipe and + // uniqueness enforcer be replaced by a transparent node with multiple parents, but such a node is not + // available + // in recipe metamodel in VIATRA 2.0 + + // Find called query + final PQuery referredQuery = constraint.getSupplierKey(); + final PlanningTrace callTrace = referQuery(referredQuery, plan, constraint.getVariablesTuple()); + + // Calculate irreflexive transitive closure + final TransitiveClosureRecipe tcRecipe = FACTORY.createTransitiveClosureRecipe(); + tcRecipe.setParent(callTrace.getRecipe()); + final PlanningTrace tcTrace = new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(constraint), + tcRecipe, callTrace); + + // Enumerate universe type + final IInputKey inputKey = constraint.getUniverseType(); + final InputRecipe universeTypeRecipe = RecipesHelper.inputRecipe(inputKey, inputKey.getStringID(), + inputKey.getArity()); + final PlanningTrace universeTypeTrace = new PlanningTrace(plan, CompilerHelper.convertVariablesTuple( + Tuples.staticArityFlatTupleOf(constraint.getVariablesTuple().get(0))), universeTypeRecipe); + + // Calculate reflexive access by duplicating universe type column + final TrimmerRecipe reflexiveRecipe = FACTORY.createTrimmerRecipe(); + reflexiveRecipe.setMask(RecipesHelper.mask(1, 0, 0)); + reflexiveRecipe.setParent(universeTypeRecipe); + final PlanningTrace reflexiveTrace = new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(constraint), + reflexiveRecipe, universeTypeTrace); + + // Finally, reduce duplicates after a join + final UniquenessEnforcerRecipe brtcRecipe = FACTORY.createUniquenessEnforcerRecipe(); + brtcRecipe.getParents().add(tcRecipe); + brtcRecipe.getParents().add(reflexiveRecipe); + + return new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(constraint), brtcRecipe, reflexiveTrace, + tcTrace); + } private PlanningTrace compileEnumerable(SubPlan plan, RepresentativeElectionConstraint constraint) { var referredQuery = constraint.getSupplierKey(); @@ -839,109 +901,110 @@ private PlanningTrace compileEnumerable(SubPlan plan, RepresentativeElectionCons return new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(constraint), recipe, callTrace); } - private PlanningTrace compileEnumerable(SubPlan plan, BinaryTransitiveClosure constraint) { - final PQuery referredQuery = constraint.getSupplierKey(); - final PlanningTrace callTrace = referQuery(referredQuery, plan, constraint.getVariablesTuple()); - - final TransitiveClosureRecipe recipe = FACTORY.createTransitiveClosureRecipe(); - recipe.setParent(callTrace.getRecipe()); - - return new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(constraint), recipe, callTrace); - } - - private PlanningTrace compileEnumerable(SubPlan plan, RelationEvaluation constraint) { - final List parentRecipes = new ArrayList(); - final List parentTraceInfos = new ArrayList(); - for (final PQuery inputQuery : constraint.getReferredQueries()) { - final CompiledQuery compiledQuery = getCompiledForm(inputQuery); - parentRecipes.add(compiledQuery.getRecipe()); - parentTraceInfos.add(compiledQuery); - } - final RelationEvaluationRecipe recipe = FACTORY.createRelationEvaluationRecipe(); - recipe.getParents().addAll(parentRecipes); - recipe.setEvaluator(RecipesHelper.expressionDefinition(constraint.getEvaluator())); - return new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(constraint), recipe, parentTraceInfos); - } - - private PlanningTrace compileEnumerable(SubPlan plan, PositivePatternCall constraint) { - final PQuery referredQuery = constraint.getReferredQuery(); - return referQuery(referredQuery, plan, constraint.getVariablesTuple()); - } - - private PlanningTrace compileEnumerable(SubPlan plan, TypeConstraint constraint) { - final IInputKey inputKey = constraint.getSupplierKey(); - final InputRecipe recipe = RecipesHelper.inputRecipe(inputKey, inputKey.getStringID(), inputKey.getArity()); - return new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(constraint), recipe); - } - - private PlanningTrace compileEnumerable(SubPlan plan, ConstantValue constraint) { - final ConstantRecipe recipe = FACTORY.createConstantRecipe(); - recipe.getConstantValues().add(constraint.getSupplierKey()); - return new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(constraint), recipe); - } - - // TODO handle recursion - private PlanningTrace referQuery(PQuery query, SubPlan plan, Tuple actualParametersTuple) { - RecipeTraceInfo referredQueryTrace = originalTraceOfReferredQuery(query); - return new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(actualParametersTuple), - referredQueryTrace.getRecipe(), referredQueryTrace.getParentRecipeTracesForCloning()); - } - - private RecipeTraceInfo originalTraceOfReferredQuery(PQuery query) { - // eliminate superfluous production node? - if (PVisibility.EMBEDDED == query.getVisibility()) { // currently inline patterns only - Set rewrittenBodies = normalizer.rewrite(query).getBodies(); - if (1 == rewrittenBodies.size()) { // non-disjunctive - // TODO in the future, check if non-recursive - (not currently permitted) - - PBody pBody = rewrittenBodies.iterator().next(); - SubPlan bodyFinalPlan = getPlan(pBody); - - // skip over any projections at the end - bodyFinalPlan = BuildHelper.eliminateTrailingProjections(bodyFinalPlan); - - // TODO checkAndTrimEqualVariables may introduce superfluous trim, - // but whatever (no uniqueness enforcer needed) - - // compile body - final CompiledSubPlan compiledBody = getCompiledForm(bodyFinalPlan); - - // project to parameter list, add uniqueness enforcer if necessary - return projectBodyFinalToParameters(compiledBody, true /* ensure uniqueness, as no production node is used */); - } - } - - // otherwise, regular reference to recipe realizing the query - return getCompiledForm(query); - } - - protected List getCompiledFormOfParents(SubPlan plan) { - List results = new ArrayList(); - for (SubPlan parentPlan : plan.getParentPlans()) { - results.add(getCompiledForm(parentPlan)); - } - return results; - } - - /** - * Returns an unmodifiable view of currently cached compiled queries. - */ - public Map getCachedCompiledQueries() { - return Collections.unmodifiableMap(queryCompilerCache); - } - - /** - * Returns an unmodifiable view of currently cached query plans. - */ - public Map getCachedQueryPlans() { - return Collections.unmodifiableMap(plannerCache); - } - - private QueryEvaluationHint getHints(SubPlan plan) { - return getHints(plan.getBody().getPattern()); - } - - private QueryEvaluationHint getHints(PQuery pattern) { - return hintProvider.getQueryEvaluationHint(pattern); - } + private PlanningTrace compileEnumerable(SubPlan plan, BinaryTransitiveClosure constraint) { + final PQuery referredQuery = constraint.getSupplierKey(); + final PlanningTrace callTrace = referQuery(referredQuery, plan, constraint.getVariablesTuple()); + + final TransitiveClosureRecipe recipe = FACTORY.createTransitiveClosureRecipe(); + recipe.setParent(callTrace.getRecipe()); + + return new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(constraint), recipe, callTrace); + } + + private PlanningTrace compileEnumerable(SubPlan plan, RelationEvaluation constraint) { + final List parentRecipes = new ArrayList(); + final List parentTraceInfos = new ArrayList(); + for (final PQuery inputQuery : constraint.getReferredQueries()) { + final CompiledQuery compiledQuery = getCompiledForm(inputQuery); + parentRecipes.add(compiledQuery.getRecipe()); + parentTraceInfos.add(compiledQuery); + } + final RelationEvaluationRecipe recipe = FACTORY.createRelationEvaluationRecipe(); + recipe.getParents().addAll(parentRecipes); + recipe.setEvaluator(RecipesHelper.expressionDefinition(constraint.getEvaluator())); + return new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(constraint), recipe, parentTraceInfos); + } + + private PlanningTrace compileEnumerable(SubPlan plan, PositivePatternCall constraint) { + final PQuery referredQuery = constraint.getReferredQuery(); + return referQuery(referredQuery, plan, constraint.getVariablesTuple()); + } + + private PlanningTrace compileEnumerable(SubPlan plan, TypeConstraint constraint) { + final IInputKey inputKey = constraint.getSupplierKey(); + final InputRecipe recipe = RecipesHelper.inputRecipe(inputKey, inputKey.getStringID(), inputKey.getArity()); + return new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(constraint), recipe); + } + + private PlanningTrace compileEnumerable(SubPlan plan, ConstantValue constraint) { + final ConstantRecipe recipe = FACTORY.createConstantRecipe(); + recipe.getConstantValues().add(constraint.getSupplierKey()); + return new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(constraint), recipe); + } + + // TODO handle recursion + private PlanningTrace referQuery(PQuery query, SubPlan plan, Tuple actualParametersTuple) { + RecipeTraceInfo referredQueryTrace = originalTraceOfReferredQuery(query); + return new PlanningTrace(plan, CompilerHelper.convertVariablesTuple(actualParametersTuple), + referredQueryTrace.getRecipe(), referredQueryTrace.getParentRecipeTracesForCloning()); + } + + private RecipeTraceInfo originalTraceOfReferredQuery(PQuery query) { + // eliminate superfluous production node? + if (PVisibility.EMBEDDED == query.getVisibility()) { // currently inline patterns only + Set rewrittenBodies = normalizer.rewrite(query).getBodies(); + if (1 == rewrittenBodies.size()) { // non-disjunctive + // TODO in the future, check if non-recursive - (not currently permitted) + + PBody pBody = rewrittenBodies.iterator().next(); + SubPlan bodyFinalPlan = getPlan(pBody); + + // skip over any projections at the end + bodyFinalPlan = BuildHelper.eliminateTrailingProjections(bodyFinalPlan); + + // TODO checkAndTrimEqualVariables may introduce superfluous trim, + // but whatever (no uniqueness enforcer needed) + + // compile body + final CompiledSubPlan compiledBody = getCompiledForm(bodyFinalPlan); + + // project to parameter list, add uniqueness enforcer if necessary + return projectBodyFinalToParameters(compiledBody, true /* ensure uniqueness, as no production node is + used */); + } + } + + // otherwise, regular reference to recipe realizing the query + return getCompiledForm(query); + } + + protected List getCompiledFormOfParents(SubPlan plan) { + List results = new ArrayList(); + for (SubPlan parentPlan : plan.getParentPlans()) { + results.add(getCompiledForm(parentPlan)); + } + return results; + } + + /** + * Returns an unmodifiable view of currently cached compiled queries. + */ + public Map getCachedCompiledQueries() { + return Collections.unmodifiableMap(queryCompilerCache); + } + + /** + * Returns an unmodifiable view of currently cached query plans. + */ + public Map getCachedQueryPlans() { + return Collections.unmodifiableMap(plannerCache); + } + + private QueryEvaluationHint getHints(SubPlan plan) { + return getHints(plan.getBody().getPattern()); + } + + private QueryEvaluationHint getHints(PQuery pattern) { + return hintProvider.getQueryEvaluationHint(pattern); + } } diff --git a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/ConnectionFactory.java b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/ConnectionFactory.java index c69757b60..fe70cbc3f 100644 --- a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/ConnectionFactory.java +++ b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/ConnectionFactory.java @@ -11,6 +11,7 @@ import tools.refinery.interpreter.matchers.tuple.Tuple; import tools.refinery.interpreter.rete.aggregation.IndexerBasedAggregatorNode; +import tools.refinery.interpreter.rete.aggregation.LeftJoinNode; import tools.refinery.interpreter.rete.boundary.InputConnector; import tools.refinery.interpreter.rete.eval.RelationEvaluatorNode; import tools.refinery.interpreter.rete.index.DualInputNode; @@ -78,9 +79,12 @@ public void connectToParents(RecipeTraceInfo recipeTrace, Node freshNode) { Slots slots = avoidActiveNodeConflict(parentTraces.get(0), parentTraces.get(1)); beta.connectToIndexers(slots.primary, slots.secondary); } else if (recipe instanceof IndexerBasedAggregatorRecipe) { - final IndexerBasedAggregatorNode aggregator = (IndexerBasedAggregatorNode) freshNode; - final IndexerBasedAggregatorRecipe aggregatorRecipe = (IndexerBasedAggregatorRecipe) recipe; - aggregator.initializeWith((ProjectionIndexer) resolveIndexer(aggregatorRecipe.getParent())); + final IndexerBasedAggregatorNode aggregator = (IndexerBasedAggregatorNode) freshNode; + final IndexerBasedAggregatorRecipe aggregatorRecipe = (IndexerBasedAggregatorRecipe) recipe; + aggregator.initializeWith((ProjectionIndexer) resolveIndexer(aggregatorRecipe.getParent())); + } else if (recipe instanceof OuterJoinNodeRecipe outerJoinNodeRecipe) { + var leftJoinNode = (LeftJoinNode) freshNode; + leftJoinNode.initializeWith((ProjectionIndexer) resolveIndexer(outerJoinNodeRecipe.getParent())); } else if (recipe instanceof MultiParentNodeRecipe) { final Receiver receiver = (Receiver) freshNode; List parentRecipes = ((MultiParentNodeRecipe) recipe).getParents(); diff --git a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/NodeFactory.java b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/NodeFactory.java index 301b757de..1f6a01ae2 100644 --- a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/NodeFactory.java +++ b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/NodeFactory.java @@ -20,6 +20,7 @@ import tools.refinery.interpreter.rete.aggregation.ColumnAggregatorNode; import tools.refinery.interpreter.rete.aggregation.CountNode; import tools.refinery.interpreter.rete.aggregation.IAggregatorNode; +import tools.refinery.interpreter.rete.aggregation.LeftJoinNode; import tools.refinery.interpreter.rete.aggregation.timely.FaithfulParallelTimelyColumnAggregatorNode; import tools.refinery.interpreter.rete.aggregation.timely.FaithfulSequentialTimelyColumnAggregatorNode; import tools.refinery.interpreter.rete.aggregation.timely.FirstOnlyParallelTimelyColumnAggregatorNode; @@ -72,18 +73,25 @@ public Indexer createIndexer(ReteContainer reteContainer, IndexerRecipe recipe, return parentNode.constructIndex(toMask(recipe.getMask()), traces); // already traced } else if (recipe instanceof AggregatorIndexerRecipe) { - int indexOfAggregateResult = recipe.getParent().getArity(); - int resultPosition = recipe.getMask().getSourceIndices().lastIndexOf(indexOfAggregateResult); - - IAggregatorNode aggregatorNode = (IAggregatorNode) parentNode; - final Indexer result = (resultPosition == -1) ? aggregatorNode.getAggregatorOuterIndexer() - : aggregatorNode.getAggregatorOuterIdentityIndexer(resultPosition); - - for (TraceInfo traceInfo : traces) - result.assignTraceInfo(traceInfo); - return result; - } else - throw new IllegalArgumentException("Unkown Indexer recipe: " + recipe); + int indexOfAggregateResult = recipe.getParent().getArity(); + int resultPosition = recipe.getMask().getSourceIndices().lastIndexOf(indexOfAggregateResult); + + IAggregatorNode aggregatorNode = (IAggregatorNode) parentNode; + final Indexer result = (resultPosition == -1) ? aggregatorNode.getAggregatorOuterIndexer() + : aggregatorNode.getAggregatorOuterIdentityIndexer(resultPosition); + + for (TraceInfo traceInfo : traces) + result.assignTraceInfo(traceInfo); + return result; + } else if (recipe instanceof OuterJoinIndexerRecipe) { + var leftJoinNode = (LeftJoinNode) parentNode; + var result = leftJoinNode.getOuterIndexer(); + for (TraceInfo traceInfo : traces) + result.assignTraceInfo(traceInfo); + return result; + } else { + throw new IllegalArgumentException("Unkown Indexer recipe: " + recipe); + } } /** @@ -134,6 +142,8 @@ private Supplier instantiateNodeDispatch(ReteContainer reteContainer, ReteNodeRe return instantiateNode(reteContainer, (CountAggregatorRecipe) recipe); if (recipe instanceof SingleColumnAggregatorRecipe) return instantiateNode(reteContainer, (SingleColumnAggregatorRecipe) recipe); + if (recipe instanceof OuterJoinNodeRecipe outerJoinNodeRecipe) + return instantiateNode(reteContainer, outerJoinNodeRecipe); if (recipe instanceof DiscriminatorDispatcherRecipe) return instantiateNode(reteContainer, (DiscriminatorDispatcherRecipe) recipe); if (recipe instanceof DiscriminatorBucketRecipe) @@ -246,6 +256,10 @@ private Supplier instantiateNode(ReteContainer reteContainer, SingleColumnAggreg } } + private Supplier instantiateNode(ReteContainer reteContainer, OuterJoinNodeRecipe recipe) { + return new LeftJoinNode(reteContainer, recipe.getDefaultValue()); + } + private Supplier instantiateNode(ReteContainer reteContainer, TransitiveClosureRecipe recipe) { return new TransitiveClosureNode(reteContainer); } diff --git a/subprojects/interpreter/src/main/java/tools/refinery/interpreter/matchers/psystem/basicdeferred/LeftJoinConstraint.java b/subprojects/interpreter/src/main/java/tools/refinery/interpreter/matchers/psystem/basicdeferred/LeftJoinConstraint.java new file mode 100644 index 000000000..1c1a895eb --- /dev/null +++ b/subprojects/interpreter/src/main/java/tools/refinery/interpreter/matchers/psystem/basicdeferred/LeftJoinConstraint.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2010-2016, Tamas Szabo, Istvan Rath and Daniel Varro + * Copyright (c) 2024 The Refinery Authors + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package tools.refinery.interpreter.matchers.psystem.basicdeferred; + +import tools.refinery.interpreter.matchers.context.IQueryMetaContext; +import tools.refinery.interpreter.matchers.psystem.ITypeInfoProviderConstraint; +import tools.refinery.interpreter.matchers.psystem.PBody; +import tools.refinery.interpreter.matchers.psystem.PVariable; +import tools.refinery.interpreter.matchers.psystem.TypeJudgement; +import tools.refinery.interpreter.matchers.psystem.queries.PQuery; +import tools.refinery.interpreter.matchers.tuple.Tuple; +import tools.refinery.interpreter.matchers.tuple.Tuples; + +import java.util.Collections; +import java.util.Set; + +public class LeftJoinConstraint extends PatternCallBasedDeferred implements ITypeInfoProviderConstraint { + protected PVariable resultVariable; + protected int optionalColumn; + protected Object defaultValue; + + public LeftJoinConstraint(PBody pBody, Tuple actualParametersTuple, PQuery query, PVariable resultVariable, + int optionalColumn, Object defaultValue) { + super(pBody, actualParametersTuple, query, Collections.singleton(resultVariable)); + this.resultVariable = resultVariable; + this.optionalColumn = optionalColumn; + this.defaultValue = defaultValue; + } + + public PVariable getResultVariable() { + return resultVariable; + } + + public int getOptionalColumn() { + return optionalColumn; + } + + public Object getDefaultValue() { + return defaultValue; + } + + @Override + public Set getDeducedVariables() { + return Collections.singleton(resultVariable); + } + + @Override + protected void doDoReplaceVariables(PVariable obsolete, PVariable replacement) { + if (resultVariable.equals(obsolete)) { + resultVariable = replacement; + } + } + + @Override + protected Set getCandidateQuantifiedVariables() { + return actualParametersTuple.getDistinctElements(); + } + + @Override + protected String toStringRest() { + return query.getFullyQualifiedName() + "@" + actualParametersTuple.toString() + "->" + + resultVariable.toString(); + } + + @Override + public Set getImpliedJudgements(IQueryMetaContext context) { + var optionalParameter = getReferredQuery().getParameters().get(optionalColumn); + var unaryType = optionalParameter.getDeclaredUnaryType(); + if (unaryType != null && !context.isEnumerable(unaryType)) { + // The outer join makes the result variable non-enumerable, since the default value might not be present in + // the model. + return Set.of(new TypeJudgement(unaryType, Tuples.staticArityFlatTupleOf(resultVariable))); + } + return Set.of(); + } +} diff --git a/subprojects/interpreter/src/main/java/tools/refinery/interpreter/matchers/psystem/rewriters/PBodyCopier.java b/subprojects/interpreter/src/main/java/tools/refinery/interpreter/matchers/psystem/rewriters/PBodyCopier.java index 993501856..1e580599c 100644 --- a/subprojects/interpreter/src/main/java/tools/refinery/interpreter/matchers/psystem/rewriters/PBodyCopier.java +++ b/subprojects/interpreter/src/main/java/tools/refinery/interpreter/matchers/psystem/rewriters/PBodyCopier.java @@ -137,7 +137,9 @@ protected void copyConstraint(PConstraint constraint) { } else if (constraint instanceof PatternMatchCounter) { copyPatternMatchCounterConstraint((PatternMatchCounter) constraint); } else if (constraint instanceof AggregatorConstraint) { - copyAggregatorConstraint((AggregatorConstraint) constraint); + copyAggregatorConstraint((AggregatorConstraint) constraint); + } else if (constraint instanceof LeftJoinConstraint leftJoinConstraint) { + copyLeftJoinConstraint((LeftJoinConstraint) constraint); } else if (constraint instanceof ExpressionEvaluation) { copyExpressionEvaluationConstraint((ExpressionEvaluation) constraint); } else { @@ -256,6 +258,15 @@ protected void copyAggregatorConstraint(AggregatorConstraint constraint) { constraint.getReferredQuery(), mappedResultVariable, constraint.getAggregatedColumn())); } + protected void copyLeftJoinConstraint(LeftJoinConstraint constraint) { + PVariable[] mappedVariables = extractMappedVariables(constraint); + PVariable mappedResultVariable = variableMapping.get(constraint.getResultVariable()); + Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables); + addTrace(constraint, new LeftJoinConstraint(body, variablesTuple, + constraint.getReferredQuery(), mappedResultVariable, constraint.getOptionalColumn(), + constraint.getDefaultValue())); + } + protected void copyExpressionEvaluationConstraint(ExpressionEvaluation expressionEvaluation) { PVariable mappedOutputVariable = variableMapping.get(expressionEvaluation.getOutputVariable()); addTrace(expressionEvaluation, new ExpressionEvaluation(body, diff --git a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java index a09a475b4..8dad8f8a5 100644 --- a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java +++ b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java @@ -24,9 +24,9 @@ import tools.refinery.language.naming.NamingUtil; import tools.refinery.language.naming.ProblemQualifiedNameConverter; import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; +import tools.refinery.language.scoping.imports.ImportAdapterProvider; import tools.refinery.language.scoping.imports.ImportCollector; import tools.refinery.language.utils.BuiltinSymbols; -import tools.refinery.language.utils.ProblemDesugarer; import tools.refinery.language.utils.ProblemUtil; import tools.refinery.language.validation.ReferenceCounter; @@ -43,10 +43,10 @@ public class ProblemCrossrefProposalProvider extends IdeCrossrefProposalProvider private ReferenceCounter referenceCounter; @Inject - private ProblemDesugarer desugarer; + private ImportCollector importCollector; @Inject - private ImportCollector importCollector; + private ImportAdapterProvider importAdapterProvider; @Override protected Iterable queryScope(IScope scope, CrossReference crossReference, @@ -125,16 +125,27 @@ protected boolean shouldBeVisible(IEObjectDescription candidate, CrossReference return oppositeShouldBeVisible(candidateReferenceDeclaration, context); } - var builtinSymbolsOption = desugarer.getBuiltinSymbols(context.getRootModel()); - if (builtinSymbolsOption.isEmpty()) { - return true; + if (eReference.equals(ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__VARIABLE_OR_NODE)) { + var assignedVariable = getAssignedVariable(context.getCurrentModel()); + if (assignedVariable != null && Objects.equals(assignedVariable, candidate.getEObjectOrProxy())) { + return false; + } } - var builtinSymbols = builtinSymbolsOption.get(); + + var builtinSymbols = importAdapterProvider.getBuiltinSymbols(context.getResource()); return builtinSymbolAwareShouldBeVisible(candidate, context, eReference, builtinSymbols, candidateEObjectOrProxy); } + private VariableOrNode getAssignedVariable(EObject context) { + var assignmentExpr = EcoreUtil2.getContainerOfType(context, AssignmentExpr.class); + if (assignmentExpr != null && assignmentExpr.getLeft() instanceof VariableOrNodeExpr variableOrNodeExpr) { + return variableOrNodeExpr.getVariableOrNode(); + } + return null; + } + private boolean importedModuleShouldBeVisible(IEObjectDescription candidate, ContentAssistContext context) { var moduleKind = candidate.getUserData(ProblemResourceDescriptionStrategy.MODULE_KIND); if (!ModuleKind.MODULE.getName().equals(moduleKind)) { @@ -187,8 +198,8 @@ private boolean builtinSymbolAwareShouldBeVisible( if (builtinSymbols.exists().equals(candidateEObjectOrProxy)) { return false; } - var arity = candidate.getUserData(ProblemResourceDescriptionStrategy.ARITY); - return arity == null || arity.equals("1"); + return ProblemResourceDescriptionStrategy.TYPE_LIKE_TRUE.equals( + candidate.getUserData(ProblemResourceDescriptionStrategy.TYPE_LIKE)); } if (eReference.equals(ProblemPackage.Literals.CLASS_DECLARATION__SUPER_TYPES)) { diff --git a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java index 891c73c7d..06f0e7586 100644 --- a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java +++ b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java @@ -18,7 +18,6 @@ import org.eclipse.xtext.util.CancelIndicator; import org.jetbrains.annotations.NotNull; import tools.refinery.language.model.problem.*; -import tools.refinery.language.utils.ProblemDesugarer; import tools.refinery.language.utils.ProblemUtil; import java.util.List; @@ -26,6 +25,8 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighlightingCalculator { private static final String BUILTIN_CLASS = "builtin"; private static final String ABSTRACT_CLASS = "abstract"; + private static final String DATATYPE_CLASS = "datatype"; + private static final String AGGREGATOR_CLASS = "aggregator"; private static final String CONTAINMENT_CLASS = "containment"; private static final String ERROR_CLASS = "error"; private static final String NODE_CLASS = "node"; @@ -35,9 +36,6 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli @Inject private OperationCanceledManager operationCanceledManager; - @Inject - private ProblemDesugarer desugarer; - @Inject private TypeHashProvider typeHashProvider; @@ -112,8 +110,14 @@ private String[] getUserDefinedElementHighlightClass(EObject eObject, EReference if (eObject instanceof ClassDeclaration classDeclaration && classDeclaration.isAbstract()) { classesBuilder.add(ABSTRACT_CLASS); } + if (eObject instanceof DatatypeDeclaration) { + classesBuilder.add(DATATYPE_CLASS); + } + if (eObject instanceof AggregatorDeclaration) { + classesBuilder.add(AGGREGATOR_CLASS); + } if (eObject instanceof ReferenceDeclaration referenceDeclaration - && desugarer.isContainmentReference(referenceDeclaration)) { + && ProblemUtil.isContainmentReference(referenceDeclaration)) { classesBuilder.add(CONTAINMENT_CLASS); } if (isError && reference != null) { diff --git a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/TypeHashProvider.java b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/TypeHashProvider.java index 82a6af06d..2821e1b68 100644 --- a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/TypeHashProvider.java +++ b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/TypeHashProvider.java @@ -17,6 +17,7 @@ import org.eclipse.xtext.util.IResourceScopeCache; import tools.refinery.language.documentation.DocumentationCommentParser; import tools.refinery.language.model.problem.*; +import tools.refinery.language.naming.NamingUtil; import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; import tools.refinery.language.scoping.imports.ImportCollector; import tools.refinery.language.utils.ProblemUtil; @@ -55,7 +56,7 @@ public String getTypeHash(Relation relation) { if (qualifiedName == null) { return null; } - var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); + var qualifiedNameString = qualifiedNameConverter.toString(NamingUtil.addRootPrefix(qualifiedName)); var problem = EcoreUtil2.getContainerOfType(relation, Problem.class); if (problem == null) { return null; diff --git a/subprojects/language-model/problem.aird b/subprojects/language-model/problem.aird index cbe413cd4..f8a50a768 100644 --- a/subprojects/language-model/problem.aird +++ b/subprojects/language-model/problem.aird @@ -7,11 +7,11 @@ build/resources/main/model/problem.genmodel - + - + @@ -69,7 +69,7 @@ - + @@ -95,7 +95,7 @@ - + @@ -104,7 +104,7 @@ - + @@ -113,7 +113,7 @@ - + @@ -219,7 +219,7 @@ - + @@ -241,7 +241,7 @@ - + @@ -250,7 +250,7 @@ - + @@ -259,7 +259,7 @@ - + @@ -268,32 +268,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -310,6 +285,10 @@ + + + + @@ -319,15 +298,11 @@ - - - - - + @@ -336,7 +311,7 @@ - + @@ -345,7 +320,7 @@ - + @@ -354,7 +329,7 @@ - + @@ -363,7 +338,7 @@ - + @@ -372,7 +347,7 @@ - + @@ -381,7 +356,7 @@ - + @@ -392,58 +367,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -495,6 +418,24 @@ + + + + + + + + + + + + + + + + + + @@ -604,7 +545,7 @@ - + @@ -738,17 +679,17 @@ - + - + - + - + @@ -1218,17 +1159,17 @@ - + - + - + - + @@ -1250,17 +1191,17 @@ - + - + - + - + @@ -1279,114 +1220,35 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - + @@ -1406,6 +1268,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1467,7 +1441,7 @@ - + KEEP_LOCATION @@ -1477,7 +1451,7 @@ - + @@ -1486,7 +1460,7 @@ - + @@ -1513,7 +1487,7 @@ - + KEEP_LOCATION @@ -1635,7 +1609,7 @@ - + KEEP_LOCATION @@ -2120,49 +2094,6 @@ - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2173,59 +2104,59 @@ - + + + + + + + + + - + - + - + - + - + - + KEEP_LOCATION KEEP_SIZE KEEP_RATIO - + - - - - - - - - - + - + italic - + @@ -2404,7 +2335,7 @@ - + KEEP_LOCATION @@ -2428,9 +2359,9 @@ - - - + + + @@ -2467,12 +2398,12 @@ - + - + italic - + @@ -2553,119 +2484,6 @@ - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - italic - - - - - - - - - - - italic - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2782,6 +2600,86 @@ + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + @@ -2808,7 +2706,7 @@ - + @@ -2817,7 +2715,7 @@ - + @@ -2826,7 +2724,7 @@ - + @@ -2877,19 +2775,23 @@ - - - + + + - - - + + + + + + + - + @@ -2907,7 +2809,7 @@ - + @@ -2925,41 +2827,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2967,7 +2840,7 @@ - + @@ -2980,7 +2853,7 @@ - + @@ -2993,7 +2866,7 @@ - + @@ -3006,7 +2879,7 @@ - + @@ -3024,7 +2897,7 @@ - + @@ -3037,7 +2910,7 @@ - + @@ -3050,7 +2923,7 @@ - + @@ -3083,14 +2956,6 @@ - - - - - - - - @@ -3103,7 +2968,7 @@ - + @@ -3134,7 +2999,7 @@ - + @@ -3143,45 +3008,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -3190,16 +3017,7 @@ - - - - - - - - - - + @@ -3212,7 +3030,7 @@ - + @@ -3237,7 +3055,73 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3284,7 +3168,7 @@ - + @@ -3300,7 +3184,7 @@ - + @@ -3322,33 +3206,33 @@ - + - + - + - + - + - + - + - + @@ -3370,17 +3254,17 @@ - + - + - + - + @@ -3450,17 +3334,17 @@ - + - + - + @@ -3498,17 +3382,17 @@ - + - + - + - + @@ -3573,7 +3457,7 @@ - + @@ -3642,17 +3526,17 @@ - + - + - + - + @@ -3672,22 +3556,6 @@ - - - - - - - - - - - - - - - - @@ -3736,22 +3604,6 @@ - - - - - - - - - - - - - - - - @@ -3768,6 +3620,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3783,7 +3747,7 @@ - + KEEP_LOCATION @@ -3832,7 +3796,7 @@ - + KEEP_LOCATION @@ -3844,7 +3808,7 @@ - + KEEP_LOCATION @@ -3996,18 +3960,26 @@ - - - - + + + + + + + + + + + + - - - - + + + + @@ -4080,24 +4052,16 @@ - + KEEP_LOCATION KEEP_SIZE KEEP_RATIO - + - - - - - - - - @@ -4112,49 +4076,6 @@ - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -4168,7 +4089,7 @@ - + KEEP_LOCATION @@ -4276,12 +4197,12 @@ - + - + italic - + @@ -4385,12 +4306,12 @@ - + - + italic - + @@ -4498,33 +4419,17 @@ - - - - - - - - - - - - - - - - - - - + + + - - - + + + @@ -4633,7 +4538,7 @@ - + KEEP_LOCATION @@ -4659,80 +4564,6 @@ - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - italic - - - - - @@ -4780,29 +4611,6 @@ - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - - - - italic - - - - - @@ -4877,6 +4685,173 @@ + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + + + + italic + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + italic + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + italic + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + italic + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + diff --git a/subprojects/language-model/src/main/resources/model/problem.ecore b/subprojects/language-model/src/main/resources/model/problem.ecore index 97355516d..9a349490c 100644 --- a/subprojects/language-model/src/main/resources/model/problem.ecore +++ b/subprojects/language-model/src/main/resources/model/problem.ecore @@ -13,13 +13,13 @@ + eType="#//ReferenceDeclaration" containment="true"/> - + @@ -150,12 +150,6 @@ - - - - - - @@ -164,14 +158,13 @@ - - - - + + - - + + + @@ -198,8 +191,9 @@ - - + + + @@ -209,13 +203,7 @@ containment="true"/> - - - - - - - + @@ -225,7 +213,7 @@ - + @@ -244,22 +232,7 @@ - - - - - - - - - - - - - - @@ -276,4 +249,19 @@ + + + + + + + + + + + + + + + diff --git a/subprojects/language-model/src/main/resources/model/problem.genmodel b/subprojects/language-model/src/main/resources/model/problem.genmodel index 23458ee5e..2a1d8522d 100644 --- a/subprojects/language-model/src/main/resources/model/problem.genmodel +++ b/subprojects/language-model/src/main/resources/model/problem.genmodel @@ -16,12 +16,6 @@ - - - - - - @@ -30,12 +24,11 @@ - - - - + + + @@ -50,19 +43,9 @@ - - - - - - - - - - - - - + + + @@ -73,6 +56,10 @@ + + + + @@ -202,7 +189,7 @@ - + @@ -210,7 +197,7 @@ - + @@ -226,16 +213,7 @@ - - - - - - - - - @@ -243,5 +221,16 @@ + + + + + + + + + + + diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java index c2bca2a51..ccfb630fc 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ @@ -8,20 +8,24 @@ import com.google.inject.Inject; import tools.refinery.language.library.BuiltinLibrary; import tools.refinery.language.model.problem.*; +import tools.refinery.language.scoping.imports.ImportAdapterProvider; import tools.refinery.language.scoping.imports.ImportCollector; import tools.refinery.language.semantics.internal.MutableSeed; import tools.refinery.language.utils.BuiltinSymbols; -import tools.refinery.language.utils.ProblemDesugarer; import tools.refinery.language.utils.ProblemUtil; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.dnf.InvalidClauseException; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.dnf.RelationalQuery; +import tools.refinery.logic.literal.*; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; +import tools.refinery.logic.term.truthvalue.TruthValue; +import tools.refinery.logic.term.uppercardinality.UpperCardinalities; import tools.refinery.store.dse.propagation.PropagationBuilder; import tools.refinery.store.model.ModelStoreBuilder; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.dnf.InvalidClauseException; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.dnf.RelationalQuery; -import tools.refinery.store.query.literal.*; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.Variable; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.scope.ScopePropagator; @@ -29,24 +33,20 @@ import tools.refinery.store.reasoning.seed.Seed; import tools.refinery.store.reasoning.translator.TranslationException; import tools.refinery.store.reasoning.translator.containment.ContainmentHierarchyTranslator; -import tools.refinery.store.reasoning.translator.metamodel.*; +import tools.refinery.store.reasoning.translator.metamodel.Metamodel; +import tools.refinery.store.reasoning.translator.metamodel.MetamodelBuilder; +import tools.refinery.store.reasoning.translator.metamodel.MetamodelTranslator; +import tools.refinery.store.reasoning.translator.metamodel.ReferenceInfo; import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; import tools.refinery.store.reasoning.translator.multiplicity.ConstrainedMultiplicity; import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; import tools.refinery.store.reasoning.translator.multiplicity.UnconstrainedMultiplicity; import tools.refinery.store.reasoning.translator.predicate.PredicateTranslator; -import tools.refinery.store.representation.TruthValue; -import tools.refinery.store.representation.cardinality.CardinalityInterval; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; -import tools.refinery.store.representation.cardinality.UpperCardinalities; import tools.refinery.store.tuple.Tuple; import java.util.*; public class ModelInitializer { - @Inject - private ProblemDesugarer desugarer; - @Inject private SemanticsUtils semanticsUtils; @@ -56,6 +56,9 @@ public class ModelInitializer { @Inject private ImportCollector importCollector; + @Inject + private ImportAdapterProvider importAdapterProvider; + private Problem problem; private final Set importedProblems = new HashSet<>(); @@ -93,8 +96,7 @@ public void readProblem(Problem problem) { importedProblems.add(problem); problemTrace.setProblem(problem); try { - builtinSymbols = desugarer.getBuiltinSymbols(problem).orElseThrow(() -> new IllegalArgumentException( - "Problem has no builtin library")); + builtinSymbols = importAdapterProvider.getBuiltinSymbols(problem); var nodeInfo = collectPartialRelation(builtinSymbols.node(), 1, TruthValue.TRUE, TruthValue.TRUE); nodeRelation = nodeInfo.partialRelation(); metamodelBuilder.type(nodeRelation); @@ -202,20 +204,7 @@ public ModelSeed getModelSeed() { private void collectNodes() { for (var importedProblem : importedProblems) { for (var statement : importedProblem.getStatements()) { - if (statement instanceof NodeDeclaration nodeDeclaration) { - for (var node : nodeDeclaration.getNodes()) { - collectNode(node); - } - } else if (statement instanceof ClassDeclaration classDeclaration) { - var newNode = classDeclaration.getNewNode(); - if (newNode != null) { - collectNode(newNode); - } - } else if (statement instanceof EnumDeclaration enumDeclaration) { - for (var literal : enumDeclaration.getLiterals()) { - collectNode(literal); - } - } + collectNodes(statement); } } for (var node : problem.getNodes()) { @@ -223,6 +212,23 @@ private void collectNodes() { } } + private void collectNodes(Statement statement) { + if (statement instanceof NodeDeclaration nodeDeclaration) { + for (var node : nodeDeclaration.getNodes()) { + collectNode(node); + } + } else if (statement instanceof ClassDeclaration classDeclaration) { + var newNode = classDeclaration.getNewNode(); + if (newNode != null) { + collectNode(newNode); + } + } else if (statement instanceof EnumDeclaration enumDeclaration) { + for (var literal : enumDeclaration.getLiterals()) { + collectNode(literal); + } + } + } + private void collectNode(Node node) { problemTrace.collectNode(node); } @@ -243,15 +249,14 @@ private void collectPartialSymbols() { private void collectClassDeclarationSymbols(ClassDeclaration classDeclaration) { collectPartialRelation(classDeclaration, 1, null, TruthValue.UNKNOWN); - for (var featureDeclaration : classDeclaration.getFeatureDeclarations()) { - if (featureDeclaration instanceof ReferenceDeclaration referenceDeclaration) { - collectPartialRelation(referenceDeclaration, 2, null, TruthValue.UNKNOWN); - var invalidMultiplicityConstraint = referenceDeclaration.getInvalidMultiplicity(); - if (invalidMultiplicityConstraint != null) { - collectPartialRelation(invalidMultiplicityConstraint, 1, TruthValue.FALSE, TruthValue.FALSE); - } - } else { - throw new TracedException(featureDeclaration, "Unknown feature declaration"); + for (var referenceDeclaration : classDeclaration.getFeatureDeclarations()) { + if (referenceDeclaration.getReferenceType() instanceof DatatypeDeclaration) { + throw new TracedException(referenceDeclaration, "Attributes are not yet supported"); + } + collectPartialRelation(referenceDeclaration, 2, null, TruthValue.UNKNOWN); + var invalidMultiplicityConstraint = referenceDeclaration.getInvalidMultiplicity(); + if (invalidMultiplicityConstraint != null) { + collectPartialRelation(invalidMultiplicityConstraint, 1, TruthValue.FALSE, TruthValue.FALSE); } } } @@ -319,10 +324,8 @@ private void collectClassDeclarationMetamodel(ClassDeclaration classDeclaration) } catch (RuntimeException e) { throw TracedException.addTrace(classDeclaration, e); } - for (var featureDeclaration : classDeclaration.getFeatureDeclarations()) { - if (featureDeclaration instanceof ReferenceDeclaration referenceDeclaration) { - collectReferenceDeclarationMetamodel(classDeclaration, referenceDeclaration); - } + for (var referenceDeclaration : classDeclaration.getFeatureDeclarations()) { + collectReferenceDeclarationMetamodel(classDeclaration, referenceDeclaration); } } @@ -681,8 +684,8 @@ private void toLiterals(Expr expr, Map true; - case NOT_EQ -> false; + case NODE_EQ -> true; + case NODE_NOT_EQ -> false; default -> throw new TracedException( comparisonExpr, "Unsupported operator"); }; @@ -726,14 +729,18 @@ private List toArgumentList( private void collectScopes() { for (var importedProblem : importedProblems) { for (var statement : importedProblem.getStatements()) { - if (statement instanceof ScopeDeclaration scopeDeclaration) { - for (var typeScope : scopeDeclaration.getTypeScopes()) { - if (typeScope.isIncrement()) { - collectTypeScopeIncrement(typeScope); - } else { - collectTypeScope(typeScope); - } - } + collectScopes(statement); + } + } + } + + private void collectScopes(Statement statement) { + if (statement instanceof ScopeDeclaration scopeDeclaration) { + for (var typeScope : scopeDeclaration.getTypeScopes()) { + if (typeScope.isIncrement()) { + collectTypeScopeIncrement(typeScope); + } else { + collectTypeScope(typeScope); } } } diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SemanticsUtils.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SemanticsUtils.java index 9c40e6dfc..5e0526bc0 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SemanticsUtils.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SemanticsUtils.java @@ -7,7 +7,6 @@ import com.google.inject.Inject; import com.google.inject.Singleton; -import com.google.inject.name.Named; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; @@ -20,7 +19,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import tools.refinery.language.model.problem.Problem; -import tools.refinery.language.naming.ProblemQualifiedNameProvider; import java.util.Optional; @@ -29,10 +27,6 @@ public class SemanticsUtils { @Inject private IQualifiedNameProvider qualifiedNameProvider; - @Inject - @Named(ProblemQualifiedNameProvider.NAMED_DELEGATE) - private IQualifiedNameProvider delegateQualifiedNameProvider; - @Inject private IQualifiedNameConverter qualifiedNameConverter; @@ -40,7 +34,7 @@ public class SemanticsUtils { private IResourceDescriptionsProvider resourceDescriptionsProvider; public Optional getNameWithoutRootPrefix(EObject eObject) { - var qualifiedName = delegateQualifiedNameProvider.getFullyQualifiedName(eObject); + var qualifiedName = qualifiedNameProvider.getFullyQualifiedName(eObject); if (qualifiedName == null) { return Optional.empty(); } diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SolutionSerializer.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SolutionSerializer.java index 377a66f35..f097143fd 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SolutionSerializer.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SolutionSerializer.java @@ -21,7 +21,8 @@ import org.eclipse.xtext.scoping.IScopeProvider; import tools.refinery.language.model.problem.*; import tools.refinery.language.naming.NamingUtil; -import tools.refinery.language.utils.ProblemDesugarer; +import tools.refinery.language.scoping.imports.ImportAdapterProvider; +import tools.refinery.language.typesystem.SignatureProvider; import tools.refinery.language.utils.ProblemUtil; import tools.refinery.store.model.Model; import tools.refinery.store.reasoning.ReasoningAdapter; @@ -30,7 +31,7 @@ import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.translator.typehierarchy.InferredType; import tools.refinery.store.reasoning.translator.typehierarchy.TypeHierarchyTranslator; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; import java.io.ByteArrayInputStream; @@ -57,10 +58,13 @@ public class SolutionSerializer { private IScopeProvider scopeProvider; @Inject - private ProblemDesugarer desugarer; + private NodeNameProvider nameProvider; @Inject - private NodeNameProvider nameProvider; + private ImportAdapterProvider importAdapterProvider; + + @Inject + private SignatureProvider signatureProvider; private ProblemTrace trace; private Model model; @@ -223,8 +227,7 @@ private void addAssertion(Relation relation, LogicValue value, Node... arguments } private void addExistsAssertions() { - var builtinSymbols = desugarer.getBuiltinSymbols(problem).orElseThrow(() -> new IllegalStateException("No " + - "builtin library in copied problem")); + var builtinSymbols = importAdapterProvider.getBuiltinSymbols(problem); // Make sure to output exists assertions in a deterministic order. var sortedNewNodes = new TreeMap(); for (var pair : trace.getNodeTrace().keyValuesView()) { @@ -336,7 +339,7 @@ private void addDefaultAssertion(PartialRelation partialRelation) { var assertion = ProblemFactory.eINSTANCE.createAssertion(); assertion.setDefault(true); assertion.setRelation(relation); - int arity = ProblemUtil.getArity(relation); + int arity = signatureProvider.getArity(relation); for (int i = 0; i < arity; i++) { var argument = ProblemFactory.eINSTANCE.createWildcardAssertionArgument(); assertion.getArguments().add(argument); diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTree.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTree.java index 5d25f1489..8aa1af287 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTree.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTree.java @@ -7,7 +7,7 @@ import org.eclipse.collections.api.factory.primitive.IntObjectMaps; import tools.refinery.store.map.Cursor; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; class DecisionTree implements MutableSeed { diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeCursor.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeCursor.java index 71b54cbd5..8b8fed369 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeCursor.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeCursor.java @@ -6,7 +6,7 @@ package tools.refinery.language.semantics.internal; import tools.refinery.store.map.Cursor; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; import java.util.ArrayDeque; diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeNode.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeNode.java index 31d6fc788..eb79e0c88 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeNode.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeNode.java @@ -7,7 +7,7 @@ import org.eclipse.collections.api.LazyIntIterable; import tools.refinery.store.tuple.Tuple; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; abstract class DecisionTreeNode { public DecisionTreeValue getReducedValue() { diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeValue.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeValue.java index 5053e7ac9..a6b559891 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeValue.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeValue.java @@ -5,7 +5,7 @@ */ package tools.refinery.language.semantics.internal; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; public enum DecisionTreeValue { UNSET(null), @@ -25,7 +25,7 @@ public TruthValue getTruthValue() { } public TruthValue merge(TruthValue other) { - return truthValue == null ? other : truthValue.merge(other); + return truthValue == null ? other : truthValue.meet(other); } public DecisionTreeValue overwrite(DecisionTreeValue other) { diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/IntermediateNode.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/IntermediateNode.java index 2ad216ce6..8942068cd 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/IntermediateNode.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/IntermediateNode.java @@ -10,7 +10,7 @@ import org.eclipse.collections.api.map.primitive.MutableIntObjectMap; import org.eclipse.collections.api.tuple.primitive.IntObjectPair; import tools.refinery.store.tuple.Tuple; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; final class IntermediateNode extends DecisionTreeNode { private final MutableIntObjectMap children; diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/MutableSeed.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/MutableSeed.java index 693b9e1f2..85611059e 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/MutableSeed.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/MutableSeed.java @@ -6,7 +6,7 @@ package tools.refinery.language.semantics.internal; import tools.refinery.store.reasoning.seed.Seed; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; public interface MutableSeed extends Seed { diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/NullaryMutableSeed.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/NullaryMutableSeed.java index f100c5a62..09107a373 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/NullaryMutableSeed.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/NullaryMutableSeed.java @@ -7,7 +7,7 @@ import tools.refinery.store.map.Cursor; import tools.refinery.store.map.Cursors; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; class NullaryMutableSeed implements MutableSeed { diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/TerminalNode.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/TerminalNode.java index dc501479d..75933fe49 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/TerminalNode.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/TerminalNode.java @@ -10,7 +10,7 @@ import org.eclipse.collections.api.map.primitive.MutableIntObjectMap; import org.eclipse.collections.api.tuple.primitive.IntObjectPair; import tools.refinery.store.tuple.Tuple; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; class TerminalNode extends DecisionTreeNode { private MutableIntObjectMap children; @@ -48,7 +48,7 @@ public void mergeValue(int level, Tuple tuple, TruthValue value) { protected void mergeAllValues(int nextLevel, Tuple tuple, TruthValue value) { otherwise = DecisionTreeValue.fromTruthValue(otherwise.merge(value)); children = IntObjectMaps.mutable.from(children.keyValuesView(), IntObjectPair::getOne, - pair -> pair.getTwo().merge(value)); + pair -> pair.getTwo().meet(value)); reduceChildren(); } diff --git a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/CountPropagationTest.java b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/CountPropagationTest.java index b679c1ef4..207bc7ffc 100644 --- a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/CountPropagationTest.java +++ b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/CountPropagationTest.java @@ -19,8 +19,8 @@ import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; import tools.refinery.store.reasoning.translator.typehierarchy.TypeHierarchy; import tools.refinery.store.reasoning.translator.typehierarchy.TypeHierarchyTranslator; -import tools.refinery.store.representation.TruthValue; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; +import tools.refinery.logic.term.truthvalue.TruthValue; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; import tools.refinery.store.tuple.Tuple; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/internal/DecisionTreeTests.java b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/internal/DecisionTreeTests.java index 61ce850f3..cb0885c1d 100644 --- a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/internal/DecisionTreeTests.java +++ b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/internal/DecisionTreeTests.java @@ -6,7 +6,7 @@ package tools.refinery.language.semantics.internal; import org.junit.jupiter.api.Test; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; import java.util.LinkedHashMap; diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/MetadataCreator.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/MetadataCreator.java index 1858fc87a..910089192 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/MetadataCreator.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/MetadataCreator.java @@ -7,7 +7,6 @@ import com.google.inject.Inject; import com.google.inject.Provider; -import com.google.inject.name.Named; import org.eclipse.emf.ecore.EObject; import org.eclipse.xtext.naming.IQualifiedNameConverter; import org.eclipse.xtext.naming.IQualifiedNameProvider; @@ -15,7 +14,6 @@ import org.eclipse.xtext.scoping.IScope; import org.eclipse.xtext.scoping.IScopeProvider; import tools.refinery.language.model.problem.*; -import tools.refinery.language.naming.ProblemQualifiedNameProvider; import tools.refinery.language.semantics.ProblemTrace; import tools.refinery.language.semantics.TracedException; import tools.refinery.language.utils.ProblemUtil; @@ -34,7 +32,6 @@ public class MetadataCreator { private IScopeProvider scopeProvider; @Inject - @Named(ProblemQualifiedNameProvider.NAMED_DELEGATE) private IQualifiedNameProvider qualifiedNameProvider; @Inject diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeMetadataFactory.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeMetadataFactory.java index ce0e50c16..f469d2dd8 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeMetadataFactory.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeMetadataFactory.java @@ -17,7 +17,7 @@ import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.translator.typehierarchy.InferredType; import tools.refinery.store.reasoning.translator.typehierarchy.TypeHierarchyTranslator; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; public class NodeMetadataFactory { diff --git a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext index f0d6c38cf..08f7a5858 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext +++ b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext @@ -17,7 +17,8 @@ enum ModuleKind: Statement: ImportStatement | Assertion | ClassDeclaration | EnumDeclaration | - PredicateDefinition | /* FunctionDefinition | RuleDefinition | */ + DatatypeDeclaration | AggregatorDeclaration | PredicateDefinition | + /* FunctionDefinition | RuleDefinition | */ ScopeDeclaration | NodeDeclaration; ImportStatement: @@ -27,7 +28,7 @@ ClassDeclaration: abstract?="abstract"? "class" name=Identifier ("extends" superTypes+=[Relation|QualifiedName] ("," superTypes+=[Relation|QualifiedName])*)? - ("{" (featureDeclarations+=FeatureDeclaration ";"?)* "}" | "."); + ("{" (featureDeclarations+=ReferenceDeclaration ";"?)* "}" | "."); EnumDeclaration: "enum" @@ -37,8 +38,11 @@ EnumDeclaration: EnumLiteral returns Node: name=Identifier; -FeatureDeclaration: - ReferenceDeclaration /* | AttributeDeclaration | FlagDeclaration */; +DatatypeDeclaration: + "extern" "datatype" name=Identifier "."; + +AggregatorDeclaration: + "extern" "aggregator" name=Identifier "."; enum ReferenceKind: REFERENCE="refers" | CONTAINMENT="contains" | CONTAINER="container"; @@ -53,15 +57,6 @@ ReferenceDeclaration: ReferenceMultiplicity returns Multiplicity: "[" Multiplicity "]"; -//enum PrimitiveType: -// INT="int" | REAL="real" | STRING="string"; -// -//AttributeDeclaration: -// attributeType=PrimitiveType name=Identifier; -// -//FlagDeclaration: -// "bool" name=Identifier; - PredicateDefinition: ("pred" | error?="error" "pred"?) name=Identifier @@ -73,14 +68,13 @@ Conjunction: literals+=Expr ("," literals+=Expr)*; //FunctionDefinition: -// "fn" functionType=PrimitiveType name=Identifier +// "fn" functionType=[DatatypeDefinition|QualifiedName] name=Identifier // "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")" // ("=" cases+=Case (";" cases+=Case)*)? // "."; // //Case: // Conjunction ({Match.condition=current} "->" value=Expr)?; - //RuleDefinition: // "rule" // name=Identifier @@ -112,25 +106,32 @@ Parameter: // name=Identifier; Expr: - ComparisonExpr; + AssignmentExpr; + +AssignmentExpr returns Expr: + BooleanExpr ({AssignmentExpr.left=current} "is" right=BooleanExpr)*; + +enum BooleanBinaryOp returns BinaryOp: + AND="&&" | OR="||" | XOR="^^"; + +BooleanExpr returns Expr: + ComparisonExpr ({ArithmeticBinaryExpr.left=current} + op=BooleanBinaryOp right=ComparisonExpr)*; enum ComparisonOp: - LESS="<" | LESS_EQ="<=" | GREATER=">" | GREATER_EQ=">=" | EQ="==" | NOT_EQ="!=" | - IN="in" | SUBSUMES=":>" | SUBSUMED_BY="<:" | ABS_EQ="===" | ABS_NOT_EQ="!=="; + LESS="<" | LESS_EQ="<=" | GREATER=">" | GREATER_EQ=">=" | EQ="===" | NOT_EQ="!==" | + IN="in" | NODE_EQ="==" | NODE_NOT_EQ="!="; ComparisonExpr returns Expr: LatticeExpr ({ComparisonExpr.left=current} op=ComparisonOp right=LatticeExpr)*; -enum LatticeOp returns BinaryOp: +enum LatticeBinaryOp: MEET="/\\" | JOIN="\\/"; LatticeExpr returns Expr: - RangeExpr ({ArithmeticBinaryExpr.left=current} - op=LatticeOp right=RangeExpr)*; - -RangeExpr returns Expr: - AdditiveExpr ({RangeExpr.left=current} ".." right=AdditiveExpr)*; + AdditiveExpr ({LatticeBinaryExpr.left=current} + op=LatticeBinaryOp right=AdditiveExpr)*; enum AdditiveOp returns BinaryOp: ADD="+" | SUB="-"; @@ -150,12 +151,15 @@ enum ExponentialOp returns BinaryOp: POW="**"; ExponentialExpr returns Expr: - UnaryExpr ({ArithmeticBinaryExpr.left=current} + RangeExpr ({ArithmeticBinaryExpr.left=current} op=ExponentialOp right=ExponentialExpr)?; +RangeExpr returns Expr: + UnaryExpr ({RangeExpr.left=current} ".." right=UnaryExpr)*; + UnaryExpr returns Expr: - ArithmeticUnaryExpr | ModalExpr | NegationExpr | CountExpr | AggregationExpr | - Atom | VariableOrNodeExpr | Constant | "(" Expr ")"; + ArithmeticUnaryExpr | NegationExpr | + CountExpr | AggregationExpr | CastExpr; enum UnaryOp: PLUS="+" | MINUS="-"; @@ -163,23 +167,21 @@ enum UnaryOp: ArithmeticUnaryExpr: op=UnaryOp body=UnaryExpr; -enum Modality: - MAY="may" | MUST="must" | CURRENT="current"; - -ModalExpr: - modality=Modality body=UnaryExpr; - NegationExpr: "!" body=UnaryExpr; CountExpr: "count" body=UnaryExpr; -enum AggregationOp: - SUM="sum" | PROD="prod" | MIN="min" | MAX="max"; - AggregationExpr: - op=AggregationOp "{" value=Expr "|" condition=Expr "}"; + aggregator=[AggregatorDeclaration|QualifiedName] + "{" value=Expr "|" condition=ComparisonExpr "}"; + +CastExpr returns Expr: + CastExprBody ({CastExpr.body=current} "as" targetType=[Relation|QualifiedName])?; + +CastExprBody returns Expr: + Atom | VariableOrNodeExpr | Constant | "(" Expr ")"; Atom: relation=[Relation|QualifiedName] @@ -190,7 +192,7 @@ VariableOrNodeExpr: variableOrNode=[VariableOrNode|QualifiedName]; Constant: - RealConstant | IntConstant | InfConstant | StringConstant | LogicConstant; + RealConstant | IntConstant | StringConstant | InfiniteConstant | LogicConstant; IntConstant: intValue=INT; @@ -198,12 +200,12 @@ IntConstant: RealConstant: realValue=Real; -InfConstant: - {InfConstant} "*"; - StringConstant: stringValue=STRING; +InfiniteConstant: + {InfiniteConstant} "*"; + enum LogicValue: TRUE="true" | FALSE="false" | UNKNOWN="unknown" | ERROR="error"; @@ -278,8 +280,8 @@ Identifier: NonContainmentIdentifier | "contains" | "container"; NonContainmentIdentifier: - ID | "atom" | "multi" | "contained" | - "sum" | "prod" | "min" | "max" | "problem" | "module"; + ID | "atom" | "multi" | "contained" | "problem" | "module" | + "datatype" | "aggregator"; Real returns ecore::EDouble: EXPONENTIAL | INT "." (INT | EXPONENTIAL); diff --git a/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java b/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java index f70390278..955a89f9c 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java +++ b/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java @@ -30,9 +30,8 @@ import org.eclipse.xtext.xbase.annotations.validation.DerivedStateAwareResourceValidator; import tools.refinery.language.conversion.ProblemValueConverterService; import tools.refinery.language.linking.ProblemLinkingService; -import tools.refinery.language.naming.ProblemDelegateQualifiedNameProvider; -import tools.refinery.language.naming.ProblemQualifiedNameConverter; import tools.refinery.language.naming.ProblemQualifiedNameProvider; +import tools.refinery.language.naming.ProblemQualifiedNameConverter; import tools.refinery.language.parser.ProblemEcoreElementFactory; import tools.refinery.language.parser.antlr.TokenSourceInjectingProblemParser; import tools.refinery.language.resource.ProblemLocationInFileProvider; @@ -68,12 +67,6 @@ public Class bindIQualifiedNameConverter() { return ProblemQualifiedNameConverter.class; } - public void configureIQualifiedNameProviderDelegate(Binder binder) { - binder.bind(IQualifiedNameProvider.class) - .annotatedWith(Names.named(ProblemQualifiedNameProvider.NAMED_DELEGATE)) - .to(ProblemDelegateQualifiedNameProvider.class); - } - @Override public Class bindIQualifiedNameProvider() { return ProblemQualifiedNameProvider.class; diff --git a/subprojects/language/src/main/java/tools/refinery/language/expressions/AbstractTermInterpreter.java b/subprojects/language/src/main/java/tools/refinery/language/expressions/AbstractTermInterpreter.java new file mode 100644 index 000000000..2530b7076 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/expressions/AbstractTermInterpreter.java @@ -0,0 +1,131 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.expressions; + +import tools.refinery.language.model.problem.BinaryOp; +import tools.refinery.language.model.problem.UnaryOp; +import tools.refinery.language.typesystem.AggregatorName; +import tools.refinery.language.typesystem.DataExprType; + +import java.util.*; + +// This class is used to configure term interpreters by clients with various arguments. +@SuppressWarnings("SameParameterValue") +public abstract class AbstractTermInterpreter implements TermInterpreter { + private final Map negations = new HashMap<>(); + private final Map unaryOperators = new HashMap<>(); + private final Set comparisons = new HashSet<>(); + private final Set ranges = new HashSet<>(); + private final Map binaryOperators = new HashMap<>(); + private final Set casts = new HashSet<>(); + private final Map aggregators = new HashMap<>(); + + protected AbstractTermInterpreter() { + } + + protected void addNegation(DataExprType type, DataExprType result) { + negations.put(type, result); + } + + protected void addNegation(DataExprType type) { + addNegation(type, type); + } + + protected void addUnaryOperator(UnaryOp op, DataExprType type, DataExprType result) { + unaryOperators.put(new UnaryKey(op, type), result); + } + + protected void addUnaryOperator(UnaryOp op, DataExprType type) { + addUnaryOperator(op, type, type); + } + + protected void addComparison(DataExprType type) { + comparisons.add(type); + } + + protected void addRange(DataExprType type) { + ranges.add(type); + } + + protected void addBinaryOperator(BinaryOp op, DataExprType leftType, DataExprType rightType, DataExprType result) { + binaryOperators.put(new BinaryKey(op, leftType, rightType), result); + } + + protected void addBinaryOperator(BinaryOp op, DataExprType type) { + addBinaryOperator(op, type, type, type); + } + + protected void addCast(DataExprType fromType, DataExprType toType) { + if (fromType.equals(toType)) { + throw new IllegalArgumentException("The fromType and toType of a cast operator must be different"); + } + casts.add(new CastKey(fromType, toType)); + } + + protected void addAggregator(AggregatorName aggregator, DataExprType type, DataExprType result) { + aggregators.put(new AggregatorKey(aggregator, type), result); + } + + protected void addAggregator(AggregatorName aggregator, DataExprType type) { + addAggregator(aggregator, type, type); + } + + @Override + public Optional getNegationType(DataExprType type) { + return Optional.ofNullable(negations.get(type)); + } + + @Override + public Optional getUnaryOperationType(UnaryOp op, DataExprType type) { + if (unaryOperators.isEmpty()) { + return Optional.empty(); + } + return Optional.ofNullable(unaryOperators.get(new UnaryKey(op, type))); + } + + @Override + public boolean isComparisonSupported(DataExprType type) { + return comparisons.contains(type); + } + + @Override + public boolean isRangeSupported(DataExprType type) { + return ranges.contains(type); + } + + @Override + public Optional getBinaryOperationType(BinaryOp op, DataExprType leftType, DataExprType rightType) { + if (binaryOperators.isEmpty()) { + return Optional.empty(); + } + return Optional.ofNullable(binaryOperators.get(new BinaryKey(op, leftType, rightType))); + } + + @Override + public Optional getAggregationType(AggregatorName aggregator, DataExprType type) { + if (aggregators.isEmpty()) { + return Optional.empty(); + } + return Optional.ofNullable(aggregators.get(new AggregatorKey(aggregator, type))); + } + + @Override + public boolean isCastSupported(DataExprType fromType, DataExprType toType) { + return casts.contains(new CastKey(fromType, toType)); + } + + private record UnaryKey(UnaryOp op, DataExprType type) { + } + + private record BinaryKey(BinaryOp op, DataExprType leftType, DataExprType rightType) { + } + + private record CastKey(DataExprType fromType, DataExprType toType) { + } + + private record AggregatorKey(AggregatorName aggregator, DataExprType type) { + } +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/expressions/BuiltinTermInterpreter.java b/subprojects/language/src/main/java/tools/refinery/language/expressions/BuiltinTermInterpreter.java new file mode 100644 index 000000000..412ed8ba7 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/expressions/BuiltinTermInterpreter.java @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.expressions; + +import tools.refinery.language.library.BuiltinLibrary; +import tools.refinery.language.model.problem.BinaryOp; +import tools.refinery.language.model.problem.UnaryOp; +import tools.refinery.language.typesystem.AggregatorName; +import tools.refinery.language.typesystem.DataExprType; + +public final class BuiltinTermInterpreter extends AbstractTermInterpreter { + public static final DataExprType BOOLEAN_TYPE = new DataExprType(BuiltinLibrary.BUILTIN_LIBRARY_NAME, "boolean"); + public static final DataExprType INT_TYPE = new DataExprType(BuiltinLibrary.BUILTIN_LIBRARY_NAME, "int"); + public static final DataExprType REAL_TYPE = new DataExprType(BuiltinLibrary.BUILTIN_LIBRARY_NAME, "real"); + public static final DataExprType STRING_TYPE = new DataExprType(BuiltinLibrary.BUILTIN_LIBRARY_NAME, "string"); + public static final AggregatorName MIN_AGGREGATOR = new AggregatorName(BuiltinLibrary.BUILTIN_LIBRARY_NAME, "min"); + public static final AggregatorName MAX_AGGREGATOR = new AggregatorName(BuiltinLibrary.BUILTIN_LIBRARY_NAME, "max"); + public static final AggregatorName SUM_AGGREGATOR = new AggregatorName(BuiltinLibrary.BUILTIN_LIBRARY_NAME, "sum"); + + public BuiltinTermInterpreter() { + addNegation(BOOLEAN_TYPE); + addBinaryOperator(BinaryOp.AND, BOOLEAN_TYPE); + addBinaryOperator(BinaryOp.OR, BOOLEAN_TYPE); + addBinaryOperator(BinaryOp.XOR, BOOLEAN_TYPE); + + addUnaryOperator(UnaryOp.PLUS, INT_TYPE); + addUnaryOperator(UnaryOp.MINUS, INT_TYPE); + addComparison(INT_TYPE); + addRange(INT_TYPE); + addBinaryOperator(BinaryOp.ADD, INT_TYPE); + addBinaryOperator(BinaryOp.SUB, INT_TYPE); + addBinaryOperator(BinaryOp.MUL, INT_TYPE); + addAggregator(MIN_AGGREGATOR, INT_TYPE); + addAggregator(MAX_AGGREGATOR, INT_TYPE); + addAggregator(SUM_AGGREGATOR, INT_TYPE); + + addUnaryOperator(UnaryOp.PLUS, REAL_TYPE); + addUnaryOperator(UnaryOp.MINUS, REAL_TYPE); + addCast(INT_TYPE, REAL_TYPE); + addComparison(REAL_TYPE); + addRange(REAL_TYPE); + addBinaryOperator(BinaryOp.ADD, REAL_TYPE); + addBinaryOperator(BinaryOp.SUB, REAL_TYPE); + addBinaryOperator(BinaryOp.MUL, REAL_TYPE); + addBinaryOperator(BinaryOp.DIV, REAL_TYPE); + addBinaryOperator(BinaryOp.POW, REAL_TYPE); + addAggregator(MIN_AGGREGATOR, REAL_TYPE); + addAggregator(MAX_AGGREGATOR, REAL_TYPE); + addAggregator(SUM_AGGREGATOR, REAL_TYPE); + } +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/expressions/CompositeTermInterpreter.java b/subprojects/language/src/main/java/tools/refinery/language/expressions/CompositeTermInterpreter.java new file mode 100644 index 000000000..b337e5dda --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/expressions/CompositeTermInterpreter.java @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.expressions; + +import tools.refinery.language.model.problem.BinaryOp; +import tools.refinery.language.model.problem.UnaryOp; +import tools.refinery.language.typesystem.AggregatorName; +import tools.refinery.language.typesystem.DataExprType; + +import java.util.List; +import java.util.Optional; + +public class CompositeTermInterpreter implements TermInterpreter { + private final List interpreters; + + public CompositeTermInterpreter(List interpreters) { + this.interpreters = interpreters; + } + + @Override + public Optional getNegationType(DataExprType type) { + for (var interpreter : interpreters) { + var result = interpreter.getNegationType(type); + if (result.isPresent()) { + return result; + } + } + return Optional.empty(); + } + + @Override + public Optional getUnaryOperationType(UnaryOp op, DataExprType type) { + for (var interpreter : interpreters) { + var result = interpreter.getUnaryOperationType(op, type); + if (result.isPresent()) { + return result; + } + } + return Optional.empty(); + } + + @Override + public boolean isComparisonSupported(DataExprType type) { + for (var interpreter : interpreters) { + var result = interpreter.isComparisonSupported(type); + if (result) { + return true; + } + } + return false; + } + + @Override + public boolean isRangeSupported(DataExprType type) { + for (var interpreter : interpreters) { + var result = interpreter.isRangeSupported(type); + if (result) { + return true; + } + } + return false; + } + + @Override + public Optional getBinaryOperationType(BinaryOp op, DataExprType leftType, DataExprType rightType) { + for (var interpreter : interpreters) { + var result = interpreter.getBinaryOperationType(op, leftType, rightType); + if (result.isPresent()) { + return result; + } + } + return Optional.empty(); + } + + @Override + public boolean isCastSupported(DataExprType fromType, DataExprType toType) { + for (var interpreter : interpreters) { + var result = interpreter.isCastSupported(fromType, toType); + if (result) { + return true; + } + } + return false; + } + + @Override + public Optional getAggregationType(AggregatorName aggregator, DataExprType type) { + for (var interpreter : interpreters) { + var result = interpreter.getAggregationType(aggregator, type); + if (result.isPresent()) { + return result; + } + } + return Optional.empty(); + } +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/expressions/TermInterpreter.java b/subprojects/language/src/main/java/tools/refinery/language/expressions/TermInterpreter.java new file mode 100644 index 000000000..122785f25 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/expressions/TermInterpreter.java @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.expressions; + +import tools.refinery.language.model.problem.BinaryOp; +import tools.refinery.language.model.problem.UnaryOp; +import tools.refinery.language.typesystem.AggregatorName; +import tools.refinery.language.typesystem.DataExprType; + +import java.util.Optional; + +public interface TermInterpreter { + Optional getNegationType(DataExprType type); + + Optional getUnaryOperationType(UnaryOp op, DataExprType type); + + boolean isComparisonSupported(DataExprType type); + + boolean isRangeSupported(DataExprType type); + + Optional getBinaryOperationType(BinaryOp op, DataExprType leftType, DataExprType rightType); + + boolean isCastSupported(DataExprType fromType, DataExprType toType); + + Optional getAggregationType(AggregatorName aggregator, DataExprType type); +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/naming/ProblemDelegateQualifiedNameProvider.java b/subprojects/language/src/main/java/tools/refinery/language/naming/ProblemDelegateQualifiedNameProvider.java deleted file mode 100644 index b39314018..000000000 --- a/subprojects/language/src/main/java/tools/refinery/language/naming/ProblemDelegateQualifiedNameProvider.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 The Refinery Authors - * - * SPDX-License-Identifier: EPL-2.0 - */ -package tools.refinery.language.naming; - -import com.google.inject.Inject; -import org.eclipse.xtext.naming.DefaultDeclarativeQualifiedNameProvider; -import org.eclipse.xtext.naming.IQualifiedNameConverter; -import org.eclipse.xtext.naming.QualifiedName; -import tools.refinery.language.model.problem.Problem; -import tools.refinery.language.scoping.imports.ImportAdapter; -import tools.refinery.language.utils.ProblemUtil; - -public class ProblemDelegateQualifiedNameProvider extends DefaultDeclarativeQualifiedNameProvider { - @Inject - private IQualifiedNameConverter qualifiedNameConverter; - - protected QualifiedName qualifiedName(Problem problem) { - var qualifiedNameString = problem.getName(); - if (qualifiedNameString != null) { - return NamingUtil.stripRootPrefix(qualifiedNameConverter.toQualifiedName(qualifiedNameString)); - } - if (!ProblemUtil.isModule(problem)) { - return null; - } - var resource = problem.eResource(); - if (resource == null) { - return null; - } - var resourceUri = resource.getURI(); - if (resourceUri == null) { - return null; - } - var resourceSet = resource.getResourceSet(); - if (resourceSet == null) { - return null; - } - var adapter = ImportAdapter.getOrInstall(resourceSet); - // If a module has no explicitly specified name, return the qualified name it was resolved under. - return adapter.getQualifiedName(resourceUri); - } -} diff --git a/subprojects/language/src/main/java/tools/refinery/language/naming/ProblemQualifiedNameProvider.java b/subprojects/language/src/main/java/tools/refinery/language/naming/ProblemQualifiedNameProvider.java index 5b6820588..2a4df4d05 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/naming/ProblemQualifiedNameProvider.java +++ b/subprojects/language/src/main/java/tools/refinery/language/naming/ProblemQualifiedNameProvider.java @@ -6,36 +6,44 @@ package tools.refinery.language.naming; import com.google.inject.Inject; -import com.google.inject.name.Named; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.xtext.naming.IQualifiedNameProvider; +import com.google.inject.Singleton; +import org.eclipse.xtext.naming.DefaultDeclarativeQualifiedNameProvider; +import org.eclipse.xtext.naming.IQualifiedNameConverter; import org.eclipse.xtext.naming.QualifiedName; -import org.eclipse.xtext.util.IResourceScopeCache; -import org.eclipse.xtext.util.Tuples; -import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; - -public class ProblemQualifiedNameProvider extends IQualifiedNameProvider.AbstractImpl { - private static final String PREFIX = "tools.refinery.language.naming.ProblemQualifiedNameProvider."; - public static final String NAMED_DELEGATE = PREFIX + "NAMED_DELEGATE"; - public static final String CACHE_KEY = PREFIX + "CACHE_KEY"; +import tools.refinery.language.model.problem.Problem; +import tools.refinery.language.scoping.imports.ImportAdapterProvider; +import tools.refinery.language.utils.ProblemUtil; +@Singleton +public class ProblemQualifiedNameProvider extends DefaultDeclarativeQualifiedNameProvider { @Inject - @Named(NAMED_DELEGATE) - private IQualifiedNameProvider delegate; + private IQualifiedNameConverter qualifiedNameConverter; @Inject - private IResourceScopeCache cache = IResourceScopeCache.NullImpl.INSTANCE; - - @Override - public QualifiedName getFullyQualifiedName(EObject obj) { - return cache.get(Tuples.pair(obj, CACHE_KEY), obj.eResource(), () -> computeFullyQualifiedName(obj)); - } + private ImportAdapterProvider importAdapterProvider; - public QualifiedName computeFullyQualifiedName(EObject obj) { - var qualifiedName = delegate.getFullyQualifiedName(obj); - if (qualifiedName != null && ProblemResourceDescriptionStrategy.shouldExport(obj)) { - return NamingUtil.addRootPrefix(qualifiedName); + protected QualifiedName qualifiedName(Problem problem) { + var qualifiedNameString = problem.getName(); + if (qualifiedNameString != null) { + return NamingUtil.stripRootPrefix(qualifiedNameConverter.toQualifiedName(qualifiedNameString)); + } + if (!ProblemUtil.isModule(problem)) { + return null; + } + var resource = problem.eResource(); + if (resource == null) { + return null; + } + var resourceUri = resource.getURI(); + if (resourceUri == null) { + return null; + } + var resourceSet = resource.getResourceSet(); + if (resourceSet == null) { + return null; } - return qualifiedName; + var adapter = importAdapterProvider.getOrInstall(resourceSet); + // If a module has no explicitly specified name, return the qualified name it was resolved under. + return adapter.getQualifiedName(resourceUri); } } diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java index 3dcf6b1f4..8fd603649 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java @@ -8,7 +8,6 @@ import com.google.common.collect.ImmutableMap; import com.google.inject.Inject; import com.google.inject.Singleton; -import com.google.inject.name.Named; import org.eclipse.emf.ecore.EObject; import org.eclipse.xtext.EcoreUtil2; import org.eclipse.xtext.naming.IQualifiedNameConverter; @@ -19,10 +18,9 @@ import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionStrategy; import org.eclipse.xtext.util.IAcceptor; import tools.refinery.language.documentation.DocumentationCommentParser; -import tools.refinery.language.naming.ProblemQualifiedNameProvider; -import tools.refinery.language.scoping.imports.ImportCollector; import tools.refinery.language.model.problem.*; import tools.refinery.language.naming.NamingUtil; +import tools.refinery.language.scoping.imports.ImportCollector; import tools.refinery.language.utils.ProblemUtil; import java.util.Map; @@ -32,13 +30,15 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy { private static final String DATA_PREFIX = "tools.refinery.language.resource.ProblemResourceDescriptionStrategy."; - public static final String ARITY = DATA_PREFIX + "ARITY"; + public static final String TYPE_LIKE = DATA_PREFIX + "ARITY"; + public static final String TYPE_LIKE_TRUE = "true"; public static final String ERROR_PREDICATE = DATA_PREFIX + "ERROR_PREDICATE"; public static final String ERROR_PREDICATE_TRUE = "true"; public static final String SHADOWING_KEY = DATA_PREFIX + "SHADOWING_KEY"; public static final String SHADOWING_KEY_PROBLEM = "problem"; public static final String SHADOWING_KEY_NODE = "node"; public static final String SHADOWING_KEY_RELATION = "relation"; + public static final String SHADOWING_KEY_AGGREGATOR = "aggregator"; public static final String PREFERRED_NAME = DATA_PREFIX + "PREFERRED_NAME"; public static final String PREFERRED_NAME_TRUE = "true"; public static final String IMPORTS = DATA_PREFIX + "IMPORTS"; @@ -51,8 +51,7 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti private IQualifiedNameConverter qualifiedNameConverter; @Inject - @Named(ProblemQualifiedNameProvider.NAMED_DELEGATE) - private IQualifiedNameProvider delegateQualifiedNameProvider; + private IQualifiedNameProvider qualifiedNameProvider; @Inject private ImportCollector importCollector; @@ -123,7 +122,7 @@ protected QualifiedName getProblemQualifiedName(Problem problem) { if (problem == null) { return QualifiedName.EMPTY; } - var qualifiedName = delegateQualifiedNameProvider.getFullyQualifiedName(problem); + var qualifiedName = qualifiedNameProvider.getFullyQualifiedName(problem); return qualifiedName == null ? QualifiedName.EMPTY : qualifiedName; } @@ -152,8 +151,11 @@ protected Map getUserData(EObject eObject) { builder.put(SHADOWING_KEY, SHADOWING_KEY_NODE); } else if (eObject instanceof Relation relation) { builder.put(SHADOWING_KEY, SHADOWING_KEY_RELATION); - int arity = ProblemUtil.getArity(relation); - builder.put(ARITY, Integer.toString(arity)); + if (ProblemUtil.isTypeLike(relation)) { + builder.put(TYPE_LIKE, TYPE_LIKE_TRUE); + } + } else if (eObject instanceof AggregatorDeclaration) { + builder.put(SHADOWING_KEY, SHADOWING_KEY_AGGREGATOR); } if (eObject instanceof PredicateDefinition predicateDefinition && predicateDefinition.isError()) { builder.put(ERROR_PREDICATE, ERROR_PREDICATE_TRUE); diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/state/DerivedVariableComputer.java b/subprojects/language/src/main/java/tools/refinery/language/resource/state/DerivedVariableComputer.java index f0baf35fc..f096264b3 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/state/DerivedVariableComputer.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/state/DerivedVariableComputer.java @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ @@ -44,15 +44,14 @@ protected void installDerivedParametricDefinitionState(ParametricDefinition defi knownVariables.add(name); } } - if (definition instanceof PredicateDefinition predicateDefinition) { - installDerivedPredicateDefinitionState(predicateDefinition, knownVariables); - } else if (definition instanceof FunctionDefinition functionDefinition) { - installDerivedFunctionDefinitionState(functionDefinition, knownVariables); - } else if (definition instanceof RuleDefinition ruleDefinition) { - installDerivedRuleDefinitionState(ruleDefinition, knownVariables); - } else { - throw new IllegalArgumentException("Unknown ParametricDefinition: " + definition); - } + switch (definition) { + case PredicateDefinition predicateDefinition -> + installDerivedPredicateDefinitionState(predicateDefinition, knownVariables); + case FunctionDefinition functionDefinition -> + installDerivedFunctionDefinitionState(functionDefinition, knownVariables); + case RuleDefinition ruleDefinition -> installDerivedRuleDefinitionState(ruleDefinition, knownVariables); + default -> throw new IllegalArgumentException("Unknown ParametricDefinition: " + definition); + } } protected void installDerivedPredicateDefinitionState(PredicateDefinition definition, Set knownVariables) { diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/state/ImplicitVariableScope.java b/subprojects/language/src/main/java/tools/refinery/language/resource/state/ImplicitVariableScope.java index e25887ade..c8e01724b 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/state/ImplicitVariableScope.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/state/ImplicitVariableScope.java @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ @@ -16,10 +16,7 @@ import tools.refinery.language.model.problem.*; import tools.refinery.language.naming.NamingUtil; -import java.util.Deque; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; public class ImplicitVariableScope { private final EObject root; @@ -71,13 +68,12 @@ private void initializeKnownVariables() { if ((hasKnownVariables && hasParent) || (!hasKnownVariables && !hasParent)) { throw new IllegalStateException("Either known variables or parent must be provided, but not both"); } - if (hasKnownVariables) { - return; - } - if (parent.knownVariables == null) { - throw new IllegalStateException("Parent scope must be processed before current scope"); + if (!hasKnownVariables) { + if (parent.knownVariables == null) { + throw new IllegalStateException("Parent scope must be processed before current scope"); + } + knownVariables = new HashSet<>(parent.knownVariables); } - knownVariables = new HashSet<>(parent.knownVariables); } private void processEObject(EObject eObject, IScopeProvider scopeProvider, LinkingHelper linkingHelper, diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/state/ProblemDerivedStateComputer.java b/subprojects/language/src/main/java/tools/refinery/language/resource/state/ProblemDerivedStateComputer.java index d905aa9af..efa77c507 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/state/ProblemDerivedStateComputer.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/state/ProblemDerivedStateComputer.java @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ @@ -51,7 +51,7 @@ protected Problem getProblem(Resource resource) { if (contents.isEmpty()) { return null; } - EObject object = contents.get(0); + EObject object = contents.getFirst(); if (object instanceof Problem problem) { return problem; } @@ -71,10 +71,8 @@ protected void installDerivedClassDeclarationState(Problem problem, Adapter adap for (var statement : problem.getStatements()) { if (statement instanceof ClassDeclaration classDeclaration) { installOrRemoveNewNode(adapter, classDeclaration); - for (var featureDeclaration : classDeclaration.getFeatureDeclarations()) { - if (featureDeclaration instanceof ReferenceDeclaration referenceDeclaration) { - installOrRemoveInvalidMultiplicityPredicate(adapter, classDeclaration, referenceDeclaration); - } + for (var referenceDeclaration : classDeclaration.getFeatureDeclarations()) { + installOrRemoveInvalidMultiplicityPredicate(adapter, classDeclaration, referenceDeclaration); } } } @@ -157,9 +155,8 @@ protected void discardDerivedProblemState(Problem problem, Adapter adapter) { if (classDeclaration.isAbstract()) { abstractClassDeclarations.add(classDeclaration); } - for (var featureDeclaration : classDeclaration.getFeatureDeclarations()) { - if (featureDeclaration instanceof ReferenceDeclaration referenceDeclaration && - ProblemUtil.hasMultiplicityConstraint(referenceDeclaration)) { + for (var referenceDeclaration : classDeclaration.getFeatureDeclarations()) { + if (ProblemUtil.hasMultiplicityConstraint(referenceDeclaration)) { referenceDeclarationsWithMultiplicity.add(referenceDeclaration); } } diff --git a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java index 0067bf94d..3b94423af 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java +++ b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java @@ -6,7 +6,6 @@ package tools.refinery.language.scoping; import com.google.inject.Inject; -import com.google.inject.name.Named; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.resource.Resource; @@ -17,14 +16,12 @@ import org.eclipse.xtext.scoping.IScope; import org.eclipse.xtext.scoping.impl.AbstractGlobalScopeDelegatingScopeProvider; import org.eclipse.xtext.util.IResourceScopeCache; -import tools.refinery.language.naming.ProblemQualifiedNameProvider; public class ProblemLocalScopeProvider extends AbstractGlobalScopeDelegatingScopeProvider { private static final String CACHE_KEY = "tools.refinery.language.scoping.ProblemLocalScopeProvider.CACHE_KEY"; @Inject - @Named(ProblemQualifiedNameProvider.NAMED_DELEGATE) - private IQualifiedNameProvider delegateQualifiedNameProvider; + private IQualifiedNameProvider qualifiedNameProvider; @Inject private IResourceDescriptionsProvider resourceDescriptionsProvider; @@ -59,7 +56,7 @@ protected ISelectable computeLocalImports(Resource resource) { if (rootElement == null) { return new NoFullyQualifiedNamesSelectable(resourceDescription); } - var rootName = delegateQualifiedNameProvider.getFullyQualifiedName(rootElement); + var rootName = qualifiedNameProvider.getFullyQualifiedName(rootElement); if (rootName == null) { return new NoFullyQualifiedNamesSelectable(resourceDescription); } diff --git a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java index a4437ba60..d94c9a132 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java +++ b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ @@ -9,17 +9,15 @@ */ package tools.refinery.language.scoping; -import com.google.inject.Inject; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.xtext.EcoreUtil2; import org.eclipse.xtext.scoping.IScope; import org.eclipse.xtext.scoping.Scopes; import tools.refinery.language.model.problem.*; -import tools.refinery.language.utils.ProblemDesugarer; -import java.util.ArrayList; -import java.util.List; +import java.util.Collection; +import java.util.LinkedHashSet; /** * This class contains custom scoping description. @@ -29,9 +27,6 @@ * on how and when to use it. */ public class ProblemScopeProvider extends AbstractProblemScopeProvider { - @Inject - private ProblemDesugarer desugarer; - @Override public IScope getScope(EObject context, EReference reference) { var scope = super.getScope(context, reference); @@ -58,7 +53,7 @@ protected IScope getNodesScope(EObject context, IScope delegateScope) { } protected IScope getVariableScope(EObject context, IScope delegateScope) { - List variables = new ArrayList<>(); + Collection variables = new LinkedHashSet<>(); addSingletonVariableToScope(context, variables); EObject currentContext = context; while (currentContext != null && !(currentContext instanceof ParametricDefinition)) { @@ -73,7 +68,7 @@ protected IScope getVariableScope(EObject context, IScope delegateScope) { return Scopes.scopeFor(variables, parentScope); } - protected void addSingletonVariableToScope(EObject context, List variables) { + protected void addSingletonVariableToScope(EObject context, Collection variables) { if (context instanceof VariableOrNodeExpr expr) { Variable singletonVariable = expr.getSingletonVariable(); if (singletonVariable != null) { @@ -82,18 +77,21 @@ protected void addSingletonVariableToScope(EObject context, List varia } } - protected void addExistentiallyQualifiedVariableToScope(EObject currentContext, List variables) { - if (currentContext instanceof ExistentialQuantifier quantifier) { - variables.addAll(quantifier.getImplicitVariables()); - } else if (currentContext instanceof Match match) { - variables.addAll(match.getCondition().getImplicitVariables()); - } else if (currentContext instanceof Consequent consequent) { + protected void addExistentiallyQualifiedVariableToScope(EObject currentContext, Collection variables) { + switch (currentContext) { + case ExistentialQuantifier quantifier -> variables.addAll(quantifier.getImplicitVariables()); + case Match match -> variables.addAll(match.getCondition().getImplicitVariables()); + case Consequent consequent -> { for (var literal : consequent.getActions()) { if (literal instanceof NewAction newAction && newAction.getVariable() != null) { variables.add(newAction.getVariable()); } } } + default -> { + // Nothing to add. + } + } } protected IScope getOppositeScope(EObject context) { @@ -105,10 +103,7 @@ protected IScope getOppositeScope(EObject context) { if (!(relation instanceof ClassDeclaration classDeclaration)) { return IScope.NULLSCOPE; } - var referenceDeclarations = classDeclaration.getFeatureDeclarations() - .stream() - .filter(ReferenceDeclaration.class::isInstance) - .toList(); + var referenceDeclarations = classDeclaration.getFeatureDeclarations(); return Scopes.scopeFor(referenceDeclarations); } } diff --git a/subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportAdapter.java b/subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportAdapter.java index d7a5304fb..753c85650 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportAdapter.java +++ b/subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportAdapter.java @@ -16,7 +16,12 @@ import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.xtext.naming.QualifiedName; +import tools.refinery.language.expressions.CompositeTermInterpreter; +import tools.refinery.language.expressions.TermInterpreter; +import tools.refinery.language.library.BuiltinLibrary; import tools.refinery.language.library.RefineryLibrary; +import tools.refinery.language.model.problem.Problem; +import tools.refinery.language.utils.BuiltinSymbols; import java.io.File; import java.nio.file.Path; @@ -25,15 +30,12 @@ public class ImportAdapter extends AdapterImpl { private static final Logger LOG = Logger.getLogger(ImportAdapter.class); private static final List DEFAULT_LIBRARIES; + private static final List DEFAULT_TERM_INTERPRETERS; private static final List DEFAULT_PATHS; static { - var serviceLoader = ServiceLoader.load(RefineryLibrary.class); - var defaultLibraries = new ArrayList(); - for (var service : serviceLoader) { - defaultLibraries.add(service); - } - DEFAULT_LIBRARIES = List.copyOf(defaultLibraries); + DEFAULT_LIBRARIES = loadServices(RefineryLibrary.class); + DEFAULT_TERM_INTERPRETERS = loadServices(TermInterpreter.class); var pathEnv = System.getenv("REFINERY_LIBRARY_PATH"); if (pathEnv == null) { DEFAULT_PATHS = List.of(); @@ -45,16 +47,29 @@ public class ImportAdapter extends AdapterImpl { } } - private final List libraries; - private final List libraryPaths; + private static List loadServices(Class serviceClass) { + var serviceLoader = ServiceLoader.load(serviceClass); + var services = new ArrayList(); + for (var service : serviceLoader) { + services.add(service); + } + return List.copyOf(services); + } + + private ResourceSet resourceSet; + private final List libraries = new ArrayList<>(DEFAULT_LIBRARIES); + private final List termInterpreters = new ArrayList<>(DEFAULT_TERM_INTERPRETERS); + private final TermInterpreter termInterpreter = new CompositeTermInterpreter(termInterpreters); + private final List libraryPaths = new ArrayList<>(DEFAULT_PATHS); private final Cache failedResolutions = CacheBuilder.newBuilder().maximumSize(100).build(); private final Map qualifiedNameToUriMap = new LinkedHashMap<>(); private final Map uriToQualifiedNameMap = new LinkedHashMap<>(); + private Problem builtinProblem; + private BuiltinSymbols builtinSymbols; - private ImportAdapter(ResourceSet resourceSet) { - libraries = new ArrayList<>(DEFAULT_LIBRARIES); - libraryPaths = new ArrayList<>(DEFAULT_PATHS); + void setResourceSet(ResourceSet resourceSet) { + this.resourceSet = resourceSet; for (var resource : resourceSet.getResources()) { resourceAdded(resource); } @@ -69,6 +84,14 @@ public List getLibraries() { return libraries; } + public List getTermInterpreters() { + return termInterpreters; + } + + public TermInterpreter getTermInterpreter() { + return termInterpreter; + } + public List getLibraryPaths() { return libraryPaths; } @@ -190,16 +213,26 @@ private void resourceRemoved(Resource resource) { } } - public static ImportAdapter getOrInstall(ResourceSet resourceSet) { - var adapter = getAdapter(resourceSet); - if (adapter == null) { - adapter = new ImportAdapter(resourceSet); - resourceSet.eAdapters().add(adapter); + public Problem getBuiltinProblem() { + if (builtinProblem == null) { + var builtinResource = resourceSet.getResource(BuiltinLibrary.BUILTIN_LIBRARY_URI, true); + if (builtinResource == null) { + throw new IllegalStateException("Failed to load builtin resource"); + } + var contents = builtinResource.getContents(); + if (contents.isEmpty()) { + throw new IllegalStateException("builtin resource is empty"); + } + builtinProblem = (Problem) contents.getFirst(); + EcoreUtil.resolveAll(builtinResource); } - return adapter; + return builtinProblem; } - private static ImportAdapter getAdapter(ResourceSet resourceSet) { - return (ImportAdapter) EcoreUtil.getAdapter(resourceSet.eAdapters(), ImportAdapter.class); + public BuiltinSymbols getBuiltinSymbols() { + if (builtinSymbols == null) { + builtinSymbols = new BuiltinSymbols(getBuiltinProblem()); + } + return builtinSymbols; } } diff --git a/subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportAdapterProvider.java b/subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportAdapterProvider.java new file mode 100644 index 000000000..5ab3a8519 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportAdapterProvider.java @@ -0,0 +1,68 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.scoping.imports; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.google.inject.Singleton; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.jetbrains.annotations.NotNull; +import tools.refinery.language.expressions.TermInterpreter; +import tools.refinery.language.utils.BuiltinSymbols; + +@Singleton +public class ImportAdapterProvider { + @Inject + private Provider delegateProvider; + + public BuiltinSymbols getBuiltinSymbols(@NotNull EObject context) { + var adapter = getOrInstall(context); + return adapter.getBuiltinSymbols(); + } + + public BuiltinSymbols getBuiltinSymbols(@NotNull Resource context) { + var adapter = getOrInstall(context); + return adapter.getBuiltinSymbols(); + } + + public TermInterpreter getTermInterpreter(@NotNull EObject context) { + var adapter = getOrInstall(context); + return adapter.getTermInterpreter(); + } + + public ImportAdapter getOrInstall(@NotNull EObject context) { + var resource = context.eResource(); + if (resource == null) { + throw new IllegalArgumentException("context is not in a resource"); + } + return getOrInstall(resource); + } + + public ImportAdapter getOrInstall(@NotNull Resource context) { + var resourceSet = context.getResourceSet(); + if (resourceSet == null) { + throw new IllegalArgumentException("context is not in a resource set"); + } + return getOrInstall(resourceSet); + } + + public ImportAdapter getOrInstall(@NotNull ResourceSet resourceSet) { + var adapter = getAdapter(resourceSet); + if (adapter == null) { + adapter = delegateProvider.get(); + adapter.setResourceSet(resourceSet); + resourceSet.eAdapters().add(adapter); + } + return adapter; + } + + public static ImportAdapter getAdapter(@NotNull ResourceSet resourceSet) { + return (ImportAdapter) EcoreUtil.getAdapter(resourceSet.eAdapters(), ImportAdapter.class); + } +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportCollector.java b/subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportCollector.java index ac5a92ba7..f3ab54ae9 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportCollector.java +++ b/subprojects/language/src/main/java/tools/refinery/language/scoping/imports/ImportCollector.java @@ -46,6 +46,9 @@ public class ImportCollector { @Inject private Provider loadOnDemandProvider; + @Inject + private ImportAdapterProvider importAdapterProvider; + public ImportCollection getDirectImports(Resource resource) { return cache.get(DIRECT_IMPORTS_KEY, resource, () -> this.computeDirectImports(resource)); } @@ -58,7 +61,7 @@ protected ImportCollection computeDirectImports(Resource resource) { if (resourceSet == null) { return ImportCollection.EMPTY; } - var adapter = ImportAdapter.getOrInstall(resourceSet); + var adapter = importAdapterProvider.getOrInstall(resourceSet); var collection = new ImportCollection(); collectAutomaticImports(collection, adapter); collectExplicitImports(problem, collection, adapter); diff --git a/subprojects/language/src/main/java/tools/refinery/language/typesystem/AggregatorName.java b/subprojects/language/src/main/java/tools/refinery/language/typesystem/AggregatorName.java new file mode 100644 index 000000000..5939865ab --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/typesystem/AggregatorName.java @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.typesystem; + +import org.eclipse.xtext.naming.QualifiedName; + +public record AggregatorName(QualifiedName qualifiedName) { + public AggregatorName(QualifiedName prefix, String name) { + this(prefix.append(name)); + } + + @Override + public String toString() { + return qualifiedName.isEmpty() ? "" : qualifiedName.getLastSegment(); + } +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/typesystem/DataExprType.java b/subprojects/language/src/main/java/tools/refinery/language/typesystem/DataExprType.java new file mode 100644 index 000000000..9bc3e6aa2 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/typesystem/DataExprType.java @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.typesystem; + +import org.eclipse.xtext.naming.QualifiedName; + +public record DataExprType(QualifiedName qualifiedName) implements FixedType { + public DataExprType(QualifiedName prefix, String name) { + this(prefix.append(name)); + } + + @Override + public String toString() { + return qualifiedName.isEmpty() ? "" : qualifiedName.getLastSegment(); + } +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/typesystem/ExprType.java b/subprojects/language/src/main/java/tools/refinery/language/typesystem/ExprType.java new file mode 100644 index 000000000..9e44063d9 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/typesystem/ExprType.java @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.typesystem; + +public sealed interface ExprType permits FixedType, MutableType { + NodeType NODE = new NodeType(); + LiteralType LITERAL = new LiteralType(); + InvalidType INVALID = new InvalidType(); + + FixedType getActualType(); + + ExprType unwrapIfSet(); +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/typesystem/FixedType.java b/subprojects/language/src/main/java/tools/refinery/language/typesystem/FixedType.java new file mode 100644 index 000000000..1b2ded48b --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/typesystem/FixedType.java @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.typesystem; + +public sealed interface FixedType extends ExprType permits NodeType, LiteralType, InvalidType, DataExprType { + @Override + default FixedType getActualType() { + return this; + } + + @Override + default FixedType unwrapIfSet() { + return this; + } +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/typesystem/InvalidType.java b/subprojects/language/src/main/java/tools/refinery/language/typesystem/InvalidType.java new file mode 100644 index 000000000..c18612bcf --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/typesystem/InvalidType.java @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.typesystem; + +public final class InvalidType implements FixedType { + InvalidType() { + } + + @Override + public String toString() { + return "invalid"; + } +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/typesystem/LiteralType.java b/subprojects/language/src/main/java/tools/refinery/language/typesystem/LiteralType.java new file mode 100644 index 000000000..7fd335530 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/typesystem/LiteralType.java @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.typesystem; + +public final class LiteralType implements FixedType { + LiteralType() { + } + + @Override + public String toString() { + return "constraint"; + } +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/typesystem/MutableType.java b/subprojects/language/src/main/java/tools/refinery/language/typesystem/MutableType.java new file mode 100644 index 000000000..78fdf884b --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/typesystem/MutableType.java @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.typesystem; + +public final class MutableType implements ExprType { + private DataExprType actualType; + + @Override + public FixedType getActualType() { + return actualType == null ? INVALID : actualType; + } + + public void setActualType(DataExprType actualType) { + if (this.actualType != null) { + throw new IllegalStateException("Actual type was already set"); + } + this.actualType = actualType; + } + + @Override + public ExprType unwrapIfSet() { + return actualType == null ? this : actualType; + } + + @Override + public String toString() { + return getActualType().toString(); + } +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/typesystem/NodeType.java b/subprojects/language/src/main/java/tools/refinery/language/typesystem/NodeType.java new file mode 100644 index 000000000..1baff2126 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/typesystem/NodeType.java @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.typesystem; + +public final class NodeType implements FixedType { + NodeType() { + } + + @Override + public String toString() { + return "node"; + } +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/typesystem/ProblemTypeAnalyzer.java b/subprojects/language/src/main/java/tools/refinery/language/typesystem/ProblemTypeAnalyzer.java new file mode 100644 index 000000000..fcf99ad88 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/typesystem/ProblemTypeAnalyzer.java @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.typesystem; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.google.inject.Singleton; +import org.eclipse.xtext.util.IResourceScopeCache; +import tools.refinery.language.model.problem.Problem; + +@Singleton +public class ProblemTypeAnalyzer { + private static final String CACHE_KEY = "tools.refinery.language.typesystem.ProblemTypeAnalyzer.CACHE_KEY"; + + @Inject + private IResourceScopeCache resourceScopeCache; + + @Inject + private Provider typedModuleProvider; + + public TypedModule getOrComputeTypes(Problem problem) { + var resource = problem.eResource(); + return resourceScopeCache.get(CACHE_KEY, resource, () -> { + var typedModule = typedModuleProvider.get(); + typedModule.setProblem(problem); + return typedModule; + }); + } +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/typesystem/Signature.java b/subprojects/language/src/main/java/tools/refinery/language/typesystem/Signature.java new file mode 100644 index 000000000..8e72c1857 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/typesystem/Signature.java @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.typesystem; + +import java.util.List; + +public record Signature(List parameterTypes, FixedType resultType) { +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/typesystem/SignatureProvider.java b/subprojects/language/src/main/java/tools/refinery/language/typesystem/SignatureProvider.java new file mode 100644 index 000000000..3e25a0f55 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/typesystem/SignatureProvider.java @@ -0,0 +1,107 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.typesystem; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import org.eclipse.xtext.naming.IQualifiedNameProvider; +import org.eclipse.xtext.util.IResourceScopeCache; +import tools.refinery.language.model.problem.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +@Singleton +public class SignatureProvider { + private static final String PREFIX = "tools.refinery.language.typesystem.SignatureProvider."; + private static final String SIGNATURE_CACHE = PREFIX + "SIGNATURE_CACHE"; + private static final String DATATYPE_CACHE = PREFIX + "DATATYPE_CACHE"; + private static final String AGGREGATOR_CACHE = PREFIX + "AGGREGATOR_CACHE"; + + @Inject + private IQualifiedNameProvider qualifiedNameProvider; + + @Inject + private IResourceScopeCache cache; + + public Signature getSignature(Relation relation) { + var signatures = cache.get(SIGNATURE_CACHE, relation.eResource(), () -> new HashMap()); + return signatures.computeIfAbsent(relation, this::computeSignature); + } + + public int getArity(Relation relation) { + return getSignature(relation).parameterTypes().size(); + } + + private Signature computeSignature(Relation relation) { + return new Signature(getParameterTypes(relation), getResultType(relation)); + } + + private List getParameterTypes(Relation relation) { + return switch (relation) { + case ClassDeclaration ignored -> List.of(ExprType.NODE); + case EnumDeclaration ignored -> List.of(ExprType.NODE); + case DatatypeDeclaration datatypeDeclaration -> List.of(getDataType(datatypeDeclaration)); + case ReferenceDeclaration referenceDeclaration -> { + if (referenceDeclaration.getReferenceType() instanceof DatatypeDeclaration) { + yield List.of(ExprType.NODE); + } + yield List.of(ExprType.NODE, ExprType.NODE); + } + case ParametricDefinition parametricDefinition -> { + var parameters = parametricDefinition.getParameters(); + var exprTypes = new ArrayList(parameters.size()); + for (var parameter : parameters) { + if (parameter.getParameterType() instanceof DatatypeDeclaration datatypeDeclaration) { + exprTypes.add(getDataType(datatypeDeclaration)); + } else { + exprTypes.add(ExprType.NODE); + } + } + yield List.copyOf(exprTypes); + } + default -> throw new IllegalArgumentException("Unknown Relation: " + relation); + }; + } + + private FixedType getResultType(Relation relation) { + if (relation instanceof ReferenceDeclaration referenceDeclaration && + referenceDeclaration.getReferenceType() instanceof DatatypeDeclaration datatypeDeclaration) { + return getDataType(datatypeDeclaration); + } + return ExprType.LITERAL; + } + + public DataExprType getDataType(DatatypeDeclaration datatypeDeclaration) { + var dataTypes = cache.get(DATATYPE_CACHE, datatypeDeclaration.eResource(), + () -> new HashMap()); + return dataTypes.computeIfAbsent(datatypeDeclaration, this::computeDataType); + } + + private DataExprType computeDataType(DatatypeDeclaration datatypeDeclaration) { + var qualifiedName = qualifiedNameProvider.getFullyQualifiedName(datatypeDeclaration); + if (qualifiedName == null) { + throw new IllegalArgumentException("Datatype declaration has no qualified name: " + datatypeDeclaration); + } + return new DataExprType(qualifiedName); + } + + public AggregatorName getAggregatorName(AggregatorDeclaration aggregatorDeclaration) { + var dataTypes = cache.get(AGGREGATOR_CACHE, aggregatorDeclaration.eResource(), + () -> new HashMap()); + return dataTypes.computeIfAbsent(aggregatorDeclaration, this::computeAggregatorName); + } + + private AggregatorName computeAggregatorName(AggregatorDeclaration aggregatorDeclaration) { + var qualifiedName = qualifiedNameProvider.getFullyQualifiedName(aggregatorDeclaration); + if (qualifiedName == null) { + throw new IllegalArgumentException( + "Aggregator declaration has no qualified name: " + aggregatorDeclaration); + } + return new AggregatorName(qualifiedName); + } +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/typesystem/TypedModule.java b/subprojects/language/src/main/java/tools/refinery/language/typesystem/TypedModule.java new file mode 100644 index 000000000..de923e0d7 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/typesystem/TypedModule.java @@ -0,0 +1,568 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.typesystem; + +import com.google.inject.Inject; +import org.eclipse.emf.common.util.Diagnostic; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.xtext.validation.CheckType; +import org.eclipse.xtext.validation.FeatureBasedDiagnostic; +import tools.refinery.language.expressions.BuiltinTermInterpreter; +import tools.refinery.language.expressions.TermInterpreter; +import tools.refinery.language.model.problem.*; +import tools.refinery.language.scoping.imports.ImportAdapterProvider; +import tools.refinery.language.validation.ProblemValidator; + +import java.util.*; + +public class TypedModule { + private static final String OPERAND_TYPE_ERROR_MESSAGE = "Cannot determine operand type."; + + @Inject + private SignatureProvider signatureProvider; + + @Inject + private ImportAdapterProvider importAdapterProvider; + + private TermInterpreter interpreter; + private final Map> assignments = new LinkedHashMap<>(); + private final Map variableTypes = new HashMap<>(); + private final Map expressionTypes = new HashMap<>(); + private final Set variablesToProcess = new LinkedHashSet<>(); + private final List diagnostics = new ArrayList<>(); + + void setProblem(Problem problem) { + interpreter = importAdapterProvider.getTermInterpreter(problem); + gatherAssignments(problem); + checkTypes(problem); + } + + private void gatherAssignments(Problem problem) { + var iterator = problem.eAllContents(); + while (iterator.hasNext()) { + var eObject = iterator.next(); + if (!(eObject instanceof AssignmentExpr assignmentExpr)) { + continue; + } + if (assignmentExpr.getLeft() instanceof VariableOrNodeExpr variableOrNodeExpr && + variableOrNodeExpr.getVariableOrNode() instanceof Variable variable) { + var assignmentList = assignments.computeIfAbsent(variable, ignored -> new ArrayList<>(1)); + assignmentList.add(assignmentExpr); + } + iterator.prune(); + } + } + + private void checkTypes(Problem problem) { + for (var statement : problem.getStatements()) { + switch (statement) { + case PredicateDefinition predicateDefinition -> checkTypes(predicateDefinition); + case Assertion assertion -> checkTypes(assertion); + default -> { + // Nothing to type check. + } + } + } + } + + private void checkTypes(PredicateDefinition predicateDefinition) { + for (var conjunction : predicateDefinition.getBodies()) { + for (var literal : conjunction.getLiterals()) { + coerceIntoLiteral(literal); + } + } + } + + private void checkTypes(Assertion assertion) { + var relation = assertion.getRelation(); + var value = assertion.getValue(); + if (relation == null) { + return; + } + var type = signatureProvider.getSignature(relation).resultType(); + if (type == ExprType.LITERAL) { + if (value == null) { + return; + } + expectType(value, BuiltinTermInterpreter.BOOLEAN_TYPE); + return; + } + if (value == null) { + var message = "Assertion value of type %s is required.".formatted(type); + error(message, assertion, ProblemPackage.Literals.ASSERTION__RELATION, 0, ProblemValidator.TYPE_ERROR); + } + expectType(value, type); + } + + public List getDiagnostics() { + return diagnostics; + } + + public FixedType getVariableType(Variable variable) { + // We can't use computeIfAbsent here, because translating referenced queries calls this method in a reentrant + // way, which would cause a ConcurrentModificationException with computeIfAbsent. + @SuppressWarnings("squid:S3824") + var type = variableTypes.get(variable); + //noinspection Java8MapApi + if (type == null) { + type = computeVariableType(variable); + variableTypes.put(variable, type); + } + return type; + } + + private FixedType computeVariableType(Variable variable) { + if (variable instanceof Parameter) { + return computeUnassignedVariableType(variable); + } + var assignmnentList = assignments.get(variable); + if (assignmnentList == null || assignmnentList.isEmpty()) { + return computeUnassignedVariableType(variable); + } + if (variablesToProcess.contains(variable)) { + throw new IllegalStateException("Circular reference to variable: " + variable.getName()); + } + if (assignmnentList.size() > 1) { + var message = "Multiple assignments for variable '%s'.".formatted(variable.getName()); + for (var assignment : assignmnentList) { + error(message, assignment, ProblemPackage.Literals.BINARY_EXPR__LEFT, 0, + ProblemValidator.INVALID_ASSIGNMENT_ISSUE); + } + return ExprType.INVALID; + } + var assignment = assignmnentList.getFirst(); + variablesToProcess.add(variable); + try { + var assignedType = getExpressionType(assignment.getRight()); + if (assignedType instanceof MutableType) { + var message = "Cannot determine type of variable '%s'.".formatted(variable.getName()); + error(message, assignment, ProblemPackage.Literals.BINARY_EXPR__RIGHT, 0, ProblemValidator.TYPE_ERROR); + return ExprType.INVALID; + } + if (assignedType instanceof DataExprType dataExprType) { + return dataExprType; + } + if (assignedType != ExprType.INVALID) { + var message = "Expected data expression for variable '%s', got %s instead." + .formatted(variable.getName(), assignedType); + error(message, assignment, ProblemPackage.Literals.BINARY_EXPR__RIGHT, 0, ProblemValidator.TYPE_ERROR); + } + return ExprType.INVALID; + } finally { + variablesToProcess.remove(variable); + } + } + + private FixedType computeUnassignedVariableType(Variable variable) { + if (variable instanceof Parameter parameter && + parameter.getParameterType() instanceof DatatypeDeclaration datatypeDeclaration) { + return signatureProvider.getDataType(datatypeDeclaration); + } + // Parameters without an explicit datatype annotation are node variables. + return ExprType.NODE; + } + + public ExprType getExpressionType(Expr expr) { + // We can't use computeIfAbsent here, because translating referenced queries calls this method in a reentrant + // way, which would cause a ConcurrentModificationException with computeIfAbsent. + @SuppressWarnings("squid:S3824") + var type = expressionTypes.get(expr); + //noinspection Java8MapApi + if (type == null) { + type = computeExpressionType(expr); + expressionTypes.put(expr, type); + } + return type.unwrapIfSet(); + } + + private ExprType computeExpressionType(Expr expr) { + return switch (expr) { + case LogicConstant logicConstant -> computeExpressionType(logicConstant); + case IntConstant ignored -> BuiltinTermInterpreter.INT_TYPE; + case RealConstant ignored -> BuiltinTermInterpreter.REAL_TYPE; + case StringConstant ignored -> BuiltinTermInterpreter.STRING_TYPE; + case InfiniteConstant ignored -> new MutableType(); + case VariableOrNodeExpr variableOrNodeExpr -> computeExpressionType(variableOrNodeExpr); + case AssignmentExpr assignmentExpr -> computeExpressionType(assignmentExpr); + case Atom atom -> computeExpressionType(atom); + case NegationExpr negationExpr -> computeExpressionType(negationExpr); + case ArithmeticUnaryExpr arithmeticUnaryExpr -> computeExpressionType(arithmeticUnaryExpr); + case CountExpr countExpr -> computeExpressionType(countExpr); + case AggregationExpr aggregationExpr -> computeExpressionType(aggregationExpr); + case ComparisonExpr comparisonExpr -> computeExpressionType(comparisonExpr); + case LatticeBinaryExpr latticeBinaryExpr -> computeExpressionType(latticeBinaryExpr); + case RangeExpr rangeExpr -> computeExpressionType(rangeExpr); + case ArithmeticBinaryExpr arithmeticBinaryExpr -> computeExpressionType(arithmeticBinaryExpr); + case CastExpr castExpr -> computeExpressionType(castExpr); + default -> { + error("Unknown expression: " + expr.getClass().getSimpleName(), expr, null, 0, + ProblemValidator.UNKNOWN_EXPRESSION_ISSUE); + yield ExprType.INVALID; + } + }; + } + + private ExprType computeExpressionType(LogicConstant expr) { + return switch (expr.getLogicValue()) { + case TRUE, FALSE -> BuiltinTermInterpreter.BOOLEAN_TYPE; + case UNKNOWN, ERROR -> new MutableType(); + case null -> ExprType.INVALID; + }; + } + + private ExprType computeExpressionType(VariableOrNodeExpr expr) { + var target = expr.getVariableOrNode(); + if (target == null || target.eIsProxy()) { + return ExprType.INVALID; + } + return switch (target) { + case Node ignored -> ExprType.NODE; + case Variable variable -> { + if (variablesToProcess.contains(variable)) { + var message = "Circular reference to variable '%s'.".formatted(variable.getName()); + error(message, expr, ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__VARIABLE_OR_NODE, 0, + ProblemValidator.INVALID_ASSIGNMENT_ISSUE); + yield ExprType.INVALID; + } + yield getVariableType(variable); + } + default -> { + error("Unknown variable: " + target.getName(), expr, + ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__VARIABLE_OR_NODE, 0, + ProblemValidator.UNKNOWN_EXPRESSION_ISSUE); + yield ExprType.INVALID; + } + }; + } + + private ExprType computeExpressionType(AssignmentExpr expr) { + // Force the left side to type check. Since the left side is a variable, it will force the right side to also + // type check in order to infer the variable type. + return getExpressionType(expr.getLeft()) == ExprType.INVALID ? ExprType.INVALID : ExprType.LITERAL; + } + + private ExprType computeExpressionType(Atom atom) { + var relation = atom.getRelation(); + if (relation == null || relation.eIsProxy()) { + return ExprType.INVALID; + } + if (relation instanceof DatatypeDeclaration) { + var message = "Invalid call to data type. Use 'as %s' for casting.".formatted( + relation.getName()); + error(message, atom, ProblemPackage.Literals.ATOM__RELATION, 0, ProblemValidator.TYPE_ERROR); + } + var signature = signatureProvider.getSignature(relation); + var parameterTypes = signature.parameterTypes(); + var arguments = atom.getArguments(); + int size = Math.min(parameterTypes.size(), arguments.size()); + boolean ok = parameterTypes.size() == arguments.size(); + for (int i = 0; i < size; i++) { + var parameterType = parameterTypes.get(i); + var argument = arguments.get(i); + if (!expectType(argument, parameterType)) { + // Avoid short-circuiting to let us type check all arguments. + ok = false; + } + } + return ok ? signature.resultType() : ExprType.INVALID; + } + + private ExprType computeExpressionType(NegationExpr negationExpr) { + var body = negationExpr.getBody(); + if (body == null) { + return ExprType.INVALID; + } + var actualType = getExpressionType(body); + if (actualType == ExprType.LITERAL) { + // Negation of literals yields another (non-enumerable) literal. + return ExprType.LITERAL; + } + if (actualType == DataExprType.INVALID) { + return ExprType.INVALID; + } + if (actualType instanceof MutableType) { + error(OPERAND_TYPE_ERROR_MESSAGE, body, null, 0, ProblemValidator.TYPE_ERROR); + return ExprType.INVALID; + } + if (actualType instanceof DataExprType dataExprType) { + var result = interpreter.getNegationType(dataExprType); + if (result.isPresent()) { + return result.get(); + } + } + var message = "Data type %s does not support negation.".formatted(actualType); + error(message, negationExpr, null, 0, ProblemValidator.TYPE_ERROR); + return ExprType.INVALID; + } + + private ExprType computeExpressionType(ArithmeticUnaryExpr expr) { + var op = expr.getOp(); + var body = expr.getBody(); + if (op == null || body == null) { + return ExprType.INVALID; + } + var actualType = getExpressionType(body); + if (actualType == DataExprType.INVALID) { + return ExprType.INVALID; + } + if (actualType instanceof MutableType) { + error(OPERAND_TYPE_ERROR_MESSAGE, body, null, 0, ProblemValidator.TYPE_ERROR); + return ExprType.INVALID; + } + if (actualType instanceof DataExprType dataExprType) { + var result = interpreter.getUnaryOperationType(op, dataExprType); + if (result.isPresent()) { + return result.get(); + } + } + var message = "Unsupported operator for data type %s.".formatted(actualType); + error(message, expr, null, 0, ProblemValidator.TYPE_ERROR); + return ExprType.INVALID; + } + + private ExprType computeExpressionType(CountExpr countExpr) { + return coerceIntoLiteral(countExpr.getBody()) ? BuiltinTermInterpreter.INT_TYPE : ExprType.INVALID; + } + + private ExprType computeExpressionType(AggregationExpr expr) { + var aggregator = expr.getAggregator(); + if (aggregator == null || aggregator.eIsProxy()) { + return null; + } + // Avoid short-circuiting to let us type check both the value and the condition. + boolean ok = coerceIntoLiteral(expr.getCondition()); + var value = expr.getValue(); + var actualType = getExpressionType(value); + if (actualType == ExprType.INVALID) { + return ExprType.INVALID; + } + if (actualType instanceof MutableType) { + error(OPERAND_TYPE_ERROR_MESSAGE, value, null, 0, ProblemValidator.TYPE_ERROR); + return ExprType.INVALID; + } + if (actualType instanceof DataExprType dataExprType) { + var aggregatorName = signatureProvider.getAggregatorName(aggregator); + var result = interpreter.getAggregationType(aggregatorName, dataExprType); + if (result.isPresent()) { + return ok ? result.get() : ExprType.INVALID; + } + } + var message = "Unsupported aggregator for type %s.".formatted(actualType); + error(message, expr, ProblemPackage.Literals.AGGREGATION_EXPR__AGGREGATOR, 0, ProblemValidator.TYPE_ERROR); + return ExprType.INVALID; + } + + private ExprType computeExpressionType(ComparisonExpr expr) { + var left = expr.getLeft(); + var right = expr.getRight(); + var op = expr.getOp(); + if (op == ComparisonOp.NODE_EQ || op == ComparisonOp.NODE_NOT_EQ) { + // Avoid short-circuiting to let us type check both arguments. + boolean leftOk = expectType(left, ExprType.NODE); + boolean rightOk = expectType(right, ExprType.NODE); + return leftOk && rightOk ? ExprType.LITERAL : ExprType.INVALID; + } + if (!(getCommonDataType(expr) instanceof DataExprType commonType)) { + return ExprType.INVALID; + } + // Data equality and inequality are always supported for data types. + if (op != ComparisonOp.EQ && op != ComparisonOp.NOT_EQ && !interpreter.isComparisonSupported(commonType)) { + var message = "Data type %s does not support comparison.".formatted(commonType); + error(message, expr, null, 0, ProblemValidator.TYPE_ERROR); + return ExprType.INVALID; + } + return BuiltinTermInterpreter.BOOLEAN_TYPE; + } + + private ExprType computeExpressionType(LatticeBinaryExpr expr) { + // Lattice operations are always supported for data types. + return getCommonDataType(expr); + } + + private ExprType computeExpressionType(RangeExpr expr) { + var left = expr.getLeft(); + var right = expr.getRight(); + if (left instanceof InfiniteConstant && right instanceof InfiniteConstant) { + // `*..*` is equivalent to `unknown` if neither subexpression have been typed yet. + var mutableType = new MutableType(); + if (expressionTypes.putIfAbsent(left, mutableType) == null && + expressionTypes.put(right, mutableType) == null) { + return mutableType; + } + } + if (!(getCommonDataType(expr) instanceof DataExprType commonType)) { + return ExprType.INVALID; + } + if (!interpreter.isRangeSupported(commonType)) { + var message = "Data type %s does not support ranges.".formatted(commonType); + error(message, expr, null, 0, ProblemValidator.TYPE_ERROR); + return ExprType.INVALID; + } + return commonType; + } + + private ExprType computeExpressionType(ArithmeticBinaryExpr expr) { + var op = expr.getOp(); + var left = expr.getLeft(); + var right = expr.getRight(); + if (op == null || left == null || right == null) { + return ExprType.INVALID; + } + // Avoid short-circuiting to let us type check both arguments. + var leftType = getExpressionType(left); + var rightType = getExpressionType(right); + if (leftType == ExprType.INVALID || rightType == ExprType.INVALID) { + return ExprType.INVALID; + } + if (rightType instanceof MutableType rightMutableType) { + if (leftType instanceof DataExprType leftExprType) { + rightMutableType.setActualType(leftExprType); + rightType = leftExprType; + } else { + error(OPERAND_TYPE_ERROR_MESSAGE, right, null, 0, ProblemValidator.TYPE_ERROR); + return ExprType.INVALID; + } + } + if (leftType instanceof MutableType leftMutableType) { + if (rightType instanceof DataExprType rightExprType) { + leftMutableType.setActualType(rightExprType); + leftType = rightExprType; + } else { + error(OPERAND_TYPE_ERROR_MESSAGE, left, null, 0, ProblemValidator.TYPE_ERROR); + return ExprType.INVALID; + } + } + if (leftType instanceof DataExprType leftExprType && rightType instanceof DataExprType rightExprType) { + var result = interpreter.getBinaryOperationType(op, leftExprType, rightExprType); + if (result.isPresent()) { + return result.get(); + } + } + var messageBuilder = new StringBuilder("Unsupported operator for "); + if (leftType.equals(rightType)) { + messageBuilder.append("data type ").append(leftType); + } else { + messageBuilder.append("data types ").append(leftType).append(" and ").append(rightType); + } + messageBuilder.append("."); + error(messageBuilder.toString(), expr, null, 0, ProblemValidator.TYPE_ERROR); + return ExprType.INVALID; + } + + private ExprType computeExpressionType(CastExpr expr) { + var body = expr.getBody(); + var targetRelation = expr.getTargetType(); + if (body == null || !(targetRelation instanceof DatatypeDeclaration targetDeclaration)) { + return null; + } + var actualType = getExpressionType(body); + if (actualType == ExprType.INVALID) { + return ExprType.INVALID; + } + var targetType = signatureProvider.getDataType(targetDeclaration); + if (actualType instanceof MutableType mutableType) { + // Type ascription for polymorphic literal (e.g., `unknown as int` for the set of all integers). + mutableType.setActualType(targetType); + return targetType; + } + if (actualType.equals(targetType)) { + return targetType; + } + if (actualType instanceof DataExprType dataExprType && interpreter.isCastSupported(dataExprType, targetType)) { + return targetType; + } + var message = "Casting from %s to %s is not supported.".formatted(actualType, targetType); + error(message, expr, null, 0, ProblemValidator.TYPE_ERROR); + return ExprType.INVALID; + } + + private FixedType getCommonDataType(BinaryExpr expr) { + var commonType = getCommonType(expr); + if (!(commonType instanceof DataExprType) && commonType != ExprType.INVALID) { + var message = "Expected data expression, got %s instead.".formatted(commonType); + error(message, expr, null, 0, ProblemValidator.TYPE_ERROR); + return ExprType.INVALID; + } + return commonType; + } + + private FixedType getCommonType(BinaryExpr expr) { + var left = expr.getLeft(); + var right = expr.getRight(); + if (left == null || right == null) { + return ExprType.INVALID; + } + var leftType = getExpressionType(left); + if (leftType instanceof FixedType fixedLeftType) { + return expectType(right, fixedLeftType) ? fixedLeftType : ExprType.INVALID; + } else { + var rightType = getExpressionType(right); + if (rightType instanceof FixedType fixedRightType) { + return expectType(left, leftType, fixedRightType) ? fixedRightType : ExprType.INVALID; + } else { + error(OPERAND_TYPE_ERROR_MESSAGE, left, null, 0, ProblemValidator.TYPE_ERROR); + error(OPERAND_TYPE_ERROR_MESSAGE, right, null, 0, ProblemValidator.TYPE_ERROR); + return ExprType.INVALID; + } + } + } + + private boolean coerceIntoLiteral(Expr expr) { + if (expr == null) { + return false; + } + var actualType = getExpressionType(expr); + if (actualType == ExprType.LITERAL) { + return true; + } + return expectType(expr, actualType, BuiltinTermInterpreter.BOOLEAN_TYPE); + } + + private boolean expectType(Expr expr, FixedType expectedType) { + if (expr == null) { + return false; + } + var actualType = getExpressionType(expr); + return expectType(expr, actualType, expectedType); + } + + private boolean expectType(Expr expr, ExprType actualType, FixedType expectedType) { + if (expectedType == ExprType.INVALID) { + // Silence any further errors is the expected type failed to compute. + return false; + } + if (actualType.equals(expectedType)) { + return true; + } + if (actualType == ExprType.INVALID) { + // We have already emitted an error previously. + return false; + } + if (actualType instanceof MutableType mutableType && expectedType instanceof DataExprType dataExprType) { + mutableType.setActualType(dataExprType); + return true; + } + var builder = new StringBuilder() + .append("Expected ") + .append(expectedType) + .append(" expression"); + if (!(actualType instanceof MutableType)) { + builder.append(", got ") + .append(actualType) + .append(" instead"); + } + builder.append("."); + error(builder.toString(), expr, null, 0, ProblemValidator.TYPE_ERROR); + return false; + } + + private void error(String message, EObject object, EStructuralFeature feature, int index, String code, + String... issueData) { + diagnostics.add(new FeatureBasedDiagnostic(Diagnostic.ERROR, message, object, feature, index, + CheckType.NORMAL, code, issueData)); + } +} diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java b/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java index c87fa0440..72f23e854 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java +++ b/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ @@ -7,7 +7,56 @@ import tools.refinery.language.model.problem.*; -public record BuiltinSymbols(Problem problem, ClassDeclaration node, PredicateDefinition equals, - PredicateDefinition exists, ClassDeclaration contained, PredicateDefinition contains, - PredicateDefinition invalidContainer) { +public final class BuiltinSymbols { + private final Problem problem; + private final ClassDeclaration node; + private final PredicateDefinition equals; + private final PredicateDefinition exists; + private final ClassDeclaration contained; + private final PredicateDefinition contains; + private final PredicateDefinition invalidContainer; + + public BuiltinSymbols(Problem problem) { + this.problem = problem; + node = getDeclaration(ClassDeclaration.class, "node"); + equals = getDeclaration(PredicateDefinition.class, "equals"); + exists = getDeclaration(PredicateDefinition.class, "exists"); + contained = getDeclaration(ClassDeclaration.class, "contained"); + contains = getDeclaration(PredicateDefinition.class, "contains"); + invalidContainer = getDeclaration(PredicateDefinition.class, "invalidContainer"); + } + + public Problem problem() { + return problem; + } + + public ClassDeclaration node() { + return node; + } + + public PredicateDefinition equals() { + return equals; + } + + public PredicateDefinition exists() { + return exists; + } + + public ClassDeclaration contained() { + return contained; + } + + public PredicateDefinition contains() { + return contains; + } + + public PredicateDefinition invalidContainer() { + return invalidContainer; + } + + private T getDeclaration(Class type, String name) { + return problem.getStatements().stream().filter(type::isInstance).map(type::cast) + .filter(declaration -> name.equals(declaration.getName())).findFirst() + .orElseThrow(() -> new IllegalArgumentException("Built-in declaration " + name + " was not found")); + } } diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java b/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java deleted file mode 100644 index 0bd1e50b6..000000000 --- a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors - * - * SPDX-License-Identifier: EPL-2.0 - */ -package tools.refinery.language.utils; - -import com.google.inject.Inject; -import com.google.inject.Singleton; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.xtext.util.IResourceScopeCache; -import org.eclipse.xtext.util.Tuples; -import tools.refinery.language.library.BuiltinLibrary; -import tools.refinery.language.model.problem.*; - -import java.util.*; - -@Singleton -public class ProblemDesugarer { - @Inject - private IResourceScopeCache cache = IResourceScopeCache.NullImpl.INSTANCE; - - public Optional getBuiltinProblem(EObject context) { - return Optional.ofNullable(context).map(EObject::eResource).flatMap(resource -> - cache.get("builtinProblem", resource, () -> doGetBuiltinProblem(resource))); - } - - private Optional doGetBuiltinProblem(Resource resource) { - return Optional.ofNullable(resource).map(Resource::getResourceSet) - .map(resourceSet -> resourceSet.getResource(BuiltinLibrary.BUILTIN_LIBRARY_URI, true)) - .map(Resource::getContents).filter(contents -> !contents.isEmpty()).map(List::getFirst) - .filter(Problem.class::isInstance).map(Problem.class::cast); - } - - public Optional getBuiltinSymbols(EObject context) { - return getBuiltinProblem(context).map(builtin -> - cache.get("builtinSymbols", builtin.eResource(), () -> doGetBuiltinSymbols(builtin))); - } - - private BuiltinSymbols doGetBuiltinSymbols(Problem builtin) { - var node = doGetDeclaration(builtin, ClassDeclaration.class, "node"); - var equals = doGetDeclaration(builtin, PredicateDefinition.class, "equals"); - var exists = doGetDeclaration(builtin, PredicateDefinition.class, "exists"); - var contained = doGetDeclaration(builtin, ClassDeclaration.class, "contained"); - var contains = doGetDeclaration(builtin, PredicateDefinition.class, "contains"); - var invalidContainer = doGetDeclaration(builtin, PredicateDefinition.class, "invalidContainer"); - return new BuiltinSymbols(builtin, node, equals, exists, contained, contains, invalidContainer); - } - - private T doGetDeclaration(Problem builtin, Class type, String name) { - return builtin.getStatements().stream().filter(type::isInstance).map(type::cast) - .filter(declaration -> name.equals(declaration.getName())).findFirst() - .orElseThrow(() -> new IllegalArgumentException("Built-in declaration " + name + " was not found")); - } - - public Collection getSuperclassesAndSelf(ClassDeclaration classDeclaration) { - return cache.get(Tuples.create(classDeclaration, "superclassesAndSelf"), classDeclaration.eResource(), - () -> doGetSuperclassesAndSelf(classDeclaration)); - } - - private Collection doGetSuperclassesAndSelf(ClassDeclaration classDeclaration) { - var builtinSymbols = getBuiltinSymbols(classDeclaration); - Set found = new HashSet<>(); - builtinSymbols.ifPresent(symbols -> found.add(symbols.node())); - Deque queue = new ArrayDeque<>(); - queue.addLast(classDeclaration); - while (!queue.isEmpty()) { - ClassDeclaration current = queue.removeFirst(); - if (!found.contains(current)) { - found.add(current); - for (Relation superType : current.getSuperTypes()) { - if (superType instanceof ClassDeclaration superDeclaration) { - queue.addLast(superDeclaration); - } - } - } - } - return found; - } - - public Collection getAllReferenceDeclarations(ClassDeclaration classDeclaration) { - return cache.get(Tuples.create(classDeclaration, "allReferenceDeclarations"), classDeclaration.eResource(), - () -> doGetAllReferenceDeclarations(classDeclaration)); - } - - private Collection doGetAllReferenceDeclarations(ClassDeclaration classDeclaration) { - Set referenceDeclarations = new HashSet<>(); - for (ClassDeclaration superclass : getSuperclassesAndSelf(classDeclaration)) { - for (FeatureDeclaration featureDeclaration : superclass.getFeatureDeclarations()) { - if (featureDeclaration instanceof ReferenceDeclaration referenceDeclaration) { - referenceDeclarations.add(referenceDeclaration); - } - } - } - return referenceDeclarations; - } - - public boolean isContainmentReference(ReferenceDeclaration referenceDeclaration) { - return referenceDeclaration.getKind() == ReferenceKind.CONTAINMENT; - } -} diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java b/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java index f70893e0b..9daa8f610 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java +++ b/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ @@ -81,6 +81,9 @@ public static boolean isInvalidMultiplicityConstraint(PredicateDefinition predic } public static boolean hasMultiplicityConstraint(ReferenceDeclaration referenceDeclaration) { + if (referenceDeclaration.getReferenceType() instanceof DatatypeDeclaration) { + return false; + } var opposite = referenceDeclaration.getOpposite(); if (opposite != null && opposite.getKind() == ReferenceKind.CONTAINMENT) { return false; @@ -95,17 +98,19 @@ public static boolean hasMultiplicityConstraint(ReferenceDeclaration referenceDe return true; } - public static int getArity(Relation relation) { - if (relation instanceof ClassDeclaration || relation instanceof EnumDeclaration) { - return 1; - } - if (relation instanceof ReferenceDeclaration) { - return 2; + public static boolean isTypeLike(Relation relation) { + if (relation instanceof ClassDeclaration || relation instanceof EnumDeclaration || + relation instanceof DatatypeDeclaration) { + return true; } if (relation instanceof PredicateDefinition predicateDefinition) { - return predicateDefinition.getParameters().size(); + return predicateDefinition.getParameters().size() == 1; } - throw new IllegalArgumentException("Unknown Relation: " + relation); + return false; + } + + public static boolean isContainmentReference(ReferenceDeclaration referenceDeclaration) { + return referenceDeclaration.getKind() == ReferenceKind.CONTAINMENT; } public static boolean isContainerReference(ReferenceDeclaration referenceDeclaration) { @@ -116,7 +121,7 @@ public static boolean isContainerReference(ReferenceDeclaration referenceDeclara return switch (kind) { case CONTAINMENT -> false; case CONTAINER -> true; - case REFERENCE -> { + case DEFAULT, REFERENCE -> { var opposite = referenceDeclaration.getOpposite(); if (opposite == null) { yield false; diff --git a/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java b/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java index d9eb5fd31..745e2d2b6 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java +++ b/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java @@ -10,6 +10,7 @@ package tools.refinery.language.validation; import com.google.inject.Inject; +import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.xtext.EcoreUtil2; @@ -18,11 +19,15 @@ import org.jetbrains.annotations.Nullable; import tools.refinery.language.model.problem.*; import tools.refinery.language.naming.NamingUtil; -import tools.refinery.language.scoping.imports.ImportAdapter; -import tools.refinery.language.utils.ProblemDesugarer; +import tools.refinery.language.scoping.imports.ImportAdapterProvider; +import tools.refinery.language.typesystem.ProblemTypeAnalyzer; +import tools.refinery.language.typesystem.SignatureProvider; import tools.refinery.language.utils.ProblemUtil; -import java.util.*; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Set; /** * This class contains custom validation rules. @@ -32,45 +37,39 @@ */ public class ProblemValidator extends AbstractProblemValidator { private static final String ISSUE_PREFIX = "tools.refinery.language.validation.ProblemValidator."; - public static final String UNEXPECTED_MODULE_NAME_ISSUE = ISSUE_PREFIX + "UNEXPECTED_MODULE_NAME"; - public static final String INVALID_IMPORT_ISSUE = ISSUE_PREFIX + "INVALID_IMPORT"; - public static final String SINGLETON_VARIABLE_ISSUE = ISSUE_PREFIX + "SINGLETON_VARIABLE"; - public static final String NODE_CONSTANT_ISSUE = ISSUE_PREFIX + "NODE_CONSTANT_ISSUE"; - public static final String DUPLICATE_NAME_ISSUE = ISSUE_PREFIX + "DUPLICATE_NAME"; - public static final String INVALID_MULTIPLICITY_ISSUE = ISSUE_PREFIX + "INVALID_MULTIPLICITY"; - public static final String ZERO_MULTIPLICITY_ISSUE = ISSUE_PREFIX + "ZERO_MULTIPLICITY"; - public static final String MISSING_OPPOSITE_ISSUE = ISSUE_PREFIX + "MISSING_OPPOSITE"; - public static final String INVALID_OPPOSITE_ISSUE = ISSUE_PREFIX + "INVALID_OPPOSITE"; - public static final String INVALID_SUPERTYPE_ISSUE = ISSUE_PREFIX + "INVALID_SUPERTYPE"; - public static final String INVALID_REFERENCE_TYPE_ISSUE = ISSUE_PREFIX + "INVALID_REFERENCE_TYPE"; - public static final String INVALID_ARITY_ISSUE = ISSUE_PREFIX + "INVALID_ARITY"; - public static final String INVALID_TRANSITIVE_CLOSURE_ISSUE = ISSUE_PREFIX + "INVALID_TRANSITIVE_CLOSURE"; - public static final String INVALID_VALUE_ISSUE = ISSUE_PREFIX + "INVALID_VALUE"; - public static final String UNSUPPORTED_ASSERTION_ISSUE = ISSUE_PREFIX + "UNSUPPORTED_ASSERTION"; + public static final String UNKNOWN_EXPRESSION_ISSUE = ISSUE_PREFIX + "UNKNOWN_EXPRESSION"; + public static final String INVALID_ASSIGNMENT_ISSUE = ISSUE_PREFIX + "INVALID_ASSIGNMENT"; + public static final String TYPE_ERROR = ISSUE_PREFIX + "TYPE_ERROR"; @Inject private ReferenceCounter referenceCounter; @Inject - private ProblemDesugarer desugarer; + private IQualifiedNameConverter qualifiedNameConverter; + + @Inject + private ImportAdapterProvider importAdapterProvider; @Inject - private IQualifiedNameConverter qualifiedNameConverter; + private SignatureProvider signatureProvider; + + @Inject + private ProblemTypeAnalyzer typeAnalyzer; @Check public void checkModuleName(Problem problem) { @@ -86,7 +85,7 @@ public void checkModuleName(Problem problem) { if (resourceSet == null) { return; } - var adapter = ImportAdapter.getOrInstall(resourceSet); + var adapter = importAdapterProvider.getOrInstall(resourceSet); var expectedName = adapter.getQualifiedName(resource.getURI()); if (expectedName == null) { return; @@ -156,15 +155,19 @@ public void checkNodeConstants(VariableOrNodeExpr expr) { public void checkUniqueDeclarations(Problem problem) { var relations = new ArrayList(); var nodes = new ArrayList(); + var aggregators = new ArrayList(); for (var statement : problem.getStatements()) { if (statement instanceof Relation relation) { relations.add(relation); } else if (statement instanceof NodeDeclaration nodeDeclaration) { nodes.addAll(nodeDeclaration.getNodes()); + } else if (statement instanceof AggregatorDeclaration aggregatorDeclaration) { + aggregators.add(aggregatorDeclaration); } } checkUniqueSimpleNames(relations); checkUniqueSimpleNames(nodes); + checkUniqueSimpleNames(aggregators); } @Check @@ -315,8 +318,9 @@ public void checkSupertypes(ClassDeclaration classDeclaration) { @Check public void checkReferenceType(ReferenceDeclaration referenceDeclaration) { - if (referenceDeclaration.getKind() == ReferenceKind.REFERENCE && - !ProblemUtil.isContainerReference(referenceDeclaration)) { + boolean isDefaultReference = referenceDeclaration.getKind() == ReferenceKind.DEFAULT && + !ProblemUtil.isContainerReference(referenceDeclaration); + if (isDefaultReference || referenceDeclaration.getKind() == ReferenceKind.REFERENCE) { checkArity(referenceDeclaration, ProblemPackage.Literals.REFERENCE_DECLARATION__REFERENCE_TYPE, 1); return; } @@ -350,11 +354,14 @@ public void checkAtom(Atom atom) { @Check public void checkAssertion(Assertion assertion) { - int argumentCount = assertion.getArguments().size(); - if (!(assertion.getValue() instanceof LogicConstant)) { - var message = "Assertion value must be one of 'true', 'false', 'unknown', or 'error'."; - acceptError(message, assertion, ProblemPackage.Literals.ASSERTION__VALUE, 0, INVALID_VALUE_ISSUE); + var relation = assertion.getRelation(); + if (relation instanceof DatatypeDeclaration) { + var message = "Assertions for data types are not supported."; + acceptError(message, assertion, ProblemPackage.Literals.ASSERTION__RELATION, 0, + UNSUPPORTED_ASSERTION_ISSUE); + return; } + int argumentCount = assertion.getArguments().size(); checkArity(assertion, ProblemPackage.Literals.ASSERTION__RELATION, argumentCount); } @@ -373,7 +380,7 @@ private void checkArity(EObject eObject, EReference reference, int expectedArity // Feature does not point to a {@link Relation}, we are probably already emitting another error. return; } - int arity = ProblemUtil.getArity(relation); + int arity = signatureProvider.getArity(relation); if (arity == expectedArity) { return; } @@ -384,11 +391,7 @@ private void checkArity(EObject eObject, EReference reference, int expectedArity @Check public void checkMultiObjectAssertion(Assertion assertion) { - var builtinSymbolsOption = desugarer.getBuiltinSymbols(assertion); - if (builtinSymbolsOption.isEmpty()) { - return; - } - var builtinSymbols = builtinSymbolsOption.get(); + var builtinSymbols = importAdapterProvider.getBuiltinSymbols(assertion); var relation = assertion.getRelation(); boolean isExists = builtinSymbols.exists().equals(relation); boolean isEquals = builtinSymbols.equals().equals(relation); @@ -492,4 +495,66 @@ private void checkImplicitNodeInModule(Assertion assertion) { } } } + + @Check + private void checkAssignmentExpr(AssignmentExpr assignmentExpr) { + var left = assignmentExpr.getLeft(); + if (left == null) { + // Syntactically invalid, so we already emit an error. + return; + } + if (!(left instanceof VariableOrNodeExpr variableOrNodeExpr)) { + var message = "Left side of an assignment must be variable."; + acceptError(message, assignmentExpr, ProblemPackage.Literals.BINARY_EXPR__LEFT, + 0, INVALID_ASSIGNMENT_ISSUE); + return; + } + var target = variableOrNodeExpr.getVariableOrNode(); + if (target == null) { + // Syntactically invalid, so we already emit an error. + return; + } + if (target instanceof Parameter) { + var message = "Parameters cannot be assigned."; + acceptError(message, variableOrNodeExpr, ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__VARIABLE_OR_NODE, + 0, INVALID_ASSIGNMENT_ISSUE); + } + if (target instanceof Node) { + var message = "Nodes cannot be assigned."; + acceptError(message, variableOrNodeExpr, ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__VARIABLE_OR_NODE, + 0, INVALID_ASSIGNMENT_ISSUE); + } + if (!(assignmentExpr.eContainer() instanceof Conjunction)) { + var message = "Assignments may only appear as top-level expressions."; + acceptError(message, assignmentExpr, null, 0, INVALID_ASSIGNMENT_ISSUE); + } + } + + @Check + private void checkInfiniteConstant(InfiniteConstant infiniteConstant) { + if (!(infiniteConstant.eContainer() instanceof RangeExpr)) { + var message = "Negative and positive infinity literals may only appear in '..' range expressions."; + acceptError(message, infiniteConstant, null, 0, TYPE_ERROR); + } + } + + @Check + private void checkTypes(Problem problem) { + var diagnostics = typeAnalyzer.getOrComputeTypes(problem).getDiagnostics(); + for (var diagnostic : diagnostics) { + switch (diagnostic.getSeverity()) { + case Diagnostic.INFO -> info(diagnostic.getMessage(), diagnostic.getSourceEObject(), + diagnostic.getFeature(), diagnostic.getIndex(), diagnostic.getIssueCode(), + diagnostic.getIssueData()); + case Diagnostic.WARNING -> warning(diagnostic.getMessage(), diagnostic.getSourceEObject(), + diagnostic.getFeature(), diagnostic.getIndex(), diagnostic.getIssueCode(), + diagnostic.getIssueData()); + case Diagnostic.ERROR -> error(diagnostic.getMessage(), diagnostic.getSourceEObject(), + diagnostic.getFeature(), diagnostic.getIndex(), diagnostic.getIssueCode(), + diagnostic.getIssueData()); + default -> throw new IllegalStateException("Unknown severity %s of %s" + .formatted(diagnostic.getSeverity(), diagnostic)); + } + } + } } diff --git a/subprojects/language/src/main/resources/META-INF/services/tools.refinery.language.expressions.TermInterpreter b/subprojects/language/src/main/resources/META-INF/services/tools.refinery.language.expressions.TermInterpreter new file mode 100644 index 000000000..11b6ccae2 --- /dev/null +++ b/subprojects/language/src/main/resources/META-INF/services/tools.refinery.language.expressions.TermInterpreter @@ -0,0 +1,4 @@ +# SPDX-FileCopyrightText: 2024 The Refinery Authors +# +# SPDX-License-Identifier: EPL-2.0 +tools.refinery.language.expressions.BuiltinTermInterpreter diff --git a/subprojects/language/src/main/resources/tools/refinery/language/library/builtin.refinery b/subprojects/language/src/main/resources/tools/refinery/language/library/builtin.refinery index 4e74ca03c..09c7d92bf 100644 --- a/subprojects/language/src/main/resources/tools/refinery/language/library/builtin.refinery +++ b/subprojects/language/src/main/resources/tools/refinery/language/library/builtin.refinery @@ -13,3 +13,17 @@ abstract class contained extends node. pred contains(container, contained contained). error invalidContainer(contained contained). + +extern datatype boolean. + +extern datatype int. + +extern datatype real. + +extern datatype string. + +extern aggregator min. + +extern aggregator max. + +extern aggregator sum. diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/validation/AssertionValidationTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/validation/AssertionValidationTest.java index 1fb088454..b995d0bb8 100644 --- a/subprojects/language/src/test/java/tools/refinery/language/tests/validation/AssertionValidationTest.java +++ b/subprojects/language/src/test/java/tools/refinery/language/tests/validation/AssertionValidationTest.java @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The Refinery Authors + * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ @@ -35,7 +35,7 @@ class Foo. """); var issues = problem.validate(); assertThat(issues, hasItem(hasProperty("issueCode", - is(ProblemValidator.INVALID_VALUE_ISSUE)))); + is(ProblemValidator.TYPE_ERROR)))); } @ParameterizedTest diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/validation/AssignmentValidationTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/validation/AssignmentValidationTest.java new file mode 100644 index 000000000..a9e0e3115 --- /dev/null +++ b/subprojects/language/src/test/java/tools/refinery/language/tests/validation/AssignmentValidationTest.java @@ -0,0 +1,61 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.language.tests.validation; + + +import com.google.inject.Inject; +import org.eclipse.xtext.testing.InjectWith; +import org.eclipse.xtext.testing.extensions.InjectionExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import tools.refinery.language.model.tests.utils.ProblemParseHelper; +import tools.refinery.language.tests.ProblemInjectorProvider; +import tools.refinery.language.validation.ProblemValidator; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +@ExtendWith(InjectionExtension.class) +@InjectWith(ProblemInjectorProvider.class) +class AssignmentValidationTest { + @Inject + private ProblemParseHelper parseHelper; + + @ParameterizedTest + @ValueSource(strings = {""" + pred foo(node a) <-> 5 is 5. + """, """ + pred foo(node a) <-> b + 2 is 5. + """, """ + pred foo(node a) <-> a is 5. + """, """ + node(n). + pred foo(node a) <-> n is 5. + """, """ + enum E { A, B } + pred foo(node a) <-> B is 5. + """}) + void invalidAssignmentTest(String text) { + var problem = parseHelper.parse(text); + var issues = problem.validate(); + assertThat(issues, hasItem(hasProperty("issueCode", is( + ProblemValidator.INVALID_ASSIGNMENT_ISSUE + )))); + } + + @Test + void validAssignmentTest() { + var problem = parseHelper.parse(""" + pred foo(node a) <-> b is 5. + """); + var issues = problem.validate(); + assertThat(issues, not(hasItem(hasProperty("issueCode", is( + ProblemValidator.INVALID_ASSIGNMENT_ISSUE + ))))); + } +} diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java index a228137ce..14ac7bfcd 100644 --- a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java @@ -1,19 +1,19 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.language.model.tests.utils; import tools.refinery.language.model.problem.ClassDeclaration; -import tools.refinery.language.model.problem.FeatureDeclaration; +import tools.refinery.language.model.problem.ReferenceDeclaration; public record WrappedClassDeclaration(ClassDeclaration classDeclaration) { public ClassDeclaration get() { return classDeclaration; } - public FeatureDeclaration feature(String name) { + public ReferenceDeclaration feature(String name) { return ProblemNavigationUtil.named(classDeclaration.getFeatureDeclarations(), name); } } diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java index 58bfce44a..b31eed6d3 100644 --- a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ @@ -7,9 +7,9 @@ import org.eclipse.emf.ecore.resource.Resource.Diagnostic; import org.eclipse.emf.ecore.util.Diagnostician; +import org.eclipse.emf.ecore.util.EcoreUtil; +import tools.refinery.language.library.BuiltinLibrary; import tools.refinery.language.model.problem.*; -import tools.refinery.language.utils.BuiltinSymbols; -import tools.refinery.language.utils.ProblemDesugarer; import java.util.List; import java.util.stream.Stream; @@ -32,11 +32,11 @@ public List validate() { } public WrappedProblem builtin() { - return new WrappedProblem(new ProblemDesugarer().getBuiltinProblem(problem).orElseThrow()); - } - - public BuiltinSymbols builtinSymbols() { - return new ProblemDesugarer().getBuiltinSymbols(problem).orElseThrow(); + var resourceSet = problem.eResource().getResourceSet(); + var builtinResource = resourceSet.getResource(BuiltinLibrary.BUILTIN_LIBRARY_URI, true); + EcoreUtil.resolveAll(builtinResource); + var builtinProblem = (Problem) builtinResource.getContents().getFirst(); + return new WrappedProblem(builtinProblem); } public List nodeNames() { diff --git a/subprojects/logic/build.gradle.kts b/subprojects/logic/build.gradle.kts new file mode 100644 index 000000000..57de8e5db --- /dev/null +++ b/subprojects/logic/build.gradle.kts @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ + +plugins { + id("tools.refinery.gradle.java-library") + id("tools.refinery.gradle.java-test-fixtures") +} + +dependencies { + testFixturesApi(libs.hamcrest) +} diff --git a/subprojects/logic/src/main/java/tools/refinery/logic/AbstractDomain.java b/subprojects/logic/src/main/java/tools/refinery/logic/AbstractDomain.java new file mode 100644 index 000000000..0b4d87d25 --- /dev/null +++ b/subprojects/logic/src/main/java/tools/refinery/logic/AbstractDomain.java @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.logic; + +public non-sealed interface AbstractDomain, C> extends AnyAbstractDomain { + @Override + Class abstractType(); + + @Override + Class concreteType(); + + A unknown(); + + A error(); + + A toAbstract(C concreteValue); +} diff --git a/subprojects/logic/src/main/java/tools/refinery/logic/AbstractValue.java b/subprojects/logic/src/main/java/tools/refinery/logic/AbstractValue.java new file mode 100644 index 000000000..0b5e0d012 --- /dev/null +++ b/subprojects/logic/src/main/java/tools/refinery/logic/AbstractValue.java @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.logic; + +import org.jetbrains.annotations.Nullable; + +public interface AbstractValue, C> { + @Nullable + C getConcrete(); + + default boolean isConcrete() { + return getConcrete() == null; + } + + @Nullable + C getArbitrary(); + + default boolean isError() { + return getArbitrary() == null; + } + + A join(A other); + + A meet(A other); + + default boolean isRefinementOf(A other) { + return equals(meet(other)); + } +} diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/AnyAbstractDomain.java b/subprojects/logic/src/main/java/tools/refinery/logic/AnyAbstractDomain.java similarity index 84% rename from subprojects/store/src/main/java/tools/refinery/store/representation/AnyAbstractDomain.java rename to subprojects/logic/src/main/java/tools/refinery/logic/AnyAbstractDomain.java index c354fab70..a296f4b24 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/AnyAbstractDomain.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/AnyAbstractDomain.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation; +package tools.refinery.logic; public sealed interface AnyAbstractDomain permits AbstractDomain { Class abstractType(); diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/Constraint.java b/subprojects/logic/src/main/java/tools/refinery/logic/Constraint.java similarity index 72% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/Constraint.java rename to subprojects/logic/src/main/java/tools/refinery/logic/Constraint.java index 916fb35c6..89c8760be 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/Constraint.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/Constraint.java @@ -1,13 +1,13 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query; +package tools.refinery.logic; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.literal.*; -import tools.refinery.store.query.term.*; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.literal.*; +import tools.refinery.logic.term.*; import java.util.List; @@ -69,4 +69,14 @@ default AssignedValue aggregateBy(DataVariable inputVariable, Aggre Variable... arguments) { return aggregateBy(inputVariable, aggregator, List.of(arguments)); } + + default AssignedValue leftJoinBy(DataVariable placeholderVariable, T defaultValue, + List arguments) { + return targetVariable -> new LeftJoinLiteral<>(targetVariable, placeholderVariable, defaultValue, this, + arguments); + } + + default AssignedValue leftJoinBy(DataVariable inputVariable, T defaultValue, Variable... arguments) { + return leftJoinBy(inputVariable, defaultValue, List.of(arguments)); + } } diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/InvalidQueryException.java b/subprojects/logic/src/main/java/tools/refinery/logic/InvalidQueryException.java similarity index 92% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/InvalidQueryException.java rename to subprojects/logic/src/main/java/tools/refinery/logic/InvalidQueryException.java index c39277a0a..b5460e0d9 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/InvalidQueryException.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/InvalidQueryException.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query; +package tools.refinery.logic; public class InvalidQueryException extends RuntimeException { public InvalidQueryException() { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/AbstractQueryBuilder.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/AbstractQueryBuilder.java similarity index 93% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/AbstractQueryBuilder.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/AbstractQueryBuilder.java index 2a3e3ce01..68712b984 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/AbstractQueryBuilder.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/AbstractQueryBuilder.java @@ -3,13 +3,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; -import tools.refinery.store.query.dnf.callback.*; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.dnf.callback.*; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; import java.util.Collection; import java.util.List; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/AnyQuery.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/AnyQuery.java similarity index 86% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/AnyQuery.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/AnyQuery.java index 5e28af680..aebfd73fb 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/AnyQuery.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/AnyQuery.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; public sealed interface AnyQuery permits Query { String name(); diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/ClausePostProcessor.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/ClausePostProcessor.java similarity index 94% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/ClausePostProcessor.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/ClausePostProcessor.java index 8800a155a..00d15a0c7 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/ClausePostProcessor.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/ClausePostProcessor.java @@ -1,19 +1,19 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; import org.jetbrains.annotations.NotNull; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.literal.*; -import tools.refinery.store.query.substitution.MapBasedSubstitution; -import tools.refinery.store.query.substitution.StatelessSubstitution; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.literal.*; +import tools.refinery.logic.substitution.MapBasedSubstitution; +import tools.refinery.logic.substitution.StatelessSubstitution; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; import java.util.*; import java.util.function.Function; @@ -112,7 +112,7 @@ private Set getEquivalentVariables(Variable variable) { .formatted(variable, representative)); } return equivalencePartition.computeIfAbsent(variable, key -> { - var set = new HashSet(1); + var set = HashSet.newHashSet(1); set.add(key); return set; }); @@ -193,7 +193,7 @@ private void validatePrivateVariables() { } private void topologicallySortLiterals() { - topologicallySortedLiterals = new LinkedHashSet<>(substitutedLiterals.size()); + topologicallySortedLiterals = LinkedHashSet.newLinkedHashSet(substitutedLiterals.size()); variableToLiteralInputMap = new HashMap<>(); literalsWithAllInputsBound = new PriorityQueue<>(); int size = substitutedLiterals.size(); diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Dnf.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/Dnf.java similarity index 91% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Dnf.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/Dnf.java index 86a1b6b28..0fc2a1ccb 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Dnf.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/Dnf.java @@ -3,17 +3,17 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; - -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.DnfEqualityChecker; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.SubstitutingLiteralEqualityHelper; -import tools.refinery.store.query.equality.SubstitutingLiteralHashCodeHelper; -import tools.refinery.store.query.literal.Reduction; -import tools.refinery.store.query.term.Parameter; -import tools.refinery.store.query.term.Variable; +package tools.refinery.logic.dnf; + +import tools.refinery.logic.Constraint; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.DnfEqualityChecker; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.SubstitutingLiteralEqualityHelper; +import tools.refinery.logic.equality.SubstitutingLiteralHashCodeHelper; +import tools.refinery.logic.literal.Reduction; +import tools.refinery.logic.term.Parameter; +import tools.refinery.logic.term.Variable; import java.util.Collection; import java.util.Collections; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfBuilder.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/DnfBuilder.java similarity index 96% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfBuilder.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/DnfBuilder.java index 0f9fd366d..b58c5c459 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfBuilder.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/DnfBuilder.java @@ -3,12 +3,12 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.dnf.callback.*; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.*; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.dnf.callback.*; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.*; import java.util.*; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfClause.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/DnfClause.java similarity index 74% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfClause.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/DnfClause.java index 94327bad4..92755d4d7 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfClause.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/DnfClause.java @@ -3,12 +3,12 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.Variable; import java.util.List; import java.util.Set; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfPostProcessor.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/DnfPostProcessor.java similarity index 83% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfPostProcessor.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/DnfPostProcessor.java index 502366421..87d071879 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfPostProcessor.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/DnfPostProcessor.java @@ -1,17 +1,17 @@ /* - * SPDX-FileCopyrightText: 2023 The Refinery Authors + * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.DnfEqualityChecker; -import tools.refinery.store.query.equality.SubstitutingLiteralEqualityHelper; -import tools.refinery.store.query.equality.SubstitutingLiteralHashCodeHelper; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.DnfEqualityChecker; +import tools.refinery.logic.equality.SubstitutingLiteralEqualityHelper; +import tools.refinery.logic.equality.SubstitutingLiteralHashCodeHelper; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; import java.util.*; @@ -26,7 +26,7 @@ public DnfPostProcessor(List parameters, List> public List postProcessClauses() { var parameterInfoMap = getParameterInfoMap(); - var postProcessedClauses = new LinkedHashSet(clauses.size()); + var postProcessedClauses = LinkedHashSet.newLinkedHashSet(clauses.size()); int index = 0; for (var literals : clauses) { var postProcessor = new ClausePostProcessor(parameterInfoMap, literals); diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfUtils.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/DnfUtils.java similarity index 93% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfUtils.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/DnfUtils.java index 65ab36341..02a619a60 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfUtils.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/DnfUtils.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; import java.util.UUID; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalDependency.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/FunctionalDependency.java similarity index 84% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalDependency.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/FunctionalDependency.java index aef07ee32..c3fc87abf 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalDependency.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/FunctionalDependency.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; -import tools.refinery.store.query.InvalidQueryException; +import tools.refinery.logic.InvalidQueryException; import java.util.HashSet; import java.util.Set; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQuery.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/FunctionalQuery.java similarity index 74% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQuery.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/FunctionalQuery.java index 225f6844e..1df63fbd7 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQuery.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/FunctionalQuery.java @@ -1,16 +1,16 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.literal.CallPolarity; -import tools.refinery.store.query.term.Aggregator; -import tools.refinery.store.query.term.AssignedValue; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.literal.CallPolarity; +import tools.refinery.logic.term.Aggregator; +import tools.refinery.logic.term.AssignedValue; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.Variable; import java.util.ArrayList; import java.util.List; @@ -94,6 +94,22 @@ public AssignedValue aggregate(Aggregator aggregator, NodeVariable. return aggregate(aggregator, List.of(arguments)); } + public AssignedValue leftJoin(T defaultValue, List arguments) { + return targetVariable -> { + var placeholderVariable = Variable.of(type); + var argumentsWithPlaceholder = new ArrayList(arguments.size() + 1); + argumentsWithPlaceholder.addAll(arguments); + argumentsWithPlaceholder.add(placeholderVariable); + return getDnf() + .leftJoinBy(placeholderVariable, defaultValue, argumentsWithPlaceholder) + .toLiteral(targetVariable); + }; + } + + public AssignedValue leftJoin(T defaultValue, NodeVariable... arguments) { + return leftJoin(defaultValue, List.of(arguments)); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQueryBuilder.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/FunctionalQueryBuilder.java similarity index 88% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQueryBuilder.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/FunctionalQueryBuilder.java index d1cd7ba8f..476f3c835 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQueryBuilder.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/FunctionalQueryBuilder.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; -import tools.refinery.store.query.term.DataVariable; +import tools.refinery.logic.term.DataVariable; public final class FunctionalQueryBuilder extends AbstractQueryBuilder> { private final DataVariable outputVariable; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/InvalidClauseException.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/InvalidClauseException.java similarity index 88% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/InvalidClauseException.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/InvalidClauseException.java index 747574b99..51a42d020 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/InvalidClauseException.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/InvalidClauseException.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; -import tools.refinery.store.query.InvalidQueryException; +import tools.refinery.logic.InvalidQueryException; public class InvalidClauseException extends InvalidQueryException { private final int clauseIndex; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Query.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/Query.java similarity index 96% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Query.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/Query.java index 83fe6ccdf..1f913ea04 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Query.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/Query.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; -import tools.refinery.store.query.dnf.callback.*; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.dnf.callback.*; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; import java.util.Objects; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/QueryBuilder.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/QueryBuilder.java similarity index 86% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/QueryBuilder.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/QueryBuilder.java index 138911bc1..a74295baa 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/QueryBuilder.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/QueryBuilder.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; -import tools.refinery.store.query.term.DataVariable; +import tools.refinery.logic.term.DataVariable; public final class QueryBuilder extends AbstractQueryBuilder { QueryBuilder(String name) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/RelationalQuery.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/RelationalQuery.java similarity index 84% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/RelationalQuery.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/RelationalQuery.java index 98f71e11c..dc2b8eb65 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/RelationalQuery.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/RelationalQuery.java @@ -3,13 +3,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.literal.CallLiteral; -import tools.refinery.store.query.literal.CallPolarity; -import tools.refinery.store.query.term.AssignedValue; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.literal.CallLiteral; +import tools.refinery.logic.literal.CallPolarity; +import tools.refinery.logic.term.AssignedValue; +import tools.refinery.logic.term.NodeVariable; import java.util.Collections; import java.util.List; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/SymbolicParameter.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/SymbolicParameter.java similarity index 81% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/SymbolicParameter.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/SymbolicParameter.java index fe9cefccb..acc775a7d 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/SymbolicParameter.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/SymbolicParameter.java @@ -3,12 +3,12 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.term.Parameter; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.term.Parameter; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; import java.util.Objects; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback0.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback0.java similarity index 71% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback0.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback0.java index d98dda2e4..2e2760304 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback0.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback0.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.literal.Literal; +import tools.refinery.logic.literal.Literal; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback1Data0.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback1Data0.java similarity index 64% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback1Data0.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback1Data0.java index 4c01a5274..f2e174b0a 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback1Data0.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback1Data0.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.NodeVariable; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback1Data1.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback1Data1.java similarity index 64% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback1Data1.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback1Data1.java index 2c0cb6eb7..4e6b5a06d 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback1Data1.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback1Data1.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.DataVariable; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.DataVariable; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data0.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback2Data0.java similarity index 65% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data0.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback2Data0.java index d764bdbab..42b7cb085 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data0.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback2Data0.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.NodeVariable; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data1.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback2Data1.java similarity index 59% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data1.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback2Data1.java index 140af03af..59e53744f 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data1.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback2Data1.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.NodeVariable; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data2.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback2Data2.java similarity index 66% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data2.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback2Data2.java index bfc8637cc..d9550d497 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data2.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback2Data2.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.DataVariable; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.DataVariable; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data0.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback3Data0.java similarity index 66% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data0.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback3Data0.java index 074df65be..e36f05db9 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data0.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback3Data0.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.NodeVariable; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data1.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback3Data1.java similarity index 60% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data1.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback3Data1.java index 24ba5187e..7227bada8 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data1.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback3Data1.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.NodeVariable; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data2.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback3Data2.java similarity index 61% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data2.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback3Data2.java index 2a2e837a2..7d8426554 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data2.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback3Data2.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.NodeVariable; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data3.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback3Data3.java similarity index 68% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data3.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback3Data3.java index 8f4bdd01b..3bc895d5e 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data3.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback3Data3.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.DataVariable; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.DataVariable; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data0.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback4Data0.java similarity index 68% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data0.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback4Data0.java index ed0f87b28..164c3208c 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data0.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback4Data0.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.NodeVariable; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data1.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback4Data1.java similarity index 61% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data1.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback4Data1.java index 9b27e2e13..d74541359 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data1.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback4Data1.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.NodeVariable; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data2.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback4Data2.java similarity index 62% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data2.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback4Data2.java index cbc4808ed..829dbcf8f 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data2.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback4Data2.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.NodeVariable; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data3.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback4Data3.java similarity index 62% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data3.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback4Data3.java index a6258f36f..50da829b5 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data3.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback4Data3.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.NodeVariable; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data4.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback4Data4.java similarity index 70% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data4.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback4Data4.java index b52a911af..46f8fbe9e 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data4.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/ClauseCallback4Data4.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.DataVariable; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.DataVariable; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback0.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/FunctionalQueryCallback0.java similarity index 62% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback0.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/FunctionalQueryCallback0.java index 63b3eee66..689a5b537 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback0.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/FunctionalQueryCallback0.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.dnf.FunctionalQueryBuilder; -import tools.refinery.store.query.term.DataVariable; +import tools.refinery.logic.dnf.FunctionalQueryBuilder; +import tools.refinery.logic.term.DataVariable; @FunctionalInterface public interface FunctionalQueryCallback0 { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback1.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/FunctionalQueryCallback1.java similarity index 57% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback1.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/FunctionalQueryCallback1.java index 1295a118a..b7d69a506 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback1.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/FunctionalQueryCallback1.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.dnf.FunctionalQueryBuilder; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.dnf.FunctionalQueryBuilder; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.NodeVariable; @FunctionalInterface public interface FunctionalQueryCallback1 { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback2.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/FunctionalQueryCallback2.java similarity index 58% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback2.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/FunctionalQueryCallback2.java index d5b7f9ff7..38fb265bc 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback2.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/FunctionalQueryCallback2.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.dnf.FunctionalQueryBuilder; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.dnf.FunctionalQueryBuilder; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.NodeVariable; @FunctionalInterface public interface FunctionalQueryCallback2 { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback3.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/FunctionalQueryCallback3.java similarity index 60% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback3.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/FunctionalQueryCallback3.java index dc8404a08..04451657a 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback3.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/FunctionalQueryCallback3.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.dnf.FunctionalQueryBuilder; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.dnf.FunctionalQueryBuilder; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.NodeVariable; @FunctionalInterface public interface FunctionalQueryCallback3 { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback4.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/FunctionalQueryCallback4.java similarity index 61% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback4.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/FunctionalQueryCallback4.java index b6d3ddb00..a39c389d8 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback4.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/FunctionalQueryCallback4.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.dnf.FunctionalQueryBuilder; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.dnf.FunctionalQueryBuilder; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.NodeVariable; @FunctionalInterface public interface FunctionalQueryCallback4 { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback0.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/QueryCallback0.java similarity index 69% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback0.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/QueryCallback0.java index 3cf1de480..bc9a6ee4a 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback0.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/QueryCallback0.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.dnf.QueryBuilder; +import tools.refinery.logic.dnf.QueryBuilder; @FunctionalInterface public interface QueryCallback0 { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback1.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/QueryCallback1.java similarity index 61% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback1.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/QueryCallback1.java index 0a1509559..807631717 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback1.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/QueryCallback1.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.dnf.QueryBuilder; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.dnf.QueryBuilder; +import tools.refinery.logic.term.NodeVariable; @FunctionalInterface public interface QueryCallback1 { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback2.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/QueryCallback2.java similarity index 62% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback2.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/QueryCallback2.java index 9493a7b4a..544231044 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback2.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/QueryCallback2.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.dnf.QueryBuilder; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.dnf.QueryBuilder; +import tools.refinery.logic.term.NodeVariable; @FunctionalInterface public interface QueryCallback2 { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback3.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/QueryCallback3.java similarity index 64% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback3.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/QueryCallback3.java index 358c7da77..eb68d4936 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback3.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/QueryCallback3.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.dnf.QueryBuilder; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.dnf.QueryBuilder; +import tools.refinery.logic.term.NodeVariable; @FunctionalInterface public interface QueryCallback3 { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback4.java b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/QueryCallback4.java similarity index 65% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback4.java rename to subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/QueryCallback4.java index 890dda168..59690af9a 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback4.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/dnf/callback/QueryCallback4.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf.callback; +package tools.refinery.logic.dnf.callback; -import tools.refinery.store.query.dnf.QueryBuilder; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.dnf.QueryBuilder; +import tools.refinery.logic.term.NodeVariable; @FunctionalInterface public interface QueryCallback4 { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/equality/DeepDnfEqualityChecker.java b/subprojects/logic/src/main/java/tools/refinery/logic/equality/DeepDnfEqualityChecker.java similarity index 87% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/equality/DeepDnfEqualityChecker.java rename to subprojects/logic/src/main/java/tools/refinery/logic/equality/DeepDnfEqualityChecker.java index d6171314c..a49ef080f 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/equality/DeepDnfEqualityChecker.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/equality/DeepDnfEqualityChecker.java @@ -3,13 +3,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.equality; +package tools.refinery.logic.equality; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.DnfClause; -import tools.refinery.store.query.dnf.SymbolicParameter; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.util.CycleDetectingMapper; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.DnfClause; +import tools.refinery.logic.dnf.SymbolicParameter; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.util.CycleDetectingMapper; import java.util.List; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/equality/DnfEqualityChecker.java b/subprojects/logic/src/main/java/tools/refinery/logic/equality/DnfEqualityChecker.java similarity index 77% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/equality/DnfEqualityChecker.java rename to subprojects/logic/src/main/java/tools/refinery/logic/equality/DnfEqualityChecker.java index e2cfd79b3..3162b0195 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/equality/DnfEqualityChecker.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/equality/DnfEqualityChecker.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.equality; +package tools.refinery.logic.equality; -import tools.refinery.store.query.dnf.Dnf; +import tools.refinery.logic.dnf.Dnf; import java.util.Objects; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/equality/LiteralEqualityHelper.java b/subprojects/logic/src/main/java/tools/refinery/logic/equality/LiteralEqualityHelper.java similarity index 81% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/equality/LiteralEqualityHelper.java rename to subprojects/logic/src/main/java/tools/refinery/logic/equality/LiteralEqualityHelper.java index 5abc76ce2..ea62061ee 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/equality/LiteralEqualityHelper.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/equality/LiteralEqualityHelper.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.equality; +package tools.refinery.logic.equality; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.term.Variable; import java.util.Objects; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/equality/LiteralHashCodeHelper.java b/subprojects/logic/src/main/java/tools/refinery/logic/equality/LiteralHashCodeHelper.java similarity index 77% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/equality/LiteralHashCodeHelper.java rename to subprojects/logic/src/main/java/tools/refinery/logic/equality/LiteralHashCodeHelper.java index 5495160a0..fccadd085 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/equality/LiteralHashCodeHelper.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/equality/LiteralHashCodeHelper.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.equality; +package tools.refinery.logic.equality; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.term.Variable; import java.util.Objects; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/equality/SubstitutingLiteralEqualityHelper.java b/subprojects/logic/src/main/java/tools/refinery/logic/equality/SubstitutingLiteralEqualityHelper.java similarity index 90% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/equality/SubstitutingLiteralEqualityHelper.java rename to subprojects/logic/src/main/java/tools/refinery/logic/equality/SubstitutingLiteralEqualityHelper.java index 50a79e077..7a16b5c9b 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/equality/SubstitutingLiteralEqualityHelper.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/equality/SubstitutingLiteralEqualityHelper.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.equality; +package tools.refinery.logic.equality; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.SymbolicParameter; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.SymbolicParameter; +import tools.refinery.logic.term.Variable; import java.util.HashMap; import java.util.List; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/equality/SubstitutingLiteralHashCodeHelper.java b/subprojects/logic/src/main/java/tools/refinery/logic/equality/SubstitutingLiteralHashCodeHelper.java similarity index 86% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/equality/SubstitutingLiteralHashCodeHelper.java rename to subprojects/logic/src/main/java/tools/refinery/logic/equality/SubstitutingLiteralHashCodeHelper.java index 754f69769..64bd97846 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/equality/SubstitutingLiteralHashCodeHelper.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/equality/SubstitutingLiteralHashCodeHelper.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.equality; +package tools.refinery.logic.equality; -import tools.refinery.store.query.dnf.SymbolicParameter; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.dnf.SymbolicParameter; +import tools.refinery.logic.term.Variable; import java.util.LinkedHashMap; import java.util.List; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCallLiteral.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/AbstractCallLiteral.java similarity index 83% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCallLiteral.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/AbstractCallLiteral.java index 0e99d441a..9ae845475 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCallLiteral.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/AbstractCallLiteral.java @@ -3,21 +3,21 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; import java.util.*; // {@link Object#equals(Object)} is implemented by {@link AbstractLiteral}. @SuppressWarnings("squid:S2160") -public abstract class AbstractCallLiteral extends AbstractLiteral { +public abstract class AbstractCallLiteral extends tools.refinery.logic.literal.AbstractLiteral { private final Constraint target; private final List arguments; private final Set inArguments; @@ -90,12 +90,12 @@ public Set getPrivateVariables(Set positiveVariabl } @Override - public Literal substitute(Substitution substitution) { + public tools.refinery.logic.literal.Literal substitute(Substitution substitution) { var substitutedArguments = arguments.stream().map(substitution::getSubstitute).toList(); return doSubstitute(substitution, substitutedArguments); } - protected abstract Literal doSubstitute(Substitution substitution, List substitutedArguments); + protected abstract tools.refinery.logic.literal.Literal doSubstitute(Substitution substitution, List substitutedArguments); public AbstractCallLiteral withTarget(Constraint newTarget) { if (Objects.equals(target, newTarget)) { @@ -107,7 +107,7 @@ public AbstractCallLiteral withTarget(Constraint newTarget) { public abstract AbstractCallLiteral withArguments(Constraint newTarget, List newArguments); @Override - public boolean equalsWithSubstitution(LiteralEqualityHelper helper, Literal other) { + public boolean equalsWithSubstitution(LiteralEqualityHelper helper, tools.refinery.logic.literal.Literal other) { if (!super.equalsWithSubstitution(helper, other)) { return false; } diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCountLiteral.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/AbstractCountLiteral.java similarity index 87% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCountLiteral.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/AbstractCountLiteral.java index 9bb572c03..ee9325984 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractCountLiteral.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/AbstractCountLiteral.java @@ -3,15 +3,15 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.term.ConstantTerm; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.term.ConstantTerm; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.Variable; import java.util.List; import java.util.Objects; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractLiteral.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/AbstractLiteral.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractLiteral.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/AbstractLiteral.java index 7d3cabd79..79100e406 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AbstractLiteral.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/AbstractLiteral.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; public abstract class AbstractLiteral implements Literal { @Override diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AggregationLiteral.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/AggregationLiteral.java similarity index 88% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AggregationLiteral.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/AggregationLiteral.java index e3acfacca..d2cc23f9f 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AggregationLiteral.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/AggregationLiteral.java @@ -1,16 +1,16 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.*; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.*; import java.util.List; import java.util.Objects; @@ -129,7 +129,12 @@ public String toString() { } builder.append(argument); while (argumentIterator.hasNext()) { - builder.append(", ").append(argumentIterator.next()); + builder.append(", "); + argument = argumentIterator.next(); + if (inputVariable.equals(argument)) { + builder.append("@Aggregate(\"").append(aggregator).append("\") "); + } + builder.append(argument); } } builder.append(")"); diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AssignLiteral.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/AssignLiteral.java similarity index 84% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AssignLiteral.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/AssignLiteral.java index dadf487f2..4929e74cb 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/AssignLiteral.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/AssignLiteral.java @@ -3,15 +3,15 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.Term; +import tools.refinery.logic.term.Variable; import java.util.Collections; import java.util.Objects; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/BooleanLiteral.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/BooleanLiteral.java similarity index 81% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/BooleanLiteral.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/BooleanLiteral.java index 6cd320da4..fd1dbf915 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/BooleanLiteral.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/BooleanLiteral.java @@ -3,12 +3,12 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Variable; import java.util.Set; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallLiteral.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/CallLiteral.java similarity index 89% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallLiteral.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/CallLiteral.java index 2d0e4e97f..d93afdc71 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallLiteral.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/CallLiteral.java @@ -3,15 +3,15 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; import java.util.*; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallPolarity.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/CallPolarity.java similarity index 88% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallPolarity.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/CallPolarity.java index 716c71094..4f3bca15b 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CallPolarity.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/CallPolarity.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; -import tools.refinery.store.query.InvalidQueryException; +import tools.refinery.logic.InvalidQueryException; public enum CallPolarity { POSITIVE(true, false), diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CanNegate.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/CanNegate.java similarity index 83% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CanNegate.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/CanNegate.java index 35dcb3fbc..649f05058 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CanNegate.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/CanNegate.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; public interface CanNegate> extends Literal { T negate(); diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CheckLiteral.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/CheckLiteral.java similarity index 80% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CheckLiteral.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/CheckLiteral.java index dfedd2cb5..86bf7ebae 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CheckLiteral.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/CheckLiteral.java @@ -3,17 +3,17 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.ConstantTerm; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.term.bool.BoolNotTerm; -import tools.refinery.store.query.term.bool.BoolTerms; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.ConstantTerm; +import tools.refinery.logic.term.Term; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.term.bool.BoolNotTerm; +import tools.refinery.logic.term.bool.BoolTerms; import java.util.Collections; import java.util.Objects; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/Connectivity.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/Connectivity.java similarity index 86% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/Connectivity.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/Connectivity.java index a058094dc..c04657169 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/Connectivity.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/Connectivity.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; import java.util.Locale; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/ConstantLiteral.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/ConstantLiteral.java similarity index 83% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/ConstantLiteral.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/ConstantLiteral.java index d83bd584c..688ddfa01 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/ConstantLiteral.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/ConstantLiteral.java @@ -3,13 +3,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.Variable; import java.util.Objects; import java.util.Set; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CountLiteral.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/CountLiteral.java similarity index 79% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CountLiteral.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/CountLiteral.java index 3d078d89a..198796929 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CountLiteral.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/CountLiteral.java @@ -3,12 +3,12 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.Variable; import java.util.List; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/EquivalenceLiteral.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/EquivalenceLiteral.java similarity index 87% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/EquivalenceLiteral.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/EquivalenceLiteral.java index 7343f7098..48e85b384 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/EquivalenceLiteral.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/EquivalenceLiteral.java @@ -3,13 +3,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Variable; import java.util.Objects; import java.util.Set; diff --git a/subprojects/logic/src/main/java/tools/refinery/logic/literal/LeftJoinLiteral.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/LeftJoinLiteral.java new file mode 100644 index 000000000..593904c5f --- /dev/null +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/LeftJoinLiteral.java @@ -0,0 +1,140 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.logic.literal; + +import tools.refinery.logic.Constraint; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.ConstantTerm; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; + +import java.util.*; + +// {@link Object#equals(Object)} is implemented by {@link AbstractLiteral}. +@SuppressWarnings("squid:S2160") +public class LeftJoinLiteral extends AbstractCallLiteral { + private final DataVariable resultVariable; + private final DataVariable placeholderVariable; + private final T defaultValue; + + public LeftJoinLiteral(DataVariable resultVariable, DataVariable placeholderVariable, + T defaultValue, Constraint target, List arguments) { + super(target, arguments); + this.resultVariable = resultVariable; + this.placeholderVariable = placeholderVariable; + this.defaultValue = defaultValue; + if (defaultValue == null) { + throw new InvalidQueryException("Default value must not be null"); + } + if (!resultVariable.getType().isInstance(defaultValue)) { + throw new InvalidQueryException("Default value %s must be assignable to result variable %s type %s" + .formatted(defaultValue, resultVariable, resultVariable.getType().getName())); + } + if (!getArgumentsOfDirection(ParameterDirection.OUT).contains(placeholderVariable)) { + throw new InvalidQueryException( + "Placeholder variable %s must be bound with direction %s in the argument list" + .formatted(resultVariable, ParameterDirection.OUT)); + } + if (arguments.contains(resultVariable)) { + throw new InvalidQueryException("Result variable must not appear in the argument list"); + } + } + + public DataVariable getResultVariable() { + return resultVariable; + } + + public DataVariable getPlaceholderVariable() { + return placeholderVariable; + } + + public T getDefaultValue() { + return defaultValue; + } + + @Override + public Set getOutputVariables() { + return Set.of(resultVariable); + } + + @Override + public Set getInputVariables(Set positiveVariablesInClause) { + var inputVariables = new LinkedHashSet<>(getArguments()); + inputVariables.remove(placeholderVariable); + return Collections.unmodifiableSet(inputVariables); + } + + @Override + public Set getPrivateVariables(Set positiveVariablesInClause) { + return Set.of(placeholderVariable); + } + + @Override + public Literal reduce() { + var reduction = getTarget().getReduction(); + return switch (reduction) { + case ALWAYS_FALSE -> resultVariable.assign(new ConstantTerm<>(resultVariable.getType(), defaultValue)); + case ALWAYS_TRUE -> throw new InvalidQueryException("Trying to left join an infinite set"); + case NOT_REDUCIBLE -> this; + }; + } + + @Override + protected Literal doSubstitute(Substitution substitution, List substitutedArguments) { + return new LeftJoinLiteral<>(substitution.getTypeSafeSubstitute(resultVariable), + substitution.getTypeSafeSubstitute(placeholderVariable), defaultValue, getTarget(), + substitutedArguments); + } + + @Override + public AbstractCallLiteral withArguments(Constraint newTarget, List newArguments) { + return new LeftJoinLiteral<>(resultVariable, placeholderVariable, defaultValue, newTarget, newArguments); + } + + @Override + public boolean equalsWithSubstitution(LiteralEqualityHelper helper, Literal other) { + if (!super.equalsWithSubstitution(helper, other)) { + return false; + } + var otherLeftJoinLiteral = (LeftJoinLiteral) other; + return helper.variableEqual(resultVariable, otherLeftJoinLiteral.resultVariable) && + helper.variableEqual(placeholderVariable, otherLeftJoinLiteral.placeholderVariable) && + Objects.equals(defaultValue, otherLeftJoinLiteral.defaultValue); + } + + @Override + public int hashCodeWithSubstitution(LiteralHashCodeHelper helper) { + return Objects.hash(super.hashCodeWithSubstitution(helper), helper.getVariableHashCode(resultVariable), + helper.getVariableHashCode(placeholderVariable), defaultValue); + } + + @Override + public String toString() { + var builder = new StringBuilder(); + var argumentIterator = getArguments().iterator(); + if (argumentIterator.hasNext()) { + appendArgument(builder, argumentIterator.next()); + while (argumentIterator.hasNext()) { + builder.append(", "); + appendArgument(builder, argumentIterator.next()); + } + } + builder.append(")"); + return builder.toString(); + } + + private void appendArgument(StringBuilder builder, Variable argument) { + if (placeholderVariable.equals(argument)) { + builder.append("@Default(").append(defaultValue).append(") "); + argument = resultVariable; + } + builder.append(argument); + } +} diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/Literal.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/Literal.java similarity index 70% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/Literal.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/Literal.java index cb16ab001..08a0241cf 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/Literal.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/Literal.java @@ -3,12 +3,12 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Variable; import java.util.Set; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/Literals.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/Literals.java similarity index 84% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/Literals.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/Literals.java index 6056da45e..2f7ddb5df 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/Literals.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/Literals.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.term.Term; public final class Literals { private Literals() { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/Reduction.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/Reduction.java similarity index 93% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/Reduction.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/Reduction.java index ee155a9a5..1f7d9a2fc 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/Reduction.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/Reduction.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; public enum Reduction { /** diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/RepresentativeElectionLiteral.java b/subprojects/logic/src/main/java/tools/refinery/logic/literal/RepresentativeElectionLiteral.java similarity index 87% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/literal/RepresentativeElectionLiteral.java rename to subprojects/logic/src/main/java/tools/refinery/logic/literal/RepresentativeElectionLiteral.java index f73239477..ff9a6bedd 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/RepresentativeElectionLiteral.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/literal/RepresentativeElectionLiteral.java @@ -3,16 +3,16 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; import java.util.List; import java.util.Set; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/AbstractRecursiveRewriter.java b/subprojects/logic/src/main/java/tools/refinery/logic/rewriter/AbstractRecursiveRewriter.java similarity index 73% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/AbstractRecursiveRewriter.java rename to subprojects/logic/src/main/java/tools/refinery/logic/rewriter/AbstractRecursiveRewriter.java index fb4c14a7a..073705f83 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/AbstractRecursiveRewriter.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/rewriter/AbstractRecursiveRewriter.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.rewriter; +package tools.refinery.logic.rewriter; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.equality.DnfEqualityChecker; -import tools.refinery.store.util.CycleDetectingMapper; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.equality.DnfEqualityChecker; +import tools.refinery.logic.util.CycleDetectingMapper; public abstract class AbstractRecursiveRewriter implements DnfRewriter { private final CycleDetectingMapper mapper = new CycleDetectingMapper<>(Dnf::name, this::map); diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/ClauseInputParameterResolver.java b/subprojects/logic/src/main/java/tools/refinery/logic/rewriter/ClauseInputParameterResolver.java similarity index 93% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/ClauseInputParameterResolver.java rename to subprojects/logic/src/main/java/tools/refinery/logic/rewriter/ClauseInputParameterResolver.java index aa06a05a4..83fd44c57 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/ClauseInputParameterResolver.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/rewriter/ClauseInputParameterResolver.java @@ -3,14 +3,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.rewriter; +package tools.refinery.logic.rewriter; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.DnfClause; -import tools.refinery.store.query.literal.*; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.DnfClause; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.literal.*; +import tools.refinery.logic.term.ParameterDirection; import java.util.*; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/CompositeRewriter.java b/subprojects/logic/src/main/java/tools/refinery/logic/rewriter/CompositeRewriter.java similarity index 87% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/CompositeRewriter.java rename to subprojects/logic/src/main/java/tools/refinery/logic/rewriter/CompositeRewriter.java index 5b4f65e5f..2e6810938 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/CompositeRewriter.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/rewriter/CompositeRewriter.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.rewriter; +package tools.refinery.logic.rewriter; -import tools.refinery.store.query.dnf.Dnf; +import tools.refinery.logic.dnf.Dnf; import java.util.ArrayList; import java.util.List; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/DnfRewriter.java b/subprojects/logic/src/main/java/tools/refinery/logic/rewriter/DnfRewriter.java similarity index 70% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/DnfRewriter.java rename to subprojects/logic/src/main/java/tools/refinery/logic/rewriter/DnfRewriter.java index 5d8359d19..f4605895c 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/DnfRewriter.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/rewriter/DnfRewriter.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.rewriter; +package tools.refinery.logic.rewriter; -import tools.refinery.store.query.dnf.AnyQuery; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.Query; +import tools.refinery.logic.dnf.AnyQuery; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.Query; @FunctionalInterface public interface DnfRewriter { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/DuplicateDnfRemover.java b/subprojects/logic/src/main/java/tools/refinery/logic/rewriter/DuplicateDnfRemover.java similarity index 86% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/DuplicateDnfRemover.java rename to subprojects/logic/src/main/java/tools/refinery/logic/rewriter/DuplicateDnfRemover.java index 0c7864707..433173383 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/DuplicateDnfRemover.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/rewriter/DuplicateDnfRemover.java @@ -3,14 +3,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.rewriter; +package tools.refinery.logic.rewriter; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.DnfClause; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.equality.DnfEqualityChecker; -import tools.refinery.store.query.literal.AbstractCallLiteral; -import tools.refinery.store.query.literal.Literal; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.DnfClause; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.equality.DnfEqualityChecker; +import tools.refinery.logic.literal.AbstractCallLiteral; +import tools.refinery.logic.literal.Literal; import java.util.ArrayList; import java.util.HashMap; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/InputParameterResolver.java b/subprojects/logic/src/main/java/tools/refinery/logic/rewriter/InputParameterResolver.java similarity index 83% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/InputParameterResolver.java rename to subprojects/logic/src/main/java/tools/refinery/logic/rewriter/InputParameterResolver.java index cd8a2e7d2..89aa43c73 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/rewriter/InputParameterResolver.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/rewriter/InputParameterResolver.java @@ -3,13 +3,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.rewriter; +package tools.refinery.logic.rewriter; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.DnfBuilder; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.DnfBuilder; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.ParameterDirection; import java.util.HashSet; import java.util.List; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/substitution/MapBasedSubstitution.java b/subprojects/logic/src/main/java/tools/refinery/logic/substitution/MapBasedSubstitution.java similarity index 81% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/substitution/MapBasedSubstitution.java rename to subprojects/logic/src/main/java/tools/refinery/logic/substitution/MapBasedSubstitution.java index a8201eefd..2977bd573 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/substitution/MapBasedSubstitution.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/substitution/MapBasedSubstitution.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.substitution; +package tools.refinery.logic.substitution; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.term.Variable; import java.util.Map; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/substitution/RenewingSubstitution.java b/subprojects/logic/src/main/java/tools/refinery/logic/substitution/RenewingSubstitution.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/substitution/RenewingSubstitution.java rename to subprojects/logic/src/main/java/tools/refinery/logic/substitution/RenewingSubstitution.java index 9b737ceb9..ca40ee50d 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/substitution/RenewingSubstitution.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/substitution/RenewingSubstitution.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.substitution; +package tools.refinery.logic.substitution; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.term.Variable; import java.util.HashMap; import java.util.Map; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/substitution/StatelessSubstitution.java b/subprojects/logic/src/main/java/tools/refinery/logic/substitution/StatelessSubstitution.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/substitution/StatelessSubstitution.java rename to subprojects/logic/src/main/java/tools/refinery/logic/substitution/StatelessSubstitution.java index bb3803d33..ab36d3db3 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/substitution/StatelessSubstitution.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/substitution/StatelessSubstitution.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.substitution; +package tools.refinery.logic.substitution; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.term.Variable; public enum StatelessSubstitution implements Substitution { FAILING { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/substitution/Substitution.java b/subprojects/logic/src/main/java/tools/refinery/logic/substitution/Substitution.java similarity index 76% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/substitution/Substitution.java rename to subprojects/logic/src/main/java/tools/refinery/logic/substitution/Substitution.java index 834fce129..8fc700bcd 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/substitution/Substitution.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/substitution/Substitution.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.substitution; +package tools.refinery.logic.substitution; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.Variable; @FunctionalInterface public interface Substitution { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/substitution/SubstitutionBuilder.java b/subprojects/logic/src/main/java/tools/refinery/logic/substitution/SubstitutionBuilder.java similarity index 91% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/substitution/SubstitutionBuilder.java rename to subprojects/logic/src/main/java/tools/refinery/logic/substitution/SubstitutionBuilder.java index 37fb69082..f30b1a5df 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/substitution/SubstitutionBuilder.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/substitution/SubstitutionBuilder.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.substitution; +package tools.refinery.logic.substitution; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.Variable; import java.util.Collections; import java.util.HashMap; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/AbstractTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/AbstractTerm.java similarity index 85% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/AbstractTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/AbstractTerm.java index 5cecc35b7..293f7e9e1 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/AbstractTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/AbstractTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; import java.util.Objects; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/Aggregator.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/Aggregator.java similarity index 88% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/Aggregator.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/Aggregator.java index 0684a9d98..40189ebc5 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/Aggregator.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/Aggregator.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; import java.util.stream.Stream; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/AnyDataVariable.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/AnyDataVariable.java similarity index 87% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/AnyDataVariable.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/AnyDataVariable.java index 3801bc116..3376bdc98 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/AnyDataVariable.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/AnyDataVariable.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; import org.jetbrains.annotations.Nullable; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.LiteralEqualityHelper; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.LiteralEqualityHelper; import java.util.Optional; import java.util.Set; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/AnyTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/AnyTerm.java similarity index 67% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/AnyTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/AnyTerm.java index f136b68d8..58b4cb1da 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/AnyTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/AnyTerm.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.substitution.Substitution; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.substitution.Substitution; import java.util.Set; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/AssignedValue.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/AssignedValue.java similarity index 72% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/AssignedValue.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/AssignedValue.java index 0cf30aa6f..78900cd65 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/AssignedValue.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/AssignedValue.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; -import tools.refinery.store.query.literal.Literal; +import tools.refinery.logic.literal.Literal; @FunctionalInterface public interface AssignedValue { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/BinaryTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/BinaryTerm.java similarity index 89% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/BinaryTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/BinaryTerm.java index cdbf592ab..356fd807a 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/BinaryTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/BinaryTerm.java @@ -3,13 +3,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.valuation.Valuation; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.valuation.Valuation; import java.util.Collections; import java.util.HashSet; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/ConstantTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/ConstantTerm.java similarity index 80% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/ConstantTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/ConstantTerm.java index 415ae286f..69c7e5f6e 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/ConstantTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/ConstantTerm.java @@ -3,13 +3,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.valuation.Valuation; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.valuation.Valuation; import java.util.Objects; import java.util.Set; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/DataVariable.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/DataVariable.java similarity index 83% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/DataVariable.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/DataVariable.java index 2206b5224..7ef69d053 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/DataVariable.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/DataVariable.java @@ -3,16 +3,16 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; import org.jetbrains.annotations.Nullable; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.literal.EquivalenceLiteral; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.valuation.Valuation; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.literal.EquivalenceLiteral; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.valuation.Valuation; import java.util.Objects; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/ExtremeValueAggregator.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/ExtremeValueAggregator.java similarity index 98% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/ExtremeValueAggregator.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/ExtremeValueAggregator.java index 657cb6318..31c61b6a5 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/ExtremeValueAggregator.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/ExtremeValueAggregator.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; import java.util.Comparator; import java.util.Objects; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/NodeVariable.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/NodeVariable.java similarity index 84% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/NodeVariable.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/NodeVariable.java index 53c32e20a..1a5f26575 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/NodeVariable.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/NodeVariable.java @@ -3,12 +3,12 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; import org.jetbrains.annotations.Nullable; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.literal.ConstantLiteral; -import tools.refinery.store.query.literal.EquivalenceLiteral; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.literal.ConstantLiteral; +import tools.refinery.logic.literal.EquivalenceLiteral; import java.util.Optional; @@ -24,7 +24,7 @@ public Optional> tryGetType() { @Override public NodeVariable renew(@Nullable String name) { - return Variable.of(name); + return of(name); } @Override diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/Parameter.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/Parameter.java similarity index 97% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/Parameter.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/Parameter.java index 577ac6e05..d4a651e11 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/Parameter.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/Parameter.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; import java.util.Objects; import java.util.Optional; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/ParameterDirection.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/ParameterDirection.java similarity index 88% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/ParameterDirection.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/ParameterDirection.java index da83f3c3f..75ee06e6b 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/ParameterDirection.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/ParameterDirection.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; public enum ParameterDirection { OUT("out"), diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/StatefulAggregate.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/StatefulAggregate.java similarity index 90% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/StatefulAggregate.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/StatefulAggregate.java index ab3105564..75e7ecff8 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/StatefulAggregate.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/StatefulAggregate.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; public interface StatefulAggregate { void add(T value); diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/StatefulAggregator.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/StatefulAggregator.java similarity index 94% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/StatefulAggregator.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/StatefulAggregator.java index df746a90b..79d325358 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/StatefulAggregator.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/StatefulAggregator.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; import java.util.stream.Stream; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/StatelessAggregator.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/StatelessAggregator.java similarity index 93% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/StatelessAggregator.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/StatelessAggregator.java index a094919eb..37db262ec 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/StatelessAggregator.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/StatelessAggregator.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; import java.util.stream.Stream; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/Term.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/Term.java similarity index 63% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/Term.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/Term.java index e6818b886..0eaa36d8d 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/Term.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/Term.java @@ -3,12 +3,12 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; -import tools.refinery.store.query.literal.AssignLiteral; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.valuation.Valuation; +import tools.refinery.logic.literal.AssignLiteral; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.valuation.Valuation; public non-sealed interface Term extends AnyTerm, AssignedValue { @Override diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/UnaryTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/UnaryTerm.java similarity index 84% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/UnaryTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/UnaryTerm.java index a464ece57..e173de3e3 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/UnaryTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/UnaryTerm.java @@ -3,13 +3,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.equality.LiteralHashCodeHelper; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.valuation.Valuation; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.equality.LiteralHashCodeHelper; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.valuation.Valuation; import java.util.Objects; import java.util.Set; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/Variable.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/Variable.java similarity index 95% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/Variable.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/Variable.java index 1b5537040..28aad21b4 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/Variable.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/Variable.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; import org.jetbrains.annotations.Nullable; -import tools.refinery.store.query.dnf.DnfUtils; +import tools.refinery.logic.dnf.DnfUtils; import java.util.Objects; import java.util.Optional; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolAndTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolAndTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolAndTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolAndTerm.java index f9e1c06f0..88c2081bc 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolAndTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolAndTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.bool; +package tools.refinery.logic.term.bool; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class BoolAndTerm extends BoolBinaryTerm { public BoolAndTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolBinaryTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolBinaryTerm.java similarity index 71% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolBinaryTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolBinaryTerm.java index a85aa63ab..6d53fb43d 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolBinaryTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolBinaryTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.bool; +package tools.refinery.logic.term.bool; -import tools.refinery.store.query.term.BinaryTerm; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.term.BinaryTerm; +import tools.refinery.logic.term.Term; public abstract class BoolBinaryTerm extends BinaryTerm { protected BoolBinaryTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolNotTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolNotTerm.java similarity index 75% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolNotTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolNotTerm.java index 8d3382b32..ec80484fb 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolNotTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolNotTerm.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.bool; +package tools.refinery.logic.term.bool; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.query.term.UnaryTerm; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; +import tools.refinery.logic.term.UnaryTerm; public class BoolNotTerm extends UnaryTerm { protected BoolNotTerm(Term body) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolOrTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolOrTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolOrTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolOrTerm.java index b5195d525..10c61bf2e 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolOrTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolOrTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.bool; +package tools.refinery.logic.term.bool; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class BoolOrTerm extends BoolBinaryTerm { public BoolOrTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolTerms.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolTerms.java similarity index 85% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolTerms.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolTerms.java index fa54f686a..5bdc32071 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolTerms.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolTerms.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.bool; +package tools.refinery.logic.term.bool; -import tools.refinery.store.query.term.ConstantTerm; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.term.ConstantTerm; +import tools.refinery.logic.term.Term; public final class BoolTerms { private BoolTerms() { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolXorTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolXorTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolXorTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolXorTerm.java index 7478b8a56..3d5247a7b 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/bool/BoolXorTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/bool/BoolXorTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.bool; +package tools.refinery.logic.term.bool; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class BoolXorTerm extends BoolBinaryTerm { public BoolXorTerm(Term left, Term right) { diff --git a/subprojects/logic/src/main/java/tools/refinery/logic/term/cardinalityinterval/CardinalityDomain.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/cardinalityinterval/CardinalityDomain.java new file mode 100644 index 000000000..297756154 --- /dev/null +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/cardinalityinterval/CardinalityDomain.java @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.logic.term.cardinalityinterval; + +import tools.refinery.logic.AbstractDomain; + +// Singleton pattern, because there is only one domain for truth values. +@SuppressWarnings("squid:S6548") +public class CardinalityDomain implements AbstractDomain { + public static final CardinalityDomain INSTANCE = new CardinalityDomain(); + + private CardinalityDomain() { + } + + @Override + public Class abstractType() { + return CardinalityInterval.class; + } + + @Override + public Class concreteType() { + return Integer.class; + } + + @Override + public CardinalityInterval unknown() { + return CardinalityIntervals.SET; + } + + @Override + public CardinalityInterval error() { + return CardinalityIntervals.ERROR; + } + + @Override + public CardinalityInterval toAbstract(Integer concreteValue) { + return CardinalityIntervals.exactly(concreteValue); + } +} diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityInterval.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/cardinalityinterval/CardinalityInterval.java similarity index 57% rename from subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityInterval.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/cardinalityinterval/CardinalityInterval.java index b20c685a6..996ebde51 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityInterval.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/cardinalityinterval/CardinalityInterval.java @@ -3,15 +3,17 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation.cardinality; +package tools.refinery.logic.term.cardinalityinterval; -public sealed interface CardinalityInterval permits NonEmptyCardinalityInterval, EmptyCardinalityInterval { +import tools.refinery.logic.AbstractValue; +import tools.refinery.logic.term.uppercardinality.UpperCardinality; + +public sealed interface CardinalityInterval extends AbstractValue + permits NonEmptyCardinalityInterval, EmptyCardinalityInterval { int lowerBound(); UpperCardinality upperBound(); - boolean isEmpty(); - CardinalityInterval min(CardinalityInterval other); CardinalityInterval max(CardinalityInterval other); @@ -21,8 +23,4 @@ public sealed interface CardinalityInterval permits NonEmptyCardinalityInterval, CardinalityInterval take(int count); CardinalityInterval multiply(CardinalityInterval other); - - CardinalityInterval meet(CardinalityInterval other); - - CardinalityInterval join(CardinalityInterval other); } diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityIntervals.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/cardinalityinterval/CardinalityIntervals.java similarity index 89% rename from subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityIntervals.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/cardinalityinterval/CardinalityIntervals.java index 855fd2486..cb64cc0d3 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityIntervals.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/cardinalityinterval/CardinalityIntervals.java @@ -3,7 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation.cardinality; +package tools.refinery.logic.term.cardinalityinterval; + +import tools.refinery.logic.term.uppercardinality.UpperCardinalities; +import tools.refinery.logic.term.uppercardinality.UpperCardinality; public final class CardinalityIntervals { public static final CardinalityInterval NONE = exactly(0); diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/EmptyCardinalityInterval.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/cardinalityinterval/EmptyCardinalityInterval.java similarity index 71% rename from subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/EmptyCardinalityInterval.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/cardinalityinterval/EmptyCardinalityInterval.java index 9e371e219..8892b278e 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/EmptyCardinalityInterval.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/cardinalityinterval/EmptyCardinalityInterval.java @@ -1,9 +1,13 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation.cardinality; +package tools.refinery.logic.term.cardinalityinterval; + +import org.jetbrains.annotations.Nullable; +import tools.refinery.logic.term.uppercardinality.UpperCardinalities; +import tools.refinery.logic.term.uppercardinality.UpperCardinality; // Singleton implementation, because there is only a single empty interval. @SuppressWarnings("squid:S6548") @@ -15,15 +19,27 @@ private EmptyCardinalityInterval() { } @Override - public int lowerBound() { - return 1; + @Nullable + public Integer getConcrete() { + return null; + } + + @Override + @Nullable + public Integer getArbitrary() { + return null; } @Override - public boolean isEmpty() { + public boolean isRefinementOf(CardinalityInterval other) { return true; } + @Override + public int lowerBound() { + return 1; + } + @Override public UpperCardinality upperBound() { return UpperCardinalities.ZERO; diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/NonEmptyCardinalityInterval.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/cardinalityinterval/NonEmptyCardinalityInterval.java similarity index 75% rename from subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/NonEmptyCardinalityInterval.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/cardinalityinterval/NonEmptyCardinalityInterval.java index 6bd66df7f..efe1464ee 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/NonEmptyCardinalityInterval.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/cardinalityinterval/NonEmptyCardinalityInterval.java @@ -1,9 +1,14 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation.cardinality; +package tools.refinery.logic.term.cardinalityinterval; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import tools.refinery.logic.term.uppercardinality.FiniteUpperCardinality; +import tools.refinery.logic.term.uppercardinality.UpperCardinality; import java.util.Objects; import java.util.function.BinaryOperator; @@ -20,10 +25,36 @@ public record NonEmptyCardinalityInterval(int lowerBound, UpperCardinality upper } @Override - public boolean isEmpty() { + @Nullable + public Integer getConcrete() { + return isConcrete() ? lowerBound : null; + } + + @Override + public boolean isConcrete() { + return upperBound instanceof FiniteUpperCardinality finiteUpperCardinality && + finiteUpperCardinality.finiteUpperBound() == lowerBound; + } + + @Override + @NotNull + public Integer getArbitrary() { + return lowerBound; + } + + @Override + public boolean isError() { return false; } + @Override + public boolean isRefinementOf(CardinalityInterval other) { + if (!(other instanceof NonEmptyCardinalityInterval nonEmptyOther)) { + return false; + } + return lowerBound >= nonEmptyOther.lowerBound() && upperBound.compareTo(nonEmptyOther.upperBound()) <= 0; + } + @Override public CardinalityInterval min(CardinalityInterval other) { return lift(other, Math::min, UpperCardinality::min); diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/ComparisonTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/ComparisonTerm.java similarity index 74% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/ComparisonTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/ComparisonTerm.java index 5ca5a0a1e..0401f984b 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/ComparisonTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/ComparisonTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.comparable; +package tools.refinery.logic.term.comparable; -import tools.refinery.store.query.term.BinaryTerm; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.term.BinaryTerm; +import tools.refinery.logic.term.Term; public abstract class ComparisonTerm extends BinaryTerm { protected ComparisonTerm(Class argumentType, Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/EqTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/EqTerm.java similarity index 81% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/EqTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/EqTerm.java index b8cf36f8b..7a1315e6b 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/EqTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/EqTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.comparable; +package tools.refinery.logic.term.comparable; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class EqTerm extends ComparisonTerm { public EqTerm(Class argumentType, Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/GreaterEqTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/GreaterEqTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/GreaterEqTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/GreaterEqTerm.java index b109eb1a6..383239993 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/GreaterEqTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/GreaterEqTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.comparable; +package tools.refinery.logic.term.comparable; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class GreaterEqTerm> extends ComparisonTerm { public GreaterEqTerm(Class argumentType, Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/GreaterTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/GreaterTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/GreaterTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/GreaterTerm.java index 1b67f8b58..7174372e0 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/GreaterTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/GreaterTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.comparable; +package tools.refinery.logic.term.comparable; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class GreaterTerm> extends ComparisonTerm { public GreaterTerm(Class argumentType, Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/LessEqTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/LessEqTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/LessEqTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/LessEqTerm.java index 1b34535ff..7a07b7b28 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/LessEqTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/LessEqTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.comparable; +package tools.refinery.logic.term.comparable; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class LessEqTerm> extends ComparisonTerm { public LessEqTerm(Class argumentType, Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/LessTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/LessTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/LessTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/LessTerm.java index 44e709028..b402f54da 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/LessTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/LessTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.comparable; +package tools.refinery.logic.term.comparable; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class LessTerm> extends ComparisonTerm { public LessTerm(Class argumentType, Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/NotEqTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/NotEqTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/NotEqTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/NotEqTerm.java index 1f9734c40..d2c697f49 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/comparable/NotEqTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/comparable/NotEqTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.comparable; +package tools.refinery.logic.term.comparable; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class NotEqTerm extends ComparisonTerm { public NotEqTerm(Class argumentType, Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntAddTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntAddTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntAddTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntAddTerm.java index dbea3efcb..73533d9bb 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntAddTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntAddTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.int_; +package tools.refinery.logic.term.int_; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class IntAddTerm extends IntBinaryTerm { public IntAddTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntBinaryTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntBinaryTerm.java similarity index 71% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntBinaryTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntBinaryTerm.java index 27ced4e4e..9543c21f8 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntBinaryTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntBinaryTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.int_; +package tools.refinery.logic.term.int_; -import tools.refinery.store.query.term.BinaryTerm; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.term.BinaryTerm; +import tools.refinery.logic.term.Term; public abstract class IntBinaryTerm extends BinaryTerm { protected IntBinaryTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntDivTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntDivTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntDivTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntDivTerm.java index 2a35058c7..f9fa70ef3 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntDivTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntDivTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.int_; +package tools.refinery.logic.term.int_; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class IntDivTerm extends IntBinaryTerm { public IntDivTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntMaxTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntMaxTerm.java similarity index 76% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntMaxTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntMaxTerm.java index f81fc5092..f7b315df2 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntMaxTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntMaxTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.int_; +package tools.refinery.logic.term.int_; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class IntMaxTerm extends IntBinaryTerm { public IntMaxTerm(Term left, Term right) { @@ -15,7 +15,7 @@ public IntMaxTerm(Term left, Term right) { @Override public Term doSubstitute(Substitution substitution, Term substitutedLeft, - Term substitutedRight) { + Term substitutedRight) { return new IntMaxTerm(substitutedLeft, substitutedRight); } diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntMinTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntMinTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntMinTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntMinTerm.java index 89182e264..73247db13 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntMinTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntMinTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.int_; +package tools.refinery.logic.term.int_; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class IntMinTerm extends IntBinaryTerm { public IntMinTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntMinusTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntMinusTerm.java similarity index 78% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntMinusTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntMinusTerm.java index 709aa5baf..006e19774 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntMinusTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntMinusTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.int_; +package tools.refinery.logic.term.int_; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class IntMinusTerm extends IntUnaryTerm { public IntMinusTerm(Term body) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntMulTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntMulTerm.java similarity index 76% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntMulTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntMulTerm.java index 89d4c5f45..18fdcb450 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntMulTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntMulTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.int_; +package tools.refinery.logic.term.int_; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class IntMulTerm extends IntBinaryTerm { public IntMulTerm(Term left, Term right) { @@ -15,7 +15,7 @@ public IntMulTerm(Term left, Term right) { @Override public Term doSubstitute(Substitution substitution, Term substitutedLeft, - Term substitutedRight) { + Term substitutedRight) { return new IntMulTerm(substitutedLeft, substitutedRight); } diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntPlusTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntPlusTerm.java similarity index 78% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntPlusTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntPlusTerm.java index aef83bb4a..1a905293b 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntPlusTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntPlusTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.int_; +package tools.refinery.logic.term.int_; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class IntPlusTerm extends IntUnaryTerm { public IntPlusTerm(Term body) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntPowTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntPowTerm.java similarity index 81% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntPowTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntPowTerm.java index d5af97a11..dac490b06 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntPowTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntPowTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.int_; +package tools.refinery.logic.term.int_; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class IntPowTerm extends IntBinaryTerm { public IntPowTerm(Term left, Term right) { @@ -15,7 +15,7 @@ public IntPowTerm(Term left, Term right) { @Override public Term doSubstitute(Substitution substitution, Term substitutedLeft, - Term substitutedRight) { + Term substitutedRight) { return new IntPowTerm(substitutedLeft, substitutedRight); } diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntSubTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntSubTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntSubTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntSubTerm.java index 2c27afb1b..943266777 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntSubTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntSubTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.int_; +package tools.refinery.logic.term.int_; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class IntSubTerm extends IntBinaryTerm { public IntSubTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntSumAggregator.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntSumAggregator.java similarity index 87% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntSumAggregator.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntSumAggregator.java index cd718c535..b42038abb 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntSumAggregator.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntSumAggregator.java @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.int_; +package tools.refinery.logic.term.int_; -import tools.refinery.store.query.term.StatelessAggregator; +import tools.refinery.logic.term.StatelessAggregator; public final class IntSumAggregator implements StatelessAggregator { public static final IntSumAggregator INSTANCE = new IntSumAggregator(); diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntTerms.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntTerms.java similarity index 89% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntTerms.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntTerms.java index acb98b94e..b152a1384 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntTerms.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntTerms.java @@ -3,13 +3,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.int_; - -import tools.refinery.store.query.term.Aggregator; -import tools.refinery.store.query.term.ConstantTerm; -import tools.refinery.store.query.term.ExtremeValueAggregator; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.query.term.comparable.*; +package tools.refinery.logic.term.int_; + +import tools.refinery.logic.term.Aggregator; +import tools.refinery.logic.term.ConstantTerm; +import tools.refinery.logic.term.ExtremeValueAggregator; +import tools.refinery.logic.term.Term; +import tools.refinery.logic.term.comparable.*; +import tools.refinery.logic.term.comparable.*; import java.util.Comparator; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntUnaryTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntUnaryTerm.java similarity index 68% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntUnaryTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntUnaryTerm.java index 49b4c6475..20449e678 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/IntUnaryTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/IntUnaryTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.int_; +package tools.refinery.logic.term.int_; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.query.term.UnaryTerm; +import tools.refinery.logic.term.UnaryTerm; +import tools.refinery.logic.term.Term; public abstract class IntUnaryTerm extends UnaryTerm { protected IntUnaryTerm(Term body) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/RealToIntTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/RealToIntTerm.java similarity index 76% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/RealToIntTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/int_/RealToIntTerm.java index 7d3835625..7611af903 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/int_/RealToIntTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/int_/RealToIntTerm.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.int_; +package tools.refinery.logic.term.int_; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.query.term.UnaryTerm; +import tools.refinery.logic.term.Term; +import tools.refinery.logic.term.UnaryTerm; +import tools.refinery.logic.substitution.Substitution; public class RealToIntTerm extends UnaryTerm { protected RealToIntTerm(Term body) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/IntToRealTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/IntToRealTerm.java similarity index 75% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/IntToRealTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/real/IntToRealTerm.java index 2f53117ac..23c6893cd 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/IntToRealTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/IntToRealTerm.java @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.real; +package tools.refinery.logic.term.real; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.query.term.UnaryTerm; +import tools.refinery.logic.term.UnaryTerm; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class IntToRealTerm extends UnaryTerm { protected IntToRealTerm(Term body) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealAddTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealAddTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealAddTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealAddTerm.java index 33fc9e41d..82b972289 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealAddTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealAddTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.real; +package tools.refinery.logic.term.real; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class RealAddTerm extends RealBinaryTerm { public RealAddTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealBinaryTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealBinaryTerm.java similarity index 71% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealBinaryTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealBinaryTerm.java index 000f36232..3c23e767e 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealBinaryTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealBinaryTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.real; +package tools.refinery.logic.term.real; -import tools.refinery.store.query.term.BinaryTerm; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.term.BinaryTerm; +import tools.refinery.logic.term.Term; public abstract class RealBinaryTerm extends BinaryTerm { protected RealBinaryTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealDivTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealDivTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealDivTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealDivTerm.java index 1e55bf427..c22399e34 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealDivTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealDivTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.real; +package tools.refinery.logic.term.real; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class RealDivTerm extends RealBinaryTerm { public RealDivTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealMaxTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealMaxTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealMaxTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealMaxTerm.java index 2a2494967..0c609c6d0 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealMaxTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealMaxTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.real; +package tools.refinery.logic.term.real; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class RealMaxTerm extends RealBinaryTerm { public RealMaxTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealMinTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealMinTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealMinTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealMinTerm.java index 2eb4cc1ed..af2c3a52d 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealMinTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealMinTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.real; +package tools.refinery.logic.term.real; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class RealMinTerm extends RealBinaryTerm { public RealMinTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealMinusTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealMinusTerm.java similarity index 78% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealMinusTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealMinusTerm.java index 4afec7a1e..e3e371c2e 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealMinusTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealMinusTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.real; +package tools.refinery.logic.term.real; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class RealMinusTerm extends RealUnaryTerm { public RealMinusTerm(Term body) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealMulTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealMulTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealMulTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealMulTerm.java index ec95ac6ff..ce8f2cd4a 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealMulTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealMulTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.real; +package tools.refinery.logic.term.real; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class RealMulTerm extends RealBinaryTerm { public RealMulTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealPlusTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealPlusTerm.java similarity index 78% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealPlusTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealPlusTerm.java index 64dd2e70c..60efc5fda 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealPlusTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealPlusTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.real; +package tools.refinery.logic.term.real; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class RealPlusTerm extends RealUnaryTerm { public RealPlusTerm(Term body) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealPowTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealPowTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealPowTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealPowTerm.java index 11c952ead..6cb50362a 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealPowTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealPowTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.real; +package tools.refinery.logic.term.real; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class RealPowTerm extends RealBinaryTerm { public RealPowTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealSubTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealSubTerm.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealSubTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealSubTerm.java index 8cc701eda..32315e8e3 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealSubTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealSubTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.real; +package tools.refinery.logic.term.real; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class RealSubTerm extends RealBinaryTerm { public RealSubTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealSumAggregator.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealSumAggregator.java similarity index 92% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealSumAggregator.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealSumAggregator.java index d21048e90..4b0901885 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealSumAggregator.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealSumAggregator.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.real; +package tools.refinery.logic.term.real; -import tools.refinery.store.query.term.StatefulAggregate; -import tools.refinery.store.query.term.StatefulAggregator; +import tools.refinery.logic.term.StatefulAggregate; +import tools.refinery.logic.term.StatefulAggregator; import java.util.Map; import java.util.TreeMap; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealTerms.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealTerms.java similarity index 89% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealTerms.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealTerms.java index 792203582..07dfa96b0 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealTerms.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealTerms.java @@ -3,13 +3,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.real; - -import tools.refinery.store.query.term.Aggregator; -import tools.refinery.store.query.term.ConstantTerm; -import tools.refinery.store.query.term.ExtremeValueAggregator; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.query.term.comparable.*; +package tools.refinery.logic.term.real; + +import tools.refinery.logic.term.Aggregator; +import tools.refinery.logic.term.ConstantTerm; +import tools.refinery.logic.term.ExtremeValueAggregator; +import tools.refinery.logic.term.Term; +import tools.refinery.logic.term.comparable.*; +import tools.refinery.logic.term.comparable.*; import java.util.Comparator; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealUnaryTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealUnaryTerm.java similarity index 67% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealUnaryTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealUnaryTerm.java index d41c4ed9b..14772411f 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/real/RealUnaryTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/real/RealUnaryTerm.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.real; +package tools.refinery.logic.term.real; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.query.term.UnaryTerm; +import tools.refinery.logic.term.UnaryTerm; +import tools.refinery.logic.term.Term; public abstract class RealUnaryTerm extends UnaryTerm { protected RealUnaryTerm(Term body) { diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/TruthValue.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/truthvalue/TruthValue.java similarity index 62% rename from subprojects/store/src/main/java/tools/refinery/store/representation/TruthValue.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/truthvalue/TruthValue.java index f81ee9a4b..59bdeab39 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/TruthValue.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/truthvalue/TruthValue.java @@ -1,11 +1,14 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation; +package tools.refinery.logic.term.truthvalue; -public enum TruthValue { +import org.jetbrains.annotations.Nullable; +import tools.refinery.logic.AbstractValue; + +public enum TruthValue implements AbstractValue { TRUE("true"), FALSE("false"), @@ -28,14 +31,41 @@ public static TruthValue toTruthValue(boolean value) { return value ? TRUE : FALSE; } + @Override + @Nullable + public Boolean getArbitrary() { + return switch (this) { + case TRUE -> true; + case FALSE, UNKNOWN -> false; + case ERROR -> null; + }; + } + + @Override + public boolean isError() { + return this == ERROR; + } + public boolean isConsistent() { - return this != ERROR; + return !isError(); } + public boolean isComplete() { return this != UNKNOWN; } + @Override + @Nullable + public Boolean getConcrete() { + return switch (this) { + case TRUE -> true; + case FALSE -> false; + default -> null; + }; + } + + @Override public boolean isConcrete() { return this == TRUE || this == FALSE; } @@ -56,15 +86,7 @@ public TruthValue not() { }; } - public TruthValue merge(TruthValue other) { - return switch (this) { - case TRUE -> other == UNKNOWN || other == TRUE ? TRUE : ERROR; - case FALSE -> other == UNKNOWN || other == FALSE ? FALSE : ERROR; - case UNKNOWN -> other; - case ERROR -> ERROR; - }; - } - + @Override public TruthValue join(TruthValue other) { return switch (this) { case TRUE -> other == ERROR || other == TRUE ? TRUE : UNKNOWN; @@ -73,4 +95,14 @@ public TruthValue join(TruthValue other) { case ERROR -> other; }; } + + @Override + public TruthValue meet(TruthValue other) { + return switch (this) { + case TRUE -> other == UNKNOWN || other == TRUE ? TRUE : ERROR; + case FALSE -> other == UNKNOWN || other == FALSE ? FALSE : ERROR; + case UNKNOWN -> other; + case ERROR -> ERROR; + }; + } } diff --git a/subprojects/logic/src/main/java/tools/refinery/logic/term/truthvalue/TruthValueDomain.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/truthvalue/TruthValueDomain.java new file mode 100644 index 000000000..de8a89be2 --- /dev/null +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/truthvalue/TruthValueDomain.java @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.logic.term.truthvalue; + +import tools.refinery.logic.AbstractDomain; + +// Singleton pattern, because there is only one domain for truth values. +@SuppressWarnings("squid:S6548") +public final class TruthValueDomain implements AbstractDomain { + public static final TruthValueDomain INSTANCE = new TruthValueDomain(); + + private TruthValueDomain() { + } + + @Override + public Class abstractType() { + return TruthValue.class; + } + + @Override + public Class concreteType() { + return Boolean.class; + } + + @Override + public TruthValue unknown() { + return TruthValue.UNKNOWN; + } + + @Override + public TruthValue error() { + return TruthValue.ERROR; + } + + @Override + public TruthValue toAbstract(Boolean concreteValue) { + return TruthValue.toTruthValue(concreteValue); + } +} diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/FiniteUpperCardinality.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/FiniteUpperCardinality.java similarity index 97% rename from subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/FiniteUpperCardinality.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/FiniteUpperCardinality.java index b63a86377..478d456b8 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/FiniteUpperCardinality.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/FiniteUpperCardinality.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation.cardinality; +package tools.refinery.logic.term.uppercardinality; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UnboundedUpperCardinality.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UnboundedUpperCardinality.java similarity index 96% rename from subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UnboundedUpperCardinality.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UnboundedUpperCardinality.java index 03c701aed..b6ecc1bd6 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UnboundedUpperCardinality.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UnboundedUpperCardinality.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation.cardinality; +package tools.refinery.logic.term.uppercardinality; import org.jetbrains.annotations.NotNull; diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UpperCardinalities.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalities.java similarity index 94% rename from subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UpperCardinalities.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalities.java index 17d1b2926..edf0afd29 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UpperCardinalities.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalities.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation.cardinality; +package tools.refinery.logic.term.uppercardinality; public final class UpperCardinalities { public static final UpperCardinality UNBOUNDED = UnboundedUpperCardinality.INSTANCE; diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UpperCardinality.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinality.java similarity index 93% rename from subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UpperCardinality.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinality.java index 3f0db0284..5a3dcfb9a 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/UpperCardinality.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinality.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation.cardinality; +package tools.refinery.logic.term.uppercardinality; import org.jetbrains.annotations.Nullable; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityAddTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityAddTerm.java similarity index 77% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityAddTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityAddTerm.java index 68905f51a..5c849b0ab 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityAddTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityAddTerm.java @@ -3,11 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.uppercardinality; +package tools.refinery.logic.term.uppercardinality; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.representation.cardinality.UpperCardinality; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class UpperCardinalityAddTerm extends UpperCardinalityBinaryTerm { protected UpperCardinalityAddTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityBinaryTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityBinaryTerm.java similarity index 66% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityBinaryTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityBinaryTerm.java index 0cf8fe444..976d61153 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityBinaryTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityBinaryTerm.java @@ -3,11 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.uppercardinality; +package tools.refinery.logic.term.uppercardinality; -import tools.refinery.store.query.term.BinaryTerm; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.representation.cardinality.UpperCardinality; +import tools.refinery.logic.term.BinaryTerm; +import tools.refinery.logic.term.Term; public abstract class UpperCardinalityBinaryTerm extends BinaryTerm { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityMaxTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityMaxTerm.java similarity index 77% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityMaxTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityMaxTerm.java index ff75f64e0..0a0c5ee47 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityMaxTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityMaxTerm.java @@ -3,11 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.uppercardinality; +package tools.refinery.logic.term.uppercardinality; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.representation.cardinality.UpperCardinality; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class UpperCardinalityMaxTerm extends UpperCardinalityBinaryTerm { protected UpperCardinalityMaxTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityMinTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityMinTerm.java similarity index 77% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityMinTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityMinTerm.java index 1e89e9f48..d6879595c 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityMinTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityMinTerm.java @@ -3,11 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.uppercardinality; +package tools.refinery.logic.term.uppercardinality; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.representation.cardinality.UpperCardinality; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class UpperCardinalityMinTerm extends UpperCardinalityBinaryTerm { protected UpperCardinalityMinTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityMulTerm.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityMulTerm.java similarity index 77% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityMulTerm.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityMulTerm.java index 3b4970f45..cb0d685f1 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityMulTerm.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityMulTerm.java @@ -3,11 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.uppercardinality; +package tools.refinery.logic.term.uppercardinality; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.representation.cardinality.UpperCardinality; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.Term; public class UpperCardinalityMulTerm extends UpperCardinalityBinaryTerm { protected UpperCardinalityMulTerm(Term left, Term right) { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregator.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalitySumAggregator.java similarity index 82% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregator.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalitySumAggregator.java index d31f00a2e..7c45e6ef2 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregator.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalitySumAggregator.java @@ -3,15 +3,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.uppercardinality; +package tools.refinery.logic.term.uppercardinality; -import tools.refinery.store.query.term.StatefulAggregate; -import tools.refinery.store.query.term.StatefulAggregator; -import tools.refinery.store.representation.cardinality.FiniteUpperCardinality; -import tools.refinery.store.representation.cardinality.UnboundedUpperCardinality; -import tools.refinery.store.representation.cardinality.UpperCardinalities; -import tools.refinery.store.representation.cardinality.UpperCardinality; +import tools.refinery.logic.term.StatefulAggregate; +import tools.refinery.logic.term.StatefulAggregator; +// Singleton implementation, since there is only one way to aggregate upper cardinalities. +@SuppressWarnings("squid:S6548") public class UpperCardinalitySumAggregator implements StatefulAggregator { public static final UpperCardinalitySumAggregator INSTANCE = new UpperCardinalitySumAggregator(); diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityTerms.java b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityTerms.java similarity index 84% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityTerms.java rename to subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityTerms.java index 13914f2dd..7ec61cacd 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityTerms.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityTerms.java @@ -3,15 +3,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.uppercardinality; +package tools.refinery.logic.term.uppercardinality; -import tools.refinery.store.query.term.Aggregator; -import tools.refinery.store.query.term.ConstantTerm; -import tools.refinery.store.query.term.ExtremeValueAggregator; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.query.term.comparable.*; -import tools.refinery.store.representation.cardinality.UpperCardinalities; -import tools.refinery.store.representation.cardinality.UpperCardinality; +import tools.refinery.logic.term.Aggregator; +import tools.refinery.logic.term.ConstantTerm; +import tools.refinery.logic.term.ExtremeValueAggregator; +import tools.refinery.logic.term.Term; +import tools.refinery.logic.term.comparable.*; import java.util.Comparator; diff --git a/subprojects/store/src/main/java/tools/refinery/store/util/CycleDetectingMapper.java b/subprojects/logic/src/main/java/tools/refinery/logic/util/CycleDetectingMapper.java similarity index 97% rename from subprojects/store/src/main/java/tools/refinery/store/util/CycleDetectingMapper.java rename to subprojects/logic/src/main/java/tools/refinery/logic/util/CycleDetectingMapper.java index 2e3026634..8a9efdd68 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/util/CycleDetectingMapper.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/util/CycleDetectingMapper.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.util; +package tools.refinery.logic.util; import java.util.*; import java.util.function.Function; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/valuation/MapBasedValuation.java b/subprojects/logic/src/main/java/tools/refinery/logic/valuation/MapBasedValuation.java similarity index 76% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/valuation/MapBasedValuation.java rename to subprojects/logic/src/main/java/tools/refinery/logic/valuation/MapBasedValuation.java index 261ceaa58..be1862d2d 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/valuation/MapBasedValuation.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/valuation/MapBasedValuation.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.valuation; +package tools.refinery.logic.valuation; -import tools.refinery.store.query.term.AnyDataVariable; -import tools.refinery.store.query.term.DataVariable; +import tools.refinery.logic.term.AnyDataVariable; +import tools.refinery.logic.term.DataVariable; import java.util.Map; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/valuation/RestrictedValuation.java b/subprojects/logic/src/main/java/tools/refinery/logic/valuation/RestrictedValuation.java similarity index 76% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/valuation/RestrictedValuation.java rename to subprojects/logic/src/main/java/tools/refinery/logic/valuation/RestrictedValuation.java index fc8406aa3..b6ac7cc96 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/valuation/RestrictedValuation.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/valuation/RestrictedValuation.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.valuation; +package tools.refinery.logic.valuation; -import tools.refinery.store.query.term.AnyDataVariable; -import tools.refinery.store.query.term.DataVariable; +import tools.refinery.logic.term.AnyDataVariable; +import tools.refinery.logic.term.DataVariable; import java.util.Set; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/valuation/SubstitutedValuation.java b/subprojects/logic/src/main/java/tools/refinery/logic/valuation/SubstitutedValuation.java similarity index 71% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/valuation/SubstitutedValuation.java rename to subprojects/logic/src/main/java/tools/refinery/logic/valuation/SubstitutedValuation.java index 1c14112c5..38491481d 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/valuation/SubstitutedValuation.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/valuation/SubstitutedValuation.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.valuation; +package tools.refinery.logic.valuation; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.DataVariable; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.DataVariable; public record SubstitutedValuation(Valuation originalValuation, Substitution substitution) implements Valuation { @Override diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/valuation/Valuation.java b/subprojects/logic/src/main/java/tools/refinery/logic/valuation/Valuation.java similarity index 78% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/valuation/Valuation.java rename to subprojects/logic/src/main/java/tools/refinery/logic/valuation/Valuation.java index 1588e957e..95ee887ec 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/valuation/Valuation.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/valuation/Valuation.java @@ -3,12 +3,12 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.valuation; +package tools.refinery.logic.valuation; import org.jetbrains.annotations.Nullable; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.AnyDataVariable; -import tools.refinery.store.query.term.DataVariable; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.AnyDataVariable; +import tools.refinery.logic.term.DataVariable; import java.util.Map; import java.util.Set; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/valuation/ValuationBuilder.java b/subprojects/logic/src/main/java/tools/refinery/logic/valuation/ValuationBuilder.java similarity index 86% rename from subprojects/store-query/src/main/java/tools/refinery/store/query/valuation/ValuationBuilder.java rename to subprojects/logic/src/main/java/tools/refinery/logic/valuation/ValuationBuilder.java index 7337dbc3b..46459ac72 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/valuation/ValuationBuilder.java +++ b/subprojects/logic/src/main/java/tools/refinery/logic/valuation/ValuationBuilder.java @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.valuation; +package tools.refinery.logic.valuation; -import tools.refinery.store.query.term.AnyDataVariable; -import tools.refinery.store.query.term.DataVariable; +import tools.refinery.logic.term.AnyDataVariable; +import tools.refinery.logic.term.DataVariable; import java.util.Collections; import java.util.HashMap; diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfBuilderLiteralEliminationTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/dnf/DnfBuilderLiteralEliminationTest.java similarity index 89% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfBuilderLiteralEliminationTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/dnf/DnfBuilderLiteralEliminationTest.java index 6a2dc0c76..d5a9ccadc 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfBuilderLiteralEliminationTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/dnf/DnfBuilderLiteralEliminationTest.java @@ -3,30 +3,28 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; -import tools.refinery.store.query.literal.BooleanLiteral; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.term.bool.BoolTerms; -import tools.refinery.store.query.view.KeyOnlyView; -import tools.refinery.store.query.view.SymbolView; -import tools.refinery.store.representation.Symbol; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.literal.BooleanLiteral; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.term.bool.BoolTerms; +import tools.refinery.logic.tests.FakeKeyOnlyView; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; -import static tools.refinery.store.query.literal.Literals.check; -import static tools.refinery.store.query.literal.Literals.not; -import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo; +import static tools.refinery.logic.literal.Literals.check; +import static tools.refinery.logic.literal.Literals.not; +import static tools.refinery.logic.tests.QueryMatchers.structurallyEqualTo; class DnfBuilderLiteralEliminationTest { - private final Symbol friend = Symbol.of("friend", 2); - private final SymbolView friendView = new KeyOnlyView<>(friend); + private final Constraint friendView = new FakeKeyOnlyView("friend", 2); private final NodeVariable p = Variable.of("p"); private final NodeVariable q = Variable.of("q"); private final Dnf trueDnf = Dnf.builder().parameter(p, ParameterDirection.IN).clause().build(); diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfBuilderVariableUnificationTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/dnf/DnfBuilderVariableUnificationTest.java similarity index 92% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfBuilderVariableUnificationTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/dnf/DnfBuilderVariableUnificationTest.java index fc40c7b3e..0e1f77e2e 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfBuilderVariableUnificationTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/dnf/DnfBuilderVariableUnificationTest.java @@ -3,25 +3,22 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; import org.junit.jupiter.api.Test; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.view.KeyOnlyView; -import tools.refinery.store.query.view.SymbolView; -import tools.refinery.store.representation.Symbol; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.tests.FakeKeyOnlyView; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; -import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo; +import static tools.refinery.logic.tests.QueryMatchers.structurallyEqualTo; class DnfBuilderVariableUnificationTest { - private final Symbol friend = Symbol.of("friend", 2); - private final Symbol children = Symbol.of("children", 2); - private final SymbolView friendView = new KeyOnlyView<>(friend); - private final SymbolView childrenView = new KeyOnlyView<>(children); + private final Constraint friendView = new FakeKeyOnlyView("friend", 2); + private final Constraint childrenView = new FakeKeyOnlyView("children", 2); @Test void equalToParameterTest() { diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfToDefinitionStringTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/dnf/DnfToDefinitionStringTest.java similarity index 69% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfToDefinitionStringTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/dnf/DnfToDefinitionStringTest.java index 12cfaa4e0..dd6245485 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfToDefinitionStringTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/dnf/DnfToDefinitionStringTest.java @@ -1,27 +1,24 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; import org.junit.jupiter.api.Test; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.view.AnySymbolView; -import tools.refinery.store.query.view.KeyOnlyView; -import tools.refinery.store.representation.Symbol; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.tests.FakeKeyOnlyView; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import static tools.refinery.store.query.literal.Literals.not; +import static tools.refinery.logic.literal.Literals.not; class DnfToDefinitionStringTest { - private static final Symbol person = Symbol.of("person", 1); - private static final Symbol friend = Symbol.of("friend", 2); - private static final AnySymbolView personView = new KeyOnlyView<>(person); - private static final AnySymbolView friendView = new KeyOnlyView<>(friend); + private static final Constraint personView = new FakeKeyOnlyView("person", 1); + private static final Constraint friendView = new FakeKeyOnlyView("friend", 2); private static final NodeVariable p = Variable.of("p"); private static final NodeVariable q = Variable.of("q"); @@ -61,7 +58,7 @@ void relationViewPositiveTest() { assertThat(dnf.toDefinitionString(), is(""" pred Example(p) <-> - @RelationView("key") friend(p, q). + friend(p, q). """)); } @@ -74,7 +71,7 @@ void relationViewNegativeTest() { assertThat(dnf.toDefinitionString(), is(""" pred Example(in p) <-> - !(@RelationView("key") friend(p, q)). + !(friend(p, q)). """)); } @@ -84,7 +81,7 @@ void relationViewTransitiveTest() { assertThat(dnf.toDefinitionString(), is(""" pred Example(p) <-> - @RelationView("key") friend+(p, q). + friend+(p, q). """)); } @@ -94,7 +91,7 @@ void multipleParametersTest() { assertThat(dnf.toDefinitionString(), is(""" pred Example(p, q) <-> - @RelationView("key") friend(p, q). + friend(p, q). """)); } @@ -111,9 +108,9 @@ void multipleLiteralsTest() { assertThat(dnf.toDefinitionString(), is(""" pred Example(p) <-> - @RelationView("key") person(p), - @RelationView("key") person(q), - @RelationView("key") friend(p, q). + person(p), + person(q), + friend(p, q). """)); } @@ -127,9 +124,9 @@ void multipleClausesTest() { assertThat(dnf.toDefinitionString(), is(""" pred Example(p) <-> - @RelationView("key") friend(p, q) + friend(p, q) ; - @RelationView("key") friend(q, p). + friend(q, p). """)); } @@ -149,8 +146,8 @@ void dnfTest() { assertThat(dnf.toDefinitionString(), is(""" pred Example(p) <-> - @RelationView("key") person(p), - @RelationView("key") person(q), + person(p), + person(q), !(@Dnf Called(p, q)). """)); } diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/HashCodeTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/dnf/HashCodeTest.java similarity index 76% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/HashCodeTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/dnf/HashCodeTest.java index 0c8eaeed9..e140be1eb 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/HashCodeTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/dnf/HashCodeTest.java @@ -3,24 +3,21 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; import org.junit.jupiter.api.Test; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.view.AnySymbolView; -import tools.refinery.store.query.view.KeyOnlyView; -import tools.refinery.store.representation.Symbol; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.tests.FakeKeyOnlyView; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; class HashCodeTest { - private static final Symbol person = Symbol.of("Person", 1); - private static final Symbol friend = Symbol.of("friend", 2); - private static final AnySymbolView personView = new KeyOnlyView<>(person); - private static final AnySymbolView friendView = new KeyOnlyView<>(friend); + private static final Constraint personView = new FakeKeyOnlyView("Person", 1); + private static final Constraint friendView = new FakeKeyOnlyView("friend", 2); private static final NodeVariable p = Variable.of("p"); private static final NodeVariable q = Variable.of("q"); diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/TopologicalSortTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/dnf/TopologicalSortTest.java similarity index 79% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/TopologicalSortTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/dnf/TopologicalSortTest.java index 854bd4694..8ea27cc94 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/TopologicalSortTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/dnf/TopologicalSortTest.java @@ -3,27 +3,25 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; import org.junit.jupiter.api.Test; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.view.AnySymbolView; -import tools.refinery.store.query.view.KeyOnlyView; -import tools.refinery.store.representation.Symbol; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.tests.FakeKeyOnlyView; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; -import static tools.refinery.store.query.literal.Literals.not; -import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo; +import static tools.refinery.logic.literal.Literals.not; +import static tools.refinery.logic.tests.QueryMatchers.structurallyEqualTo; class TopologicalSortTest { - private static final Symbol friend = Symbol.of("friend", 2); - private static final AnySymbolView friendView = new KeyOnlyView<>(friend); + private static final Constraint friendView = new FakeKeyOnlyView("friend", 2); private static final Dnf example = Dnf.of("example", builder -> { var a = builder.parameter("a", ParameterDirection.IN); var b = builder.parameter("b", ParameterDirection.IN); diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/VariableDirectionTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/dnf/VariableDirectionTest.java similarity index 80% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/VariableDirectionTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/dnf/VariableDirectionTest.java index fc3f5d48c..f9f39b8a6 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/VariableDirectionTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/dnf/VariableDirectionTest.java @@ -1,23 +1,22 @@ /* - * SPDX-FileCopyrightText: 2023 The Refinery Authors + * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.dnf; +package tools.refinery.logic.dnf; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import tools.refinery.store.query.literal.BooleanLiteral; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.view.AnySymbolView; -import tools.refinery.store.query.view.FunctionView; -import tools.refinery.store.query.view.KeyOnlyView; -import tools.refinery.store.representation.Symbol; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.literal.BooleanLiteral; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.tests.FakeFunctionView; +import tools.refinery.logic.tests.FakeKeyOnlyView; import java.util.ArrayList; import java.util.List; @@ -28,16 +27,13 @@ import static org.hamcrest.Matchers.not; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; -import static tools.refinery.store.query.literal.Literals.not; -import static tools.refinery.store.query.term.int_.IntTerms.INT_SUM; +import static tools.refinery.logic.literal.Literals.not; +import static tools.refinery.logic.term.int_.IntTerms.INT_SUM; class VariableDirectionTest { - private static final Symbol person = Symbol.of("Person", 1); - private static final Symbol friend = Symbol.of("friend", 2); - private static final Symbol age = Symbol.of("age", 1, Integer.class); - private static final AnySymbolView personView = new KeyOnlyView<>(person); - private static final AnySymbolView friendView = new KeyOnlyView<>(friend); - private static final FunctionView ageView = new FunctionView<>(age); + private static final Constraint personView = new FakeKeyOnlyView("Person", 1); + private static final Constraint friendView = new FakeKeyOnlyView("friend", 2); + private static final FakeFunctionView ageView = new FakeFunctionView<>("age", 1, Integer.class); private static final NodeVariable p = Variable.of("p"); private static final NodeVariable q = Variable.of("q"); private static final DataVariable x = Variable.of("x", Integer.class); @@ -57,8 +53,8 @@ void unboundInVariableTest(List clause) { var builder = Dnf.builder().parameter(p, ParameterDirection.IN).clause(clause); var dnf = assertDoesNotThrow(builder::build); var clauses = dnf.getClauses(); - if (clauses.size() > 0) { - assertThat(clauses.get(0).positiveVariables(), hasItem(p)); + if (!clauses.isEmpty()) { + assertThat(clauses.getFirst().positiveVariables(), hasItem(p)); } } @@ -70,8 +66,8 @@ void boundPrivateVariableTest(List clause) { var builder = Dnf.builder().clause(clauseWithBinding); var dnf = assertDoesNotThrow(builder::build); var clauses = dnf.getClauses(); - if (clauses.size() > 0) { - assertThat(clauses.get(0).positiveVariables(), hasItem(p)); + if (!clauses.isEmpty()) { + assertThat(clauses.getFirst().positiveVariables(), hasItem(p)); } } @@ -88,8 +84,8 @@ void unboundPrivateVariableTest(List clause) { var builder = Dnf.builder().clause(clause); var dnf = assertDoesNotThrow(builder::build); var clauses = dnf.getClauses(); - if (clauses.size() > 0) { - assertThat(clauses.get(0).positiveVariables(), not(hasItem(p))); + if (!clauses.isEmpty()) { + assertThat(clauses.getFirst().positiveVariables(), not(hasItem(p))); } } @@ -167,7 +163,7 @@ void unboundPrivateVariableTest(Literal literal) { void boundPrivateVariableInputTest(Literal literal) { var builder = Dnf.builder().clause(personView.call(p), literal); var dnf = assertDoesNotThrow(builder::build); - assertThat(dnf.getClauses().get(0).positiveVariables(), hasItem(p)); + assertThat(dnf.getClauses().getFirst().positiveVariables(), hasItem(p)); } static Stream literalsWithRequiredVariableInput() { @@ -201,7 +197,7 @@ static Stream literalsWithRequiredVariableInput() { void boundParameterTest(Literal literal) { var builder = Dnf.builder().parameter(p, ParameterDirection.OUT).clause(literal); var dnf = assertDoesNotThrow(builder::build); - assertThat(dnf.getClauses().get(0).positiveVariables(), hasItem(p)); + assertThat(dnf.getClauses().getFirst().positiveVariables(), hasItem(p)); } @ParameterizedTest @@ -209,7 +205,7 @@ void boundParameterTest(Literal literal) { void boundTwiceParameterTest(Literal literal) { var builder = Dnf.builder().parameter(p, ParameterDirection.IN).clause(literal); var dnf = assertDoesNotThrow(builder::build); - assertThat(dnf.getClauses().get(0).positiveVariables(), hasItem(p)); + assertThat(dnf.getClauses().getFirst().positiveVariables(), hasItem(p)); } @ParameterizedTest @@ -221,7 +217,7 @@ void boundPrivateVariableOutputTest(Literal literal) { .build(); var builder = Dnf.builder().clause(dnfWithInput.call(p), literal); var dnf = assertDoesNotThrow(builder::build); - assertThat(dnf.getClauses().get(0).positiveVariables(), hasItem(p)); + assertThat(dnf.getClauses().getFirst().positiveVariables(), hasItem(p)); } @ParameterizedTest @@ -229,7 +225,7 @@ void boundPrivateVariableOutputTest(Literal literal) { void boundTwicePrivateVariableOutputTest(Literal literal) { var builder = Dnf.builder().clause(personView.call(p), literal); var dnf = assertDoesNotThrow(builder::build); - assertThat(dnf.getClauses().get(0).positiveVariables(), hasItem(p)); + assertThat(dnf.getClauses().getFirst().positiveVariables(), hasItem(p)); } static Stream literalsWithVariableOutput() { diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/literal/AggregationLiteralTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/literal/AggregationLiteralTest.java similarity index 83% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/literal/AggregationLiteralTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/literal/AggregationLiteralTest.java index ddd57e969..76639e18b 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/literal/AggregationLiteralTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/literal/AggregationLiteralTest.java @@ -3,14 +3,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; import org.junit.jupiter.api.Test; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.InvalidClauseException; -import tools.refinery.store.query.term.*; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.InvalidClauseException; +import tools.refinery.logic.term.*; import java.util.List; import java.util.Set; @@ -19,9 +19,9 @@ import static org.hamcrest.Matchers.*; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertThrows; -import static tools.refinery.store.query.literal.Literals.not; -import static tools.refinery.store.query.term.int_.IntTerms.INT_SUM; -import static tools.refinery.store.query.term.int_.IntTerms.constant; +import static tools.refinery.logic.literal.Literals.not; +import static tools.refinery.logic.term.int_.IntTerms.INT_SUM; +import static tools.refinery.logic.term.int_.IntTerms.constant; class AggregationLiteralTest { private static final NodeVariable p = Variable.of("p"); diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/literal/CallLiteralTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/literal/CallLiteralTest.java similarity index 89% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/literal/CallLiteralTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/literal/CallLiteralTest.java index a01c65864..0fb2e7c9f 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/literal/CallLiteralTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/literal/CallLiteralTest.java @@ -3,14 +3,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.literal; +package tools.refinery.logic.literal; import org.junit.jupiter.api.Test; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.Parameter; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.Parameter; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; import java.util.List; import java.util.Set; @@ -19,7 +19,7 @@ import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; import static org.junit.jupiter.api.Assertions.assertAll; -import static tools.refinery.store.query.literal.Literals.not; +import static tools.refinery.logic.literal.Literals.not; class CallLiteralTest { private static final NodeVariable p = Variable.of("p"); diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/DuplicateDnfRemoverTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/rewriter/DuplicateDnfRemoverTest.java similarity index 85% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/DuplicateDnfRemoverTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/rewriter/DuplicateDnfRemoverTest.java index ebb24ab52..7b2ce8b29 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/DuplicateDnfRemoverTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/rewriter/DuplicateDnfRemoverTest.java @@ -3,28 +3,26 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.rewriter; +package tools.refinery.logic.rewriter; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.literal.AbstractCallLiteral; -import tools.refinery.store.query.literal.Reduction; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.view.AnySymbolView; -import tools.refinery.store.query.view.KeyOnlyView; -import tools.refinery.store.representation.Symbol; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.literal.AbstractCallLiteral; +import tools.refinery.logic.literal.Reduction; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.tests.FakeKeyOnlyView; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; -import static tools.refinery.store.query.literal.Literals.not; +import static tools.refinery.logic.literal.Literals.not; class DuplicateDnfRemoverTest { - private final static Symbol friend = Symbol.of("friend", 2); - private final static AnySymbolView friendView = new KeyOnlyView<>(friend); + private final static Constraint friendView = new FakeKeyOnlyView("friend", 2); private DuplicateDnfRemover sut; @@ -116,8 +114,8 @@ void notDuplicateRecursiveTest() { assertThat(one, is(oneResult)); assertThat(oneResult, is(not(twoResult))); - var oneCall = (AbstractCallLiteral) oneResult.getDnf().getClauses().get(0).literals().get(0); - var twoCall = (AbstractCallLiteral) twoResult.getDnf().getClauses().get(0).literals().get(0); + var oneCall = (AbstractCallLiteral) oneResult.getDnf().getClauses().getFirst().literals().getFirst(); + var twoCall = (AbstractCallLiteral) twoResult.getDnf().getClauses().getFirst().literals().getFirst(); assertThat(oneCall.getTarget(), is(twoCall.getTarget())); } diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/InputParameterResolverTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/rewriter/InputParameterResolverTest.java similarity index 87% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/InputParameterResolverTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/rewriter/InputParameterResolverTest.java index ef0077e42..5e5fdb647 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/InputParameterResolverTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/rewriter/InputParameterResolverTest.java @@ -3,30 +3,27 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.rewriter; +package tools.refinery.logic.rewriter; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.view.AnySymbolView; -import tools.refinery.store.query.view.KeyOnlyView; -import tools.refinery.store.representation.Symbol; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.tests.FakeKeyOnlyView; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import static tools.refinery.store.query.literal.Literals.not; -import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo; +import static tools.refinery.logic.literal.Literals.not; +import static tools.refinery.logic.tests.QueryMatchers.structurallyEqualTo; class InputParameterResolverTest { - private final static Symbol person = Symbol.of("Person", 1); - private final static Symbol friend = Symbol.of("friend", 2); - private final static AnySymbolView personView = new KeyOnlyView<>(person); - private final static AnySymbolView friendView = new KeyOnlyView<>(friend); + private final static Constraint personView = new FakeKeyOnlyView("Person", 1); + private final static Constraint friendView = new FakeKeyOnlyView("friend", 2); private InputParameterResolver sut; diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/TermSubstitutionTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/term/TermSubstitutionTest.java similarity index 87% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/term/TermSubstitutionTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/term/TermSubstitutionTest.java index 1fae2492c..52b216927 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/TermSubstitutionTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/term/TermSubstitutionTest.java @@ -3,20 +3,20 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term; +package tools.refinery.logic.term; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import tools.refinery.store.query.equality.DnfEqualityChecker; -import tools.refinery.store.query.equality.SubstitutingLiteralEqualityHelper; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.bool.BoolTerms; -import tools.refinery.store.query.term.int_.IntTerms; -import tools.refinery.store.query.term.real.RealTerms; -import tools.refinery.store.query.term.uppercardinality.UpperCardinalityTerms; -import tools.refinery.store.representation.cardinality.UpperCardinality; +import tools.refinery.logic.equality.DnfEqualityChecker; +import tools.refinery.logic.equality.SubstitutingLiteralEqualityHelper; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.bool.BoolTerms; +import tools.refinery.logic.term.int_.IntTerms; +import tools.refinery.logic.term.real.RealTerms; +import tools.refinery.logic.term.uppercardinality.UpperCardinality; +import tools.refinery.logic.term.uppercardinality.UpperCardinalityTerms; import java.util.List; import java.util.stream.Stream; diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/bool/BoolTermsEvaluateTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/term/bool/BoolTermsEvaluateTest.java similarity index 94% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/term/bool/BoolTermsEvaluateTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/term/bool/BoolTermsEvaluateTest.java index beff705ee..7f65591f0 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/bool/BoolTermsEvaluateTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/term/bool/BoolTermsEvaluateTest.java @@ -3,11 +3,12 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.bool; +package tools.refinery.logic.term.bool; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; -import tools.refinery.store.query.valuation.Valuation; +import tools.refinery.logic.term.bool.BoolTerms; +import tools.refinery.logic.valuation.Valuation; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; diff --git a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/CardinalityIntervalTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/term/cardinalityinterval/CardinalityIntervalTest.java similarity index 95% rename from subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/CardinalityIntervalTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/term/cardinalityinterval/CardinalityIntervalTest.java index 6a66fa84b..ee2dd61c3 100644 --- a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/CardinalityIntervalTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/term/cardinalityinterval/CardinalityIntervalTest.java @@ -3,18 +3,17 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation.cardinality; +package tools.refinery.logic.term.cardinalityinterval; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import tools.refinery.store.representation.cardinality.CardinalityInterval; import java.util.stream.Stream; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static tools.refinery.store.representation.cardinality.CardinalityIntervals.*; +import static tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals.*; class CardinalityIntervalTest { @ParameterizedTest(name = "min({0}, {1}) == {2}") diff --git a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/CardinalityIntervalsTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/term/cardinalityinterval/CardinalityIntervalsTest.java similarity index 60% rename from subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/CardinalityIntervalsTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/term/cardinalityinterval/CardinalityIntervalsTest.java index 9fe761597..d68df3352 100644 --- a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/CardinalityIntervalsTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/term/cardinalityinterval/CardinalityIntervalsTest.java @@ -3,26 +3,25 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation.cardinality; +package tools.refinery.logic.term.cardinalityinterval; import org.junit.jupiter.api.Test; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; -import tools.refinery.store.representation.cardinality.UpperCardinalities; +import tools.refinery.logic.term.uppercardinality.UpperCardinalities; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.equalTo; class CardinalityIntervalsTest { @Test void betweenEmptyTest() { var interval = CardinalityIntervals.between(2, 1); - assertThat(interval.isEmpty(), equalTo(true)); + assertThat(interval.isError(), equalTo(true)); } @Test void betweenNegativeUpperBoundTest() { var interval = CardinalityIntervals.between(0, -1); assertThat(interval.upperBound(), equalTo(UpperCardinalities.UNBOUNDED)); - assertThat(interval.isEmpty(), equalTo(false)); + assertThat(interval.isError(), equalTo(false)); } } diff --git a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/EmptyCardinalityIntervalTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/term/cardinalityinterval/EmptyCardinalityIntervalTest.java similarity index 77% rename from subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/EmptyCardinalityIntervalTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/term/cardinalityinterval/EmptyCardinalityIntervalTest.java index 24a788a86..0dbc7f61d 100644 --- a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/EmptyCardinalityIntervalTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/term/cardinalityinterval/EmptyCardinalityIntervalTest.java @@ -3,10 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation.cardinality; +package tools.refinery.logic.term.cardinalityinterval; import org.junit.jupiter.api.Test; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.lessThan; diff --git a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/FiniteCardinalityIntervalTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/term/cardinalityinterval/FiniteCardinalityIntervalTest.java similarity index 69% rename from subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/FiniteCardinalityIntervalTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/term/cardinalityinterval/FiniteCardinalityIntervalTest.java index 6cf56fae4..588b25ab0 100644 --- a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/FiniteCardinalityIntervalTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/term/cardinalityinterval/FiniteCardinalityIntervalTest.java @@ -3,12 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation.cardinality; +package tools.refinery.logic.term.cardinalityinterval; import org.junit.jupiter.api.Test; -import tools.refinery.store.representation.cardinality.NonEmptyCardinalityInterval; -import tools.refinery.store.representation.cardinality.UpperCardinalities; -import tools.refinery.store.representation.cardinality.UpperCardinality; +import tools.refinery.logic.term.uppercardinality.UpperCardinality; +import tools.refinery.logic.term.uppercardinality.UpperCardinalities; import static org.junit.jupiter.api.Assertions.assertThrows; diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/int_/IntTermsEvaluateTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/term/int_/IntTermsEvaluateTest.java similarity index 97% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/term/int_/IntTermsEvaluateTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/term/int_/IntTermsEvaluateTest.java index abe50d754..55d9b7404 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/int_/IntTermsEvaluateTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/term/int_/IntTermsEvaluateTest.java @@ -3,14 +3,15 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.int_; +package tools.refinery.logic.term.int_; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.MethodSource; -import tools.refinery.store.query.term.real.RealTerms; -import tools.refinery.store.query.valuation.Valuation; +import tools.refinery.logic.term.int_.IntTerms; +import tools.refinery.logic.term.real.RealTerms; +import tools.refinery.logic.valuation.Valuation; import java.util.stream.Stream; diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/real/RealTermEvaluateTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/term/real/RealTermEvaluateTest.java similarity index 97% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/term/real/RealTermEvaluateTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/term/real/RealTermEvaluateTest.java index 6a8eebf1e..042d1807a 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/real/RealTermEvaluateTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/term/real/RealTermEvaluateTest.java @@ -3,13 +3,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.real; +package tools.refinery.logic.term.real; import org.hamcrest.Matcher; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; -import tools.refinery.store.query.term.int_.IntTerms; -import tools.refinery.store.query.valuation.Valuation; +import tools.refinery.logic.term.int_.IntTerms; +import tools.refinery.logic.term.real.RealTerms; +import tools.refinery.logic.valuation.Valuation; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; diff --git a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/FiniteUpperCardinalityTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/FiniteUpperCardinalityTest.java similarity index 74% rename from subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/FiniteUpperCardinalityTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/FiniteUpperCardinalityTest.java index 7c641c471..8a57f0294 100644 --- a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/FiniteUpperCardinalityTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/FiniteUpperCardinalityTest.java @@ -3,10 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation.cardinality; +package tools.refinery.logic.term.uppercardinality; import org.junit.jupiter.api.Test; -import tools.refinery.store.representation.cardinality.FiniteUpperCardinality; import static org.junit.jupiter.api.Assertions.assertThrows; diff --git a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/UpperCardinalitiesTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/UpperCardinalitiesTest.java similarity index 94% rename from subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/UpperCardinalitiesTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/UpperCardinalitiesTest.java index e403eec2b..bdb6a8332 100644 --- a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/UpperCardinalitiesTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/UpperCardinalitiesTest.java @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation.cardinality; +package tools.refinery.logic.term.uppercardinality; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregatorStreamTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/UpperCardinalitySumAggregatorStreamTest.java similarity index 83% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregatorStreamTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/UpperCardinalitySumAggregatorStreamTest.java index 31baf36e9..fc8522d40 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregatorStreamTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/UpperCardinalitySumAggregatorStreamTest.java @@ -3,26 +3,24 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.uppercardinality; +package tools.refinery.logic.term.uppercardinality; +import org.hamcrest.Matchers; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import tools.refinery.store.representation.cardinality.UpperCardinalities; -import tools.refinery.store.representation.cardinality.UpperCardinality; import java.util.List; import java.util.stream.Stream; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; class UpperCardinalitySumAggregatorStreamTest { @ParameterizedTest @MethodSource void testStream(List list, UpperCardinality expected) { var result = UpperCardinalitySumAggregator.INSTANCE.aggregateStream(list.stream()); - assertThat(result, is(expected)); + assertThat(result, Matchers.is(expected)); } static Stream testStream() { diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregatorTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/UpperCardinalitySumAggregatorTest.java similarity index 64% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregatorTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/UpperCardinalitySumAggregatorTest.java index 780cd0abe..e252b0975 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregatorTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/UpperCardinalitySumAggregatorTest.java @@ -3,16 +3,15 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.uppercardinality; +package tools.refinery.logic.term.uppercardinality; +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import tools.refinery.store.query.term.StatefulAggregate; -import tools.refinery.store.representation.cardinality.UpperCardinalities; -import tools.refinery.store.representation.cardinality.UpperCardinality; +import tools.refinery.logic.term.StatefulAggregate; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; class UpperCardinalitySumAggregatorTest { private StatefulAggregate accumulator; @@ -24,33 +23,33 @@ void beforeEach() { @Test void emptyAggregationTest() { - assertThat(accumulator.getResult(), is(UpperCardinality.of(0))); + MatcherAssert.assertThat(accumulator.getResult(), Matchers.is(UpperCardinality.of(0))); } @Test void singleBoundedTest() { accumulator.add(UpperCardinality.of(3)); - assertThat(accumulator.getResult(), is(UpperCardinality.of(3))); + MatcherAssert.assertThat(accumulator.getResult(), Matchers.is(UpperCardinality.of(3))); } @Test void multipleBoundedTest() { accumulator.add(UpperCardinality.of(2)); accumulator.add(UpperCardinality.of(3)); - assertThat(accumulator.getResult(), is(UpperCardinality.of(5))); + MatcherAssert.assertThat(accumulator.getResult(), Matchers.is(UpperCardinality.of(5))); } @Test void singleUnboundedTest() { accumulator.add(UpperCardinalities.UNBOUNDED); - assertThat(accumulator.getResult(), is(UpperCardinalities.UNBOUNDED)); + assertThat(accumulator.getResult(), Matchers.is(UpperCardinalities.UNBOUNDED)); } @Test void multipleUnboundedTest() { accumulator.add(UpperCardinalities.UNBOUNDED); accumulator.add(UpperCardinalities.UNBOUNDED); - assertThat(accumulator.getResult(), is(UpperCardinalities.UNBOUNDED)); + assertThat(accumulator.getResult(), Matchers.is(UpperCardinalities.UNBOUNDED)); } @Test @@ -58,7 +57,7 @@ void removeBoundedTest() { accumulator.add(UpperCardinality.of(2)); accumulator.add(UpperCardinality.of(3)); accumulator.remove(UpperCardinality.of(2)); - assertThat(accumulator.getResult(), is(UpperCardinality.of(3))); + MatcherAssert.assertThat(accumulator.getResult(), Matchers.is(UpperCardinality.of(3))); } @Test @@ -66,7 +65,7 @@ void removeAllUnboundedTest() { accumulator.add(UpperCardinalities.UNBOUNDED); accumulator.add(UpperCardinality.of(3)); accumulator.remove(UpperCardinalities.UNBOUNDED); - assertThat(accumulator.getResult(), is(UpperCardinality.of(3))); + MatcherAssert.assertThat(accumulator.getResult(), Matchers.is(UpperCardinality.of(3))); } @Test @@ -75,6 +74,6 @@ void removeSomeUnboundedTest() { accumulator.add(UpperCardinalities.UNBOUNDED); accumulator.add(UpperCardinality.of(3)); accumulator.remove(UpperCardinalities.UNBOUNDED); - assertThat(accumulator.getResult(), is(UpperCardinalities.UNBOUNDED)); + assertThat(accumulator.getResult(), Matchers.is(UpperCardinalities.UNBOUNDED)); } } diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityTermsEvaluateTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityTermsEvaluateTest.java similarity index 89% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityTermsEvaluateTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityTermsEvaluateTest.java index 9d0f3bde6..ab71b7162 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityTermsEvaluateTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityTermsEvaluateTest.java @@ -3,14 +3,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.term.uppercardinality; +package tools.refinery.logic.term.uppercardinality; +import org.hamcrest.Matchers; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import tools.refinery.store.query.valuation.Valuation; -import tools.refinery.store.representation.cardinality.UpperCardinalities; -import tools.refinery.store.representation.cardinality.UpperCardinality; +import tools.refinery.logic.valuation.Valuation; import java.util.stream.Stream; @@ -23,7 +22,7 @@ class UpperCardinalityTermsEvaluateTest { void minTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) { var term = UpperCardinalityTerms.min(UpperCardinalityTerms.constant(a), UpperCardinalityTerms.constant(b)); assertThat(term.getType(), is(UpperCardinality.class)); - assertThat(term.evaluate(Valuation.empty()), is(expected)); + assertThat(term.evaluate(Valuation.empty()), Matchers.is(expected)); } static Stream minTest() { @@ -45,7 +44,7 @@ static Stream minTest() { void maxTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) { var term = UpperCardinalityTerms.max(UpperCardinalityTerms.constant(a), UpperCardinalityTerms.constant(b)); assertThat(term.getType(), is(UpperCardinality.class)); - assertThat(term.evaluate(Valuation.empty()), is(expected)); + assertThat(term.evaluate(Valuation.empty()), Matchers.is(expected)); } static Stream maxTest() { @@ -67,7 +66,7 @@ static Stream maxTest() { void addTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) { var term = UpperCardinalityTerms.add(UpperCardinalityTerms.constant(a), UpperCardinalityTerms.constant(b)); assertThat(term.getType(), is(UpperCardinality.class)); - assertThat(term.evaluate(Valuation.empty()), is(expected)); + assertThat(term.evaluate(Valuation.empty()), Matchers.is(expected)); } static Stream addTest() { @@ -87,7 +86,7 @@ static Stream addTest() { void mulTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) { var term = UpperCardinalityTerms.mul(UpperCardinalityTerms.constant(a), UpperCardinalityTerms.constant(b)); assertThat(term.getType(), is(UpperCardinality.class)); - assertThat(term.evaluate(Valuation.empty()), is(expected)); + assertThat(term.evaluate(Valuation.empty()), Matchers.is(expected)); } static Stream mulTest() { diff --git a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/UpperCardinalityTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityTest.java similarity index 95% rename from subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/UpperCardinalityTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityTest.java index 10b4dd20b..70cb6695d 100644 --- a/subprojects/store/src/test/java/tools/refinery/store/representation/cardinality/UpperCardinalityTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/term/uppercardinality/UpperCardinalityTest.java @@ -3,13 +3,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.representation.cardinality; +package tools.refinery.logic.term.uppercardinality; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import tools.refinery.store.representation.cardinality.UpperCardinalities; -import tools.refinery.store.representation.cardinality.UpperCardinality; import java.util.stream.Stream; diff --git a/subprojects/logic/src/test/java/tools/refinery/logic/tests/FakeFunctionView.java b/subprojects/logic/src/test/java/tools/refinery/logic/tests/FakeFunctionView.java new file mode 100644 index 000000000..4a55f5614 --- /dev/null +++ b/subprojects/logic/src/test/java/tools/refinery/logic/tests/FakeFunctionView.java @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.logic.tests; + +import tools.refinery.logic.Constraint; +import tools.refinery.logic.term.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public record FakeFunctionView(String name, int keyArity, Class valueType) implements Constraint { + @Override + public int arity() { + return keyArity + 1; + } + + @Override + public List getParameters() { + var parameters = new Parameter[keyArity + 1]; + Arrays.fill(parameters, Parameter.NODE_OUT); + parameters[keyArity] = new Parameter(valueType, ParameterDirection.OUT); + return List.of(parameters); + } + + public AssignedValue aggregate(Aggregator aggregator, List arguments) { + return targetVariable -> { + var placeholderVariable = Variable.of(valueType); + var argumentsWithPlaceholder = new ArrayList(arguments.size() + 1); + argumentsWithPlaceholder.addAll(arguments); + argumentsWithPlaceholder.add(placeholderVariable); + return aggregateBy(placeholderVariable, aggregator, argumentsWithPlaceholder).toLiteral(targetVariable); + }; + } + + public AssignedValue aggregate(Aggregator aggregator, NodeVariable... arguments) { + return aggregate(aggregator, List.of(arguments)); + } + + public AssignedValue leftJoin(T defaultValue, List arguments) { + return targetVariable -> { + var placeholderVariable = Variable.of(valueType); + var argumentsWithPlaceholder = new ArrayList(arguments.size() + 1); + argumentsWithPlaceholder.addAll(arguments); + argumentsWithPlaceholder.add(placeholderVariable); + return leftJoinBy(placeholderVariable, defaultValue, argumentsWithPlaceholder).toLiteral(targetVariable); + }; + } + + public AssignedValue leftJoin(T defaultValue, NodeVariable... arguments) { + return leftJoin(defaultValue, List.of(arguments)); + + } +} diff --git a/subprojects/logic/src/test/java/tools/refinery/logic/tests/FakeKeyOnlyView.java b/subprojects/logic/src/test/java/tools/refinery/logic/tests/FakeKeyOnlyView.java new file mode 100644 index 000000000..7e09ddab3 --- /dev/null +++ b/subprojects/logic/src/test/java/tools/refinery/logic/tests/FakeKeyOnlyView.java @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.logic.tests; + +import tools.refinery.logic.Constraint; +import tools.refinery.logic.term.Parameter; + +import java.util.Arrays; +import java.util.List; + +public record FakeKeyOnlyView(String name, int arity) implements Constraint { + @Override + public List getParameters() { + var parameters = new Parameter[arity]; + Arrays.fill(parameters, Parameter.NODE_OUT); + return List.of(parameters); + } +} diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToRawTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/tests/StructurallyEqualToRawTest.java similarity index 82% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToRawTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/tests/StructurallyEqualToRawTest.java index d447e99c0..52a22ce1a 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToRawTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/tests/StructurallyEqualToRawTest.java @@ -3,17 +3,15 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.tests; +package tools.refinery.logic.tests; import org.junit.jupiter.api.Test; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.SymbolicParameter; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.view.AnySymbolView; -import tools.refinery.store.query.view.KeyOnlyView; -import tools.refinery.store.representation.Symbol; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.SymbolicParameter; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; import java.util.List; @@ -21,13 +19,11 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.junit.jupiter.api.Assertions.assertThrows; -import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo; +import static tools.refinery.logic.tests.QueryMatchers.structurallyEqualTo; class StructurallyEqualToRawTest { - private static final Symbol person = Symbol.of("Person", 1); - private static final Symbol friend = Symbol.of("friend", 2); - private static final AnySymbolView personView = new KeyOnlyView<>(person); - private static final AnySymbolView friendView = new KeyOnlyView<>(friend); + private static final Constraint personView = new FakeKeyOnlyView("Person", 1); + private static final Constraint friendView = new FakeKeyOnlyView("friend", 2); private static final NodeVariable p = Variable.of("p"); private static final NodeVariable q = Variable.of("q"); diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToTest.java b/subprojects/logic/src/test/java/tools/refinery/logic/tests/StructurallyEqualToTest.java similarity index 82% rename from subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToTest.java rename to subprojects/logic/src/test/java/tools/refinery/logic/tests/StructurallyEqualToTest.java index f716b805b..663b115ae 100644 --- a/subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToTest.java +++ b/subprojects/logic/src/test/java/tools/refinery/logic/tests/StructurallyEqualToTest.java @@ -3,27 +3,23 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.tests; +package tools.refinery.logic.tests; import org.junit.jupiter.api.Test; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.view.AnySymbolView; -import tools.refinery.store.query.view.KeyOnlyView; -import tools.refinery.store.representation.Symbol; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; -import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo; +import static tools.refinery.logic.tests.QueryMatchers.structurallyEqualTo; class StructurallyEqualToTest { - private static final Symbol person = Symbol.of("Person", 1); - private static final Symbol friend = Symbol.of("friend", 2); - private static final AnySymbolView personView = new KeyOnlyView<>(person); - private static final AnySymbolView friendView = new KeyOnlyView<>(friend); + private static final Constraint personView = new FakeKeyOnlyView("Person", 1); + private static final Constraint friendView = new FakeKeyOnlyView("friend", 2); private static final NodeVariable p = Variable.of("p"); private static final NodeVariable q = Variable.of("q"); diff --git a/subprojects/store-query/src/testFixtures/java/tools/refinery/store/query/tests/MismatchDescribingDnfEqualityChecker.java b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/MismatchDescribingDnfEqualityChecker.java similarity index 87% rename from subprojects/store-query/src/testFixtures/java/tools/refinery/store/query/tests/MismatchDescribingDnfEqualityChecker.java rename to subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/MismatchDescribingDnfEqualityChecker.java index 6a3301b30..aa73baec4 100644 --- a/subprojects/store-query/src/testFixtures/java/tools/refinery/store/query/tests/MismatchDescribingDnfEqualityChecker.java +++ b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/MismatchDescribingDnfEqualityChecker.java @@ -3,13 +3,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.tests; +package tools.refinery.logic.tests; import org.hamcrest.Description; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.SymbolicParameter; -import tools.refinery.store.query.equality.DeepDnfEqualityChecker; -import tools.refinery.store.query.literal.Literal; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.SymbolicParameter; +import tools.refinery.logic.equality.DeepDnfEqualityChecker; +import tools.refinery.logic.literal.Literal; import java.util.List; diff --git a/subprojects/store-query/src/testFixtures/java/tools/refinery/store/query/tests/QueryMatchers.java b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/QueryMatchers.java similarity index 89% rename from subprojects/store-query/src/testFixtures/java/tools/refinery/store/query/tests/QueryMatchers.java rename to subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/QueryMatchers.java index cd449a6a0..40332a8c5 100644 --- a/subprojects/store-query/src/testFixtures/java/tools/refinery/store/query/tests/QueryMatchers.java +++ b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/QueryMatchers.java @@ -3,12 +3,12 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.tests; +package tools.refinery.logic.tests; import org.hamcrest.Matcher; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.SymbolicParameter; -import tools.refinery.store.query.literal.Literal; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.SymbolicParameter; +import tools.refinery.logic.literal.Literal; import java.util.List; diff --git a/subprojects/store-query/src/testFixtures/java/tools/refinery/store/query/tests/StructurallyEqualTo.java b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/StructurallyEqualTo.java similarity index 88% rename from subprojects/store-query/src/testFixtures/java/tools/refinery/store/query/tests/StructurallyEqualTo.java rename to subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/StructurallyEqualTo.java index 861491410..257e68508 100644 --- a/subprojects/store-query/src/testFixtures/java/tools/refinery/store/query/tests/StructurallyEqualTo.java +++ b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/StructurallyEqualTo.java @@ -3,12 +3,12 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.tests; +package tools.refinery.logic.tests; import org.hamcrest.Description; import org.hamcrest.TypeSafeMatcher; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.equality.DeepDnfEqualityChecker; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.equality.DeepDnfEqualityChecker; public class StructurallyEqualTo extends TypeSafeMatcher { private final Dnf expected; diff --git a/subprojects/store-query/src/testFixtures/java/tools/refinery/store/query/tests/StructurallyEqualToRaw.java b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/StructurallyEqualToRaw.java similarity index 86% rename from subprojects/store-query/src/testFixtures/java/tools/refinery/store/query/tests/StructurallyEqualToRaw.java rename to subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/StructurallyEqualToRaw.java index 2f8c29444..944ab1acf 100644 --- a/subprojects/store-query/src/testFixtures/java/tools/refinery/store/query/tests/StructurallyEqualToRaw.java +++ b/subprojects/logic/src/testFixtures/java/tools/refinery/logic/tests/StructurallyEqualToRaw.java @@ -3,14 +3,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package tools.refinery.store.query.tests; +package tools.refinery.logic.tests; import org.hamcrest.Description; import org.hamcrest.TypeSafeMatcher; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.SymbolicParameter; -import tools.refinery.store.query.equality.DeepDnfEqualityChecker; -import tools.refinery.store.query.literal.Literal; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.SymbolicParameter; +import tools.refinery.logic.equality.DeepDnfEqualityChecker; +import tools.refinery.logic.literal.Literal; import java.util.List; diff --git a/subprojects/store-dse-visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java b/subprojects/store-dse-visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java index ef10dd302..5d0a32929 100644 --- a/subprojects/store-dse-visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java +++ b/subprojects/store-dse-visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java @@ -11,7 +11,7 @@ import tools.refinery.store.model.Interpretation; import tools.refinery.store.model.Model; import tools.refinery.store.representation.AnySymbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; import tools.refinery.visualization.ModelVisualizerAdapter; import tools.refinery.visualization.ModelVisualizerStoreAdapter; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/CreateActionLiteral.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/CreateActionLiteral.java index 5b86a5e1e..a6c583819 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/CreateActionLiteral.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/CreateActionLiteral.java @@ -9,7 +9,7 @@ import tools.refinery.store.dse.transition.actions.AbstractActionLiteral; import tools.refinery.store.dse.transition.actions.BoundActionLiteral; import tools.refinery.store.model.Model; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; import java.util.List; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/DeleteActionLiteral.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/DeleteActionLiteral.java index 18ad2b9d3..e13e9c11d 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/DeleteActionLiteral.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/DeleteActionLiteral.java @@ -10,7 +10,7 @@ import tools.refinery.store.dse.transition.actions.AbstractActionLiteral; import tools.refinery.store.dse.transition.actions.BoundActionLiteral; import tools.refinery.store.model.Model; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; import tools.refinery.store.tuple.Tuple; import java.util.List; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/ModificationActionLiterals.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/ModificationActionLiterals.java index 31f50ac76..4de482f0d 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/ModificationActionLiterals.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/ModificationActionLiterals.java @@ -6,7 +6,7 @@ package tools.refinery.store.dse.modification.actions; import tools.refinery.store.dse.modification.DanglingEdges; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; public class ModificationActionLiterals { private ModificationActionLiterals() { diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/Rule.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/Rule.java index ff45ed3e6..14a9c5563 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/Rule.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/Rule.java @@ -9,7 +9,7 @@ import tools.refinery.store.dse.transition.actions.BoundAction; import tools.refinery.store.dse.transition.callback.*; import tools.refinery.store.model.Model; -import tools.refinery.store.query.dnf.RelationalQuery; +import tools.refinery.logic.dnf.RelationalQuery; public class Rule { private final String name; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/RuleBuilder.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/RuleBuilder.java index 865ac369e..c2e43e0d4 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/RuleBuilder.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/RuleBuilder.java @@ -8,9 +8,9 @@ import tools.refinery.store.dse.transition.actions.Action; import tools.refinery.store.dse.transition.actions.ActionLiteral; import tools.refinery.store.dse.transition.callback.*; -import tools.refinery.store.query.dnf.AbstractQueryBuilder; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.dnf.AbstractQueryBuilder; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.term.Variable; import java.util.List; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/Action.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/Action.java index d63ddfdd1..0ce0c3a4f 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/Action.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/Action.java @@ -9,9 +9,9 @@ import org.eclipse.collections.api.map.primitive.MutableObjectIntMap; import org.jetbrains.annotations.Nullable; import tools.refinery.store.model.Model; -import tools.refinery.store.query.dnf.RelationalQuery; -import tools.refinery.store.query.dnf.SymbolicParameter; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.dnf.RelationalQuery; +import tools.refinery.logic.dnf.SymbolicParameter; +import tools.refinery.logic.term.NodeVariable; import java.util.*; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiteral.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiteral.java index a721ef739..86b4e3cd4 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiteral.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiteral.java @@ -6,7 +6,7 @@ package tools.refinery.store.dse.transition.actions; import tools.refinery.store.model.Model; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; import java.util.List; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiterals.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiterals.java index 275e1e256..d06e24794 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiterals.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiterals.java @@ -5,7 +5,7 @@ */ package tools.refinery.store.dse.transition.actions; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; import tools.refinery.store.representation.Symbol; import java.util.List; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/PutActionLiteral.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/PutActionLiteral.java index 862889214..6657b157e 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/PutActionLiteral.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/PutActionLiteral.java @@ -6,7 +6,7 @@ package tools.refinery.store.dse.transition.actions; import tools.refinery.store.model.Model; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; import tools.refinery.store.representation.Symbol; import tools.refinery.store.tuple.Tuple; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback1.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback1.java index 869f1a967..7e1dd5b7a 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback1.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback1.java @@ -6,7 +6,7 @@ package tools.refinery.store.dse.transition.callback; import tools.refinery.store.dse.transition.actions.ActionLiteral; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; import java.util.List; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback2.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback2.java index a648fc932..1361482db 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback2.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback2.java @@ -6,7 +6,7 @@ package tools.refinery.store.dse.transition.callback; import tools.refinery.store.dse.transition.actions.ActionLiteral; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; import java.util.List; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback3.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback3.java index a9b1d334e..870ba0886 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback3.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback3.java @@ -6,7 +6,7 @@ package tools.refinery.store.dse.transition.callback; import tools.refinery.store.dse.transition.actions.ActionLiteral; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; import java.util.List; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback4.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback4.java index aef1351cb..46c056efe 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback4.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback4.java @@ -6,7 +6,7 @@ package tools.refinery.store.dse.transition.callback; import tools.refinery.store.dse.transition.actions.ActionLiteral; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; import java.util.List; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback1.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback1.java index bd7bf4f55..603500aea 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback1.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback1.java @@ -6,7 +6,7 @@ package tools.refinery.store.dse.transition.callback; import tools.refinery.store.dse.transition.RuleBuilder; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; @FunctionalInterface public interface RuleCallback1 { diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback2.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback2.java index 7b02b68a6..88d3e43c2 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback2.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback2.java @@ -6,7 +6,7 @@ package tools.refinery.store.dse.transition.callback; import tools.refinery.store.dse.transition.RuleBuilder; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; @FunctionalInterface public interface RuleCallback2 { diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback3.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback3.java index 6f112d48a..d4d35e193 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback3.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback3.java @@ -6,7 +6,7 @@ package tools.refinery.store.dse.transition.callback; import tools.refinery.store.dse.transition.RuleBuilder; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; @FunctionalInterface public interface RuleCallback3 { diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback4.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback4.java index dbcf8567f..67690169d 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback4.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback4.java @@ -6,7 +6,7 @@ package tools.refinery.store.dse.transition.callback; import tools.refinery.store.dse.transition.RuleBuilder; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; @FunctionalInterface public interface RuleCallback4 { diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/AndCriterion.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/AndCriterion.java index 0ad2b7a44..2a02ff140 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/AndCriterion.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/AndCriterion.java @@ -5,9 +5,9 @@ */ package tools.refinery.store.dse.transition.objectives; +import tools.refinery.logic.literal.Reduction; import tools.refinery.store.model.Model; import tools.refinery.store.model.ModelStore; -import tools.refinery.store.query.literal.Reduction; import java.util.ArrayList; import java.util.Collection; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CompositeCriterion.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CompositeCriterion.java index 5746cc7e3..1f2defab7 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CompositeCriterion.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CompositeCriterion.java @@ -5,11 +5,11 @@ */ package tools.refinery.store.dse.transition.objectives; -import tools.refinery.store.model.ModelStore; import tools.refinery.store.model.ModelStoreBuilder; -import tools.refinery.store.query.literal.Reduction; -import java.util.*; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; public abstract sealed class CompositeCriterion implements Criterion permits AndCriterion, OrCriterion { private final List criteria; @@ -31,9 +31,6 @@ public List getCriteria() { return criteria; } - @Override - public abstract Reduction getReduction(ModelStore store); - @Override public void configure(ModelStoreBuilder storeBuilder) { for (var criterion : criteria) { diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CountObjective.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CountObjective.java index fbd05ded0..f9fe14599 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CountObjective.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CountObjective.java @@ -5,14 +5,14 @@ */ package tools.refinery.store.dse.transition.objectives; +import tools.refinery.logic.dnf.RelationalQuery; +import tools.refinery.logic.literal.Reduction; import tools.refinery.store.model.Model; import tools.refinery.store.model.ModelStore; import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.query.ModelQueryAdapter; import tools.refinery.store.query.ModelQueryBuilder; import tools.refinery.store.query.ModelQueryStoreAdapter; -import tools.refinery.store.query.dnf.RelationalQuery; -import tools.refinery.store.query.literal.Reduction; public class CountObjective implements Objective { private final RelationalQuery query; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criteria.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criteria.java index 0e4ec5c9e..7d4c97ada 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criteria.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criteria.java @@ -5,7 +5,7 @@ */ package tools.refinery.store.dse.transition.objectives; -import tools.refinery.store.query.dnf.AnyQuery; +import tools.refinery.logic.dnf.AnyQuery; import java.util.Collection; import java.util.List; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criterion.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criterion.java index c827f20ef..da6b21025 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criterion.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criterion.java @@ -5,10 +5,10 @@ */ package tools.refinery.store.dse.transition.objectives; +import tools.refinery.logic.literal.Reduction; import tools.refinery.store.model.Model; import tools.refinery.store.model.ModelStore; import tools.refinery.store.model.ModelStoreBuilder; -import tools.refinery.store.query.literal.Reduction; public interface Criterion { default void configure(ModelStoreBuilder storeBuilder) { diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Objectives.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Objectives.java index e552d14c5..d2364c6ad 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Objectives.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Objectives.java @@ -5,8 +5,8 @@ */ package tools.refinery.store.dse.transition.objectives; -import tools.refinery.store.query.dnf.FunctionalQuery; -import tools.refinery.store.query.dnf.RelationalQuery; +import tools.refinery.logic.dnf.FunctionalQuery; +import tools.refinery.logic.dnf.RelationalQuery; import java.util.Collection; import java.util.List; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/OrCriterion.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/OrCriterion.java index 7a8d77784..4f7fcb267 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/OrCriterion.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/OrCriterion.java @@ -5,9 +5,9 @@ */ package tools.refinery.store.dse.transition.objectives; +import tools.refinery.logic.literal.Reduction; import tools.refinery.store.model.Model; import tools.refinery.store.model.ModelStore; -import tools.refinery.store.query.literal.Reduction; import java.util.ArrayList; import java.util.Collection; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryCriterion.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryCriterion.java index e15e4e417..82dd87123 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryCriterion.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryCriterion.java @@ -5,14 +5,14 @@ */ package tools.refinery.store.dse.transition.objectives; +import tools.refinery.logic.dnf.AnyQuery; +import tools.refinery.logic.literal.Reduction; import tools.refinery.store.model.Model; import tools.refinery.store.model.ModelStore; import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.query.ModelQueryAdapter; import tools.refinery.store.query.ModelQueryBuilder; import tools.refinery.store.query.ModelQueryStoreAdapter; -import tools.refinery.store.query.dnf.AnyQuery; -import tools.refinery.store.query.literal.Reduction; public class QueryCriterion implements Criterion { protected final boolean satisfiedIfHasMatch; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryObjective.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryObjective.java index 5a7ba8f4d..1fa6327e1 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryObjective.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryObjective.java @@ -9,7 +9,7 @@ import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.query.ModelQueryAdapter; import tools.refinery.store.query.ModelQueryBuilder; -import tools.refinery.store.query.dnf.FunctionalQuery; +import tools.refinery.logic.dnf.FunctionalQuery; public class QueryObjective implements Objective { protected final FunctionalQuery objectiveFunction; diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java index fa0b3c73b..7502f3501 100644 --- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java +++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java @@ -18,9 +18,9 @@ import tools.refinery.store.dse.transition.objectives.Objectives; import tools.refinery.store.model.ModelStore; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.dnf.RelationalQuery; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.dnf.RelationalQuery; +import tools.refinery.logic.term.Variable; import tools.refinery.store.query.interpreter.QueryInterpreterAdapter; import tools.refinery.store.query.view.AnySymbolView; import tools.refinery.store.query.view.KeyOnlyView; @@ -36,7 +36,7 @@ import static tools.refinery.store.dse.modification.actions.ModificationActionLiterals.delete; import static tools.refinery.store.dse.transition.actions.ActionLiterals.add; import static tools.refinery.store.dse.transition.actions.ActionLiterals.remove; -import static tools.refinery.store.query.literal.Literals.not; +import static tools.refinery.logic.literal.Literals.not; class CRAExamplesTest { private static final Symbol name = Symbol.of("Name", 1, String.class); diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/TransitionTests.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/TransitionTests.java index a79547ecf..eb0ca8f97 100644 --- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/TransitionTests.java +++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/TransitionTests.java @@ -6,17 +6,17 @@ package tools.refinery.store.dse.transition; import org.junit.jupiter.api.Test; +import tools.refinery.logic.dnf.FunctionalQuery; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.dnf.RelationalQuery; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.term.int_.IntTerms; import tools.refinery.store.dse.modification.ModificationAdapter; import tools.refinery.store.dse.transition.objectives.Criteria; import tools.refinery.store.dse.transition.objectives.Objectives; import tools.refinery.store.model.Model; import tools.refinery.store.model.ModelStore; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.FunctionalQuery; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.dnf.RelationalQuery; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.term.int_.IntTerms; import tools.refinery.store.query.interpreter.QueryInterpreterAdapter; import tools.refinery.store.query.view.AnySymbolView; import tools.refinery.store.query.view.KeyOnlyView; @@ -27,8 +27,8 @@ import java.util.List; import static org.junit.jupiter.api.Assertions.*; -import static tools.refinery.store.query.literal.Literals.check; -import static tools.refinery.store.query.literal.Literals.not; +import static tools.refinery.logic.literal.Literals.check; +import static tools.refinery.logic.literal.Literals.not; class TransitionBuildTests { Symbol person = new Symbol<>("Person", 1, Boolean.class, false); diff --git a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/QueryInterpreterBuilder.java b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/QueryInterpreterBuilder.java index 6e167d0d0..010164e2d 100644 --- a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/QueryInterpreterBuilder.java +++ b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/QueryInterpreterBuilder.java @@ -7,9 +7,9 @@ import tools.refinery.store.model.ModelStore; import tools.refinery.store.query.ModelQueryBuilder; -import tools.refinery.store.query.dnf.AnyQuery; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.rewriter.DnfRewriter; +import tools.refinery.logic.dnf.AnyQuery; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.rewriter.DnfRewriter; import tools.refinery.interpreter.api.InterpreterEngineOptions; import tools.refinery.interpreter.matchers.backend.IQueryBackendFactory; import tools.refinery.interpreter.matchers.backend.QueryEvaluationHint; diff --git a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/QueryInterpreterAdapterImpl.java b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/QueryInterpreterAdapterImpl.java index ee527fd35..c54232233 100644 --- a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/QueryInterpreterAdapterImpl.java +++ b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/QueryInterpreterAdapterImpl.java @@ -7,10 +7,10 @@ import tools.refinery.store.model.Model; import tools.refinery.store.model.ModelListener; -import tools.refinery.store.query.dnf.AnyQuery; -import tools.refinery.store.query.dnf.FunctionalQuery; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.dnf.RelationalQuery; +import tools.refinery.logic.dnf.AnyQuery; +import tools.refinery.logic.dnf.FunctionalQuery; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.dnf.RelationalQuery; import tools.refinery.store.query.resultset.AnyResultSet; import tools.refinery.store.query.resultset.EmptyResultSet; import tools.refinery.store.query.resultset.ResultSet; diff --git a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/QueryInterpreterBuilderImpl.java b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/QueryInterpreterBuilderImpl.java index 4e839b434..1791e6263 100644 --- a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/QueryInterpreterBuilderImpl.java +++ b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/QueryInterpreterBuilderImpl.java @@ -9,12 +9,12 @@ import tools.refinery.interpreter.rete.recipes.RecipesPackage; import tools.refinery.store.adapter.AbstractModelAdapterBuilder; import tools.refinery.store.model.ModelStore; -import tools.refinery.store.query.dnf.AnyQuery; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.rewriter.CompositeRewriter; -import tools.refinery.store.query.rewriter.DnfRewriter; -import tools.refinery.store.query.rewriter.DuplicateDnfRemover; -import tools.refinery.store.query.rewriter.InputParameterResolver; +import tools.refinery.logic.dnf.AnyQuery; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.rewriter.CompositeRewriter; +import tools.refinery.logic.rewriter.DnfRewriter; +import tools.refinery.logic.rewriter.DuplicateDnfRemover; +import tools.refinery.logic.rewriter.InputParameterResolver; import tools.refinery.store.query.interpreter.QueryInterpreterBuilder; import tools.refinery.store.query.interpreter.internal.localsearch.FlatCostFunction; import tools.refinery.store.query.interpreter.internal.matcher.RawPatternMatcher; diff --git a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/QueryInterpreterStoreAdapterImpl.java b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/QueryInterpreterStoreAdapterImpl.java index 10e7a4023..d1ec3e3e4 100644 --- a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/QueryInterpreterStoreAdapterImpl.java +++ b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/QueryInterpreterStoreAdapterImpl.java @@ -11,8 +11,8 @@ import tools.refinery.interpreter.matchers.context.IInputKey; import tools.refinery.store.model.Model; import tools.refinery.store.model.ModelStore; -import tools.refinery.store.query.dnf.AnyQuery; -import tools.refinery.store.query.dnf.Query; +import tools.refinery.logic.dnf.AnyQuery; +import tools.refinery.logic.dnf.Query; import tools.refinery.store.query.interpreter.QueryInterpreterStoreAdapter; import tools.refinery.store.query.interpreter.internal.matcher.RawPatternMatcher; import tools.refinery.store.query.view.AnySymbolView; diff --git a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/context/RelationalQueryMetaContext.java b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/context/RelationalQueryMetaContext.java index 2b1ff2b45..117e81bac 100644 --- a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/context/RelationalQueryMetaContext.java +++ b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/context/RelationalQueryMetaContext.java @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ @@ -48,7 +48,7 @@ public Collection getImplications(IInputKey implyingKey) { } var symbolView = checkKey(implyingKey); var relationViewImplications = symbolView.getImpliedRelationViews(); - var inputKeyImplications = new HashSet(relationViewImplications.size()); + var inputKeyImplications = HashSet.newHashSet(relationViewImplications.size()); for (var relationViewImplication : relationViewImplications) { if (!symbolView.equals(relationViewImplication.implyingView())) { throw new IllegalArgumentException("Relation view %s returned unrelated implication %s".formatted( @@ -82,7 +82,7 @@ public Map, Set> getFunctionalDependencies(IInputKey key) } var relationView = checkKey(key); var functionalDependencies = relationView.getFunctionalDependencies(); - var flattened = new HashMap, Set>(functionalDependencies.size()); + var flattened = HashMap., Set>newHashMap(functionalDependencies.size()); for (var functionalDependency : functionalDependencies) { var forEach = functionalDependency.forEach(); checkValidIndices(relationView, forEach); diff --git a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/matcher/AbstractInterpretedMatcher.java b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/matcher/AbstractInterpretedMatcher.java index 8cec0bf62..8e6a74ed3 100644 --- a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/matcher/AbstractInterpretedMatcher.java +++ b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/matcher/AbstractInterpretedMatcher.java @@ -7,7 +7,7 @@ import tools.refinery.interpreter.matchers.backend.IQueryResultProvider; import tools.refinery.interpreter.matchers.backend.IUpdateable; -import tools.refinery.store.query.dnf.Query; +import tools.refinery.logic.dnf.Query; import tools.refinery.store.query.resultset.AbstractResultSet; import tools.refinery.store.query.interpreter.internal.QueryInterpreterAdapterImpl; diff --git a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/matcher/InterpretedFunctionalMatcher.java b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/matcher/InterpretedFunctionalMatcher.java index 249664a4f..bf7074877 100644 --- a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/matcher/InterpretedFunctionalMatcher.java +++ b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/matcher/InterpretedFunctionalMatcher.java @@ -11,7 +11,7 @@ import tools.refinery.interpreter.rete.index.IterableIndexer; import tools.refinery.interpreter.rete.matcher.RetePatternMatcher; import tools.refinery.store.map.Cursor; -import tools.refinery.store.query.dnf.FunctionalQuery; +import tools.refinery.logic.dnf.FunctionalQuery; import tools.refinery.store.query.interpreter.internal.QueryInterpreterAdapterImpl; import tools.refinery.store.tuple.Tuple; diff --git a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/matcher/InterpretedRelationalMatcher.java b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/matcher/InterpretedRelationalMatcher.java index 9278b46d6..9d9c30428 100644 --- a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/matcher/InterpretedRelationalMatcher.java +++ b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/matcher/InterpretedRelationalMatcher.java @@ -12,7 +12,7 @@ import tools.refinery.interpreter.rete.matcher.RetePatternMatcher; import tools.refinery.store.map.Cursor; import tools.refinery.store.map.Cursors; -import tools.refinery.store.query.dnf.RelationalQuery; +import tools.refinery.logic.dnf.RelationalQuery; import tools.refinery.store.query.interpreter.internal.QueryInterpreterAdapterImpl; import tools.refinery.store.tuple.Tuple; diff --git a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/CheckEvaluator.java b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/CheckEvaluator.java index 4a71e879e..8cfc22264 100644 --- a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/CheckEvaluator.java +++ b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/CheckEvaluator.java @@ -6,7 +6,7 @@ package tools.refinery.store.query.interpreter.internal.pquery; import tools.refinery.interpreter.matchers.psystem.IValueProvider; -import tools.refinery.store.query.term.Term; +import tools.refinery.logic.term.Term; class CheckEvaluator extends TermEvaluator { public CheckEvaluator(Term term) { diff --git a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/Dnf2PQuery.java b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/Dnf2PQuery.java index 24205cf42..0ffaa6b2a 100644 --- a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/Dnf2PQuery.java +++ b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/Dnf2PQuery.java @@ -1,25 +1,10 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.query.interpreter.internal.pquery; -import tools.refinery.interpreter.matchers.psystem.annotations.ParameterReference; -import tools.refinery.interpreter.matchers.psystem.basicdeferred.*; -import tools.refinery.interpreter.matchers.psystem.basicenumerables.*; -import tools.refinery.interpreter.matchers.psystem.basicenumerables.Connectivity; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.DnfClause; -import tools.refinery.store.query.dnf.SymbolicParameter; -import tools.refinery.store.query.literal.*; -import tools.refinery.store.query.term.ConstantTerm; -import tools.refinery.store.query.term.StatefulAggregator; -import tools.refinery.store.query.term.StatelessAggregator; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.view.AnySymbolView; -import tools.refinery.store.util.CycleDetectingMapper; import tools.refinery.interpreter.matchers.backend.IQueryBackendFactory; import tools.refinery.interpreter.matchers.backend.QueryEvaluationHint; import tools.refinery.interpreter.matchers.context.IInputKey; @@ -28,11 +13,27 @@ import tools.refinery.interpreter.matchers.psystem.aggregations.BoundAggregator; import tools.refinery.interpreter.matchers.psystem.aggregations.IMultisetAggregationOperator; import tools.refinery.interpreter.matchers.psystem.annotations.PAnnotation; +import tools.refinery.interpreter.matchers.psystem.annotations.ParameterReference; +import tools.refinery.interpreter.matchers.psystem.basicdeferred.*; +import tools.refinery.interpreter.matchers.psystem.basicenumerables.Connectivity; +import tools.refinery.interpreter.matchers.psystem.basicenumerables.*; import tools.refinery.interpreter.matchers.psystem.queries.PParameter; import tools.refinery.interpreter.matchers.psystem.queries.PParameterDirection; import tools.refinery.interpreter.matchers.psystem.queries.PQuery; import tools.refinery.interpreter.matchers.tuple.Tuple; import tools.refinery.interpreter.matchers.tuple.Tuples; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.DnfClause; +import tools.refinery.logic.dnf.FunctionalDependency; +import tools.refinery.logic.dnf.SymbolicParameter; +import tools.refinery.logic.literal.*; +import tools.refinery.logic.term.ConstantTerm; +import tools.refinery.logic.term.StatefulAggregator; +import tools.refinery.logic.term.StatelessAggregator; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.util.CycleDetectingMapper; +import tools.refinery.store.query.view.AnySymbolView; import java.util.ArrayList; import java.util.HashMap; @@ -79,15 +80,7 @@ private RawPQuery doTranslate(Dnf dnfQuery) { pQuery.setParameters(parameterList); for (var functionalDependency : dnfQuery.getFunctionalDependencies()) { - var functionalDependencyAnnotation = new PAnnotation("FunctionalDependency"); - for (var forEachVariable : functionalDependency.forEach()) { - var reference = new ParameterReference(forEachVariable.getUniqueName()); - functionalDependencyAnnotation.addAttribute("forEach", reference); - } - for (var uniqueVariable : functionalDependency.unique()) { - var reference = new ParameterReference(uniqueVariable.getUniqueName()); - functionalDependencyAnnotation.addAttribute("unique", reference); - } + var functionalDependencyAnnotation = getFunctionalDependencyAnnotation(functionalDependency); pQuery.addAnnotation(functionalDependencyAnnotation); } @@ -108,26 +101,33 @@ private RawPQuery doTranslate(Dnf dnfQuery) { return pQuery; } - private void translateLiteral(Literal literal, PBody body) { - if (literal instanceof EquivalenceLiteral equivalenceLiteral) { - translateEquivalenceLiteral(equivalenceLiteral, body); - } else if (literal instanceof CallLiteral callLiteral) { - translateCallLiteral(callLiteral, body); - } else if (literal instanceof ConstantLiteral constantLiteral) { - translateConstantLiteral(constantLiteral, body); - } else if (literal instanceof AssignLiteral assignLiteral) { - translateAssignLiteral(assignLiteral, body); - } else if (literal instanceof CheckLiteral checkLiteral) { - translateCheckLiteral(checkLiteral, body); - } else if (literal instanceof CountLiteral countLiteral) { - translateCountLiteral(countLiteral, body); - } else if (literal instanceof AggregationLiteral aggregationLiteral) { - translateAggregationLiteral(aggregationLiteral, body); - } else if (literal instanceof RepresentativeElectionLiteral representativeElectionLiteral) { - translateRepresentativeElectionLiteral(representativeElectionLiteral, body); - } else { - throw new IllegalArgumentException("Unknown literal: " + literal.toString()); + private static PAnnotation getFunctionalDependencyAnnotation(FunctionalDependency functionalDependency) { + var functionalDependencyAnnotation = new PAnnotation("FunctionalDependency"); + for (var forEachVariable : functionalDependency.forEach()) { + var reference = new ParameterReference(forEachVariable.getUniqueName()); + functionalDependencyAnnotation.addAttribute("forEach", reference); } + for (var uniqueVariable : functionalDependency.unique()) { + var reference = new ParameterReference(uniqueVariable.getUniqueName()); + functionalDependencyAnnotation.addAttribute("unique", reference); + } + return functionalDependencyAnnotation; + } + + private void translateLiteral(Literal literal, PBody body) { + switch (literal) { + case EquivalenceLiteral equivalenceLiteral -> translateEquivalenceLiteral(equivalenceLiteral, body); + case CallLiteral callLiteral -> translateCallLiteral(callLiteral, body); + case ConstantLiteral constantLiteral -> translateConstantLiteral(constantLiteral, body); + case AssignLiteral assignLiteral -> translateAssignLiteral(assignLiteral, body); + case CheckLiteral checkLiteral -> translateCheckLiteral(checkLiteral, body); + case CountLiteral countLiteral -> translateCountLiteral(countLiteral, body); + case AggregationLiteral aggregationLiteral -> translateAggregationLiteral(aggregationLiteral, body); + case LeftJoinLiteral leftJoinLiteral -> translateLeftJoinLiteral(leftJoinLiteral, body); + case RepresentativeElectionLiteral representativeElectionLiteral -> + translateRepresentativeElectionLiteral(representativeElectionLiteral, body); + case null, default -> throw new IllegalArgumentException("Unknown literal: " + literal); + } } private void translateEquivalenceLiteral(EquivalenceLiteral equivalenceLiteral, PBody body) { @@ -244,6 +244,21 @@ private void translateAggregationLiteral(AggregationLiteral aggrega aggregatedColumn); } + private void translateLeftJoinLiteral(LeftJoinLiteral leftJoinLiteral, PBody body) { + var wrappedCall = wrapperFactory.maybeWrapConstraint(leftJoinLiteral); + var substitution = translateSubstitution(wrappedCall.remappedArguments(), body); + var placeholderVariable = body.getOrCreateVariableByName( + leftJoinLiteral.getPlaceholderVariable().getUniqueName()); + var optionalColumn = substitution.invertIndex().get(placeholderVariable); + if (optionalColumn == null) { + throw new IllegalStateException("Placeholder variable %s not found in substitution %s" + .formatted(placeholderVariable, substitution)); + } + var resultVariable = body.getOrCreateVariableByName(leftJoinLiteral.getResultVariable().getUniqueName()); + new LeftJoinConstraint(body, substitution, wrappedCall.pattern(), resultVariable, optionalColumn, + leftJoinLiteral.getDefaultValue()); + } + private void translateRepresentativeElectionLiteral(RepresentativeElectionLiteral literal, PBody body) { var substitution = translateSubstitution(literal.getArguments(), body); var pattern = wrapConstraintWithIdentityArguments(literal.getTarget()); diff --git a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/QueryWrapperFactory.java b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/QueryWrapperFactory.java index a710dab35..f855f1f05 100644 --- a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/QueryWrapperFactory.java +++ b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/QueryWrapperFactory.java @@ -16,15 +16,15 @@ import tools.refinery.interpreter.matchers.psystem.queries.PVisibility; import tools.refinery.interpreter.matchers.tuple.Tuple; import tools.refinery.interpreter.matchers.tuple.Tuples; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.DnfUtils; -import tools.refinery.store.query.literal.AbstractCallLiteral; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.DnfUtils; +import tools.refinery.logic.literal.AbstractCallLiteral; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; import tools.refinery.store.query.view.AnySymbolView; import tools.refinery.store.query.view.SymbolView; -import tools.refinery.store.util.CycleDetectingMapper; +import tools.refinery.logic.util.CycleDetectingMapper; import java.util.*; import java.util.function.ToIntFunction; diff --git a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/StatefulMultisetAggregator.java b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/StatefulMultisetAggregator.java index 7552117b5..936b35132 100644 --- a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/StatefulMultisetAggregator.java +++ b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/StatefulMultisetAggregator.java @@ -6,8 +6,8 @@ package tools.refinery.store.query.interpreter.internal.pquery; import tools.refinery.interpreter.matchers.psystem.aggregations.IMultisetAggregationOperator; -import tools.refinery.store.query.term.StatefulAggregate; -import tools.refinery.store.query.term.StatefulAggregator; +import tools.refinery.logic.term.StatefulAggregate; +import tools.refinery.logic.term.StatefulAggregator; import java.util.stream.Stream; diff --git a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/StatelessMultisetAggregator.java b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/StatelessMultisetAggregator.java index 2da7ba87a..01432a5b3 100644 --- a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/StatelessMultisetAggregator.java +++ b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/StatelessMultisetAggregator.java @@ -6,7 +6,7 @@ package tools.refinery.store.query.interpreter.internal.pquery; import tools.refinery.interpreter.matchers.psystem.aggregations.IMultisetAggregationOperator; -import tools.refinery.store.query.term.StatelessAggregator; +import tools.refinery.logic.term.StatelessAggregator; import java.util.stream.Stream; diff --git a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/TermEvaluator.java b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/TermEvaluator.java index ed9910911..8da9ece7d 100644 --- a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/TermEvaluator.java +++ b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/TermEvaluator.java @@ -5,8 +5,8 @@ */ package tools.refinery.store.query.interpreter.internal.pquery; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.term.Term; +import tools.refinery.logic.term.Variable; import tools.refinery.interpreter.matchers.psystem.IExpressionEvaluator; import tools.refinery.interpreter.matchers.psystem.IValueProvider; diff --git a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/ValueProviderBasedValuation.java b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/ValueProviderBasedValuation.java index 4124c9bbc..a69c8bd25 100644 --- a/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/ValueProviderBasedValuation.java +++ b/subprojects/store-query-interpreter/src/main/java/tools/refinery/store/query/interpreter/internal/pquery/ValueProviderBasedValuation.java @@ -6,8 +6,8 @@ package tools.refinery.store.query.interpreter.internal.pquery; import tools.refinery.interpreter.matchers.psystem.IValueProvider; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.valuation.Valuation; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.valuation.Valuation; public record ValueProviderBasedValuation(IValueProvider valueProvider) implements Valuation { @Override diff --git a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/AggregatorBatchingTest.java b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/AggregatorBatchingTest.java index d8e06d820..209d7ac01 100644 --- a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/AggregatorBatchingTest.java +++ b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/AggregatorBatchingTest.java @@ -9,10 +9,10 @@ import tools.refinery.store.model.Model; import tools.refinery.store.model.ModelStore; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.term.StatefulAggregate; -import tools.refinery.store.query.term.StatefulAggregator; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.term.StatefulAggregate; +import tools.refinery.logic.term.StatefulAggregator; +import tools.refinery.logic.term.Variable; import tools.refinery.store.query.view.AnySymbolView; import tools.refinery.store.query.view.FunctionView; import tools.refinery.store.query.view.KeyOnlyView; diff --git a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/DiagonalQueryTest.java b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/DiagonalQueryTest.java index 76de86797..eba7173b9 100644 --- a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/DiagonalQueryTest.java +++ b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/DiagonalQueryTest.java @@ -8,8 +8,8 @@ import tools.refinery.interpreter.matchers.backend.QueryEvaluationHint; import tools.refinery.store.model.ModelStore; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.Query; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.Query; import tools.refinery.store.query.interpreter.tests.QueryEngineTest; import tools.refinery.store.query.view.AnySymbolView; import tools.refinery.store.query.view.FunctionView; @@ -21,8 +21,8 @@ import java.util.Map; import java.util.Optional; -import static tools.refinery.store.query.literal.Literals.not; -import static tools.refinery.store.query.term.int_.IntTerms.INT_SUM; +import static tools.refinery.logic.literal.Literals.not; +import static tools.refinery.logic.term.int_.IntTerms.INT_SUM; import static tools.refinery.store.query.interpreter.tests.QueryAssertions.assertNullableResults; import static tools.refinery.store.query.interpreter.tests.QueryAssertions.assertResults; diff --git a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/FunctionalQueryTest.java b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/FunctionalQueryTest.java index b6c96676d..c845e5ff7 100644 --- a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/FunctionalQueryTest.java +++ b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/FunctionalQueryTest.java @@ -9,15 +9,15 @@ import tools.refinery.store.map.Cursor; import tools.refinery.store.model.ModelStore; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.term.Variable; import tools.refinery.store.query.interpreter.tests.QueryEngineTest; import tools.refinery.store.query.view.AnySymbolView; import tools.refinery.store.query.view.FilteredView; import tools.refinery.store.query.view.FunctionView; import tools.refinery.store.query.view.KeyOnlyView; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; import java.util.List; @@ -29,8 +29,8 @@ import static org.hamcrest.Matchers.nullValue; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertThrows; -import static tools.refinery.store.query.literal.Literals.check; -import static tools.refinery.store.query.term.int_.IntTerms.*; +import static tools.refinery.logic.literal.Literals.check; +import static tools.refinery.logic.term.int_.IntTerms.*; import static tools.refinery.store.query.interpreter.tests.QueryAssertions.assertNullableResults; import static tools.refinery.store.query.interpreter.tests.QueryAssertions.assertResults; @@ -553,7 +553,6 @@ void multipleFunctionalQueriesTest(QueryEvaluationHint hint) { friendInterpretation.put(Tuple.of(1, 0), TruthValue.TRUE); friendInterpretation.put(Tuple.of(1, 2), TruthValue.TRUE); - queryEngine.flushChanges(); queryEngine.flushChanges(); assertNullableResults(Map.of( Tuple.of(0), Optional.of(25), diff --git a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/LeftJoinTest.java b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/LeftJoinTest.java new file mode 100644 index 000000000..6633b3b19 --- /dev/null +++ b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/LeftJoinTest.java @@ -0,0 +1,129 @@ +/* + * SPDX-FileCopyrightText: 2024 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.store.query.interpreter; + +import org.junit.jupiter.api.Test; +import tools.refinery.store.model.ModelStore; +import tools.refinery.store.query.ModelQueryAdapter; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.term.int_.IntTerms; +import tools.refinery.store.query.view.AnySymbolView; +import tools.refinery.store.query.view.FunctionView; +import tools.refinery.store.query.view.KeyOnlyView; +import tools.refinery.store.representation.Symbol; +import tools.refinery.store.tuple.Tuple; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static tools.refinery.store.query.interpreter.tests.QueryAssertions.assertNullableResults; +import static tools.refinery.store.query.interpreter.tests.QueryAssertions.assertResults; + +class LeftJoinTest { + private static final Symbol person = Symbol.of("Person", 1); + private static final Symbol age = Symbol.of("age", 1, Integer.class); + private static final AnySymbolView personView = new KeyOnlyView<>(person); + private static final FunctionView ageView = new FunctionView<>(age); + + @Test + void unarySymbolTest() { + var query = Query.of("Query", Integer.class, (builder, p1, output) -> builder + .clause( + personView.call(p1), + output.assign(ageView.leftJoin(18, p1)) + )); + + var store = ModelStore.builder() + .symbols(person, age) + .with(QueryInterpreterAdapter.builder() + .queries(query)) + .build(); + + var model = store.createEmptyModel(); + var personInterpretation = model.getInterpretation(person); + var ageInterpretation = model.getInterpretation(age); + var queryEngine = model.getAdapter(ModelQueryAdapter.class); + var queryResultSet = queryEngine.getResultSet(query); + + personInterpretation.put(Tuple.of(0), true); + personInterpretation.put(Tuple.of(1), true); + personInterpretation.put(Tuple.of(2), true); + + ageInterpretation.put(Tuple.of(2), 24); + + queryEngine.flushChanges(); + assertNullableResults(Map.of( + Tuple.of(0), Optional.of(18), + Tuple.of(1), Optional.of(18), + Tuple.of(2), Optional.of(24), + Tuple.of(3), Optional.empty() + ), queryResultSet); + + personInterpretation.put(Tuple.of(0), false); + + ageInterpretation.put(Tuple.of(1), 20); + ageInterpretation.put(Tuple.of(2), null); + + queryEngine.flushChanges(); + assertNullableResults(Map.of( + Tuple.of(0), Optional.empty(), + Tuple.of(1), Optional.of(20), + Tuple.of(2), Optional.of(18), + Tuple.of(3), Optional.empty() + ), queryResultSet); + } + + @Test + void unarySymbolWithAssignmentTest() { + // Tests an edge case where the outer joined variable is already bound in the query plan. + var query = Query.of("Query", (builder, p1) -> builder + .clause(Integer.class, v1 -> List.of( + personView.call(p1), + v1.assign(IntTerms.constant(18)), + v1.assign(ageView.leftJoin(18, p1)) + ))); + + var store = ModelStore.builder() + .symbols(person, age) + .with(QueryInterpreterAdapter.builder() + .queries(query)) + .build(); + + var model = store.createEmptyModel(); + var personInterpretation = model.getInterpretation(person); + var ageInterpretation = model.getInterpretation(age); + var queryEngine = model.getAdapter(ModelQueryAdapter.class); + var queryResultSet = queryEngine.getResultSet(query); + + personInterpretation.put(Tuple.of(0), true); + personInterpretation.put(Tuple.of(1), true); + personInterpretation.put(Tuple.of(2), true); + + ageInterpretation.put(Tuple.of(2), 24); + + queryEngine.flushChanges(); + assertResults(Map.of( + Tuple.of(0), true, + Tuple.of(1), true, + Tuple.of(2), false, + Tuple.of(3), false + ), queryResultSet); + + personInterpretation.put(Tuple.of(0), false); + + ageInterpretation.put(Tuple.of(1), 20); + ageInterpretation.put(Tuple.of(2), null); + + queryEngine.flushChanges(); + assertResults(Map.of( + Tuple.of(0), false, + Tuple.of(1), false, + Tuple.of(2), true, + Tuple.of(3), false + ), queryResultSet); + } +} diff --git a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/OrderedResultSetTest.java b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/OrderedResultSetTest.java index 96d0f3021..cc3ddc106 100644 --- a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/OrderedResultSetTest.java +++ b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/OrderedResultSetTest.java @@ -8,9 +8,9 @@ import org.junit.jupiter.api.Test; import tools.refinery.store.model.ModelStore; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.Query; +import tools.refinery.logic.dnf.Query; import tools.refinery.store.query.resultset.OrderedResultSet; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.term.Variable; import tools.refinery.store.query.view.AnySymbolView; import tools.refinery.store.query.view.KeyOnlyView; import tools.refinery.store.representation.Symbol; diff --git a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/QueryTest.java b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/QueryTest.java index 72728dcd2..59f431479 100644 --- a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/QueryTest.java +++ b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/QueryTest.java @@ -9,26 +9,26 @@ import org.junit.jupiter.api.Test; import tools.refinery.store.model.ModelStore; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; import tools.refinery.store.query.interpreter.tests.QueryEngineTest; import tools.refinery.store.query.view.AnySymbolView; import tools.refinery.store.query.view.FilteredView; import tools.refinery.store.query.view.FunctionView; import tools.refinery.store.query.view.KeyOnlyView; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; import java.util.List; import java.util.Map; -import static tools.refinery.store.query.literal.Literals.check; -import static tools.refinery.store.query.literal.Literals.not; -import static tools.refinery.store.query.term.int_.IntTerms.constant; -import static tools.refinery.store.query.term.int_.IntTerms.greaterEq; +import static tools.refinery.logic.literal.Literals.check; +import static tools.refinery.logic.literal.Literals.not; +import static tools.refinery.logic.term.int_.IntTerms.constant; +import static tools.refinery.logic.term.int_.IntTerms.greaterEq; import static tools.refinery.store.query.interpreter.tests.QueryAssertions.assertResults; class QueryTest { diff --git a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/QueryTransactionTest.java b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/QueryTransactionTest.java index 1cd05d91e..eb1ed68aa 100644 --- a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/QueryTransactionTest.java +++ b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/QueryTransactionTest.java @@ -9,8 +9,8 @@ import org.junit.jupiter.api.Test; import tools.refinery.store.model.ModelStore; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.dnf.RelationalQuery; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.dnf.RelationalQuery; import tools.refinery.store.query.view.AnySymbolView; import tools.refinery.store.query.view.FilteredView; import tools.refinery.store.query.view.FunctionView; diff --git a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/StronglyConnectedComponentsTest.java b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/StronglyConnectedComponentsTest.java index edbd9affc..f8b12d193 100644 --- a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/StronglyConnectedComponentsTest.java +++ b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/StronglyConnectedComponentsTest.java @@ -6,11 +6,11 @@ package tools.refinery.store.query.interpreter; import org.junit.jupiter.api.Test; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.literal.Connectivity; +import tools.refinery.logic.literal.RepresentativeElectionLiteral; import tools.refinery.store.model.ModelStore; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.literal.Connectivity; -import tools.refinery.store.query.literal.RepresentativeElectionLiteral; import tools.refinery.store.query.view.AnySymbolView; import tools.refinery.store.query.view.KeyOnlyView; import tools.refinery.store.representation.Symbol; diff --git a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/WeaklyConnectedComponentsTest.java b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/WeaklyConnectedComponentsTest.java index 3fc854800..95b37f096 100644 --- a/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/WeaklyConnectedComponentsTest.java +++ b/subprojects/store-query-interpreter/src/test/java/tools/refinery/store/query/interpreter/WeaklyConnectedComponentsTest.java @@ -6,11 +6,11 @@ package tools.refinery.store.query.interpreter; import org.junit.jupiter.api.Test; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.literal.Connectivity; +import tools.refinery.logic.literal.RepresentativeElectionLiteral; import tools.refinery.store.model.ModelStore; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.literal.Connectivity; -import tools.refinery.store.query.literal.RepresentativeElectionLiteral; import tools.refinery.store.query.view.AnySymbolView; import tools.refinery.store.query.view.KeyOnlyView; import tools.refinery.store.representation.Symbol; diff --git a/subprojects/store-query/build.gradle.kts b/subprojects/store-query/build.gradle.kts index 4d8e2605b..f5cbdebc4 100644 --- a/subprojects/store-query/build.gradle.kts +++ b/subprojects/store-query/build.gradle.kts @@ -6,10 +6,9 @@ plugins { id("tools.refinery.gradle.java-library") - id("tools.refinery.gradle.java-test-fixtures") } dependencies { + api(project(":refinery-logic")) api(project(":refinery-store")) - testFixturesApi(libs.hamcrest) } diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryAdapter.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryAdapter.java index 1fa96a079..513825b7e 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryAdapter.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryAdapter.java @@ -6,8 +6,8 @@ package tools.refinery.store.query; import tools.refinery.store.adapter.ModelAdapter; -import tools.refinery.store.query.dnf.AnyQuery; -import tools.refinery.store.query.dnf.Query; +import tools.refinery.logic.dnf.AnyQuery; +import tools.refinery.logic.dnf.Query; import tools.refinery.store.query.resultset.AnyResultSet; import tools.refinery.store.query.resultset.ResultSet; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryBuilder.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryBuilder.java index 332e63816..71e2c5bf5 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryBuilder.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryBuilder.java @@ -7,8 +7,8 @@ import tools.refinery.store.adapter.ModelAdapterBuilder; import tools.refinery.store.model.ModelStore; -import tools.refinery.store.query.dnf.AnyQuery; -import tools.refinery.store.query.rewriter.DnfRewriter; +import tools.refinery.logic.dnf.AnyQuery; +import tools.refinery.logic.rewriter.DnfRewriter; import java.util.Collection; import java.util.List; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryStoreAdapter.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryStoreAdapter.java index 8b67c5c1a..fec8c9990 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryStoreAdapter.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/ModelQueryStoreAdapter.java @@ -7,8 +7,8 @@ import tools.refinery.store.adapter.ModelStoreAdapter; import tools.refinery.store.model.Model; -import tools.refinery.store.query.dnf.AnyQuery; -import tools.refinery.store.query.dnf.Query; +import tools.refinery.logic.dnf.AnyQuery; +import tools.refinery.logic.dnf.Query; import tools.refinery.store.query.view.AnySymbolView; import java.util.Collection; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AbstractResultSet.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AbstractResultSet.java index dcfe6cc53..f8290b487 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AbstractResultSet.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AbstractResultSet.java @@ -6,7 +6,7 @@ package tools.refinery.store.query.resultset; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.Query; +import tools.refinery.logic.dnf.Query; import tools.refinery.store.tuple.Tuple; import java.util.ArrayList; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AnyResultSet.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AnyResultSet.java index 5b75b1031..038ca7f93 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AnyResultSet.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/AnyResultSet.java @@ -6,7 +6,7 @@ package tools.refinery.store.query.resultset; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.AnyQuery; +import tools.refinery.logic.dnf.AnyQuery; public sealed interface AnyResultSet permits ResultSet { ModelQueryAdapter getAdapter(); diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/EmptyResultSet.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/EmptyResultSet.java index 991b1e322..daebfe7ca 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/EmptyResultSet.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/EmptyResultSet.java @@ -8,7 +8,7 @@ import tools.refinery.store.map.Cursor; import tools.refinery.store.map.Cursors; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.Query; +import tools.refinery.logic.dnf.Query; import tools.refinery.store.tuple.Tuple; public record EmptyResultSet(ModelQueryAdapter adapter, Query query) implements ResultSet { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/OrderedResultSet.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/OrderedResultSet.java index df12b9671..606e197c5 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/OrderedResultSet.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/OrderedResultSet.java @@ -7,7 +7,7 @@ import tools.refinery.store.map.Cursor; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.Query; +import tools.refinery.logic.dnf.Query; import tools.refinery.store.query.utils.OrderStatisticTree; import tools.refinery.store.tuple.Tuple; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/ResultSet.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/ResultSet.java index a6e99784e..e84634ac2 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/ResultSet.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/resultset/ResultSet.java @@ -6,7 +6,7 @@ package tools.refinery.store.query.resultset; import tools.refinery.store.map.Cursor; -import tools.refinery.store.query.dnf.Query; +import tools.refinery.logic.dnf.Query; import tools.refinery.store.tuple.Tuple; public non-sealed interface ResultSet extends AnyResultSet { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java index f130fa594..d98099917 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java @@ -7,8 +7,8 @@ import tools.refinery.store.map.CursorAsIterator; import tools.refinery.store.model.Model; -import tools.refinery.store.query.dnf.FunctionalDependency; -import tools.refinery.store.query.term.Parameter; +import tools.refinery.logic.dnf.FunctionalDependency; +import tools.refinery.logic.term.Parameter; import tools.refinery.store.representation.Symbol; import tools.refinery.store.tuple.Tuple; import tools.refinery.store.tuple.Tuple1; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AnySymbolView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AnySymbolView.java index 7e9bf6df5..b01c39881 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AnySymbolView.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AnySymbolView.java @@ -5,10 +5,10 @@ */ package tools.refinery.store.query.view; +import tools.refinery.logic.dnf.FunctionalDependency; import tools.refinery.store.model.Model; -import tools.refinery.store.query.dnf.FunctionalDependency; +import tools.refinery.logic.Constraint; import tools.refinery.store.representation.AnySymbol; -import tools.refinery.store.query.Constraint; import java.util.Set; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java index 924277edd..7ce074423 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java @@ -5,7 +5,7 @@ */ package tools.refinery.store.query.view; -import tools.refinery.store.query.InvalidQueryException; +import tools.refinery.logic.InvalidQueryException; import tools.refinery.store.tuple.Tuple; import tools.refinery.store.representation.Symbol; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/ForbiddenView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/ForbiddenView.java index c312330e3..8323ace78 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/ForbiddenView.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/ForbiddenView.java @@ -6,7 +6,7 @@ package tools.refinery.store.query.view; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; public class ForbiddenView extends TuplePreservingView { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FunctionView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FunctionView.java index 74a5be070..5585f5f26 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FunctionView.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FunctionView.java @@ -1,11 +1,11 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.query.view; -import tools.refinery.store.query.term.*; +import tools.refinery.logic.term.*; import tools.refinery.store.representation.Symbol; import java.util.ArrayList; @@ -33,4 +33,18 @@ public AssignedValue aggregate(Aggregator aggregator, List AssignedValue aggregate(Aggregator aggregator, NodeVariable... arguments) { return aggregate(aggregator, List.of(arguments)); } + + public AssignedValue leftJoin(T defaultValue, List arguments) { + return targetVariable -> { + var placeholderVariable = Variable.of(getSymbol().valueType()); + var argumentsWithPlaceholder = new ArrayList(arguments.size() + 1); + argumentsWithPlaceholder.addAll(arguments); + argumentsWithPlaceholder.add(placeholderVariable); + return leftJoinBy(placeholderVariable, defaultValue, argumentsWithPlaceholder).toLiteral(targetVariable); + }; + } + + public AssignedValue leftJoin(T defaultValue, NodeVariable... arguments) { + return leftJoin(defaultValue, List.of(arguments)); + } } diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MayView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MayView.java index c322e220d..3a6cc93b0 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MayView.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MayView.java @@ -6,7 +6,7 @@ package tools.refinery.store.query.view; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; public class MayView extends TuplePreservingView { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MustView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MustView.java index 65bb4e4c3..af984327e 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MustView.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MustView.java @@ -6,7 +6,7 @@ package tools.refinery.store.query.view; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; public class MustView extends TuplePreservingView { diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/NodeFunctionView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/NodeFunctionView.java index fcf115067..01865cbe5 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/NodeFunctionView.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/NodeFunctionView.java @@ -5,7 +5,7 @@ */ package tools.refinery.store.query.view; -import tools.refinery.store.query.term.Parameter; +import tools.refinery.logic.term.Parameter; import tools.refinery.store.representation.Symbol; import tools.refinery.store.tuple.Tuple1; diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/TuplePreservingView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/TuplePreservingView.java index ed12cd9dd..6841488d0 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/TuplePreservingView.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/TuplePreservingView.java @@ -7,7 +7,7 @@ import tools.refinery.store.map.CursorAsIterator; import tools.refinery.store.model.Model; -import tools.refinery.store.query.term.Parameter; +import tools.refinery.logic.term.Parameter; import tools.refinery.store.representation.Symbol; import tools.refinery.store.tuple.Tuple; import tools.refinery.store.tuple.Tuple1; diff --git a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/BoundScopePropagator.java b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/BoundScopePropagator.java index ecca61173..3a9efa583 100644 --- a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/BoundScopePropagator.java +++ b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/BoundScopePropagator.java @@ -13,12 +13,17 @@ import org.eclipse.collections.api.factory.primitive.IntSets; import org.eclipse.collections.api.map.primitive.MutableIntObjectMap; import org.eclipse.collections.api.set.primitive.MutableIntSet; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; +import tools.refinery.logic.term.uppercardinality.FiniteUpperCardinality; +import tools.refinery.logic.term.uppercardinality.UnboundedUpperCardinality; +import tools.refinery.logic.term.uppercardinality.UpperCardinalities; +import tools.refinery.logic.term.uppercardinality.UpperCardinality; import tools.refinery.store.dse.propagation.BoundPropagator; import tools.refinery.store.dse.propagation.PropagationResult; import tools.refinery.store.model.Interpretation; import tools.refinery.store.model.Model; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.representation.cardinality.*; import tools.refinery.store.tuple.Tuple; class BoundScopePropagator implements BoundPropagator { diff --git a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/LowerTypeScopePropagator.java b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/LowerTypeScopePropagator.java index 702e570ff..0700c6960 100644 --- a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/LowerTypeScopePropagator.java +++ b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/LowerTypeScopePropagator.java @@ -5,26 +5,26 @@ */ package tools.refinery.store.reasoning.scope; +import tools.refinery.logic.dnf.AnyQuery; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.dnf.RelationalQuery; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.term.uppercardinality.UpperCardinality; +import tools.refinery.logic.term.uppercardinality.UpperCardinalityTerms; import tools.refinery.store.dse.transition.DesignSpaceExplorationBuilder; import tools.refinery.store.dse.transition.objectives.Criteria; import tools.refinery.store.dse.transition.objectives.Objectives; import tools.refinery.store.model.ModelStoreBuilder; -import tools.refinery.store.query.dnf.AnyQuery; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.dnf.RelationalQuery; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.term.uppercardinality.UpperCardinalityTerms; import tools.refinery.store.reasoning.ReasoningBuilder; import tools.refinery.store.reasoning.literal.CountCandidateLowerBoundLiteral; import tools.refinery.store.reasoning.literal.CountUpperBoundLiteral; import tools.refinery.store.reasoning.representation.PartialRelation; -import tools.refinery.store.representation.cardinality.UpperCardinality; import java.util.Collection; import java.util.List; -import static tools.refinery.store.query.literal.Literals.check; -import static tools.refinery.store.query.term.int_.IntTerms.*; +import static tools.refinery.logic.literal.Literals.check; +import static tools.refinery.logic.term.int_.IntTerms.*; import static tools.refinery.store.reasoning.literal.PartialLiterals.may; import static tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator.MULTI_VIEW; diff --git a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/ScopePropagator.java b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/ScopePropagator.java index 25b1966c5..94e6bbd7a 100644 --- a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/ScopePropagator.java +++ b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/ScopePropagator.java @@ -13,8 +13,8 @@ import tools.refinery.store.reasoning.translator.TranslationException; import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.cardinality.CardinalityInterval; -import tools.refinery.store.representation.cardinality.FiniteUpperCardinality; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; +import tools.refinery.logic.term.uppercardinality.FiniteUpperCardinality; import java.util.*; @@ -48,7 +48,7 @@ public ScopePropagator scope(PartialRelation type, CardinalityInterval interval) } var newValue = scopes.compute(type, (ignoredKey, oldValue) -> oldValue == null ? interval : oldValue.meet(interval)); - if (newValue.isEmpty()) { + if (newValue.isError()) { throw new TranslationException(type, "Unsatisfiable scope for type %s".formatted(type)); } return this; diff --git a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/TypeScopePropagator.java b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/TypeScopePropagator.java index 193c132c6..d117b0e2f 100644 --- a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/TypeScopePropagator.java +++ b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/TypeScopePropagator.java @@ -8,8 +8,8 @@ import com.google.ortools.linearsolver.MPConstraint; import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.query.ModelQueryBuilder; -import tools.refinery.store.query.dnf.AnyQuery; -import tools.refinery.store.query.dnf.RelationalQuery; +import tools.refinery.logic.dnf.AnyQuery; +import tools.refinery.logic.dnf.RelationalQuery; import tools.refinery.store.query.resultset.ResultSet; import tools.refinery.store.tuple.Tuple; diff --git a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/UpperTypeScopePropagator.java b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/UpperTypeScopePropagator.java index b2f8d39b6..ad56b9bdb 100644 --- a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/UpperTypeScopePropagator.java +++ b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/UpperTypeScopePropagator.java @@ -5,14 +5,14 @@ */ package tools.refinery.store.reasoning.scope; +import tools.refinery.logic.dnf.AnyQuery; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.dnf.RelationalQuery; +import tools.refinery.logic.term.Variable; import tools.refinery.store.dse.transition.DesignSpaceExplorationBuilder; import tools.refinery.store.dse.transition.objectives.Criteria; import tools.refinery.store.dse.transition.objectives.Objectives; import tools.refinery.store.model.ModelStoreBuilder; -import tools.refinery.store.query.dnf.AnyQuery; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.dnf.RelationalQuery; -import tools.refinery.store.query.term.Variable; import tools.refinery.store.reasoning.ReasoningBuilder; import tools.refinery.store.reasoning.literal.CountCandidateUpperBoundLiteral; import tools.refinery.store.reasoning.literal.CountLowerBoundLiteral; @@ -21,8 +21,8 @@ import java.util.Collection; import java.util.List; -import static tools.refinery.store.query.literal.Literals.check; -import static tools.refinery.store.query.term.int_.IntTerms.*; +import static tools.refinery.logic.literal.Literals.check; +import static tools.refinery.logic.term.int_.IntTerms.*; import static tools.refinery.store.reasoning.literal.PartialLiterals.must; import static tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator.MULTI_VIEW; diff --git a/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/MultiObjectTest.java b/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/MultiObjectTest.java index 97b9fa5e0..2b8b4557c 100644 --- a/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/MultiObjectTest.java +++ b/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/MultiObjectTest.java @@ -20,9 +20,9 @@ import tools.refinery.store.reasoning.translator.PartialRelationTranslator; import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; -import tools.refinery.store.representation.cardinality.CardinalityInterval; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; +import tools.refinery.logic.term.truthvalue.TruthValue; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; import tools.refinery.store.tuple.Tuple; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/PredicateScopeTest.java b/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/PredicateScopeTest.java index 5ee97ce18..f4d5fb60d 100644 --- a/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/PredicateScopeTest.java +++ b/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/PredicateScopeTest.java @@ -9,13 +9,15 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.dse.propagation.PropagationAdapter; import tools.refinery.store.dse.strategy.BestFirstStoreManager; import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter; import tools.refinery.store.model.ModelStore; -import tools.refinery.store.query.dnf.Query; import tools.refinery.store.query.interpreter.QueryInterpreterAdapter; -import tools.refinery.store.query.term.Variable; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.reasoning.ReasoningStoreAdapter; import tools.refinery.store.reasoning.interpretation.PartialInterpretation; @@ -27,14 +29,12 @@ import tools.refinery.store.reasoning.translator.metamodel.Metamodel; import tools.refinery.store.reasoning.translator.metamodel.MetamodelTranslator; import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; -import tools.refinery.store.representation.TruthValue; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; import tools.refinery.store.statecoding.StateCoderAdapter; import tools.refinery.store.tuple.Tuple; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import static tools.refinery.store.query.literal.Literals.not; +import static tools.refinery.logic.literal.Literals.not; class PredicateScopeTest { private static final PartialRelation index = new PartialRelation("Index", 1); diff --git a/subprojects/store-reasoning-smt/build.gradle.kts b/subprojects/store-reasoning-smt/build.gradle.kts new file mode 100644 index 000000000..4a784e421 --- /dev/null +++ b/subprojects/store-reasoning-smt/build.gradle.kts @@ -0,0 +1,15 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ + +plugins { + id("tools.refinery.gradle.java-library") +} + +dependencies { + api(project(":refinery-store-reasoning")) + implementation(libs.refinery.z3) + testImplementation(project(":refinery-store-query-interpreter")) +} diff --git a/subprojects/store-reasoning-smt/src/main/java/tools/refinery/store/reasoning/smt/SmtPropagator.java b/subprojects/store-reasoning-smt/src/main/java/tools/refinery/store/reasoning/smt/SmtPropagator.java new file mode 100644 index 000000000..b63ab5612 --- /dev/null +++ b/subprojects/store-reasoning-smt/src/main/java/tools/refinery/store/reasoning/smt/SmtPropagator.java @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.store.reasoning.smt; + +import com.microsoft.z3.Context; +import tools.refinery.z3.Z3SolverLoader; + +public class SmtPropagator { + public void propagate() { + Z3SolverLoader.loadNativeLibraries(); + try (var context = new Context()) { + var solver = context.mkSolver(); + solver.check(); + } + } +} diff --git a/subprojects/store-reasoning/build.gradle.kts b/subprojects/store-reasoning/build.gradle.kts index 068256c20..d1d3c2e5b 100644 --- a/subprojects/store-reasoning/build.gradle.kts +++ b/subprojects/store-reasoning/build.gradle.kts @@ -10,6 +10,6 @@ plugins { dependencies { api(project(":refinery-store-dse")) - testImplementation(testFixtures(project(":refinery-store-query"))) + testImplementation(testFixtures(project(":refinery-logic"))) testImplementation(project(":refinery-store-query-interpreter")) } diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/ReasoningAdapter.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/ReasoningAdapter.java index 7f0ef8b43..a9b3141ad 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/ReasoningAdapter.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/ReasoningAdapter.java @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.reasoning; import org.jetbrains.annotations.Nullable; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.adapter.ModelAdapter; import tools.refinery.store.reasoning.internal.ReasoningBuilderImpl; import tools.refinery.store.reasoning.interpretation.AnyPartialInterpretation; @@ -27,17 +28,19 @@ public interface ReasoningAdapter extends ModelAdapter { default AnyPartialInterpretation getPartialInterpretation(Concreteness concreteness, AnyPartialSymbol partialSymbol) { - return getPartialInterpretation(concreteness, (PartialSymbol) partialSymbol); + var typedPartialSymbol = (PartialSymbol) partialSymbol; + return getPartialInterpretation(concreteness, typedPartialSymbol); } - PartialInterpretation getPartialInterpretation(Concreteness concreteness, - PartialSymbol partialSymbol); + , C> PartialInterpretation getPartialInterpretation( + Concreteness concreteness, PartialSymbol partialSymbol); default AnyPartialInterpretationRefiner getRefiner(AnyPartialSymbol partialSymbol) { - return getRefiner((PartialSymbol) partialSymbol); + var typedPartialSymbol = (PartialSymbol) partialSymbol; + return getRefiner(typedPartialSymbol); } - PartialInterpretationRefiner getRefiner(PartialSymbol partialSymbol); + , C> PartialInterpretationRefiner getRefiner(PartialSymbol partialSymbol); @Nullable Tuple1 split(int parentMultiObject); diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/ReasoningBuilder.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/ReasoningBuilder.java index 79bce33e0..7ffa6faa4 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/ReasoningBuilder.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/ReasoningBuilder.java @@ -8,10 +8,10 @@ import tools.refinery.store.adapter.ModelAdapterBuilder; import tools.refinery.store.dse.transition.objectives.Objective; import tools.refinery.store.model.ModelStore; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.FunctionalQuery; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.dnf.RelationalQuery; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.FunctionalQuery; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.dnf.RelationalQuery; import tools.refinery.store.reasoning.literal.Concreteness; import tools.refinery.store.reasoning.literal.Modality; import tools.refinery.store.reasoning.refinement.PartialModelInitializer; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/CleanupActionLiteral.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/CleanupActionLiteral.java index 62c35cee2..6a0004d9a 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/CleanupActionLiteral.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/CleanupActionLiteral.java @@ -8,7 +8,7 @@ import tools.refinery.store.dse.transition.actions.AbstractActionLiteral; import tools.refinery.store.dse.transition.actions.BoundActionLiteral; import tools.refinery.store.model.Model; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.tuple.Tuple; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/FocusActionLiteral.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/FocusActionLiteral.java index 5a6f22d23..c819a1f99 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/FocusActionLiteral.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/FocusActionLiteral.java @@ -8,7 +8,7 @@ import tools.refinery.store.dse.transition.actions.AbstractActionLiteral; import tools.refinery.store.dse.transition.actions.BoundActionLiteral; import tools.refinery.store.model.Model; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; import tools.refinery.store.reasoning.ReasoningAdapter; import java.util.List; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/MergeActionLiteral.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/MergeActionLiteral.java index 8d0d79616..86256331d 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/MergeActionLiteral.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/MergeActionLiteral.java @@ -1,21 +1,22 @@ /* - * SPDX-FileCopyrightText: 2023 The Refinery Authors + * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.reasoning.actions; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.dse.transition.actions.AbstractActionLiteral; import tools.refinery.store.dse.transition.actions.BoundActionLiteral; import tools.refinery.store.model.Model; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.term.NodeVariable; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.reasoning.representation.PartialSymbol; import tools.refinery.store.tuple.Tuple; import java.util.List; -public class MergeActionLiteral extends AbstractActionLiteral { +public class MergeActionLiteral, C> extends AbstractActionLiteral { private final PartialSymbol partialSymbol; private final List parameters; private final A value; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/PartialActionLiterals.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/PartialActionLiterals.java index f36fde441..e8e6880af 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/PartialActionLiterals.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/actions/PartialActionLiterals.java @@ -5,10 +5,11 @@ */ package tools.refinery.store.reasoning.actions; -import tools.refinery.store.query.term.NodeVariable; +import tools.refinery.logic.AbstractValue; +import tools.refinery.logic.term.NodeVariable; import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.representation.PartialSymbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import java.util.List; @@ -17,8 +18,8 @@ private PartialActionLiterals() { throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); } - public static MergeActionLiteral merge(PartialSymbol partialSymbol, A value, - NodeVariable... parameters) { + public static , C> MergeActionLiteral merge( + PartialSymbol partialSymbol, A value, NodeVariable... parameters) { return new MergeActionLiteral<>(partialSymbol, value, List.of(parameters)); } diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/PartialClauseRewriter.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/PartialClauseRewriter.java index 409932350..dc508a7bf 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/PartialClauseRewriter.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/PartialClauseRewriter.java @@ -5,25 +5,25 @@ */ package tools.refinery.store.reasoning.internal; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.DnfBuilder; -import tools.refinery.store.query.dnf.DnfClause; -import tools.refinery.store.query.literal.AbstractCallLiteral; -import tools.refinery.store.query.literal.AbstractCountLiteral; -import tools.refinery.store.query.literal.CallPolarity; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.Aggregator; -import tools.refinery.store.query.term.ConstantTerm; -import tools.refinery.store.query.term.Term; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.term.int_.IntTerms; -import tools.refinery.store.query.term.uppercardinality.UpperCardinalityTerms; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.DnfBuilder; +import tools.refinery.logic.dnf.DnfClause; +import tools.refinery.logic.literal.AbstractCallLiteral; +import tools.refinery.logic.literal.AbstractCountLiteral; +import tools.refinery.logic.literal.CallPolarity; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.Aggregator; +import tools.refinery.logic.term.ConstantTerm; +import tools.refinery.logic.term.Term; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.term.int_.IntTerms; +import tools.refinery.logic.term.uppercardinality.UpperCardinalities; +import tools.refinery.logic.term.uppercardinality.UpperCardinalityTerms; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.reasoning.literal.*; import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; -import tools.refinery.store.representation.cardinality.UpperCardinalities; import java.util.*; import java.util.function.BinaryOperator; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/PartialQueryRewriter.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/PartialQueryRewriter.java index 79cba263b..9a916b69f 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/PartialQueryRewriter.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/PartialQueryRewriter.java @@ -5,8 +5,8 @@ */ package tools.refinery.store.reasoning.internal; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.rewriter.AbstractRecursiveRewriter; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.rewriter.AbstractRecursiveRewriter; import tools.refinery.store.reasoning.interpretation.PartialRelationRewriter; import tools.refinery.store.reasoning.lifting.DnfLifter; import tools.refinery.store.reasoning.representation.PartialRelation; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningAdapterImpl.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningAdapterImpl.java index bd16bdfa7..386ae1d84 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningAdapterImpl.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningAdapterImpl.java @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.reasoning.internal; import org.jetbrains.annotations.Nullable; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.model.Interpretation; import tools.refinery.store.model.Model; import tools.refinery.store.reasoning.ReasoningAdapter; @@ -19,8 +20,8 @@ import tools.refinery.store.reasoning.representation.PartialSymbol; import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.cardinality.CardinalityInterval; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; import tools.refinery.store.tuple.Tuple; import tools.refinery.store.tuple.Tuple1; @@ -49,7 +50,7 @@ class ReasoningAdapterImpl implements ReasoningAdapter { createPartialInterpretations(); var refinerFactories = storeAdapter.getSymbolRefiners(); - refiners = new HashMap<>(refinerFactories.size()); + refiners = HashMap.newHashMap(refinerFactories.size()); createRefiners(); storageRefiners = storeAdapter.createStorageRefiner(model); @@ -69,7 +70,7 @@ private void createPartialInterpretations() { for (int i = 0; i < concretenessLength; i++) { var concreteness = Concreteness.values()[i]; if (supportedInterpretations.contains(concreteness)) { - partialInterpretations[i] = new HashMap<>(interpretationFactories.size()); + partialInterpretations[i] = HashMap.newHashMap(interpretationFactories.size()); } } // Create the partial interpretations in order so that factories may refer to interpretations of symbols @@ -87,7 +88,7 @@ private void createPartialInterpretations() { } } - private PartialInterpretation createPartialInterpretation( + private , C> PartialInterpretation createPartialInterpretation( Concreteness concreteness, PartialInterpretation.Factory interpreter, AnyPartialSymbol symbol) { // The builder only allows well-typed assignment of interpreters to symbols. @SuppressWarnings("unchecked") @@ -107,7 +108,7 @@ private void createRefiners() { } } - private PartialInterpretationRefiner createRefiner( + private , C> PartialInterpretationRefiner createRefiner( PartialInterpretationRefiner.Factory factory, AnyPartialSymbol symbol) { // The builder only allows well-typed assignment of interpreters to symbols. @SuppressWarnings("unchecked") @@ -126,8 +127,8 @@ public ReasoningStoreAdapterImpl getStoreAdapter() { } @Override - public PartialInterpretation getPartialInterpretation(Concreteness concreteness, - PartialSymbol partialSymbol) { + public , C> PartialInterpretation getPartialInterpretation( + Concreteness concreteness, PartialSymbol partialSymbol) { var map = partialInterpretations[concreteness.ordinal()]; if (map == null) { throw new IllegalArgumentException("No interpretation for concreteness: " + concreteness); @@ -143,7 +144,8 @@ public PartialInterpretation getPartialInterpretation(Concreteness } @Override - public PartialInterpretationRefiner getRefiner(PartialSymbol partialSymbol) { + public , C> PartialInterpretationRefiner getRefiner( + PartialSymbol partialSymbol) { var refiner = refiners.get(partialSymbol); if (refiner == null) { throw new IllegalArgumentException("No refiner for partial symbol: " + partialSymbol); diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningBuilderImpl.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningBuilderImpl.java index 722458c80..87122b1d1 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningBuilderImpl.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/internal/ReasoningBuilderImpl.java @@ -12,10 +12,10 @@ import tools.refinery.store.model.ModelStore; import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.query.ModelQueryBuilder; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.FunctionalQuery; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.dnf.RelationalQuery; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.FunctionalQuery; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.dnf.RelationalQuery; import tools.refinery.store.reasoning.ReasoningBuilder; import tools.refinery.store.reasoning.interpretation.PartialInterpretation; import tools.refinery.store.reasoning.lifting.DnfLifter; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/AbstractPartialInterpretation.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/AbstractPartialInterpretation.java index ed291eaca..4f51957ba 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/AbstractPartialInterpretation.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/AbstractPartialInterpretation.java @@ -5,11 +5,13 @@ */ package tools.refinery.store.reasoning.interpretation; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.reasoning.literal.Concreteness; import tools.refinery.store.reasoning.representation.PartialSymbol; -public abstract class AbstractPartialInterpretation implements PartialInterpretation { +public abstract class AbstractPartialInterpretation, C> + implements PartialInterpretation { private final ReasoningAdapter adapter; private final PartialSymbol partialSymbol; private final Concreteness concreteness; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/PartialInterpretation.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/PartialInterpretation.java index 86ffe7516..5a304030e 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/PartialInterpretation.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/PartialInterpretation.java @@ -1,10 +1,11 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.reasoning.interpretation; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.map.Cursor; import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.reasoning.ReasoningAdapter; @@ -14,7 +15,7 @@ import java.util.Set; -public non-sealed interface PartialInterpretation extends AnyPartialInterpretation { +public non-sealed interface PartialInterpretation, C> extends AnyPartialInterpretation { @Override PartialSymbol getPartialSymbol(); @@ -23,7 +24,7 @@ public non-sealed interface PartialInterpretation extends AnyPartialInterp Cursor getAll(); @FunctionalInterface - interface Factory { + interface Factory, C> { PartialInterpretation create(ReasoningAdapter adapter, Concreteness concreteness, PartialSymbol partialSymbol); diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/PartialRelationRewriter.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/PartialRelationRewriter.java index 6ad35c206..72ad386cc 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/PartialRelationRewriter.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/PartialRelationRewriter.java @@ -5,9 +5,9 @@ */ package tools.refinery.store.reasoning.interpretation; -import tools.refinery.store.query.literal.AbstractCallLiteral; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.literal.AbstractCallLiteral; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.Variable; import tools.refinery.store.reasoning.literal.Concreteness; import tools.refinery.store.reasoning.literal.Modality; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/QueryBasedRelationInterpretationFactory.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/QueryBasedRelationInterpretationFactory.java index 5cdaa1856..8fe34b273 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/QueryBasedRelationInterpretationFactory.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/QueryBasedRelationInterpretationFactory.java @@ -9,12 +9,12 @@ import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.query.ModelQueryAdapter; import tools.refinery.store.query.ModelQueryBuilder; -import tools.refinery.store.query.dnf.Query; +import tools.refinery.logic.dnf.Query; import tools.refinery.store.query.resultset.ResultSet; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.reasoning.literal.Concreteness; import tools.refinery.store.reasoning.representation.PartialSymbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; import java.util.Set; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/QueryBasedRelationRewriter.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/QueryBasedRelationRewriter.java index 78fdbb893..a6850e750 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/QueryBasedRelationRewriter.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/QueryBasedRelationRewriter.java @@ -5,10 +5,10 @@ */ package tools.refinery.store.reasoning.interpretation; -import tools.refinery.store.query.dnf.RelationalQuery; -import tools.refinery.store.query.literal.AbstractCallLiteral; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.dnf.RelationalQuery; +import tools.refinery.logic.literal.AbstractCallLiteral; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.Variable; import tools.refinery.store.reasoning.literal.Concreteness; import tools.refinery.store.reasoning.literal.Modality; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/lifting/ClauseLifter.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/lifting/ClauseLifter.java index 17916c029..02e16dc50 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/lifting/ClauseLifter.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/lifting/ClauseLifter.java @@ -5,13 +5,13 @@ */ package tools.refinery.store.reasoning.lifting; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.DnfClause; -import tools.refinery.store.query.literal.*; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.ParameterDirection; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.DnfClause; +import tools.refinery.logic.literal.*; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.Variable; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.reasoning.literal.Concreteness; import tools.refinery.store.reasoning.literal.ModalConstraint; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/lifting/DnfLifter.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/lifting/DnfLifter.java index 889f595fc..1eeb5de15 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/lifting/DnfLifter.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/lifting/DnfLifter.java @@ -5,9 +5,9 @@ */ package tools.refinery.store.reasoning.lifting; -import tools.refinery.store.query.dnf.*; -import tools.refinery.store.query.equality.DnfEqualityChecker; -import tools.refinery.store.query.literal.Literal; +import tools.refinery.logic.dnf.*; +import tools.refinery.logic.equality.DnfEqualityChecker; +import tools.refinery.logic.literal.Literal; import tools.refinery.store.reasoning.literal.Concreteness; import tools.refinery.store.reasoning.literal.Modality; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountCandidateLowerBoundLiteral.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountCandidateLowerBoundLiteral.java index 91dd2b72a..e4c180fc3 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountCandidateLowerBoundLiteral.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountCandidateLowerBoundLiteral.java @@ -5,13 +5,13 @@ */ package tools.refinery.store.reasoning.literal; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.literal.AbstractCallLiteral; -import tools.refinery.store.query.literal.AbstractCountLiteral; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.literal.AbstractCallLiteral; +import tools.refinery.logic.literal.AbstractCountLiteral; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.Variable; import java.util.List; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountCandidateUpperBoundLiteral.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountCandidateUpperBoundLiteral.java index 94c9399da..2faeda22d 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountCandidateUpperBoundLiteral.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountCandidateUpperBoundLiteral.java @@ -5,13 +5,13 @@ */ package tools.refinery.store.reasoning.literal; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.literal.AbstractCallLiteral; -import tools.refinery.store.query.literal.AbstractCountLiteral; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.literal.AbstractCallLiteral; +import tools.refinery.logic.literal.AbstractCountLiteral; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.Variable; import java.util.List; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountLowerBoundLiteral.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountLowerBoundLiteral.java index b75b0cab4..c009cfaee 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountLowerBoundLiteral.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountLowerBoundLiteral.java @@ -5,13 +5,13 @@ */ package tools.refinery.store.reasoning.literal; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.literal.AbstractCallLiteral; -import tools.refinery.store.query.literal.AbstractCountLiteral; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.literal.AbstractCallLiteral; +import tools.refinery.logic.literal.AbstractCountLiteral; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.Variable; import java.util.List; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountUpperBoundLiteral.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountUpperBoundLiteral.java index 038421436..84bea8c0a 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountUpperBoundLiteral.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/CountUpperBoundLiteral.java @@ -5,15 +5,15 @@ */ package tools.refinery.store.reasoning.literal; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.literal.AbstractCallLiteral; -import tools.refinery.store.query.literal.AbstractCountLiteral; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.substitution.Substitution; -import tools.refinery.store.query.term.DataVariable; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.representation.cardinality.UpperCardinalities; -import tools.refinery.store.representation.cardinality.UpperCardinality; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.literal.AbstractCallLiteral; +import tools.refinery.logic.literal.AbstractCountLiteral; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.substitution.Substitution; +import tools.refinery.logic.term.DataVariable; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.term.uppercardinality.UpperCardinalities; +import tools.refinery.logic.term.uppercardinality.UpperCardinality; import java.util.List; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/ModalConstraint.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/ModalConstraint.java index 2235a95d8..6b8af4608 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/ModalConstraint.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/ModalConstraint.java @@ -5,11 +5,11 @@ */ package tools.refinery.store.reasoning.literal; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.equality.LiteralEqualityHelper; -import tools.refinery.store.query.literal.Reduction; -import tools.refinery.store.query.term.Parameter; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.equality.LiteralEqualityHelper; +import tools.refinery.logic.literal.Reduction; +import tools.refinery.logic.term.Parameter; import tools.refinery.store.query.view.AnySymbolView; import java.util.List; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/Modality.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/Modality.java index c99a03994..045b71471 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/Modality.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/Modality.java @@ -5,7 +5,8 @@ */ package tools.refinery.store.reasoning.literal; -import tools.refinery.store.query.literal.CallPolarity; + +import tools.refinery.logic.literal.CallPolarity; import java.util.Locale; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/PartialLiterals.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/PartialLiterals.java index 2614c26e1..72b085a5a 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/PartialLiterals.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/literal/PartialLiterals.java @@ -5,8 +5,8 @@ */ package tools.refinery.store.reasoning.literal; -import tools.refinery.store.query.InvalidQueryException; -import tools.refinery.store.query.literal.CallLiteral; +import tools.refinery.logic.InvalidQueryException; +import tools.refinery.logic.literal.CallLiteral; public final class PartialLiterals { private PartialLiterals() { diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/AbstractPartialInterpretationRefiner.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/AbstractPartialInterpretationRefiner.java index a7fc5b7e5..42943490f 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/AbstractPartialInterpretationRefiner.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/AbstractPartialInterpretationRefiner.java @@ -1,14 +1,16 @@ /* - * SPDX-FileCopyrightText: 2023 The Refinery Authors + * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.reasoning.refinement; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.reasoning.representation.PartialSymbol; -public abstract class AbstractPartialInterpretationRefiner implements PartialInterpretationRefiner { +public abstract class AbstractPartialInterpretationRefiner, C> + implements PartialInterpretationRefiner { private final ReasoningAdapter adapter; private final PartialSymbol partialSymbol; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/ConcreteSymbolRefiner.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/ConcreteSymbolRefiner.java index ebb9b8249..d6ac0e9db 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/ConcreteSymbolRefiner.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/ConcreteSymbolRefiner.java @@ -1,10 +1,11 @@ /* - * SPDX-FileCopyrightText: 2023 The Refinery Authors + * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.reasoning.refinement; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.model.Interpretation; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.reasoning.representation.PartialSymbol; @@ -13,7 +14,8 @@ import java.util.Objects; -public class ConcreteSymbolRefiner extends AbstractPartialInterpretationRefiner { +public class ConcreteSymbolRefiner, C> + extends AbstractPartialInterpretationRefiner { private final Interpretation interpretation; public ConcreteSymbolRefiner(ReasoningAdapter adapter, PartialSymbol partialSymbol, @@ -25,14 +27,14 @@ public ConcreteSymbolRefiner(ReasoningAdapter adapter, PartialSymbol parti @Override public boolean merge(Tuple key, A value) { var currentValue = interpretation.get(key); - var mergedValue = getPartialSymbol().abstractDomain().commonRefinement(currentValue, value); + var mergedValue = currentValue.meet(value); if (!Objects.equals(currentValue, mergedValue)) { interpretation.put(key, mergedValue); } return true; } - public static Factory of(Symbol concreteSymbol) { + public static , C1> Factory of(Symbol concreteSymbol) { return (adapter, partialSymbol) -> new ConcreteSymbolRefiner<>(adapter, partialSymbol, concreteSymbol); } } diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/PartialInterpretationRefiner.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/PartialInterpretationRefiner.java index f48d1d1f7..c8b182b8f 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/PartialInterpretationRefiner.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/PartialInterpretationRefiner.java @@ -1,22 +1,24 @@ /* - * SPDX-FileCopyrightText: 2023 The Refinery Authors + * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.reasoning.refinement; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.reasoning.representation.PartialSymbol; import tools.refinery.store.tuple.Tuple; -public non-sealed interface PartialInterpretationRefiner extends AnyPartialInterpretationRefiner { +public non-sealed interface PartialInterpretationRefiner, C> + extends AnyPartialInterpretationRefiner { @Override PartialSymbol getPartialSymbol(); boolean merge(Tuple key, A value); @FunctionalInterface - interface Factory { + interface Factory, C> { PartialInterpretationRefiner create(ReasoningAdapter adapter, PartialSymbol partialSymbol); } } diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/RefinementBasedInitializer.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/RefinementBasedInitializer.java index b6bccb016..1a2c03a65 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/RefinementBasedInitializer.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/refinement/RefinementBasedInitializer.java @@ -1,16 +1,17 @@ /* - * SPDX-FileCopyrightText: 2023 The Refinery Authors + * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.reasoning.refinement; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.model.Model; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.reasoning.representation.PartialSymbol; import tools.refinery.store.reasoning.seed.ModelSeed; -public class RefinementBasedInitializer implements PartialModelInitializer { +public class RefinementBasedInitializer, C> implements PartialModelInitializer { private final PartialSymbol partialSymbol; public RefinementBasedInitializer(PartialSymbol partialSymbol) { diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/AnyPartialSymbol.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/AnyPartialSymbol.java index 788eef730..3e10c6c15 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/AnyPartialSymbol.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/AnyPartialSymbol.java @@ -5,7 +5,7 @@ */ package tools.refinery.store.reasoning.representation; -import tools.refinery.store.representation.AnyAbstractDomain; +import tools.refinery.logic.AnyAbstractDomain; public sealed interface AnyPartialSymbol permits AnyPartialFunction, PartialSymbol { String name(); diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/PartialFunction.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/PartialFunction.java index e59c8af83..88b98da8d 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/PartialFunction.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/PartialFunction.java @@ -1,14 +1,16 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.reasoning.representation; -import tools.refinery.store.representation.AbstractDomain; +import tools.refinery.logic.AbstractDomain; +import tools.refinery.logic.AbstractValue; -public record PartialFunction(String name, int arity, AbstractDomain abstractDomain) - implements AnyPartialFunction, PartialSymbol { +public record PartialFunction, C>( + String name, int arity, AbstractDomain abstractDomain) implements AnyPartialFunction, + PartialSymbol { @Override public A defaultValue() { return null; @@ -21,7 +23,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - // Compare by identity to make hash table lookups more efficient. + // Compare by identity to make hash table look-ups more efficient. return System.identityHashCode(this); } diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/PartialRelation.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/PartialRelation.java index 4ccb7033a..0f108247b 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/PartialRelation.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/PartialRelation.java @@ -5,11 +5,11 @@ */ package tools.refinery.store.reasoning.representation; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.term.Parameter; -import tools.refinery.store.representation.AbstractDomain; -import tools.refinery.store.representation.TruthValue; -import tools.refinery.store.representation.TruthValueDomain; +import tools.refinery.logic.AbstractDomain; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.term.Parameter; +import tools.refinery.logic.term.truthvalue.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValueDomain; import java.util.Arrays; import java.util.List; @@ -44,7 +44,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - // Compare by identity to make hash table lookups more efficient. + // Compare by identity to make hash table look-ups more efficient. return System.identityHashCode(this); } diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/PartialSymbol.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/PartialSymbol.java index 38b2e4663..21cbfefad 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/PartialSymbol.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/representation/PartialSymbol.java @@ -1,13 +1,15 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.reasoning.representation; -import tools.refinery.store.representation.AbstractDomain; +import tools.refinery.logic.AbstractDomain; +import tools.refinery.logic.AbstractValue; -public sealed interface PartialSymbol extends AnyPartialSymbol permits PartialFunction, PartialRelation { +public sealed interface PartialSymbol, C> extends AnyPartialSymbol + permits PartialFunction, PartialRelation { @Override AbstractDomain abstractDomain(); @@ -17,7 +19,8 @@ static PartialRelation of(String name, int arity) { return new PartialRelation(name, arity); } - static PartialFunction of(String name, int arity, AbstractDomain abstractDomain) { + static , C> PartialFunction of( + String name, int arity, AbstractDomain abstractDomain) { return new PartialFunction<>(name, arity, abstractDomain); } } diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/ModelSeed.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/ModelSeed.java index e6b3eaf94..9cd4862b2 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/ModelSeed.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/ModelSeed.java @@ -1,10 +1,11 @@ /* - * SPDX-FileCopyrightText: 2023 The Refinery Authors + * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.reasoning.seed; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.map.Cursor; import tools.refinery.store.reasoning.representation.AnyPartialSymbol; import tools.refinery.store.reasoning.representation.PartialSymbol; @@ -29,7 +30,7 @@ public int getNodeCount() { return nodeCount; } - public Seed getSeed(PartialSymbol partialSymbol) { + public > Seed getSeed(PartialSymbol partialSymbol) { var seed = seeds.get(partialSymbol); if (seed == null) { throw new IllegalArgumentException("No seed for partial symbol " + partialSymbol); @@ -48,7 +49,8 @@ public Set getSeededSymbols() { return Collections.unmodifiableSet(seeds.keySet()); } - public Cursor getCursor(PartialSymbol partialSymbol, A defaultValue) { + public > Cursor getCursor(PartialSymbol partialSymbol, + A defaultValue) { return getSeed(partialSymbol).getCursor(defaultValue, nodeCount); } @@ -67,7 +69,7 @@ private Builder(int nodeCount) { this.nodeCount = nodeCount; } - public Builder seed(PartialSymbol partialSymbol, Seed seed) { + public > Builder seed(PartialSymbol partialSymbol, Seed seed) { if (seed.arity() != partialSymbol.arity()) { throw new IllegalStateException("Expected seed of arity %d for partial symbol %s, but got %d instead" .formatted(partialSymbol.arity(), partialSymbol, seed.arity())); @@ -82,7 +84,8 @@ public Builder seed(PartialSymbol partialSymbol, Seed seed) { return this; } - public Builder seed(PartialSymbol partialSymbol, Consumer> callback) { + public > Builder seed(PartialSymbol partialSymbol, + Consumer> callback) { var builder = Seed.builder(partialSymbol); callback.accept(builder); return seed(partialSymbol, builder.build()); diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/Seed.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/Seed.java index d9bad866b..32562f01b 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/Seed.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/Seed.java @@ -1,10 +1,11 @@ /* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.reasoning.seed; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.map.Cursor; import tools.refinery.store.reasoning.representation.PartialSymbol; import tools.refinery.store.representation.Symbol; @@ -33,7 +34,7 @@ static Builder builder(Symbol symbol) { return builder(symbol.arity(), symbol.valueType(), symbol.defaultValue()); } - static Builder builder(PartialSymbol partialSymbol) { + static > Builder builder(PartialSymbol partialSymbol) { return builder(partialSymbol.arity(), partialSymbol.abstractDomain().abstractType(), partialSymbol.defaultValue()); } diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/SeedInitializer.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/SeedInitializer.java index 9af457d85..138e3a640 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/SeedInitializer.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/seed/SeedInitializer.java @@ -1,16 +1,17 @@ /* - * SPDX-FileCopyrightText: 2023 The Refinery Authors + * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.reasoning.seed; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.model.Model; import tools.refinery.store.reasoning.refinement.PartialModelInitializer; import tools.refinery.store.reasoning.representation.PartialSymbol; import tools.refinery.store.representation.Symbol; -public class SeedInitializer implements PartialModelInitializer { +public class SeedInitializer> implements PartialModelInitializer { private final Symbol symbol; private final PartialSymbol partialSymbol; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialRelationTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialRelationTranslator.java index c2039afc0..75fb3397b 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialRelationTranslator.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialRelationTranslator.java @@ -5,18 +5,19 @@ */ package tools.refinery.store.reasoning.translator; +import tools.refinery.logic.Constraint; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.dnf.QueryBuilder; +import tools.refinery.logic.dnf.RelationalQuery; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.dse.transition.Rule; import tools.refinery.store.dse.transition.objectives.Criteria; import tools.refinery.store.dse.transition.objectives.Criterion; import tools.refinery.store.dse.transition.objectives.Objective; import tools.refinery.store.dse.transition.objectives.Objectives; import tools.refinery.store.model.ModelStoreBuilder; -import tools.refinery.store.query.Constraint; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.dnf.QueryBuilder; -import tools.refinery.store.query.dnf.RelationalQuery; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.NodeVariable; import tools.refinery.store.query.view.MayView; import tools.refinery.store.query.view.MustView; import tools.refinery.store.reasoning.ReasoningAdapter; @@ -36,12 +37,11 @@ import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.representation.AnySymbol; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; import java.util.ArrayList; import java.util.function.BiConsumer; -import static tools.refinery.store.query.literal.Literals.not; +import static tools.refinery.logic.literal.Literals.not; @SuppressWarnings("UnusedReturnValue") public final class PartialRelationTranslator extends PartialSymbolTranslator { diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialSymbolTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialSymbolTranslator.java index 6cdb287df..f25830981 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialSymbolTranslator.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialSymbolTranslator.java @@ -6,6 +6,7 @@ package tools.refinery.store.reasoning.translator; import org.jetbrains.annotations.Nullable; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.dse.transition.DesignSpaceExplorationBuilder; import tools.refinery.store.dse.transition.Rule; import tools.refinery.store.dse.transition.objectives.Criterion; @@ -25,8 +26,8 @@ import java.util.List; @SuppressWarnings("UnusedReturnValue") -public abstract sealed class PartialSymbolTranslator implements AnyPartialSymbolTranslator - permits PartialRelationTranslator { +public abstract sealed class PartialSymbolTranslator, C> + implements AnyPartialSymbolTranslator permits PartialRelationTranslator { private final PartialSymbol partialSymbol; private boolean configured = false; protected PartialInterpretationRefiner.Factory interpretationRefiner; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainmentHierarchyTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainmentHierarchyTranslator.java index c85bd8b78..1183d4565 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainmentHierarchyTranslator.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainmentHierarchyTranslator.java @@ -5,16 +5,18 @@ */ package tools.refinery.store.reasoning.translator.containment; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.dnf.RelationalQuery; +import tools.refinery.logic.literal.Connectivity; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.literal.RepresentativeElectionLiteral; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; +import tools.refinery.logic.term.uppercardinality.FiniteUpperCardinality; import tools.refinery.store.dse.transition.DesignSpaceExplorationBuilder; import tools.refinery.store.dse.transition.Rule; import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.model.ModelStoreConfiguration; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.dnf.RelationalQuery; -import tools.refinery.store.query.literal.Connectivity; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.literal.RepresentativeElectionLiteral; -import tools.refinery.store.query.term.Variable; import tools.refinery.store.query.view.AnySymbolView; import tools.refinery.store.reasoning.lifting.DnfLifter; import tools.refinery.store.reasoning.literal.Concreteness; @@ -28,17 +30,15 @@ import tools.refinery.store.reasoning.translator.multiplicity.ConstrainedMultiplicity; import tools.refinery.store.reasoning.translator.multiplicity.InvalidMultiplicityErrorTranslator; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; -import tools.refinery.store.representation.cardinality.FiniteUpperCardinality; import java.util.ArrayList; import java.util.List; import java.util.Map; -import static tools.refinery.store.query.literal.Literals.check; -import static tools.refinery.store.query.literal.Literals.not; -import static tools.refinery.store.query.term.int_.IntTerms.constant; -import static tools.refinery.store.query.term.int_.IntTerms.less; +import static tools.refinery.logic.term.int_.IntTerms.constant; +import static tools.refinery.logic.term.int_.IntTerms.less; +import static tools.refinery.logic.literal.Literals.check; +import static tools.refinery.logic.literal.Literals.not; import static tools.refinery.store.reasoning.ReasoningAdapter.EXISTS_SYMBOL; import static tools.refinery.store.reasoning.actions.PartialActionLiterals.add; import static tools.refinery.store.reasoning.actions.PartialActionLiterals.focus; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainmentLinkRefiner.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainmentLinkRefiner.java index e44fcffde..e83c33ac7 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainmentLinkRefiner.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainmentLinkRefiner.java @@ -12,7 +12,7 @@ import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.representation.PartialSymbol; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; import java.util.ArrayList; @@ -64,7 +64,7 @@ public InferredContainment mustLink(InferredContainment oldValue) { if (mustLinks.contains(factory.linkType)) { return oldValue; } - return new InferredContainment(oldValue.contains().merge(TruthValue.TRUE), + return new InferredContainment(oldValue.contains().meet(TruthValue.TRUE), addToSet(mustLinks, factory.linkType), oldValue.forbiddenLinks()); } diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainsRefiner.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainsRefiner.java index a7196a1cf..008200406 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainsRefiner.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/ContainsRefiner.java @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The Refinery Authors + * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ @@ -11,7 +11,7 @@ import tools.refinery.store.reasoning.refinement.PartialInterpretationRefiner; import tools.refinery.store.reasoning.representation.PartialSymbol; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; import java.util.LinkedHashMap; @@ -23,7 +23,7 @@ class ContainsRefiner extends AbstractPartialInterpretationRefiner(values.length); + EMPTY_VALUES = LinkedHashMap.newLinkedHashMap(values.length); for (var value : values) { EMPTY_VALUES.put(value, new InferredContainment(value, Set.of(), Set.of())); } @@ -53,7 +53,7 @@ public boolean merge(Tuple key, TruthValue value) { } public InferredContainment mergeLink(InferredContainment oldValue, TruthValue toMerge) { - var newContains = oldValue.contains().merge(toMerge); + var newContains = oldValue.contains().meet(toMerge); if (newContains.equals(oldValue.contains())) { return oldValue; } diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/InferredContainment.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/InferredContainment.java index 8a757ed2c..0b6503c3c 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/InferredContainment.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/containment/InferredContainment.java @@ -6,7 +6,7 @@ package tools.refinery.store.reasoning.translator.containment; import tools.refinery.store.reasoning.representation.PartialRelation; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import java.util.Objects; import java.util.Set; @@ -31,11 +31,11 @@ private static TruthValue adjustContains(TruthValue contains, Set forbiddenLinks) { var result = contains; if (!mustLinks.isEmpty()) { - result = result.merge(TruthValue.TRUE); + result = result.meet(TruthValue.TRUE); } boolean hasErrorLink = mustLinks.stream().anyMatch(forbiddenLinks::contains); if (mustLinks.size() >= 2 || hasErrorLink) { - result = result.merge(TruthValue.ERROR); + result = result.meet(TruthValue.ERROR); } return result; } diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/CrossReferenceUtils.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/CrossReferenceUtils.java index c4a2f2b3d..26449df5d 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/CrossReferenceUtils.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/CrossReferenceUtils.java @@ -5,22 +5,22 @@ */ package tools.refinery.store.reasoning.translator.crossreference; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.dnf.RelationalQuery; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.dnf.RelationalQuery; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.term.uppercardinality.FiniteUpperCardinality; import tools.refinery.store.reasoning.literal.CountLowerBoundLiteral; import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; -import tools.refinery.store.representation.cardinality.FiniteUpperCardinality; import java.util.ArrayList; import java.util.List; -import static tools.refinery.store.query.literal.Literals.check; -import static tools.refinery.store.query.term.int_.IntTerms.constant; -import static tools.refinery.store.query.term.int_.IntTerms.less; +import static tools.refinery.logic.literal.Literals.check; +import static tools.refinery.logic.term.int_.IntTerms.constant; +import static tools.refinery.logic.term.int_.IntTerms.less; import static tools.refinery.store.reasoning.literal.PartialLiterals.may; class CrossReferenceUtils { diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceInfo.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceInfo.java index 7241b0327..982f835f0 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceInfo.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceInfo.java @@ -7,7 +7,7 @@ import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; public record DirectedCrossReferenceInfo(PartialRelation sourceType, Multiplicity sourceMultiplicity, PartialRelation targetType, Multiplicity targetMultiplicity, diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceInitializer.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceInitializer.java index 9347e91e0..7cb16a282 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceInitializer.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceInitializer.java @@ -11,7 +11,7 @@ import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.seed.ModelSeed; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; class DirectedCrossReferenceInitializer implements PartialModelInitializer { diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceRefiner.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceRefiner.java index 2e804b444..75dd5dad3 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceRefiner.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceRefiner.java @@ -11,7 +11,7 @@ import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.representation.PartialSymbol; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; class DirectedCrossReferenceRefiner extends ConcreteSymbolRefiner { diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceTranslator.java index fc7477f1e..5bf1f5aba 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceTranslator.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/DirectedCrossReferenceTranslator.java @@ -5,12 +5,13 @@ */ package tools.refinery.store.reasoning.translator.crossreference; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.dnf.RelationalQuery; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.dse.propagation.PropagationBuilder; import tools.refinery.store.dse.transition.Rule; import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.model.ModelStoreConfiguration; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.dnf.RelationalQuery; import tools.refinery.store.query.view.ForbiddenView; import tools.refinery.store.reasoning.lifting.DnfLifter; import tools.refinery.store.reasoning.literal.Concreteness; @@ -21,9 +22,8 @@ import tools.refinery.store.reasoning.translator.multiplicity.InvalidMultiplicityErrorTranslator; import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; -import static tools.refinery.store.query.literal.Literals.not; +import static tools.refinery.logic.literal.Literals.not; import static tools.refinery.store.reasoning.actions.PartialActionLiterals.add; import static tools.refinery.store.reasoning.actions.PartialActionLiterals.merge; import static tools.refinery.store.reasoning.literal.PartialLiterals.*; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceInfo.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceInfo.java index 34e9032a2..560eb04a6 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceInfo.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceInfo.java @@ -7,7 +7,7 @@ import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; public record UndirectedCrossReferenceInfo(PartialRelation type, Multiplicity multiplicity, TruthValue defaultValue) { public boolean isConstrained() { diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceInitializer.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceInitializer.java index 77339aa0c..84dcfdc56 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceInitializer.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceInitializer.java @@ -13,7 +13,7 @@ import tools.refinery.store.reasoning.seed.ModelSeed; import tools.refinery.store.reasoning.translator.TranslationException; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; import java.util.LinkedHashMap; @@ -73,7 +73,7 @@ private LinkedHashMap getMergedMap(ModelSeed modelSeed) { // Already processed entry. continue; } - var mergedValue = value.merge(oppositeValue == null ? defaultValue : oppositeValue); + var mergedValue = value.meet(oppositeValue == null ? defaultValue : oppositeValue); mergedMap.put(key, mergedValue); if (first != second) { mergedMap.put(oppositeKey, mergedValue); diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceRefiner.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceRefiner.java index 43c1462b8..54aca80f6 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceRefiner.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceRefiner.java @@ -11,7 +11,7 @@ import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.representation.PartialSymbol; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; class UndirectedCrossReferenceRefiner extends ConcreteSymbolRefiner { diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceTranslator.java index b76838b3f..97c0b8002 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceTranslator.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/crossreference/UndirectedCrossReferenceTranslator.java @@ -9,7 +9,7 @@ import tools.refinery.store.dse.transition.Rule; import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.model.ModelStoreConfiguration; -import tools.refinery.store.query.dnf.Query; +import tools.refinery.logic.dnf.Query; import tools.refinery.store.query.view.ForbiddenView; import tools.refinery.store.reasoning.lifting.DnfLifter; import tools.refinery.store.reasoning.literal.Concreteness; @@ -19,9 +19,9 @@ import tools.refinery.store.reasoning.translator.TranslationException; import tools.refinery.store.reasoning.translator.multiplicity.InvalidMultiplicityErrorTranslator; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; -import static tools.refinery.store.query.literal.Literals.not; +import static tools.refinery.logic.literal.Literals.not; import static tools.refinery.store.reasoning.actions.PartialActionLiterals.add; import static tools.refinery.store.reasoning.actions.PartialActionLiterals.merge; import static tools.refinery.store.reasoning.literal.PartialLiterals.*; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilder.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilder.java index a5047768a..d1979b8cd 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilder.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilder.java @@ -131,7 +131,7 @@ private void processReferenceInfo(PartialRelation linkType, ReferenceInfo info) var oppositeInfo = referenceInfoMap.get(opposite); validateOpposite(linkType, info, opposite, oppositeInfo); targetMultiplicity = oppositeInfo.multiplicity(); - defaultValue = defaultValue.merge(oppositeInfo.defaultValue()); + defaultValue = defaultValue.meet(oppositeInfo.defaultValue()); if (oppositeInfo.containment()) { // Skip processing this reference and process it once we encounter its containment opposite. return; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/ReferenceInfo.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/ReferenceInfo.java index 9d7fc9c38..47a2e95f2 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/ReferenceInfo.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/ReferenceInfo.java @@ -7,7 +7,7 @@ import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; public record ReferenceInfo(boolean containment, PartialRelation sourceType, Multiplicity multiplicity, PartialRelation targetType, PartialRelation opposite, TruthValue defaultValue) { diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/ReferenceInfoBuilder.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/ReferenceInfoBuilder.java index 43d01503d..39240d6b6 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/ReferenceInfoBuilder.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/metamodel/ReferenceInfoBuilder.java @@ -11,8 +11,8 @@ import tools.refinery.store.reasoning.translator.multiplicity.ConstrainedMultiplicity; import tools.refinery.store.reasoning.translator.multiplicity.Multiplicity; import tools.refinery.store.reasoning.translator.multiplicity.UnconstrainedMultiplicity; -import tools.refinery.store.representation.TruthValue; -import tools.refinery.store.representation.cardinality.CardinalityInterval; +import tools.refinery.logic.term.truthvalue.TruthValue; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; public final class ReferenceInfoBuilder { private boolean containment; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/EqualsRefiner.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/EqualsRefiner.java index d8db4ec4a..075959328 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/EqualsRefiner.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/EqualsRefiner.java @@ -10,9 +10,9 @@ import tools.refinery.store.reasoning.refinement.AbstractPartialInterpretationRefiner; import tools.refinery.store.reasoning.representation.PartialSymbol; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; -import tools.refinery.store.representation.cardinality.CardinalityInterval; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; +import tools.refinery.logic.term.truthvalue.TruthValue; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; import tools.refinery.store.tuple.Tuple; public class EqualsRefiner extends AbstractPartialInterpretationRefiner { @@ -51,7 +51,7 @@ public boolean merge(Tuple key, TruthValue value) { return false; } var newCount = currentCount.meet(CardinalityIntervals.LONE); - if (newCount.isEmpty()) { + if (newCount.isError()) { return false; } countInterpretation.put(unaryKey, newCount); diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/EqualsRelationRewriter.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/EqualsRelationRewriter.java index 61b9488cc..d4852f91c 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/EqualsRelationRewriter.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/EqualsRelationRewriter.java @@ -5,25 +5,25 @@ */ package tools.refinery.store.reasoning.translator.multiobject; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.dnf.RelationalQuery; -import tools.refinery.store.query.literal.AbstractCallLiteral; -import tools.refinery.store.query.literal.CallLiteral; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.dnf.RelationalQuery; +import tools.refinery.logic.literal.AbstractCallLiteral; +import tools.refinery.logic.literal.CallLiteral; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.term.uppercardinality.UpperCardinalities; +import tools.refinery.logic.term.uppercardinality.UpperCardinality; import tools.refinery.store.query.view.AnySymbolView; import tools.refinery.store.reasoning.interpretation.QueryBasedRelationRewriter; import tools.refinery.store.reasoning.literal.Concreteness; import tools.refinery.store.reasoning.literal.Modality; -import tools.refinery.store.representation.cardinality.UpperCardinalities; -import tools.refinery.store.representation.cardinality.UpperCardinality; import java.util.List; import java.util.Set; -import static tools.refinery.store.query.literal.Literals.check; -import static tools.refinery.store.query.term.uppercardinality.UpperCardinalityTerms.constant; -import static tools.refinery.store.query.term.uppercardinality.UpperCardinalityTerms.lessEq; +import static tools.refinery.logic.literal.Literals.check; +import static tools.refinery.logic.term.uppercardinality.UpperCardinalityTerms.constant; +import static tools.refinery.logic.term.uppercardinality.UpperCardinalityTerms.lessEq; class EqualsRelationRewriter extends QueryBasedRelationRewriter { private EqualsRelationRewriter(RelationalQuery may, RelationalQuery must) { diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/ExistsRefiner.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/ExistsRefiner.java index f134fe921..83fa4377d 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/ExistsRefiner.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/ExistsRefiner.java @@ -10,9 +10,9 @@ import tools.refinery.store.reasoning.refinement.AbstractPartialInterpretationRefiner; import tools.refinery.store.reasoning.representation.PartialSymbol; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; -import tools.refinery.store.representation.cardinality.CardinalityInterval; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; +import tools.refinery.logic.term.truthvalue.TruthValue; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; import tools.refinery.store.tuple.Tuple; public class ExistsRefiner extends AbstractPartialInterpretationRefiner { @@ -42,7 +42,7 @@ public boolean merge(Tuple key, TruthValue value) { } default -> throw new IllegalArgumentException("Unknown TruthValue: " + value); } - if (newCount.isEmpty()) { + if (newCount.isError()) { return false; } countInterpretation.put(key, newCount); diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/LowerCardinalityView.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/LowerCardinalityView.java index 9873888ce..5691b9e3f 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/LowerCardinalityView.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/LowerCardinalityView.java @@ -5,10 +5,10 @@ */ package tools.refinery.store.reasoning.translator.multiobject; -import tools.refinery.store.query.term.Parameter; +import tools.refinery.logic.term.Parameter; import tools.refinery.store.query.view.AbstractFunctionView; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.cardinality.CardinalityInterval; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; class LowerCardinalityView extends AbstractFunctionView { public LowerCardinalityView(Symbol symbol) { diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectInitializer.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectInitializer.java index 899181552..eb13174cf 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectInitializer.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectInitializer.java @@ -12,9 +12,9 @@ import tools.refinery.store.reasoning.seed.ModelSeed; import tools.refinery.store.reasoning.translator.TranslationException; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; -import tools.refinery.store.representation.cardinality.CardinalityInterval; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; +import tools.refinery.logic.term.truthvalue.TruthValue; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; import tools.refinery.store.tuple.Tuple; import java.util.Arrays; @@ -37,7 +37,7 @@ public void initialize(Model model, ModelSeed modelSeed) { var uniqueTable = new HashMap(); for (int i = 0; i < intervals.length; i++) { var interval = intervals[i]; - if (interval.isEmpty()) { + if (interval.isError()) { throw new TranslationException(ReasoningAdapter.EXISTS_SYMBOL, "Inconsistent existence or equality for node " + i); } diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectStorageRefiner.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectStorageRefiner.java index e48934d8c..ab401f9ee 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectStorageRefiner.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectStorageRefiner.java @@ -9,8 +9,8 @@ import tools.refinery.store.model.Model; import tools.refinery.store.reasoning.refinement.StorageRefiner; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.cardinality.CardinalityInterval; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; import tools.refinery.store.tuple.Tuple; class MultiObjectStorageRefiner implements StorageRefiner { @@ -28,7 +28,7 @@ public boolean split(int parentNode, int childNode) { return false; } var newParentCount = parentCount.take(1); - if (newParentCount.isEmpty()) { + if (newParentCount.isError()) { return false; } var childKey = Tuple.of(childNode); diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectTranslator.java index 97fda9d51..be15b6d70 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectTranslator.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiObjectTranslator.java @@ -5,17 +5,21 @@ */ package tools.refinery.store.reasoning.translator.multiobject; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.literal.Literals; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.term.cardinalityinterval.CardinalityDomain; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; +import tools.refinery.logic.term.int_.IntTerms; +import tools.refinery.logic.term.uppercardinality.UpperCardinalities; +import tools.refinery.logic.term.uppercardinality.UpperCardinality; +import tools.refinery.logic.term.uppercardinality.UpperCardinalityTerms; import tools.refinery.store.dse.propagation.PropagationBuilder; import tools.refinery.store.dse.transition.Rule; import tools.refinery.store.dse.transition.objectives.Criteria; import tools.refinery.store.dse.transition.objectives.Objectives; import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.model.ModelStoreConfiguration; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.literal.Literals; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.term.int_.IntTerms; -import tools.refinery.store.query.term.uppercardinality.UpperCardinalityTerms; import tools.refinery.store.query.view.AnySymbolView; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.reasoning.ReasoningBuilder; @@ -24,15 +28,11 @@ import tools.refinery.store.reasoning.translator.PartialRelationTranslator; import tools.refinery.store.reasoning.translator.RoundingMode; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.cardinality.CardinalityDomain; -import tools.refinery.store.representation.cardinality.CardinalityInterval; -import tools.refinery.store.representation.cardinality.UpperCardinalities; -import tools.refinery.store.representation.cardinality.UpperCardinality; import java.util.List; -import static tools.refinery.store.query.literal.Literals.check; -import static tools.refinery.store.query.term.int_.IntTerms.*; +import static tools.refinery.logic.literal.Literals.check; +import static tools.refinery.logic.term.int_.IntTerms.*; public class MultiObjectTranslator implements ModelStoreConfiguration { public static final Symbol COUNT_STORAGE = Symbol.of("COUNT", 1, CardinalityInterval.class, diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiView.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiView.java index 498bcd83c..d81274b39 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiView.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/MultiView.java @@ -7,8 +7,8 @@ import tools.refinery.store.query.view.TuplePreservingView; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.cardinality.CardinalityInterval; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; import tools.refinery.store.tuple.Tuple; class MultiView extends TuplePreservingView { diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/UpperCardinalityView.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/UpperCardinalityView.java index 6be6ae1b8..5797c4b03 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/UpperCardinalityView.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiobject/UpperCardinalityView.java @@ -5,11 +5,11 @@ */ package tools.refinery.store.reasoning.translator.multiobject; -import tools.refinery.store.query.term.Parameter; +import tools.refinery.logic.term.Parameter; import tools.refinery.store.query.view.AbstractFunctionView; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.cardinality.CardinalityInterval; -import tools.refinery.store.representation.cardinality.UpperCardinality; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; +import tools.refinery.logic.term.uppercardinality.UpperCardinality; class UpperCardinalityView extends AbstractFunctionView { public UpperCardinalityView(Symbol symbol) { diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/ConstrainedMultiplicity.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/ConstrainedMultiplicity.java index 9db9cc963..c327aac83 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/ConstrainedMultiplicity.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/ConstrainedMultiplicity.java @@ -7,9 +7,9 @@ import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.translator.TranslationException; -import tools.refinery.store.representation.cardinality.CardinalityInterval; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; -import tools.refinery.store.representation.cardinality.NonEmptyCardinalityInterval; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; +import tools.refinery.logic.term.cardinalityinterval.NonEmptyCardinalityInterval; public record ConstrainedMultiplicity(NonEmptyCardinalityInterval multiplicity, PartialRelation errorSymbol) implements Multiplicity { diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/InvalidMultiplicityErrorTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/InvalidMultiplicityErrorTranslator.java index a506d8028..0ca6eac24 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/InvalidMultiplicityErrorTranslator.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/InvalidMultiplicityErrorTranslator.java @@ -5,31 +5,26 @@ */ package tools.refinery.store.reasoning.translator.multiplicity; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.term.uppercardinality.FiniteUpperCardinality; +import tools.refinery.logic.term.uppercardinality.UpperCardinalities; +import tools.refinery.logic.term.uppercardinality.UpperCardinality; +import tools.refinery.logic.term.uppercardinality.UpperCardinalityTerms; import tools.refinery.store.dse.transition.objectives.Objectives; import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.model.ModelStoreConfiguration; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.term.Variable; -import tools.refinery.store.query.term.int_.IntTerms; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.reasoning.lifting.DnfLifter; import tools.refinery.store.reasoning.literal.*; import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.translator.PartialRelationTranslator; import tools.refinery.store.reasoning.translator.TranslationException; -import tools.refinery.store.representation.cardinality.FiniteUpperCardinality; -import tools.refinery.store.representation.cardinality.UpperCardinalities; -import tools.refinery.store.representation.cardinality.UpperCardinality; import java.util.List; -import static tools.refinery.store.query.literal.Literals.check; -import static tools.refinery.store.query.term.int_.IntTerms.INT_SUM; -import static tools.refinery.store.query.term.int_.IntTerms.constant; -import static tools.refinery.store.query.term.int_.IntTerms.greater; -import static tools.refinery.store.query.term.int_.IntTerms.sub; -import static tools.refinery.store.query.term.uppercardinality.UpperCardinalityTerms.constant; -import static tools.refinery.store.query.term.uppercardinality.UpperCardinalityTerms.less; +import static tools.refinery.logic.literal.Literals.check; +import static tools.refinery.logic.term.int_.IntTerms.*; import static tools.refinery.store.reasoning.literal.PartialLiterals.candidateMust; import static tools.refinery.store.reasoning.literal.PartialLiterals.must; @@ -81,17 +76,18 @@ public void apply(ModelStoreBuilder storeBuilder) { mustBuilder.clause(UpperCardinality.class, existingContents -> List.of( must(nodeType.call(node)), new CountUpperBoundLiteral(existingContents, linkType, arguments), - check(less(existingContents, constant(lowerBoundCardinality))) + check(UpperCardinalityTerms.less(existingContents, + UpperCardinalityTerms.constant(lowerBoundCardinality))) )); candidateMayBuilder.clause(Integer.class, existingContents -> List.of( candidateMust(nodeType.call(node)), new CountCandidateLowerBoundLiteral(existingContents, linkType, arguments), - check(IntTerms.less(existingContents, constant(lowerBound))) + check(less(existingContents, constant(lowerBound))) )); candidateMustBuilder.clause(Integer.class, existingContents -> List.of( candidateMust(nodeType.call(node)), new CountCandidateUpperBoundLiteral(existingContents, linkType, arguments), - check(IntTerms.less(existingContents, constant(lowerBound))) + check(less(existingContents, constant(lowerBound))) )); missingBuilder.clause(Integer.class, existingContents -> List.of( candidateMust(nodeType.call(node)), diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/Multiplicity.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/Multiplicity.java index d1d6dd1e3..d6035781e 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/Multiplicity.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/Multiplicity.java @@ -5,7 +5,7 @@ */ package tools.refinery.store.reasoning.translator.multiplicity; -import tools.refinery.store.representation.cardinality.CardinalityInterval; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; public sealed interface Multiplicity permits ConstrainedMultiplicity, UnconstrainedMultiplicity { CardinalityInterval multiplicity(); diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/UnconstrainedMultiplicity.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/UnconstrainedMultiplicity.java index 2159b88cf..fb669a790 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/UnconstrainedMultiplicity.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/multiplicity/UnconstrainedMultiplicity.java @@ -5,8 +5,8 @@ */ package tools.refinery.store.reasoning.translator.multiplicity; -import tools.refinery.store.representation.cardinality.CardinalityInterval; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; +import tools.refinery.logic.term.cardinalityinterval.CardinalityInterval; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; // Singleton implementation, because there is only a single complete interval. @SuppressWarnings("squid:S6548") diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/opposite/OppositeInterpretation.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/opposite/OppositeInterpretation.java index 7290ab407..75828086a 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/opposite/OppositeInterpretation.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/opposite/OppositeInterpretation.java @@ -1,11 +1,11 @@ /* - * SPDX-FileCopyrightText: 2023 The Refinery Authors + * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.reasoning.translator.opposite; - +import tools.refinery.logic.AbstractValue; import tools.refinery.store.map.AnyVersionedMap; import tools.refinery.store.map.Cursor; import tools.refinery.store.reasoning.ReasoningAdapter; @@ -17,7 +17,7 @@ import java.util.Set; -class OppositeInterpretation extends AbstractPartialInterpretation { +class OppositeInterpretation, C> extends AbstractPartialInterpretation { private final PartialInterpretation opposite; private OppositeInterpretation(ReasoningAdapter adapter, Concreteness concreteness, @@ -36,7 +36,7 @@ public Cursor getAll() { return new OppositeCursor<>(opposite.getAll()); } - public static Factory of(PartialSymbol oppositeSymbol) { + public static , C1> Factory of(PartialSymbol oppositeSymbol) { return (adapter, concreteness, partialSymbol) -> { var opposite = adapter.getPartialInterpretation(concreteness, oppositeSymbol); return new OppositeInterpretation<>(adapter, concreteness, partialSymbol, opposite); diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/opposite/OppositeRefiner.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/opposite/OppositeRefiner.java index d09684dfd..47e3ac6a8 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/opposite/OppositeRefiner.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/opposite/OppositeRefiner.java @@ -1,17 +1,18 @@ /* - * SPDX-FileCopyrightText: 2023 The Refinery Authors + * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors * * SPDX-License-Identifier: EPL-2.0 */ package tools.refinery.store.reasoning.translator.opposite; +import tools.refinery.logic.AbstractValue; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.reasoning.refinement.AbstractPartialInterpretationRefiner; import tools.refinery.store.reasoning.refinement.PartialInterpretationRefiner; import tools.refinery.store.reasoning.representation.PartialSymbol; import tools.refinery.store.tuple.Tuple; -public class OppositeRefiner extends AbstractPartialInterpretationRefiner { +public class OppositeRefiner, C> extends AbstractPartialInterpretationRefiner { private final PartialInterpretationRefiner opposite; protected OppositeRefiner(ReasoningAdapter adapter, PartialSymbol partialSymbol, @@ -26,7 +27,7 @@ public boolean merge(Tuple key, A value) { return opposite.merge(oppositeKey, value); } - public static Factory of(PartialSymbol oppositeSymbol) { + public static , C1> Factory of(PartialSymbol oppositeSymbol) { return (adapter, partialSymbol) -> new OppositeRefiner<>(adapter, partialSymbol, oppositeSymbol); } } diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/opposite/OppositeRelationTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/opposite/OppositeRelationTranslator.java index 6e15a628e..29abed7a8 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/opposite/OppositeRelationTranslator.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/opposite/OppositeRelationTranslator.java @@ -5,11 +5,11 @@ */ package tools.refinery.store.reasoning.translator.opposite; +import tools.refinery.logic.literal.AbstractCallLiteral; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.Variable; import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.model.ModelStoreConfiguration; -import tools.refinery.store.query.literal.AbstractCallLiteral; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.Variable; import tools.refinery.store.reasoning.interpretation.PartialRelationRewriter; import tools.refinery.store.reasoning.literal.Concreteness; import tools.refinery.store.reasoning.literal.ModalConstraint; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/predicate/PredicateTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/predicate/PredicateTranslator.java index b401118e4..010ce9771 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/predicate/PredicateTranslator.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/predicate/PredicateTranslator.java @@ -5,13 +5,14 @@ */ package tools.refinery.store.reasoning.translator.predicate; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.dnf.RelationalQuery; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.NodeVariable; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.model.ModelStoreConfiguration; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.dnf.RelationalQuery; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.NodeVariable; -import tools.refinery.store.query.term.Variable; import tools.refinery.store.query.view.ForbiddenView; import tools.refinery.store.query.view.MayView; import tools.refinery.store.query.view.MustView; @@ -19,9 +20,8 @@ import tools.refinery.store.reasoning.translator.PartialRelationTranslator; import tools.refinery.store.reasoning.translator.TranslationException; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; -import static tools.refinery.store.query.literal.Literals.not; +import static tools.refinery.logic.literal.Literals.not; import static tools.refinery.store.reasoning.literal.PartialLiterals.may; import static tools.refinery.store.reasoning.literal.PartialLiterals.must; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/proxy/PartialRelationTranslatorProxy.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/proxy/PartialRelationTranslatorProxy.java index 45dc5bd22..508739937 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/proxy/PartialRelationTranslatorProxy.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/proxy/PartialRelationTranslatorProxy.java @@ -5,11 +5,11 @@ */ package tools.refinery.store.reasoning.translator.proxy; +import tools.refinery.logic.literal.AbstractCallLiteral; +import tools.refinery.logic.literal.Literal; +import tools.refinery.logic.term.Variable; import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.model.ModelStoreConfiguration; -import tools.refinery.store.query.literal.AbstractCallLiteral; -import tools.refinery.store.query.literal.Literal; -import tools.refinery.store.query.term.Variable; import tools.refinery.store.reasoning.interpretation.PartialRelationRewriter; import tools.refinery.store.reasoning.literal.Concreteness; import tools.refinery.store.reasoning.literal.ModalConstraint; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredTypeRefiner.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredTypeRefiner.java index 40a7b3fa3..257b91366 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredTypeRefiner.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredTypeRefiner.java @@ -10,7 +10,7 @@ import tools.refinery.store.reasoning.refinement.AbstractPartialInterpretationRefiner; import tools.refinery.store.reasoning.representation.PartialSymbol; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; class InferredTypeRefiner extends AbstractPartialInterpretationRefiner { diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeAnalysisResult.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeAnalysisResult.java index ebe0d1b9a..324e2b9e3 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeAnalysisResult.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeAnalysisResult.java @@ -6,7 +6,7 @@ package tools.refinery.store.reasoning.translator.typehierarchy; import tools.refinery.store.reasoning.representation.PartialRelation; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import java.util.*; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyInitializer.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyInitializer.java index 233e43f02..aa76d927f 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyInitializer.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyInitializer.java @@ -10,7 +10,7 @@ import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.seed.ModelSeed; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; import java.util.Arrays; diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTranslator.java index 37ea14484..700bbe88f 100644 --- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTranslator.java +++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTranslator.java @@ -5,11 +5,11 @@ */ package tools.refinery.store.reasoning.translator.typehierarchy; +import tools.refinery.logic.dnf.Query; import tools.refinery.store.dse.transition.Rule; import tools.refinery.store.dse.transition.actions.ActionLiteral; import tools.refinery.store.model.ModelStoreBuilder; import tools.refinery.store.model.ModelStoreConfiguration; -import tools.refinery.store.query.dnf.Query; import tools.refinery.store.reasoning.ReasoningBuilder; import tools.refinery.store.reasoning.actions.PartialActionLiterals; import tools.refinery.store.reasoning.literal.PartialLiterals; @@ -21,7 +21,7 @@ import java.util.ArrayList; -import static tools.refinery.store.query.literal.Literals.not; +import static tools.refinery.logic.literal.Literals.not; import static tools.refinery.store.reasoning.literal.PartialLiterals.candidateMust; import static tools.refinery.store.reasoning.literal.PartialLiterals.may; diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/PartialModelTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/PartialModelTest.java index f81351029..2aa058a4b 100644 --- a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/PartialModelTest.java +++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/PartialModelTest.java @@ -6,10 +6,11 @@ package tools.refinery.store.reasoning; import org.junit.jupiter.api.Test; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.term.Variable; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.model.ModelStore; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.term.Variable; import tools.refinery.store.query.interpreter.QueryInterpreterAdapter; import tools.refinery.store.query.view.ForbiddenView; import tools.refinery.store.reasoning.literal.Concreteness; @@ -18,14 +19,13 @@ import tools.refinery.store.reasoning.translator.PartialRelationTranslator; import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; import tools.refinery.store.tuple.Tuple; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; -import static tools.refinery.store.query.literal.Literals.not; +import static tools.refinery.logic.literal.Literals.not; import static tools.refinery.store.reasoning.ReasoningAdapter.EQUALS_SYMBOL; import static tools.refinery.store.reasoning.ReasoningAdapter.EXISTS_SYMBOL; import static tools.refinery.store.reasoning.literal.PartialLiterals.may; diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/lifting/DnfLifterTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/lifting/DnfLifterTest.java index 793d1cec5..f3e4d3b03 100644 --- a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/lifting/DnfLifterTest.java +++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/lifting/DnfLifterTest.java @@ -7,9 +7,10 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import tools.refinery.store.query.dnf.Dnf; -import tools.refinery.store.query.dnf.Query; -import tools.refinery.store.query.term.ParameterDirection; +import tools.refinery.logic.dnf.Dnf; +import tools.refinery.logic.dnf.Query; +import tools.refinery.logic.term.ParameterDirection; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.query.view.AnySymbolView; import tools.refinery.store.query.view.FunctionView; import tools.refinery.store.query.view.MustView; @@ -20,15 +21,14 @@ import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.representation.PartialSymbol; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; -import static tools.refinery.store.query.literal.Literals.check; -import static tools.refinery.store.query.literal.Literals.not; -import static tools.refinery.store.query.term.int_.IntTerms.*; -import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo; +import static tools.refinery.logic.literal.Literals.check; +import static tools.refinery.logic.literal.Literals.not; +import static tools.refinery.logic.term.int_.IntTerms.*; +import static tools.refinery.logic.tests.QueryMatchers.structurallyEqualTo; class DnfLifterTest { private static final Symbol friendSymbol = Symbol.of("friend", 2, TruthValue.class, @@ -49,7 +49,7 @@ void beforeEach() { @Test void liftPartialRelationCallTest() { var input = Query.of("Actual", (builder, p1) -> builder.clause((v1) -> List.of( - friend.call(p1, v1) + friend.call(p1, v1) ))).getDnf(); var actual = sut.lift(Modality.MUST, Concreteness.PARTIAL, input); @@ -204,7 +204,7 @@ void liftPartialDnfQuantifiedNegativeInputCallTest() { @Test void liftPartialRelationTransitiveCallTest() { - var input = Query.of("Actual", (builder, p1, p2)-> builder.clause( + var input = Query.of("Actual", (builder, p1, p2) -> builder.clause( friend.callTransitive(p1, p2), not(person.call(p2)) )).getDnf(); @@ -233,7 +233,7 @@ void liftPartialRelationTransitiveCallTest() { @Test void liftPartialSymbolTransitiveCallTest() { - var input = Query.of("Actual", (builder, p1, p2)-> builder.clause( + var input = Query.of("Actual", (builder, p1, p2) -> builder.clause( friendMustView.callTransitive(p1, p2), not(person.call(p2)) )).getDnf(); @@ -332,7 +332,8 @@ void liftNotEquivalentTest() { var expected = Query.of("Expected", (builder, p1, p2) -> builder.clause( ModalConstraint.of(Modality.MAY, Concreteness.PARTIAL, friend).call(p1, p2), - not(ModalConstraint.of(Modality.MUST, Concreteness.PARTIAL, ReasoningAdapter.EQUALS_SYMBOL).call(p1, p2)) + not(ModalConstraint.of(Modality.MUST, Concreteness.PARTIAL, ReasoningAdapter.EQUALS_SYMBOL).call(p1, + p2)) )).getDnf(); assertThat(actual, structurallyEqualTo(expected)); diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/containment/ContainmentHierarchyTranslatorTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/containment/ContainmentHierarchyTranslatorTest.java index 1d0ac02d1..e889b80df 100644 --- a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/containment/ContainmentHierarchyTranslatorTest.java +++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/containment/ContainmentHierarchyTranslatorTest.java @@ -18,8 +18,8 @@ import tools.refinery.store.reasoning.translator.multiplicity.UnconstrainedMultiplicity; import tools.refinery.store.reasoning.translator.typehierarchy.TypeHierarchy; import tools.refinery.store.reasoning.translator.typehierarchy.TypeHierarchyTranslator; -import tools.refinery.store.representation.TruthValue; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; +import tools.refinery.logic.term.truthvalue.TruthValue; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; import tools.refinery.store.tuple.Tuple; import java.util.Map; diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilderTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilderTest.java index ba6ba6da6..e2b3f31eb 100644 --- a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilderTest.java +++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelBuilderTest.java @@ -8,7 +8,7 @@ import org.junit.jupiter.api.Test; import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.translator.TranslationException; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; import static org.junit.jupiter.api.Assertions.assertThrows; diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelTest.java index 88e6a4d7f..f8e9e1b50 100644 --- a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelTest.java +++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/metamodel/MetamodelTest.java @@ -16,8 +16,8 @@ import tools.refinery.store.reasoning.seed.ModelSeed; import tools.refinery.store.reasoning.translator.containment.ContainmentHierarchyTranslator; import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; -import tools.refinery.store.representation.TruthValue; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; +import tools.refinery.logic.term.truthvalue.TruthValue; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; import tools.refinery.store.tuple.Tuple; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/multiobject/PartialCountTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/multiobject/PartialCountTest.java index 48a046fc7..5ef189d5d 100644 --- a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/multiobject/PartialCountTest.java +++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/multiobject/PartialCountTest.java @@ -8,9 +8,9 @@ import org.junit.jupiter.api.Test; import tools.refinery.store.model.ModelStore; import tools.refinery.store.query.ModelQueryAdapter; -import tools.refinery.store.query.dnf.Query; +import tools.refinery.logic.dnf.Query; import tools.refinery.store.query.resultset.ResultSet; -import tools.refinery.store.query.term.Variable; +import tools.refinery.logic.term.Variable; import tools.refinery.store.query.interpreter.QueryInterpreterAdapter; import tools.refinery.store.reasoning.ReasoningAdapter; import tools.refinery.store.reasoning.ReasoningStoreAdapter; @@ -20,17 +20,17 @@ import tools.refinery.store.reasoning.seed.ModelSeed; import tools.refinery.store.reasoning.translator.PartialRelationTranslator; import tools.refinery.store.representation.Symbol; -import tools.refinery.store.representation.TruthValue; -import tools.refinery.store.representation.cardinality.CardinalityIntervals; -import tools.refinery.store.representation.cardinality.UpperCardinalities; -import tools.refinery.store.representation.cardinality.UpperCardinality; +import tools.refinery.logic.term.truthvalue.TruthValue; +import tools.refinery.logic.term.cardinalityinterval.CardinalityIntervals; +import tools.refinery.logic.term.uppercardinality.UpperCardinalities; +import tools.refinery.logic.term.uppercardinality.UpperCardinality; import tools.refinery.store.tuple.Tuple; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import static tools.refinery.store.query.literal.Literals.not; +import static tools.refinery.logic.literal.Literals.not; import static tools.refinery.store.reasoning.literal.PartialLiterals.must; class PartialCountTest { diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/ConcreteSupertypeTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/ConcreteSupertypeTest.java index 4bef9d8e1..b9edcf758 100644 --- a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/ConcreteSupertypeTest.java +++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/ConcreteSupertypeTest.java @@ -14,7 +14,7 @@ import tools.refinery.store.reasoning.literal.Concreteness; import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.seed.ModelSeed; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeAnalysisExampleHierarchyTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeAnalysisExampleHierarchyTest.java index d9a5477ee..d860c7d61 100644 --- a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeAnalysisExampleHierarchyTest.java +++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeAnalysisExampleHierarchyTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import tools.refinery.store.reasoning.representation.PartialRelation; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import java.util.Set; diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyPartialModelTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyPartialModelTest.java index 5af725bb7..e87b26842 100644 --- a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyPartialModelTest.java +++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyPartialModelTest.java @@ -16,7 +16,7 @@ import tools.refinery.store.reasoning.literal.Concreteness; import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.seed.ModelSeed; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import tools.refinery.store.tuple.Tuple; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTest.java b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTest.java index 931c62dd9..b7c99d2d5 100644 --- a/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTest.java +++ b/subprojects/store-reasoning/src/test/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test; import tools.refinery.store.reasoning.representation.PartialRelation; import tools.refinery.store.reasoning.translator.TranslationException; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.logic.term.truthvalue.TruthValue; import java.util.Set; diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/AbstractDomain.java b/subprojects/store/src/main/java/tools/refinery/store/representation/AbstractDomain.java deleted file mode 100644 index dfdb43bd9..000000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/AbstractDomain.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors - * - * SPDX-License-Identifier: EPL-2.0 - */ -package tools.refinery.store.representation; - -import java.util.Objects; -import java.util.Optional; - -public non-sealed interface AbstractDomain extends AnyAbstractDomain { - @Override - Class abstractType(); - - @Override - Class concreteType(); - - A toAbstract(C concreteValue); - - Optional toConcrete(A abstractValue); - - default boolean isConcrete(A abstractValue) { - return toConcrete(abstractValue).isPresent(); - } - - default boolean isRefinement(A originalValue, A refinedValue) { - return Objects.equals(commonRefinement(originalValue, refinedValue), refinedValue); - } - - A commonRefinement(A leftValue, A rightValue); - - A commonAncestor(A leftValue, A rightValue); - - A unknown(); - - boolean isError(A abstractValue); -} diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/TruthValueDomain.java b/subprojects/store/src/main/java/tools/refinery/store/representation/TruthValueDomain.java deleted file mode 100644 index 61696dcaf..000000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/TruthValueDomain.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors - * - * SPDX-License-Identifier: EPL-2.0 - */ -package tools.refinery.store.representation; - -import java.util.Optional; - -// Singleton pattern, because there is only one domain for truth values. -@SuppressWarnings("squid:S6548") -public final class TruthValueDomain implements AbstractDomain { - public static final TruthValueDomain INSTANCE = new TruthValueDomain(); - - private TruthValueDomain() { - } - - @Override - public Class abstractType() { - return TruthValue.class; - } - - @Override - public Class concreteType() { - return Boolean.class; - } - - @Override - public TruthValue toAbstract(Boolean concreteValue) { - return TruthValue.toTruthValue(concreteValue); - } - - @Override - public Optional toConcrete(TruthValue abstractValue) { - return switch (abstractValue) { - case TRUE -> Optional.of(true); - case FALSE -> Optional.of(false); - default -> Optional.empty(); - }; - } - - @Override - public boolean isConcrete(TruthValue abstractValue) { - return abstractValue.isConcrete(); - } - - @Override - public TruthValue commonRefinement(TruthValue leftValue, TruthValue rightValue) { - return leftValue.merge(rightValue); - } - - @Override - public TruthValue commonAncestor(TruthValue leftValue, TruthValue rightValue) { - return leftValue.join(rightValue); - } - - @Override - public TruthValue unknown() { - return TruthValue.UNKNOWN; - } - - @Override - public boolean isError(TruthValue abstractValue) { - return !abstractValue.isConsistent(); - } -} diff --git a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityDomain.java b/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityDomain.java deleted file mode 100644 index 7ae2d935a..000000000 --- a/subprojects/store/src/main/java/tools/refinery/store/representation/cardinality/CardinalityDomain.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 The Refinery Authors - * - * SPDX-License-Identifier: EPL-2.0 - */ -package tools.refinery.store.representation.cardinality; - -import tools.refinery.store.representation.AbstractDomain; - -import java.util.Optional; - -// Singleton pattern, because there is only one domain for truth values. -@SuppressWarnings("squid:S6548") -public class CardinalityDomain implements AbstractDomain { - public static final CardinalityDomain INSTANCE = new CardinalityDomain(); - - private CardinalityDomain() { - } - - @Override - public Class abstractType() { - return CardinalityInterval.class; - } - - @Override - public Class concreteType() { - return Integer.class; - } - - @Override - public CardinalityInterval toAbstract(Integer concreteValue) { - return CardinalityIntervals.exactly(concreteValue); - } - - @Override - public Optional toConcrete(CardinalityInterval abstractValue) { - return isConcrete(abstractValue) ? Optional.of(abstractValue.lowerBound()) : Optional.empty(); - } - - @Override - public boolean isConcrete(CardinalityInterval abstractValue) { - if (!(abstractValue instanceof NonEmptyCardinalityInterval nonEmptyValue) || - !((nonEmptyValue.upperBound()) instanceof FiniteUpperCardinality finiteUpperCardinality)) { - return false; - } - return nonEmptyValue.lowerBound() == finiteUpperCardinality.finiteUpperBound(); - } - - @Override - public CardinalityInterval commonRefinement(CardinalityInterval leftValue, CardinalityInterval rightValue) { - return leftValue.meet(rightValue); - } - - @Override - public CardinalityInterval commonAncestor(CardinalityInterval leftValue, CardinalityInterval rightValue) { - return leftValue.join(rightValue); - } - - @Override - public CardinalityInterval unknown() { - return CardinalityIntervals.SET; - } - - @Override - public boolean isError(CardinalityInterval abstractValue) { - return abstractValue.isEmpty(); - } -} diff --git a/z3/build.gradle.kts b/z3/build.gradle.kts new file mode 100644 index 000000000..74ee6bc8d --- /dev/null +++ b/z3/build.gradle.kts @@ -0,0 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2023 The Refinery Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +plugins { + alias(libs.plugins.versions) +} diff --git a/z3/buildSrc/build.gradle.kts b/z3/buildSrc/build.gradle.kts new file mode 100644 index 000000000..adc19562a --- /dev/null +++ b/z3/buildSrc/build.gradle.kts @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2023 The Refinery Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +plugins { + `kotlin-dsl` + alias(libs.plugins.versions) +} + +repositories { + mavenCentral() +} + +dependencies { + implementation(libs.asm) +} diff --git a/z3/buildSrc/settings.gradle.kts b/z3/buildSrc/settings.gradle.kts new file mode 100644 index 000000000..095ab24c9 --- /dev/null +++ b/z3/buildSrc/settings.gradle.kts @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2023 The Refinery Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} diff --git a/z3/buildSrc/src/main/java/tools/refinery/z3/gradle/ClassFilePatcher.java b/z3/buildSrc/src/main/java/tools/refinery/z3/gradle/ClassFilePatcher.java new file mode 100644 index 000000000..5ac560052 --- /dev/null +++ b/z3/buildSrc/src/main/java/tools/refinery/z3/gradle/ClassFilePatcher.java @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: 2023 The Refinery Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ +package tools.refinery.z3.gradle; + +import org.objectweb.asm.*; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +public final class ClassFilePatcher { + private ClassFilePatcher() { + throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); + } + + public static void removeClassInitializer(File classFile) throws IOException { + byte[] resultBytes; + try (var fileReader = new FileInputStream(classFile)) { + var classReader = new ClassReader(fileReader); + var classWriter = new ClassWriter(classReader, 0); + var classVisitor = new Visitor(classWriter); + classReader.accept(classVisitor, 0); + resultBytes = classWriter.toByteArray(); + } + try (var fileWriter = new FileOutputStream(classFile)) { + fileWriter.write(resultBytes); + } + } + + private static class Visitor extends ClassVisitor { + protected Visitor(ClassVisitor classVisitor) { + super(Opcodes.ASM9, classVisitor); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, + String[] exceptions) { + if (name.equals("")) { + return null; + } + return super.visitMethod(access, name, descriptor, signature, exceptions); + } + } +} diff --git a/z3/buildSrc/src/main/kotlin/tools/refinery/z3/gradle/java-library.gradle.kts b/z3/buildSrc/src/main/kotlin/tools/refinery/z3/gradle/java-library.gradle.kts new file mode 100644 index 000000000..75d64a6f7 --- /dev/null +++ b/z3/buildSrc/src/main/kotlin/tools/refinery/z3/gradle/java-library.gradle.kts @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2023 The Refinery Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ +package tools.refinery.z3.gradle + +plugins { + `java-library` + `maven-publish` +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + } +} + +repositories { + mavenCentral() + + // Configuration based on https://stackoverflow.com/a/34327202 to pretend that GitHub is an Ivy repository + // in order to take advantage of Gradle dependency caching. + val github = ivy { + setUrl("https://github.com") + patternLayout { + artifact("/[organisation]/[module]/releases/download/[module]-[revision]/[classifier].[ext]") + artifact("/[organisation]/[module]/archive/refs/tags/[module]-[revision].[ext]") + } + metadataSources { + artifact() + } + } + + exclusiveContent { + forRepositories(github) + filter { + includeGroup("Z3Prover") + } + } +} + +val z3: Provider by configurations.registering { + isCanBeConsumed = false + isCanBeResolved = true +} + +tasks { + jar { + manifest { + attributes( + "Bundle-SymbolicName" to "${project.group}.${project.name}", + "Bundle-Version" to project.version + ) + } + } +} + +publishing.publications { + register("mavenJava") { + from(components["java"]) + pom { + licenses { + license { + name = "MIT License" + url = "https://raw.githubusercontent.com/Z3Prover/z3/master/LICENSE.txt" + } + license { + name = "The Apache License, Version 2.0" + url = "http://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + } + } +} diff --git a/z3/docker/.gitignore b/z3/docker/.gitignore new file mode 100644 index 000000000..d5b53f811 --- /dev/null +++ b/z3/docker/.gitignore @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2023 The Refinery Authors +# +# SPDX-License-Identifier: CC0-1.0 + +out/ diff --git a/z3/docker/README.md b/z3/docker/README.md new file mode 100644 index 000000000..d979fd5ef --- /dev/null +++ b/z3/docker/README.md @@ -0,0 +1,14 @@ + + +# Scripts for cross-building Z3 for linux-aarch64 + +We intentionally build in Ubuntu Focal to avoid a dependency on glibc 2.35. +See https://github.com/Z3Prover/z3/issues/6572 for details. + +This should not be necessary once Z3 4.12.3 is released, as now Z3 nighly +includes linux-aarch64 builds. +See https://github.com/Z3Prover/z3/issues/6835 for details. diff --git a/z3/docker/build_in_docker.sh b/z3/docker/build_in_docker.sh new file mode 100755 index 000000000..549e823de --- /dev/null +++ b/z3/docker/build_in_docker.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2023 The Refinery Authors +# +# SPDX-License-Identifier: Apache-2.0 + +set -euo pipefail + +z3_version="$1" +target_uid="$2" +target_gid="$3" + +apt-get update +apt-get install -y python3 make gcc-aarch64-linux-gnu g++-aarch64-linux-gnu unzip +wget "https://github.com/Z3Prover/z3/archive/refs/tags/z3-${z3_version}.zip" +unzip "z3-${z3_version}.zip" +cd "z3-z3-${z3_version}" +export CC=aarch64-linux-gnu-gcc +export CXX=aarch64-linux-gnu-g++ +# See https://docs.aws.amazon.com/linux/al2023/ug/performance-optimizations.html +export CFLAGS="-march=armv8.2-a+crypto -mtune=neoverse-n1 -ftree-vectorize" +export CXXFLAGS="${CFLAGS}" +python3 scripts/mk_unix_dist.py -f --nodotnet --arch=arm64 +cp --preserve=all "./dist/z3-${z3_version}-arm64-glibc-2.31/bin"/*.so /data/out/ +chown "${target_uid}:${target_gid}" /data/out/* diff --git a/z3/docker/cross_build.sh b/z3/docker/cross_build.sh new file mode 100755 index 000000000..522d5c028 --- /dev/null +++ b/z3/docker/cross_build.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2023 The Refinery Authors +# +# SPDX-License-Identifier: Apache-2.0 + +set -euo pipefail + +z3_version="$(grep '^version=' ../gradle.properties | cut -d'=' -f2)" + +rm -rf out +mkdir out +docker run --platform linux/amd64 --rm -it -v "${PWD}:/data" --entrypoint /bin/bash docker.io/eclipse-temurin:17-jdk-focal /data/build_in_docker.sh "${z3_version}" "$(id -u)" "$(id -g)" +rm -rf ../subprojects/solver-linux-aarch64/src/main/resources/z3java-linux-aarch64/*.so +cp ./out/* ../subprojects/solver-linux-aarch64/src/main/resources/z3java-linux-aarch64/ diff --git a/z3/gradle.properties b/z3/gradle.properties new file mode 100644 index 000000000..73b4d5965 --- /dev/null +++ b/z3/gradle.properties @@ -0,0 +1,9 @@ +# SPDX-FileCopyrightText: 2023 The Refinery Authors +# +# SPDX-License-Identifier: Apache-2.0 + +file.encoding=UTF-8 +group=tools.refinery.z3 +org.gradle.configuration-cache=false +org.gradle.parallel=true +version=4.12.6 diff --git a/z3/gradle/libs.versions.toml b/z3/gradle/libs.versions.toml new file mode 100644 index 000000000..7c6c5ad7e --- /dev/null +++ b/z3/gradle/libs.versions.toml @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: 2023 The Refinery Authors +# +# SPDX-License-Identifier: Apache-2.0 + +[versions] +junit = "5.10.2" + +[libraries] +asm = { group = "org.ow2.asm", name = "asm", version = "9.6" } +jna = { group = "net.java.dev.jna", name = "jna", version = "5.14.0" } +junit-api = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junit" } +junit-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine", version.ref = "junit" } + +[plugins] +versions = { id = "com.github.ben-manes.versions", version = "0.51.0" } diff --git a/z3/settings.gradle.kts b/z3/settings.gradle.kts new file mode 100644 index 000000000..a857f5ce8 --- /dev/null +++ b/z3/settings.gradle.kts @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +rootProject.name = "refinery-z3" + +include( + "solver", + "solver-darwin-aarch64", + "solver-darwin-x86-64", + "solver-linux-aarch64", + "solver-linux-x86-64", + "solver-win32-x86-64", +) + +for (project in rootProject.children) { + val projectName = project.name + project.name = "${rootProject.name}-$projectName" + project.projectDir = file("subprojects/$projectName") +} diff --git a/z3/subprojects/solver-darwin-aarch64/build.gradle.kts b/z3/subprojects/solver-darwin-aarch64/build.gradle.kts new file mode 100644 index 000000000..21c9739c4 --- /dev/null +++ b/z3/subprojects/solver-darwin-aarch64/build.gradle.kts @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2023 The Refinery Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +plugins { + id("tools.refinery.z3.gradle.java-library") +} + +val classifier = "z3-${version}-arm64-osx-11.0" +val library = "z3java-darwin-aarch64" + +dependencies { + z3("Z3Prover:z3:${version}:${classifier}@zip") +} + +val extractZ3Libs by tasks.registering(Sync::class) { + dependsOn(configurations.z3) + from({ + val zipFile = configurations.z3.map { it.singleFile } + zipTree(zipFile).matching { + include("${classifier}/bin/*.so") + includeEmptyDirs = false + } + }) + eachFile { + val pathInBin = relativePath.segments.drop(2).toTypedArray() + relativePath = RelativePath(true, library, *pathInBin) + } + into(layout.buildDirectory.dir("z3-extracted")) +} + +sourceSets.main { + resources.srcDir(extractZ3Libs) +} diff --git a/z3/subprojects/solver-darwin-x86-64/build.gradle.kts b/z3/subprojects/solver-darwin-x86-64/build.gradle.kts new file mode 100644 index 000000000..75e592677 --- /dev/null +++ b/z3/subprojects/solver-darwin-x86-64/build.gradle.kts @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2023 The Refinery Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +plugins { + id("tools.refinery.z3.gradle.java-library") +} + +val classifier = "z3-${version}-x64-osx-10.16" +val library = "z3java-darwin-x86-64" + +dependencies { + z3("Z3Prover:z3:${version}:${classifier}@zip") +} + +val extractZ3Libs by tasks.registering(Sync::class) { + dependsOn(configurations.z3) + from({ + val zipFile = configurations.z3.map { it.singleFile } + zipTree(zipFile).matching { + include("${classifier}/bin/*.so") + includeEmptyDirs = false + } + }) + eachFile { + val pathInBin = relativePath.segments.drop(2).toTypedArray() + relativePath = RelativePath(true, library, *pathInBin) + } + into(layout.buildDirectory.dir("z3-extracted")) +} + +sourceSets.main { + resources.srcDir(extractZ3Libs) +} diff --git a/z3/subprojects/solver-linux-aarch64/build.gradle.kts b/z3/subprojects/solver-linux-aarch64/build.gradle.kts new file mode 100644 index 000000000..a8e7e2597 --- /dev/null +++ b/z3/subprojects/solver-linux-aarch64/build.gradle.kts @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2023 The Refinery Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +plugins { + id("tools.refinery.z3.gradle.java-library") +} + +tasks.jar { + // License information is redundant here, since it already gets added to the POM. + exclude("**/*.license") +} diff --git a/z3/subprojects/solver-linux-aarch64/src/main/resources/z3java-linux-aarch64/libz3.so b/z3/subprojects/solver-linux-aarch64/src/main/resources/z3java-linux-aarch64/libz3.so new file mode 100755 index 000000000..574ee3ab9 Binary files /dev/null and b/z3/subprojects/solver-linux-aarch64/src/main/resources/z3java-linux-aarch64/libz3.so differ diff --git a/z3/subprojects/solver-linux-aarch64/src/main/resources/z3java-linux-aarch64/libz3.so.license b/z3/subprojects/solver-linux-aarch64/src/main/resources/z3java-linux-aarch64/libz3.so.license new file mode 100644 index 000000000..0993dbf7e --- /dev/null +++ b/z3/subprojects/solver-linux-aarch64/src/main/resources/z3java-linux-aarch64/libz3.so.license @@ -0,0 +1,6 @@ +Copyright (c) Microsoft Corporations + +SPDX-License-Identifier: MIT + +This file was created from the Z3 4.12.6 release sources using the +z3/docker/cross_build.sh script in this repository. diff --git a/z3/subprojects/solver-linux-aarch64/src/main/resources/z3java-linux-aarch64/libz3java.so b/z3/subprojects/solver-linux-aarch64/src/main/resources/z3java-linux-aarch64/libz3java.so new file mode 100755 index 000000000..aace2c305 Binary files /dev/null and b/z3/subprojects/solver-linux-aarch64/src/main/resources/z3java-linux-aarch64/libz3java.so differ diff --git a/z3/subprojects/solver-linux-aarch64/src/main/resources/z3java-linux-aarch64/libz3java.so.license b/z3/subprojects/solver-linux-aarch64/src/main/resources/z3java-linux-aarch64/libz3java.so.license new file mode 100644 index 000000000..0993dbf7e --- /dev/null +++ b/z3/subprojects/solver-linux-aarch64/src/main/resources/z3java-linux-aarch64/libz3java.so.license @@ -0,0 +1,6 @@ +Copyright (c) Microsoft Corporations + +SPDX-License-Identifier: MIT + +This file was created from the Z3 4.12.6 release sources using the +z3/docker/cross_build.sh script in this repository. diff --git a/z3/subprojects/solver-linux-x86-64/build.gradle.kts b/z3/subprojects/solver-linux-x86-64/build.gradle.kts new file mode 100644 index 000000000..89c737b65 --- /dev/null +++ b/z3/subprojects/solver-linux-x86-64/build.gradle.kts @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2023 The Refinery Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +plugins { + id("tools.refinery.z3.gradle.java-library") +} + +val classifier = "z3-${version}-x64-glibc-2.31" +val library = "z3java-linux-x86-64" + +dependencies { + z3("Z3Prover:z3:${version}:${classifier}@zip") +} + +val extractZ3Libs by tasks.registering(Sync::class) { + dependsOn(configurations.z3) + from({ + val zipFile = configurations.z3.map { it.singleFile } + zipTree(zipFile).matching { + include("${classifier}/bin/*.so") + includeEmptyDirs = false + } + }) + eachFile { + val pathInBin = relativePath.segments.drop(2).toTypedArray() + relativePath = RelativePath(true, library, *pathInBin) + } + into(layout.buildDirectory.dir("z3-extracted")) +} + +sourceSets.main { + resources.srcDir(extractZ3Libs) +} diff --git a/z3/subprojects/solver-win32-x86-64/build.gradle.kts b/z3/subprojects/solver-win32-x86-64/build.gradle.kts new file mode 100644 index 000000000..c5fa04216 --- /dev/null +++ b/z3/subprojects/solver-win32-x86-64/build.gradle.kts @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +plugins { + id("tools.refinery.z3.gradle.java-library") +} + +val classifier = "z3-${version}-x64-win" +val library = "z3java-win32-x86-64" + +dependencies { + z3("Z3Prover:z3:${version}:${classifier}@zip") +} + +val extractZ3Libs by tasks.registering(Sync::class) { + dependsOn(configurations.z3) + from({ + val zipFile = configurations.z3.map { it.singleFile } + zipTree(zipFile).matching { + include("${classifier}/bin/*.dll") + // Do not include .NET assembly. + exclude("${classifier}/bin/Microsoft.Z3.dll") + includeEmptyDirs = false + } + }) + eachFile { + val pathInBin = relativePath.segments.drop(2).toTypedArray() + relativePath = RelativePath(true, library, *pathInBin) + } + into(layout.buildDirectory.dir("z3-extracted")) +} + +sourceSets.main { + resources.srcDir(extractZ3Libs) +} diff --git a/z3/subprojects/solver/build.gradle.kts b/z3/subprojects/solver/build.gradle.kts new file mode 100644 index 000000000..7e898b3e4 --- /dev/null +++ b/z3/subprojects/solver/build.gradle.kts @@ -0,0 +1,107 @@ +/* + * SPDX-FileCopyrightText: 2023 The Refinery Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import tools.refinery.z3.gradle.ClassFilePatcher + +plugins { + id("tools.refinery.z3.gradle.java-library") +} + +val classifier = "z3-${version}-x64-glibc-2.31" +val extractedClassesDir = layout.buildDirectory.dir("z3-extracted") +val extractedSourcesDir = layout.buildDirectory.dir("z3-sources") + +java { + withJavadocJar() + withSourcesJar() +} + +val z3Source: Configuration by configurations.creating { + isCanBeConsumed = false + isCanBeResolved = true +} + +val extractZ3Jar by tasks.registering(Sync::class) { + dependsOn(configurations.z3) + from({ + val zipFile = configurations.z3.map { it.singleFile } + val jarFile = zipTree(zipFile).matching { + include("${classifier}/bin/com.microsoft.z3.jar") + }.singleFile + zipTree(jarFile).matching { + exclude("META-INF/MANIFEST.MF") + includeEmptyDirs = false + } + }) + into(extractedClassesDir) + doLast { + // The class initializer off {@see com.microsoft.z3.Native} will try to load the Z3 native libraries + // from the system default library path unless the {@code z3.skipLibraryLoad} system property is set. + // Since we don't control the library path or system properties, we remove the class initializer entirely. + val nativeClassFile = extractedClassesDir.get().file("com/microsoft/z3/Native.class").asFile + ClassFilePatcher.removeClassInitializer(nativeClassFile) + } +} + +val extractZ3Source by tasks.registering(Sync::class) { + dependsOn(z3Source) + from({ + val zipFile = z3Source.singleFile + zipTree(zipFile).matching { + include("z3-z3-${version}/src/api/java/**/*") + includeEmptyDirs = false + } + }) + eachFile { + val pathInBin = relativePath.segments.drop(4).toTypedArray() + relativePath = RelativePath(true, "com", "microsoft", "z3", *pathInBin) + } + into(extractedSourcesDir) +} + +tasks.jar { + // Add class files to our jar manually. + from(extractZ3Jar) +} + +tasks.test { + useJUnitPlatform() +} + +tasks.named("sourcesJar") { + from(extractZ3Source) +} + +tasks.named("javadoc") { + source(sourceSets.main.map { it.allJava }) + source(fileTree(extractedSourcesDir) { + builtBy(extractZ3Source) + include("**/*.java") + }) + options { + this as StandardJavadocDocletOptions + addBooleanOption("Xdoclint:none", true) + // {@code -Xmaxwarns 0} will print all warnings, so we must keep at least one. + addStringOption("Xmaxwarns", "1") + quiet() + } +} + +dependencies { + z3("Z3Prover:z3:${version}:${classifier}@zip") + z3Source("Z3Prover:z3:${version}@zip") + // This dependency doesn't get added to Maven metadata, so we have to add the class files to our jar manually. + api(files(extractZ3Jar)) + implementation(libs.jna) + implementation(project(":refinery-z3-solver-darwin-aarch64")) + implementation(project(":refinery-z3-solver-darwin-x86-64")) + implementation(project(":refinery-z3-solver-linux-aarch64")) + implementation(project(":refinery-z3-solver-linux-x86-64")) + implementation(project(":refinery-z3-solver-win32-x86-64")) + testImplementation(libs.junit.api) + testRuntimeOnly(libs.junit.engine) + testRuntimeOnly("org.junit.platform:junit-platform-launcher") +} diff --git a/z3/subprojects/solver/src/main/java/tools/refinery/z3/Z3SolverLoader.java b/z3/subprojects/solver/src/main/java/tools/refinery/z3/Z3SolverLoader.java new file mode 100644 index 000000000..84f99540b --- /dev/null +++ b/z3/subprojects/solver/src/main/java/tools/refinery/z3/Z3SolverLoader.java @@ -0,0 +1,154 @@ +/* + * Copyright 2010-2022 Google LLC + * Copyright 2023 The Refinery Authors + * + * SPDX-License-Identifier: Apache-2.0 + * + * This file is based on + * https://github.com/google/or-tools/blob/f3d1d5f6a67356ec38a7fd2ab607624eea8ad3a6/ortools/java/com/google/ortools/Loader.java + * We adapted the loader logic to extract the JNI libraries of Z3 and the corresponding dependencies instead of the + * Google OR-Tools JNI libraries. + */ +package tools.refinery.z3; + +import com.sun.jna.Platform; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.Map; + +public final class Z3SolverLoader { + private static final String JNI_LIBRARY_NAME = "z3java"; + private static final String SOLVER_LIBRARY_NAME = "z3"; + + private static boolean loaded; + + private Z3SolverLoader() { + throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); + } + + public static synchronized void loadNativeLibraries() { + if (loaded) { + return; + } + try { + System.loadLibrary(getOsSpecificLibraryName(JNI_LIBRARY_NAME)); + loaded = true; + return; + } catch (UnsatisfiedLinkError e) { + // Continue, we'll have to extract the libraries from the classpath. + } + try { + extractAndLoad(); + loaded = true; + } catch (IOException e) { + throw new IllegalStateException("Could not extract and load " + JNI_LIBRARY_NAME, e); + } + } + + private static void extractAndLoad() throws IOException { + var resourceName = JNI_LIBRARY_NAME + "-" + Platform.RESOURCE_PREFIX; + var resource = Z3SolverLoader.class.getClassLoader().getResource(resourceName); + if (resource == null) { + throw new IllegalStateException("Resource %s was not found".formatted(resourceName)); + } + URI resourceUri; + try { + resourceUri = resource.toURI(); + } catch (URISyntaxException e) { + throw new IllegalStateException("Invalid resource URI: " + resource); + } + FileSystem fileSystem = null; + boolean newFileSystem = false; + Path extractedPath; + try { + try { + fileSystem = FileSystems.newFileSystem(resourceUri, Map.of()); + newFileSystem = true; + } catch (FileSystemAlreadyExistsException e) { + fileSystem = FileSystems.getFileSystem(resourceUri); + } + var resourcePath = fileSystem.provider().getPath(resourceUri); + if (fileSystem.equals(FileSystems.getDefault())) { + extractedPath = resourcePath; + } else { + extractedPath = extract(resourcePath); + } + } finally { + if (newFileSystem) { + fileSystem.close(); + } + } + // We can't rely on RPATH, so we load libraries in reverse dependency order manually. + try { + loadFromPath(extractedPath, SOLVER_LIBRARY_NAME); + } catch (UnsatisfiedLinkError e) { + if (Platform.isWindows()) { + // Try again with our packaged msvcp140 if the system one is missing. + loadFromPathExactName(extractedPath, "vcruntime140.dll"); + loadFromPathExactName(extractedPath, "vcruntime140_1.dll"); + loadFromPathExactName(extractedPath, "msvcp140.dll"); + loadFromPath(extractedPath, SOLVER_LIBRARY_NAME); + } else { + throw e; + } + } + loadFromPath(extractedPath, JNI_LIBRARY_NAME); + } + + private static Path extract(Path resourcePath) throws IOException { + var tempDir = Files.createTempDirectory(JNI_LIBRARY_NAME).toAbsolutePath(); + tempDir.toFile().deleteOnExit(); + Files.walkFileTree(resourcePath, new SimpleFileVisitor<>() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + var result = super.preVisitDirectory(dir, attrs); + var targetPath = getTargetPath(dir, resourcePath, tempDir); + if (!Files.exists(targetPath)) { + Files.createDirectory(targetPath); + targetPath.toFile().deleteOnExit(); + } + return result; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + var result = super.visitFile(file, attrs); + var targetPath = getTargetPath(file, resourcePath, tempDir); + Files.copy(file, targetPath); + targetPath.toFile().deleteOnExit(); + return result; + } + }); + return tempDir; + } + + private static Path getTargetPath(Path sourcePath, Path resourcePath, Path tempDir) { + var targetPath = tempDir.resolve(resourcePath.relativize(sourcePath).toString()).normalize(); + if (!targetPath.startsWith(tempDir)) { + throw new IllegalStateException("Target path '%s' for '%s' is outside '%s'" + .formatted(targetPath, sourcePath, tempDir)); + } + return targetPath; + } + + private static String getOsSpecificLibraryName(String libraryName) { + var osSpecificLibraryNamePrefix = Platform.isWindows() ? "lib" : ""; + return osSpecificLibraryNamePrefix + libraryName; + } + + private static void loadFromPath(Path extractedPath, String libraryName) { + var osSpecificLibraryName = getOsSpecificLibraryName(libraryName); + loadFromPathExactName(extractedPath, System.mapLibraryName(osSpecificLibraryName)); + } + + private static void loadFromPathExactName(Path extractedPath, String exactName) { + var library = extractedPath.resolve(exactName) + .toAbsolutePath() + .toString(); + System.load(library); + } +} diff --git a/z3/subprojects/solver/src/test/java/tools/refinery/z3/Z3SolverLoaderTest.java b/z3/subprojects/solver/src/test/java/tools/refinery/z3/Z3SolverLoaderTest.java new file mode 100644 index 000000000..df3139cca --- /dev/null +++ b/z3/subprojects/solver/src/test/java/tools/refinery/z3/Z3SolverLoaderTest.java @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2023 The Refinery Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ +package tools.refinery.z3; + +import com.microsoft.z3.*; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class Z3SolverLoaderTest { + @Test + void testLoad() { + assertDoesNotThrow(Z3SolverLoader::loadNativeLibraries); + try (var context = new Context()) { + var solver = context.mkSolver(); + var a = context.mkConst("a", context.getIntSort()); + var b = context.mkConst("b", context.getIntSort()); + solver.add(context.mkEq(a, context.mkInt(3))); + solver.add(context.mkEq(b, context.mkMul(context.mkInt(2), a))); + assertEquals(Status.SATISFIABLE, solver.check()); + var model = solver.getModel(); + var bValue = (IntNum) model.getConstInterp(b); + assertEquals(6, bValue.getInt()); + } + } +}