Ejemplo n.º 1
0
    def end_class(self, cls: ClassDefinition) -> None:
        if cls.is_a:
            self._add_constraint(self.namespaces.uri_for(camelcase(cls.is_a) + "_t"))
        for mixin in cls.mixins:
            if self._class_has_expressions(mixin):
                self._add_constraint(self.namespaces.uri_for(camelcase(mixin) + "_t"))
        if cls.name in self.synopsis.applytorefs:
            for applyto in self.synopsis.applytorefs[cls.name].classrefs:
                if self._class_has_expressions(applyto):
                    self._add_constraint(self.namespaces.uri_for(camelcase(applyto) + '_t'))

        self.shape.closed = True
        self.shape.extra = [RDF.type]
        if self.shape.expression:
            # TODO: Figure out how to label a single triple expression
            if isinstance_(self.shape.expression, tripleExprLabel):
                self.shape.expression = EachOf(expressions=[self.shape.expression, wildcard(None)])
            self.shape.expression.id = self.namespaces.uri_for(camelcase(cls.name) + "_t")
        else:
            self.shape.expression = wildcard(self.namespaces.uri_for(camelcase(cls.name) + "_t"))

        if self.class_identifier(cls):
            self.shape.extra = [RDF.type]
            type_constraint = TripleConstraint()
            type_constraint.predicate = RDF.type
            type_constraint.valueExpr = NodeConstraint(values=[IRIREF(self.namespaces.uri_for(cls.class_uri))])
            if not self.shape.expression:
                self.shape.expression = type_constraint
            else:
                self.shape.expression = EachOf(expressions=[self.shape.expression, type_constraint])

        shapeExpr = self.shape
        shapeExpr.id = self._shape_iri(cls.name)
        self.shapes.append(shapeExpr)
Ejemplo n.º 2
0
    def gen_multivalued_slot(self, target_name_base: str,
                             target_type: IRIREF) -> IRIREF:
        """ Generate a shape that represents an RDF list of target_type

        @param target_name_base:
        @param target_type:
        @return:
        """
        list_shape_id = IRIREF(target_name_base + "__List")
        if list_shape_id not in self.list_shapes:
            list_shape = Shape(id=list_shape_id, closed=True)
            list_shape.expression = EachOf()
            expressions = [
                TripleConstraint(predicate=RDF.first,
                                 valueExpr=target_type,
                                 min=0,
                                 max=1)
            ]
            targets = ShapeOr()
            targets.shapeExprs = [(NodeConstraint(values=[RDF.nil])),
                                  list_shape_id]
            expressions.append(
                TripleConstraint(predicate=RDF.rest, valueExpr=targets))
            list_shape.expression.expressions = expressions
            self.shapes.append(list_shape)
            self.list_shapes.append(list_shape_id)
        return list_shape_id
def matchesTripleConstraint(cntxt: Context, t: RDFTriple,
                            expr: ShExJ.TripleConstraint,
                            c: DebugContext) -> bool:
    """
    expr is a TripleConstraint and:

    * t is a triple
    * t's predicate equals expr's predicate.
      Let value be t's subject if inverse is true, else t's object.
    * if inverse is true, t is in arcsIn, else t is in arcsOut.

    """
    from pyshex.shape_expressions_language.p5_3_shape_expressions import satisfies

    if c.debug:
        print(c.i(1, " triple: " + t))
        print(c.i(1, '', expr._as_json_dumps().split('\n')))

    if uriref_matches_iriref(t.p, expr.predicate):
        value = t.s if expr.inverse else t.o
        return expr.valueExpr is None or satisfies(cntxt, value,
                                                   expr.valueExpr)
    else:
        cntxt.fail_reason = "Predicate mismatch: " + t.p + " ≠ " + expr.predicate
        return False
