use of ai.grakn.concept.Concept 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));
}
use of ai.grakn.concept.Concept in project grakn by graknlabs.
the class ResourceAtom method materialise.
@Override
public Stream<Answer> materialise() {
Answer substitution = getParentQuery().getSubstitution();
AttributeType type = getSchemaConcept().asAttributeType();
Concept owner = substitution.get(getVarName());
Var resourceVariable = getPredicateVariable();
// if the attribute already exists, only attach a new link to the owner, otherwise create a new attribute
if (substitution.containsVar(resourceVariable)) {
Attribute attribute = substitution.get(resourceVariable).asAttribute();
attachAttribute(owner, attribute);
return Stream.of(substitution);
} else {
Attribute attribute = AttributeTypeImpl.from(type).putAttributeInferred(Iterables.getOnlyElement(getMultiPredicate()).getPredicate().equalsValue().get());
attachAttribute(owner, attribute);
return Stream.of(substitution.merge(new QueryAnswer(ImmutableMap.of(resourceVariable, attribute))));
}
}
use of ai.grakn.concept.Concept in project grakn by graknlabs.
the class GraqlTest method testPaths.
@Test
public void testPaths() throws InvalidKBException {
addSchemaAndEntities();
try (GraknTx graph = session.open(GraknTxType.WRITE)) {
PathsQuery query = graph.graql().parse("compute paths from '" + entityId1 + "' to '" + entityId2 + "';");
List<List<Concept>> path = query.execute();
assertEquals(1, path.size());
List<String> result = path.get(0).stream().map(Concept::getId).map(ConceptId::getValue).collect(Collectors.toList());
List<String> expected = Lists.newArrayList(entityId1, relationId12, entityId2);
assertEquals(expected, result);
}
}
use of ai.grakn.concept.Concept in project grakn by graknlabs.
the class GraqlTest method testPath.
@Test
public void testPath() throws InvalidKBException {
addSchemaAndEntities();
try (GraknTx graph = session.open(GraknTxType.WRITE)) {
PathQuery query = graph.graql().parse("compute path from '" + entityId1 + "' to '" + entityId2 + "';");
Optional<List<Concept>> path = query.execute();
List<String> result = path.get().stream().map(Concept::getId).map(ConceptId::getValue).collect(Collectors.toList());
List<String> expected = Lists.newArrayList(entityId1, relationId12, entityId2);
assertEquals(expected, result);
}
}
use of ai.grakn.concept.Concept in project grakn by graknlabs.
the class GraqlControllerInsertTest method setupMock.
@Before
public void setupMock() {
when(mockFactory.tx(eq(keyspace), any())).thenReturn(tx);
when(tx.keyspace()).thenReturn(keyspace);
when(printer.graqlString(any())).thenReturn(Json.object().toString());
// Describe expected response to a typical query
Query<Object> query = tx.graql().parser().parseQuery("insert $x isa person;");
Concept person = mock(Concept.class, RETURNS_DEEP_STUBS);
when(person.getId()).thenReturn(ConceptId.of("V123"));
when(person.isThing()).thenReturn(true);
when(person.asThing().type().getLabel()).thenReturn(Label.of("person"));
when(query.execute()).thenReturn(ImmutableList.of(new QueryAnswer(ImmutableMap.of(var("x"), person))));
}
Aggregations