From 1d87633ef1dcf924f27949ff4dc2fedb4a8b67ef Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Sun, 29 Jan 2023 02:06:57 +0100 Subject: feat: negative and transitive RelationViewAtom Use PVisibility.EMBEDDED helper patterns to avoid superfluous production nodes in the Rete net. --- .../query/viatra/internal/pquery/DNF2PQuery.java | 47 ++++++++++++++++++---- .../query/viatra/internal/pquery/RawPQuery.java | 8 +++- 2 files changed, 46 insertions(+), 9 deletions(-) (limited to 'subprojects/store-query-viatra/src/main') diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java index 2b5618d2..eb815588 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java @@ -12,10 +12,12 @@ import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.Consta import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; import tools.refinery.store.query.DNF; import tools.refinery.store.query.DNFAnd; +import tools.refinery.store.query.DNFUtils; import tools.refinery.store.query.Variable; import tools.refinery.store.query.atom.*; import tools.refinery.store.query.view.AnyRelationView; @@ -124,8 +126,19 @@ public class DNF2PQuery { } private void translateRelationViewAtom(RelationViewAtom relationViewAtom, PBody body) { - new TypeConstraint(body, translateSubstitution(relationViewAtom.getSubstitution(), body), - wrapView(relationViewAtom.getTarget())); + var substitution = translateSubstitution(relationViewAtom.getSubstitution(), body); + var polarity = relationViewAtom.getPolarity(); + var relationView = relationViewAtom.getTarget(); + if (polarity == CallPolarity.POSITIVE) { + new TypeConstraint(body, substitution, wrapView(relationView)); + } else { + var embeddedPQuery = translateEmbeddedRelationViewPQuery(relationView); + switch (polarity) { + case TRANSITIVE -> new BinaryTransitiveClosure(body, substitution, embeddedPQuery); + case NEGATIVE -> new NegativePatternCall(body, substitution, embeddedPQuery); + default -> throw new IllegalArgumentException("Unknown polarity: " + polarity); + } + } } private static Tuple translateSubstitution(List substitution, PBody body) { @@ -138,16 +151,36 @@ public class DNF2PQuery { return Tuples.flatTupleOf(variables); } + private RawPQuery translateEmbeddedRelationViewPQuery(AnyRelationView relationView) { + var embeddedPQuery = new RawPQuery(DNFUtils.generateUniqueName(relationView.name()), PVisibility.EMBEDDED); + var body = new PBody(embeddedPQuery); + int arity = relationView.arity(); + var parameters = new ArrayList(arity); + var arguments = new Object[arity]; + var symbolicParameters = new ArrayList(arity); + for (int i = 0; i < arity; i++) { + var parameterName = "p" + i; + var parameter = new PParameter(parameterName); + parameters.add(parameter); + var variable = body.getOrCreateVariableByName(parameterName); + arguments[i] = variable; + symbolicParameters.add(new ExportedParameter(body, variable, parameter)); + } + embeddedPQuery.setParameters(parameters); + body.setSymbolicParameters(symbolicParameters); + var argumentTuple = Tuples.flatTupleOf(arguments); + new TypeConstraint(body, argumentTuple, wrapView(relationView)); + embeddedPQuery.addBody(body); + return embeddedPQuery; + } + private RelationViewWrapper wrapView(AnyRelationView relationView) { return view2WrapperMap.computeIfAbsent(relationView, RelationViewWrapper::new); } - private void translateCallAtom(CallAtom callAtom, PBody body) { - if (!(callAtom.getTarget() instanceof DNF target)) { - throw new IllegalArgumentException("Only calls to DNF are supported"); - } + private void translateCallAtom(DNFCallAtom callAtom, PBody body) { var variablesTuple = translateSubstitution(callAtom.getSubstitution(), body); - var translatedReferred = translate(target); + var translatedReferred = translate(callAtom.getTarget()); var polarity = callAtom.getPolarity(); switch (polarity) { case POSITIVE -> new PositivePatternCall(body, variablesTuple, translatedReferred); diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RawPQuery.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RawPQuery.java index 5d0b9e82..830495b2 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RawPQuery.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RawPQuery.java @@ -18,11 +18,15 @@ public class RawPQuery extends BasePQuery { private List parameters; private final LinkedHashSet bodies = new LinkedHashSet<>(); - public RawPQuery(String name) { - super(PVisibility.PUBLIC); + public RawPQuery(String name, PVisibility visibility) { + super(visibility); fullyQualifiedName = name; } + public RawPQuery(String name) { + this(name, PVisibility.PUBLIC); + } + @Override public String getFullyQualifiedName() { return fullyQualifiedName; -- cgit v1.2.3-70-g09d2