Ejemplo n.º 4
0
    def end_class(self, cls: ClassDefinition) -> None:
        # On entry self.shape contains all of the triple expressions that define the body of the shape

        # Finish off the shape definition itself

        # If there is nothing yet, we're at the very root of things.  Add in a final catch-all for any additional
        # type arcs.  NOTE: Here is where you can sink other things as well if you want to ignore categories of things
        if self.shape.expression is None:
            self._add_constraint(TripleConstraint(predicate=RDF.type, min=0, max=-1))
        self.shape.expression.id = self._class_or_type_uri(cls, '_tes')
        self.shape.expression = EachOf(expressions=[self.shape.expression,
                                                    self._type_arc(cls.class_uri,
                                                                   not bool(self.class_identifier(cls)))])
        self.shape.closed = not (cls.abstract or cls.mixin)

        # If this class has subtypes, define the class as the union of its subtypes and itself (if not abstract)
        if cls.name in self.synopsis.isarefs:
            childrenExprs = []
            for child_classname in sorted(list(self.synopsis.isarefs[cls.name].classrefs)):
                childrenExprs.append(self._class_or_type_uri(child_classname))
            if not (cls.mixin or cls.abstract) or len(childrenExprs) == 1:
                childrenExprs.insert(0, self.shape)
                self.shapes.append(ShapeOr(id=self._class_or_type_uri(cls), shapeExprs=childrenExprs))
            else:
                self.shapes.append(ShapeOr(id=self._class_or_type_uri(cls), shapeExprs=childrenExprs))
                self.shape.id = self._class_or_type_uri(cls, "_struct")
                self.shapes.append(self.shape)
        else:
            self.shape.id = self._class_or_type_uri(cls)
            self.shapes.append(self.shape)
Ejemplo n.º 5
0
def wildcard(id: str) -> TripleConstraint:
    """
    Return a synthetic 'wild card' constraint of the form {p .?}
    :param id: Triple identifier
    :return: Corresponding constraint
    """
    return TripleConstraint(id=id, predicate="http://ex.org/dummy", min=0, max=1)
Ejemplo n.º 6
0
 def _type_arc(self,
               target: URIorCURIE,
               opt: bool = False) -> TripleConstraint:
     return TripleConstraint(
         predicate=RDF.type,
         valueExpr=NodeConstraint(
             values=[IRIREF(self.namespaces.uri_for(target))]),
         min=0 if opt else 1)
Ejemplo n.º 7
0
    def visit_class_slot(self, cls: ClassDefinition, aliased_slot_name: str,
                         slot: SlotDefinition) -> None:
        constraint = TripleConstraint()
        # Juggling to get the constraint to be either a single triple constraint or an eachof construct
        if not self.shape.expression:
            self.shape.expression = constraint
        elif isinstance(self.shape.expression, TripleConstraint):
            self.shape.expression = EachOf(
                expressions=[self.shape.expression, constraint])
        else:
            self.shape.expression.expressions.append(constraint)

        constraint.predicate = self._predicate(slot.name)
        # JSON-LD generates multi-valued entries as lists
        constraint.min = 1 if slot.primary_key or slot.required else 0
        constraint.max = 1 if not slot.multivalued or self.collections else -1
        # TODO: This should not be hard coded -- figure out where to go with it
        rng = IRIREF(META.SlotRangeTypes) if slot.range == 'anytype' else\
              self._type_constraint(slot.range) if slot.range and slot.range not in self.schema.classes else\
              self._shapeIRI(slot.range)
        name_base = ("XSD_" +
                     self.grounded_slot_range(slot.range)) if isinstance(
                         rng, NodeConstraint) else str(rng)
        constraint.valueExpr = self.gen_multivalued_slot(name_base, rng) \
            if slot.multivalued and self.collections else rng
Ejemplo n.º 8
0
 def visitUnaryTripleExpr(self, ctx: ShExDocParser.UnaryTripleExprContext):
     """ unaryTripleExpr: ('$' tripleExprLabel)? (tripleConstraint | bracketedTripleExpr) | include """
     if ctx.include():
         self.expression = self.context.tripleexprlabel_to_iriref(
             ctx.include().tripleExprLabel())
     else:
         lbl = self.context.tripleexprlabel_to_iriref(
             ctx.tripleExprLabel()) if ctx.tripleExprLabel() else None
         if ctx.tripleConstraint():
             self.expression = TripleConstraint(lbl)
             self.visit(ctx.tripleConstraint())
         elif ctx.bracketedTripleExpr():
             self.visit(ctx.bracketedTripleExpr())
             self.expression.id = lbl
Ejemplo n.º 9
0
 def visit_class_slot(self, cls: ClassDefinition, aliased_slot_name: SlotDefinitionName, slot: SlotDefinition) \
         -> None:
     if not (slot.identifier or slot.abstract or slot.mixin):
         constraint = TripleConstraint()
         self._add_constraint(constraint)
         constraint.predicate = self.namespaces.uri_for(slot.slot_uri)
         constraint.min = int(bool(slot.required))
         constraint.max = 1 if not slot.multivalued else -1
         constraint.valueExpr = self._class_or_type_uri(slot.range)
Ejemplo n.º 10
0
def nevermatch() -> TripleConstraint:
    """
    Return a triple constraint that can never be matched
    """
    return TripleConstraint(predicate="http://ex.org/dummy", min=1, max=1)