From 575f4b0060fdd7caefdb1b96b1df7f3519b17941 Mon Sep 17 00:00:00 2001 From: OszkarSemerath Date: Fri, 22 Oct 2021 02:13:47 +0200 Subject: Almost finished QueriableModel and QueryableModelStore --- .../tools/refinery/store/query/QueriableModel.java | 30 ++++ .../refinery/store/query/QueriableModelStore.java | 23 +++ .../store/query/QueriableModelStoreImpl.java | 127 +++++++++++++++ .../store/query/internal/QueriableModelImpl.java | 180 +++++++++++++++++++++ 4 files changed, 360 insertions(+) create mode 100644 store/src/main/java/tools/refinery/store/query/QueriableModel.java create mode 100644 store/src/main/java/tools/refinery/store/query/QueriableModelStore.java create mode 100644 store/src/main/java/tools/refinery/store/query/QueriableModelStoreImpl.java create mode 100644 store/src/main/java/tools/refinery/store/query/internal/QueriableModelImpl.java (limited to 'store/src/main') diff --git a/store/src/main/java/tools/refinery/store/query/QueriableModel.java b/store/src/main/java/tools/refinery/store/query/QueriableModel.java new file mode 100644 index 00000000..f669b3ed --- /dev/null +++ b/store/src/main/java/tools/refinery/store/query/QueriableModel.java @@ -0,0 +1,30 @@ +package tools.refinery.store.query; + +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +import tools.refinery.store.model.Model; +import tools.refinery.store.query.building.DNFPredicate; + +public interface QueriableModel extends Model{ + Set getPredicates(); + + void flushChanges(); + + boolean hasResult(DNFPredicate predicate); + + boolean hasResult(DNFPredicate predicate, Object[] parameters); + + Optional oneResult(DNFPredicate predicate); + + Optional oneResult(DNFPredicate predicate, Object[] parameters); + + Stream allResults(DNFPredicate predicate); + + Stream allResults(DNFPredicate predicate, Object[] parameters); + + int countResults(DNFPredicate predicate); + + int countResults(DNFPredicate predicate, Object[] parameters); +} diff --git a/store/src/main/java/tools/refinery/store/query/QueriableModelStore.java b/store/src/main/java/tools/refinery/store/query/QueriableModelStore.java new file mode 100644 index 00000000..3a5b51ff --- /dev/null +++ b/store/src/main/java/tools/refinery/store/query/QueriableModelStore.java @@ -0,0 +1,23 @@ +package tools.refinery.store.query; + +import java.util.Set; + +import tools.refinery.store.model.ModelDiffCursor; +import tools.refinery.store.model.ModelStore; +import tools.refinery.store.model.representation.DataRepresentation; +import tools.refinery.store.query.building.DNFPredicate; +import tools.refinery.store.query.view.RelationView; + +public interface QueriableModelStore extends ModelStore{ + @SuppressWarnings("squid:S1452") + Set> getDataRepresentations(); + @SuppressWarnings("squid:S1452") + Set> getViews(); + Set getPredicates(); + + QueriableModel createModel(); + QueriableModel createModel(long state); + + Set getStates(); + ModelDiffCursor getDiffCursor(long from, long to); +} diff --git a/store/src/main/java/tools/refinery/store/query/QueriableModelStoreImpl.java b/store/src/main/java/tools/refinery/store/query/QueriableModelStoreImpl.java new file mode 100644 index 00000000..3902e013 --- /dev/null +++ b/store/src/main/java/tools/refinery/store/query/QueriableModelStoreImpl.java @@ -0,0 +1,127 @@ +package tools.refinery.store.query; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; + +import tools.refinery.store.model.ModelDiffCursor; +import tools.refinery.store.model.ModelStore; +import tools.refinery.store.model.ModelStoreImpl; +import tools.refinery.store.model.representation.DataRepresentation; +import tools.refinery.store.query.building.DNFAnd; +import tools.refinery.store.query.building.DNFAtom; +import tools.refinery.store.query.building.DNFPredicate; +import tools.refinery.store.query.building.PredicateAtom; +import tools.refinery.store.query.building.RelationAtom; +import tools.refinery.store.query.internal.DNF2PQuery; +import tools.refinery.store.query.internal.RawPatternMatcher; +import tools.refinery.store.query.view.RelationView; + +public class QueriableModelStoreImpl implements QueriableModelStore { + protected final ModelStore store; + protected final Set> relationViews; + protected final Map> predicates; + + public QueriableModelStoreImpl(Set> dataRepresentations, + Set> relationViews, Set predicates) { + this.store = new ModelStoreImpl(dataRepresentations); + validateViews(dataRepresentations, relationViews); + this.relationViews = Collections.unmodifiableSet(relationViews); + validatePredicates(relationViews, predicates); + this.predicates = initPredicates(predicates); + } + + private void validateViews(Set> dataRepresentations, Set> relationViews) { + for (RelationView relationView : relationViews) { + // TODO: make it work for non-relation representation? + if (!dataRepresentations.contains(relationView.getRepresentation())) { + throw new IllegalArgumentException( + DataRepresentation.class.getSimpleName() + " " + relationView.getStringID() + " added to " + + QueriableModelStore.class.getSimpleName() + " without a referred representation."); + } + } + } + + private void validatePredicates(Set> relationViews, Set predicates) { + for (DNFPredicate dnfPredicate : predicates) { + for (DNFAnd clause : dnfPredicate.getClauses()) { + for (DNFAtom atom : clause.getConstraints()) { + if (atom instanceof RelationAtom relationAtom) { + validateRelationAtom(relationViews, dnfPredicate, relationAtom); + } else if (atom instanceof PredicateAtom predicateAtom) { + validatePredicateAtom(predicates, dnfPredicate, predicateAtom); + } + } + } + } + } + + private void validateRelationAtom(Set> relationViews, DNFPredicate dnfPredicate, + RelationAtom relationAtom) { + if (!relationViews.contains(relationAtom.getView())) { + throw new IllegalArgumentException(DNFPredicate.class.getSimpleName() + " " + + dnfPredicate.getUniqueName() + " contains reference to a view of " + + relationAtom.getView().getRepresentation().getName() + + " that is not in the model."); + } + } + private void validatePredicateAtom(Set predicates, DNFPredicate dnfPredicate, + PredicateAtom predicateAtom) { + if (!predicates.contains(predicateAtom.getReferred())) { + throw new IllegalArgumentException( + DNFPredicate.class.getSimpleName() + " " + dnfPredicate.getUniqueName() + + " contains reference to a predicate " + + predicateAtom.getReferred().getName() + + "that is not in the model."); + } + } + + private Map> initPredicates(Set predicates) { + Map> result = new HashMap<>(); + + for (DNFPredicate dnfPredicate : predicates) { + GenericQuerySpecification query = DNF2PQuery.translate(dnfPredicate).build(); + result.put(dnfPredicate, query); + } + + return result; + } + + @Override + public Set> getDataRepresentations() { + return store.getDataRepresentations(); + } + @Override + public Set> getViews() { + return this.relationViews; + } + @Override + public Set getPredicates() { + return predicates.keySet(); + } + + @Override + public QueriableModel createModel() { + // TODO Auto-generated method stub + return null; + } + + @Override + public QueriableModel createModel(long state) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getStates() { + return this.store.getStates(); + } + + @Override + public ModelDiffCursor getDiffCursor(long from, long to) { + return this.store.getDiffCursor(from, to); + } +} diff --git a/store/src/main/java/tools/refinery/store/query/internal/QueriableModelImpl.java b/store/src/main/java/tools/refinery/store/query/internal/QueriableModelImpl.java new file mode 100644 index 00000000..5b96ba74 --- /dev/null +++ b/store/src/main/java/tools/refinery/store/query/internal/QueriableModelImpl.java @@ -0,0 +1,180 @@ +package tools.refinery.store.query.internal; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.GenericQueryGroup; +import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; +import org.eclipse.viatra.query.runtime.api.IQueryGroup; + +import tools.refinery.store.map.Cursor; +import tools.refinery.store.model.Model; +import tools.refinery.store.model.ModelDiffCursor; +import tools.refinery.store.model.representation.DataRepresentation; +import tools.refinery.store.query.QueriableModel; +import tools.refinery.store.query.QueriableModelStore; +import tools.refinery.store.query.RelationalScope; +import tools.refinery.store.query.building.DNFPredicate; + +public class QueriableModelImpl implements QueriableModel { + protected final QueriableModelStore store; + protected final Model model; + + protected final AdvancedViatraQueryEngine engine; + protected final Map predicate2Matcher; + + public QueriableModelImpl(QueriableModelStore store, Model model, + Map> predicates2PQuery) { + this.store = store; + this.model = model; + this.engine = initEngine(store, model); + this.predicate2Matcher = initMatchers(engine, predicates2PQuery); + } + + private AdvancedViatraQueryEngine initEngine(QueriableModelStore store, Model model) { + RelationalScope scope = new RelationalScope(model, store.getViews()); + return AdvancedViatraQueryEngine.createUnmanagedEngine(scope); + } + + private Map initMatchers(AdvancedViatraQueryEngine engine, + Map> predicates2pQuery) { + // 1. prepare group + IQueryGroup queryGroup = GenericQueryGroup.of(Set.copyOf(predicates2pQuery.values())); + engine.prepareGroup(queryGroup, null); + + // 2. then get all matchers + Map result = new HashMap<>(); + for (var entry : predicates2pQuery.entrySet()) { + var matcher = engine.getMatcher(entry.getValue()); + result.put(entry.getKey(), matcher); + } + return result; + } + + @Override + public Set> getDataRepresentations() { + return model.getDataRepresentations(); + } + + @Override + public Set getPredicates() { + return store.getPredicates(); + } + + @Override + public V get(DataRepresentation representation, K key) { + return model.get(representation, key); + } + + @Override + public Cursor getAll(DataRepresentation representation) { + return model.getAll(representation); + } + + @Override + public V put(DataRepresentation representation, K key, V value) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void putAll(DataRepresentation representation, Cursor cursor) { + // TODO Auto-generated method stub + + } + + @Override + public long getSize(DataRepresentation representation) { + return model.getSize(representation); + } + + protected PredicateResult getPredicateResult(DNFPredicate predicate) { + var result = this.predicate2Matcher.get(predicate); + if (result == null) { + throw new IllegalArgumentException("Model does not contain predicate " + predicate.getName() + "!"); + } else + return result; + } + + protected void validateParameters(DNFPredicate predicate, Object[] parameters) { + int predicateArity = predicate.getVariables().size(); + int parameterArity = parameters.length; + if (parameterArity != predicateArity) { + throw new IllegalArgumentException("Predicate " + predicate.getName() + " with " + predicateArity + + " arity called with different number of parameters (" + parameterArity + ")!"); + } + } + + @Override + public boolean hasResult(DNFPredicate predicate) { + return getPredicateResult(predicate).hasResult(); + } + + @Override + public boolean hasResult(DNFPredicate predicate, Object[] parameters) { + validateParameters(predicate, parameters); + return getPredicateResult(predicate).hasResult(parameters); + } + + @Override + public Optional oneResult(DNFPredicate predicate){ + return getPredicateResult(predicate).oneResult(); + } + + @Override + public Optional oneResult(DNFPredicate predicate, Object[] parameters){ + validateParameters(predicate, parameters); + return getPredicateResult(predicate).oneResult(parameters); + } + + @Override + public Stream allResults(DNFPredicate predicate){ + return getPredicateResult(predicate).allResults(); + } + + @Override + public Stream allResults(DNFPredicate predicate, Object[] parameters){ + validateParameters(predicate, parameters); + return getPredicateResult(predicate).allResults(parameters); + } + + @Override + public int countResults(DNFPredicate predicate){ + return getPredicateResult(predicate).countResults(); + } + + @Override + public int countResults(DNFPredicate predicate, Object[] parameters){ + validateParameters(predicate, parameters); + return getPredicateResult(predicate).countResults(parameters); + + } + @Override + public void flushChanges() { + // TODO Auto-generated method stub + + } + + @Override + public ModelDiffCursor getDiffCursor(long to) { + // TODO Auto-generated method stub + return null; + } + + @Override + public long commit() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void restore(long state) { + // TODO Auto-generated method stub + + } + +} -- cgit v1.2.3-54-g00ecf