Search in sources :

Example 1 with Partition

use of ai.grakn.graql.internal.util.Partition in project grakn by graknlabs.

the class QueryOperationExecutor method create.

private static QueryOperationExecutor create(Collection<VarPatternAdmin> patterns, GraknTx graph, ExecutionType executionType) {
    ImmutableSet<VarAndProperty> properties = patterns.stream().flatMap(pattern -> VarAndProperty.fromPattern(pattern, executionType)).collect(toImmutableSet());
    /*
            We build several many-to-many relations, indicated by a `Multimap<X, Y>`. These are used to represent
            the dependencies between properties and variables.

            `propDependencies.containsEntry(prop, var)` indicates that the property `prop` cannot be inserted until
            the concept represented by the variable `var` is created.

            For example, the property `$x isa $y` depends on the existence of the concept represented by `$y`.
         */
    Multimap<VarAndProperty, Var> propDependencies = HashMultimap.create();
    for (VarAndProperty property : properties) {
        for (Var requiredVar : property.executor().requiredVars()) {
            propDependencies.put(property, requiredVar);
        }
    }
    /*
            `varDependencies.containsEntry(var, prop)` indicates that the concept represented by the variable `var`
            cannot be created until the property `prop` is inserted.

            For example, the concept represented by `$x` will not exist before the property `$x isa $y` is inserted.
         */
    Multimap<Var, VarAndProperty> varDependencies = HashMultimap.create();
    for (VarAndProperty property : properties) {
        for (Var producedVar : property.executor().producedVars()) {
            varDependencies.put(producedVar, property);
        }
    }
    /*
            Equivalent vars are variables that must represent the same concept as another var.

                 $X label movie, sub entity;
                 $Y label movie;
                 $z isa $Y;

            In this example, `$z isa $Y` must not be inserted before `$Y` is. However, `$Y` does not have enough
            information to insert on its own. It also needs a super type!

            We know `$Y` must represent the same concept as `$X`, because they both share the same label property.
            Therefore, we can share their dependencies, such that:

                varDependencies.containsEntry($X, prop) <=> varDependencies.containsEntry($Y, prop)

            Therefore:

                varDependencies.containsEntry($X, `$X sub entity`) => varDependencies.containsEntry($Y, `$X sub entity`)

            Now we know that `$Y` depends on `$X sub entity` as well as `$X label movie`, which is enough information to
            insert the type!
         */
    Partition<Var> equivalentVars = Partition.singletons(Collections.emptyList());
    equivalentProperties(properties).asMap().values().forEach(vars -> {
        // These vars must refer to the same concept, so share their dependencies
        Collection<VarAndProperty> producers = vars.stream().flatMap(var -> varDependencies.get(var).stream()).collect(toList());
        Var first = vars.iterator().next();
        vars.forEach(var -> {
            varDependencies.replaceValues(var, producers);
            equivalentVars.merge(first, var);
        });
    });
    /*
            Together, `propDependencies` and `varDependencies` can be composed into a single many-to-many relation:

                dependencies = propDependencies ∘ varDependencies

            By doing so, we map _directly_ between properties, skipping the vars. For example, if we previously had:

                propDependencies.containsEntry(`$x isa $y`, `$y`);         // `$x isa $y` depends on `$y`
                varDependencies.containsEntry(`$y`, `$y label movie`);     // `$y` depends on `$y label movie`

            Then it follows that:

                dependencies.containsEntry(`$x isa $y`, `$y label movie`); // `$x isa $y` depends on `$y label movie`

            The `dependencies` relation contains all the information to decide what order to execute the properties.
         */
    Multimap<VarAndProperty, VarAndProperty> dependencies = composeMultimaps(propDependencies, varDependencies);
    return new QueryOperationExecutor(graph, properties, equivalentVars, ImmutableMultimap.copyOf(dependencies));
}
Also used : PropertyExecutor(ai.grakn.graql.internal.pattern.property.PropertyExecutor) Concept(ai.grakn.concept.Concept) InsertQuery(ai.grakn.graql.InsertQuery) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) Answer(ai.grakn.graql.admin.Answer) Multimap(com.google.common.collect.Multimap) Multimaps(com.google.common.collect.Multimaps) HashMultimap(com.google.common.collect.HashMultimap) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) Partition(ai.grakn.graql.internal.util.Partition) GraknTx(ai.grakn.GraknTx) Map(java.util.Map) QueryAnswer(ai.grakn.graql.internal.query.QueryAnswer) ImmutableMultimap(com.google.common.collect.ImmutableMultimap) Nullable(javax.annotation.Nullable) CommonUtil.toImmutableSet(ai.grakn.util.CommonUtil.toImmutableSet) Patterns(ai.grakn.graql.internal.pattern.Patterns) VarPropertyInternal(ai.grakn.graql.internal.pattern.property.VarPropertyInternal) GraqlQueryException(ai.grakn.exception.GraqlQueryException) ImmutableSet(com.google.common.collect.ImmutableSet) Logger(org.slf4j.Logger) ImmutableMap(com.google.common.collect.ImmutableMap) Collection(java.util.Collection) Set(java.util.Set) Maps(com.google.common.collect.Maps) Query(ai.grakn.graql.Query) Sets(com.google.common.collect.Sets) VarProperty(ai.grakn.graql.admin.VarProperty) Collectors.toList(java.util.stream.Collectors.toList) Stream(java.util.stream.Stream) Var(ai.grakn.graql.Var) AutoValue(com.google.auto.value.AutoValue) DefineQuery(ai.grakn.graql.DefineQuery) VarPatternAdmin(ai.grakn.graql.admin.VarPatternAdmin) Optional(java.util.Optional) Queue(java.util.Queue) ArrayDeque(java.util.ArrayDeque) Collections(java.util.Collections) Var(ai.grakn.graql.Var)

Aggregations

GraknTx (ai.grakn.GraknTx)1 Concept (ai.grakn.concept.Concept)1 GraqlQueryException (ai.grakn.exception.GraqlQueryException)1 DefineQuery (ai.grakn.graql.DefineQuery)1 InsertQuery (ai.grakn.graql.InsertQuery)1 Query (ai.grakn.graql.Query)1 Var (ai.grakn.graql.Var)1 Answer (ai.grakn.graql.admin.Answer)1 VarPatternAdmin (ai.grakn.graql.admin.VarPatternAdmin)1 VarProperty (ai.grakn.graql.admin.VarProperty)1 Patterns (ai.grakn.graql.internal.pattern.Patterns)1 PropertyExecutor (ai.grakn.graql.internal.pattern.property.PropertyExecutor)1 VarPropertyInternal (ai.grakn.graql.internal.pattern.property.VarPropertyInternal)1 QueryAnswer (ai.grakn.graql.internal.query.QueryAnswer)1 Partition (ai.grakn.graql.internal.util.Partition)1 CommonUtil.toImmutableSet (ai.grakn.util.CommonUtil.toImmutableSet)1 AutoValue (com.google.auto.value.AutoValue)1 HashMultimap (com.google.common.collect.HashMultimap)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1