public void resolve()

in asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrite/resolve/ExhaustiveSearchResolver.java [407:501]


    public void resolve(PatternGroup patternGroup) throws CompilationException {
        // Populate our vertex / edge expression map.
        for (VertexPatternExpr vertexPatternExpr : patternGroup.getVertexPatternSet()) {
            VariableExpr vertexVariable = vertexPatternExpr.getVariableExpr();
            canonicalExpressionsMap.putIfAbsent(vertexVariable, new ArrayList<>());
            originalExpressionMap.put(vertexVariable, vertexPatternExpr);
        }
        for (EdgePatternExpr edgePatternExpr : patternGroup.getEdgePatternSet()) {
            EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor();
            VariableExpr edgeVariable = edgeDescriptor.getVariableExpr();
            canonicalExpressionsMap.putIfAbsent(edgeVariable, new ArrayList<>());
            originalExpressionMap.put(edgeVariable, edgePatternExpr);
        }

        // Expand the given pattern group and then prune the invalid pattern groups.
        List<PatternGroup> validPatternGroups = pruneInvalidPatternGroups(expandPatternGroups(patternGroup));
        for (PatternGroup validPatternGroup : validPatternGroups) {
            for (AbstractExpression canonicalExpr : validPatternGroup) {
                if (canonicalExpr instanceof VertexPatternExpr) {
                    VertexPatternExpr vertexPatternExpr = (VertexPatternExpr) canonicalExpr;
                    VariableExpr vertexVariable = vertexPatternExpr.getVariableExpr();
                    canonicalExpressionsMap.get(vertexVariable).add(deepCopyVisitor.visit(vertexPatternExpr, null));

                } else { // canonicalExpr instanceof EdgePatternExpr
                    EdgePatternExpr edgePatternExpr = (EdgePatternExpr) canonicalExpr;
                    EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor();
                    VariableExpr edgeVariable = edgeDescriptor.getVariableExpr();
                    canonicalExpressionsMap.get(edgeVariable).add(deepCopyVisitor.visit(edgePatternExpr, null));

                    // We must also visit the vertices of our edge (to find internal vertices).
                    VertexPatternExpr leftVertex = edgePatternExpr.getLeftVertex();
                    VertexPatternExpr rightVertex = edgePatternExpr.getRightVertex();
                    VariableExpr leftVariable = leftVertex.getVariableExpr();
                    VariableExpr rightVariable = rightVertex.getVariableExpr();
                    canonicalExpressionsMap.putIfAbsent(leftVariable, new ArrayList<>());
                    canonicalExpressionsMap.putIfAbsent(rightVariable, new ArrayList<>());
                    canonicalExpressionsMap.get(leftVariable).add(deepCopyVisitor.visit(leftVertex, null));
                    canonicalExpressionsMap.get(rightVariable).add(deepCopyVisitor.visit(rightVertex, null));
                }
            }
        }

        // Propagate the facts of our expression map to the original expressions.
        final Function<VariableExpr, Stream<VertexPatternExpr>> canonicalVertexStreamProvider =
                v -> canonicalExpressionsMap.get(v).stream().map(t -> (VertexPatternExpr) t);
        final Function<VariableExpr, Stream<EdgePatternExpr>> canonicalEdgeStreamProvider =
                v -> canonicalExpressionsMap.get(v).stream().map(t -> (EdgePatternExpr) t);
        for (Map.Entry<VariableExpr, AbstractExpression> mapEntry : originalExpressionMap.entrySet()) {
            if (canonicalExpressionsMap.get(mapEntry.getKey()).isEmpty()) {
                SourceLocation sourceLocation = mapEntry.getValue().getSourceLocation();
                throw new CompilationException(ErrorCode.COMPILATION_ERROR, sourceLocation,
                        "Encountered graph element that does not conform the queried graph schema!");
            }

            if (mapEntry.getValue() instanceof VertexPatternExpr) {
                VertexPatternExpr vertexPatternExpr = (VertexPatternExpr) mapEntry.getValue();
                vertexPatternExpr.getLabels().clear();
                Stream<VertexPatternExpr> vertexStream = canonicalVertexStreamProvider.apply(mapEntry.getKey());
                vertexStream.forEach(v -> vertexPatternExpr.getLabels().addAll(v.getLabels()));

            } else { // originalExpr instanceof EdgePatternExpr
                EdgePatternExpr edgePatternExpr = (EdgePatternExpr) mapEntry.getValue();
                EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor();
                Integer maximumHopLength = edgeDescriptor.getMaximumHops();

                // Update our edge labels.
                edgeDescriptor.getEdgeLabels().clear();
                Stream<EdgePatternExpr> edgeStream = canonicalEdgeStreamProvider.apply(mapEntry.getKey());
                edgeStream.forEach(e -> edgeDescriptor.getEdgeLabels().addAll(e.getEdgeDescriptor().getEdgeLabels()));

                // Update our direction, if we have resolved it.
                Set<EdgeDirection> resolvedDirections = canonicalEdgeStreamProvider.apply(mapEntry.getKey())
                        .map(e -> e.getEdgeDescriptor().getEdgeDirection()).collect(Collectors.toSet());
                if (resolvedDirections.size() == 1) {
                    edgeDescriptor.setEdgeDirection(resolvedDirections.iterator().next());
                }

                // Update the vertex references of our edge.
                VariableExpr leftVariable = edgePatternExpr.getLeftVertex().getVariableExpr();
                VariableExpr rightVariable = edgePatternExpr.getRightVertex().getVariableExpr();
                edgePatternExpr.getLeftVertex().getLabels().clear();
                edgePatternExpr.getRightVertex().getLabels().clear();
                Stream<VertexPatternExpr> leftStream = canonicalVertexStreamProvider.apply(leftVariable);
                Stream<VertexPatternExpr> rightStream = canonicalVertexStreamProvider.apply(rightVariable);
                leftStream.forEach(v -> edgePatternExpr.getLeftVertex().getLabels().addAll(v.getLabels()));
                rightStream.forEach(v -> edgePatternExpr.getRightVertex().getLabels().addAll(v.getLabels()));
                if (edgeDescriptor.getPatternType() == EdgeDescriptor.PatternType.PATH && maximumHopLength != 1) {
                    VariableExpr internalVariable = edgePatternExpr.getInternalVertex().getVariableExpr();
                    edgePatternExpr.getInternalVertex().getLabels().clear();
                    Stream<VertexPatternExpr> internalStream = canonicalVertexStreamProvider.apply(internalVariable);
                    internalStream.forEach(v -> edgePatternExpr.getInternalVertex().getLabels().addAll(v.getLabels()));
                }
            }
        }
    }