From 31465875054c847943e625d9e84bbbd52bc3695e Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Thu, 22 Feb 2024 02:02:21 +0100 Subject: feat(query): left join for data variables --- .../psystem/basicdeferred/LeftJoinConstraint.java | 82 ++++++++++++++++++++++ .../matchers/psystem/rewriters/PBodyCopier.java | 13 +++- 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 subprojects/interpreter/src/main/java/tools/refinery/interpreter/matchers/psystem/basicdeferred/LeftJoinConstraint.java (limited to 'subprojects/interpreter') 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 00000000..1c1a895e --- /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 99350185..1e580599 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 @@ public class PBodyCopier extends AbstractRewriterTraceSource { } 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 @@ public class PBodyCopier extends AbstractRewriterTraceSource { 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, -- cgit v1.2.3-54-g00ecf