Skip to main content

Parser from SHACL into the SHACL Logical Syntax.

Project description

SHACL Logical Syntax parser

This project was originally used as a sub-package for experiments done for our work on Provenance for SHACL, paper.

However, this logical syntax parser can be used for multiple purposes so this project extends and publishes it as its own package.

Features

  • Parsing a SHACL shapes graph into a parse tree of the SHACL Logical Syntax (slsparser.parse)
  • Transforming the parse tree (see slsparser.utilities):
    • expand_shape: inline all HASSHAPE references
    • negation_normal_form: push negations down to the leaves
    • clean_parsetree: simplify the tree (remove TOP/BOT, collapse trivial AND/OR, ...)

Roadmap (not yet implemented)

  • Given a parse tree of the logical syntax, output a SHACL shapes graph

This framework allows for more shapes than you currently can write with W3C SHACL. However, every shape that you can write in W3C SHACL can be written in this framework.

Data Structure

When you parse a SHACL shapes graph, the output is a tuple of two dictionaries.

  • The first dictionary represent all the shape definitions. The keys are rdflib IdentifiedNode objects. The values are SANode objects.
  • The second dictionary represent all target statements. The keys are rdflib IdentifiedNode objects. The values are SANode objects.

SANodes

A SANode is an object that represents a shape. The underlying idea is that this is a syntax tree of the logical syntax representation of a shape. It consists of two components:

  • a type, which is an Enum called Op
  • a list of children, the elements of this list are dependent on the Op

Op

There are more/other Op types than there are defined in the logical syntax in the paper. Mostly out of efficiency considerations.

  • Op.HASVALUE has one rdflib IdentifiedNode or Literal object as a child. Only the value itself satisfies this shape.
  • Op.TEST has different children, depending on what kind of test it represents.

The first child is an IRI with the corresponding constraint component. The list of children can be:

  • [sh:LanguageInConstraintComponent ...]

  • [sh:DatatypeConstraintComponent, xsd:string] or other datatypes

  • [sh:NodeKindConstraintComponent, sh:iri] or other: any of the six combinations

  • [sh:PatternConstraintComponent, patternstring, flags]

  • [numeric_range, <range_statement>, <value>]

    • <range_statement> is one of: sh:MinExclusiveConstraintComponent, sh:MaxExclusiveConstraintComponent, sh:MinInclusiveConstraintComponent, sh:MaxInclusiveConstraintComponent
    • <value> is an rdflib literal (numeric) value There is at most one of min_... and at most one of max_... followed by a value
    • [length_range, <range_statement>, <value>]
      • <range_statement> is one of: sh:MinLengthConstraintComponent, sh:MaxLengthConstraintComponent
        • <value> is an rdflib literal (numeric) value
    • There is at most one of min_... and at most one of max_... followed by a value
  • Op.NOT has one SANode object as a child. The shape is satisfied if the shape represented by the child is not satisfied.

  • Op.AND has one or more SANode objects as children. The shape is satisfied if all the shapes represented by the children are satisfied.

  • Op.OR has one or more SANode objects as children. The shape is satisfied if at least one of the shapes represented by the children is satisfied.

  • Op.HASSHAPE has one rdflib IdentifiedNode as a child. The IdentifiedNode represents a shape name. The shape is satisfied if the shape corresponding to the shapename is satisfied.

  • Op.FORALL has exactly two children. The first is a PANode representing a path expression. The second is an SANode representing a shape. A node satisfies the forall shape, if all nodes reachable by the path expression satisfy the shape represented by the SANode.

  • Op.EQ has exactly two children. Both are PANode objects representing path expressions. A node satisfies this shape if the set of nodes reachable by the first path expression is equal to the set of nodes reachable by the second path expression.

  • Op.DISJ has exactly two children. Both are PANode objects representing path expressions. A node satisfies this shape if the set of nodes reachable by the first path expression is disjoint from the set of nodes reachable by the second path expression.

  • Op.CLOSED has one or more rdflib uriref objects as children. The shape is satisfied by nodes that are only subjects of triples that have a predicate present in the list of children.

  • Op.LESSTHAN has exactly two children. Both are PANodes.

  • Op.LESSTHANEQ has exactly two children. Both are PANodes.

  • Op.UNIQUELANG has exactly one PANode child.

  • Op.TOP has no children. All nodes satisfy this shape.

  • Op.BOT has no children. No node satisfies this shape.

PANodes

A PANode is an object that represent a path expression. It is very similar to the structure of the SANode. The underlying idea is that this is a syntax tree of the path expressions. It consists of two components:

  • a type, which is an Enum called POp
  • a list of children, the elements of this list are dependent on the POp

POp

There are several POp types:

  • POp.PROP has one child, which is an URIRef representing a property name. It represents a simple property name.
  • POp.INV has one child, which is a PANode. It represents the inverse of that PANode.
  • POp.ZEROORONE has one child, which is a PANode. It represents the zero-or-one path expression.
  • POp.ALT has one or more children, which are PANodes. It represents the alternative path expression.
  • POp.KLEENE has one child, which is a PANode. It represents the zero-or-more path expression.
  • POp.COMP has one or more children, which are PANodes. It represents the sequence path expression.
  • POp.ID has no children. It represents the identity path expression. It is used to represent the path from which every node can only reach itself. It has no W3C SHACL standard counterpart, however it is useful to express some shapes.

Use

The main function is slsparser.shapels.parse(graph: rdflib.Graph). This function has as its argument an rdflib Graph object that represents the shapesgraph (your SHACL turtle file). It returns a tuple of dictionaries. The first dictionary represents the shape definitions. The keys are all the shape names that were defined in the shapesgraph. These are represented by rdflib Identifiers. The values are SANodes. The second dictionary represents the targeting statements for every shape that has one. The keys are the shapes with targeting statements, and the values are SANodes representing the targeting type.

Contact

The package is to be used for my research purposes, but it may be useful for other applications. If you are interested, please let me know. Currently, I'm working on an alternative SHACL syntax based on the SHACL Logical Syntax.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

slsparser-1.0.0.tar.gz (13.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

slsparser-1.0.0-py3-none-any.whl (13.1 kB view details)

Uploaded Python 3

File details

Details for the file slsparser-1.0.0.tar.gz.

File metadata

  • Download URL: slsparser-1.0.0.tar.gz
  • Upload date:
  • Size: 13.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for slsparser-1.0.0.tar.gz
Algorithm Hash digest
SHA256 35663f68018483bd29beeae6222ecce837b3b4593a4c3a0a9238cd277a788573
MD5 8f2245ce4e6cef413f196b0169acb068
BLAKE2b-256 a830dffa4c72df5047147be3ff28f18c968db561bd4447678a1eda96a5d0bc2d

See more details on using hashes here.

File details

Details for the file slsparser-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: slsparser-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 13.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for slsparser-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5d1297526fce76f6ff5fd9a36943cb72f24eda954fe4b5e99174afc110ed68ff
MD5 a2485d597ace735460b0f4df8fda2fd6
BLAKE2b-256 9d5e05a7e98daa15ea0e1d0a10a96c9d6e84732fc95baad6c949b3046cf4d49f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page