use of ai.grakn.graql.internal.gremlin.fragment.Fragment in project grakn by graknlabs.
the class GraqlTraversalPlanner method planFromTraversal.
/**
* @param atoms list of current atoms of interest
* @param queryPattern corresponding pattern
* @return an optimally ordered list of provided atoms
*/
static ImmutableList<Atom> planFromTraversal(List<Atom> atoms, PatternAdmin queryPattern, EmbeddedGraknTx<?> tx) {
Multimap<VarProperty, Atom> propertyMap = HashMultimap.create();
atoms.stream().filter(at -> !(at instanceof OntologicalAtom)).forEach(at -> at.getVarProperties().forEach(p -> propertyMap.put(p, at)));
Set<VarProperty> properties = propertyMap.keySet();
GraqlTraversal graqlTraversal = GreedyTraversalPlan.createTraversal(queryPattern, tx);
ImmutableList<Fragment> fragments = graqlTraversal.fragments().iterator().next();
ImmutableList.Builder<Atom> builder = ImmutableList.builder();
builder.addAll(atoms.stream().filter(at -> at instanceof OntologicalAtom).iterator());
builder.addAll(fragments.stream().map(Fragment::varProperty).filter(Objects::nonNull).filter(properties::contains).distinct().flatMap(p -> propertyMap.get(p).stream()).distinct().iterator());
return builder.build();
}
use of ai.grakn.graql.internal.gremlin.fragment.Fragment in project grakn by graknlabs.
the class GraqlTraversal method getGraphTraversal.
/**
* Get the {@code GraphTraversal} that this {@code GraqlTraversal} represents.
*/
// Because 'union' accepts an array, we can't use generics
@SuppressWarnings("unchecked")
public GraphTraversal<Vertex, Map<String, Element>> getGraphTraversal(EmbeddedGraknTx<?> tx, Set<Var> vars) {
if (fragments().size() == 1) {
// If there are no disjunctions, we don't need to union them and get a performance boost
ImmutableList<Fragment> list = Iterables.getOnlyElement(fragments());
return getConjunctionTraversal(tx, tx.getTinkerTraversal().V(), vars, list);
} else {
Traversal[] traversals = fragments().stream().map(list -> getConjunctionTraversal(tx, __.V(), vars, list)).toArray(Traversal[]::new);
// This is a sneaky trick - we want to do a union but tinkerpop requires all traversals to start from
// somewhere, so we start from a single arbitrary vertex.
GraphTraversal traversal = tx.getTinkerTraversal().V().limit(1).union(traversals);
return selectVars(traversal, vars);
}
}
use of ai.grakn.graql.internal.gremlin.fragment.Fragment in project grakn by graknlabs.
the class GreedyTraversalPlan method greedyTraversal.
private static void greedyTraversal(List<Fragment> plan, Arborescence<Node> arborescence, Map<NodeId, Node> nodes, Map<Node, Map<Node, Fragment>> edgeFragmentChildToParent) {
Map<Node, Set<Node>> edgesParentToChild = new HashMap<>();
arborescence.getParents().forEach((child, parent) -> {
if (!edgesParentToChild.containsKey(parent)) {
edgesParentToChild.put(parent, new HashSet<>());
}
edgesParentToChild.get(parent).add(child);
});
Node root = arborescence.getRoot();
Set<Node> reachableNodes = Sets.newHashSet(root);
while (!reachableNodes.isEmpty()) {
Optional<Node> optionalNodeWithMinCost = reachableNodes.stream().min(Comparator.comparingDouble(node -> branchWeight(node, arborescence, edgesParentToChild, edgeFragmentChildToParent)));
assert optionalNodeWithMinCost.isPresent() : "reachableNodes is never empty, so there is always a minimum";
Node nodeWithMinCost = optionalNodeWithMinCost.get();
// add edge fragment first, then node fragments
getEdgeFragment(nodeWithMinCost, arborescence, edgeFragmentChildToParent).ifPresent(plan::add);
addNodeFragmentToPlan(nodeWithMinCost, plan, nodes, true);
reachableNodes.remove(nodeWithMinCost);
if (edgesParentToChild.containsKey(nodeWithMinCost)) {
reachableNodes.addAll(edgesParentToChild.get(nodeWithMinCost));
}
}
}
use of ai.grakn.graql.internal.gremlin.fragment.Fragment in project grakn by graknlabs.
the class GreedyTraversalPlan method addNodeFragmentToPlan.
private static void addNodeFragmentToPlan(Node node, List<Fragment> plan, Map<NodeId, Node> nodes, boolean visited) {
if (!visited) {
node.getFragmentsWithoutDependency().stream().min(Comparator.comparingDouble(Fragment::fragmentCost)).ifPresent(firstNodeFragment -> {
plan.add(firstNodeFragment);
node.getFragmentsWithoutDependency().remove(firstNodeFragment);
});
}
node.getFragmentsWithoutDependency().addAll(node.getFragmentsWithDependencyVisited());
plan.addAll(node.getFragmentsWithoutDependency().stream().sorted(Comparator.comparingDouble(Fragment::fragmentCost)).collect(Collectors.toList()));
node.getFragmentsWithoutDependency().clear();
node.getFragmentsWithDependencyVisited().clear();
node.getDependants().forEach(fragment -> {
Node otherNode = nodes.get(new NodeId(NodeId.NodeType.VAR, fragment.start()));
if (node.equals(otherNode)) {
otherNode = nodes.get(new NodeId(NodeId.NodeType.VAR, fragment.dependencies().iterator().next()));
}
otherNode.getDependants().remove(fragment.getInverse());
otherNode.getFragmentsWithDependencyVisited().add(fragment);
});
node.getDependants().clear();
}
use of ai.grakn.graql.internal.gremlin.fragment.Fragment in project grakn by graknlabs.
the class GraqlTraversalTest method testAllTraversalsSimpleQuery.
@Test
public void testAllTraversalsSimpleQuery() {
IdProperty titanicId = IdProperty.of(ConceptId.of("Titanic"));
IdProperty movieId = IdProperty.of(ConceptId.of("movie"));
SubProperty subProperty = SubProperty.of(Patterns.varPattern(y, ImmutableSet.of(movieId)));
VarPattern pattern = Patterns.varPattern(x, ImmutableSet.of(titanicId, subProperty));
Set<GraqlTraversal> traversals = allGraqlTraversals(pattern).collect(toSet());
assertEquals(12, traversals.size());
Fragment xId = id(titanicId, x, ConceptId.of("Titanic"));
Fragment yId = id(movieId, y, ConceptId.of("movie"));
Fragment xSubY = outSub(subProperty, x, y);
Fragment ySubX = inSub(subProperty, y, x);
Set<GraqlTraversal> expected = ImmutableSet.of(traversal(xId, xSubY, yId), traversal(xId, ySubX, yId), traversal(xId, yId, xSubY), traversal(xId, yId, ySubX), traversal(xSubY, xId, yId), traversal(xSubY, yId, xId), traversal(ySubX, xId, yId), traversal(ySubX, yId, xId), traversal(yId, xId, xSubY), traversal(yId, xId, ySubX), traversal(yId, xSubY, xId), traversal(yId, ySubX, xId));
assertEquals(expected, traversals);
}
Aggregations