packages feed

hydra-rdf-0.17.5: src/main/haskell/Hydra/Rdf/ShaclRdf.hs

-- Note: this is an automatically generated file. Do not edit.

-- | Serialize a SHACL ShapesGraph to RDF triples using the SHACL vocabulary

module Hydra.Rdf.ShaclRdf where

import qualified Hydra.Ast as Ast
import qualified Hydra.Coders as Coders
import qualified Hydra.Core as Core
import qualified Hydra.Docs as Docs
import qualified Hydra.Error.Checking as Checking
import qualified Hydra.Error.Core as ErrorCore
import qualified Hydra.Error.File as ErrorFile
import qualified Hydra.Error.Packaging as ErrorPackaging
import qualified Hydra.Error.System as ErrorSystem
import qualified Hydra.Errors as Errors
import qualified Hydra.File as File
import qualified Hydra.Graph as Graph
import qualified Hydra.Json.Model as JsonModel
import qualified Hydra.Overlay.Haskell.Lib.Lists as Lists
import qualified Hydra.Overlay.Haskell.Lib.Literals as Literals
import qualified Hydra.Overlay.Haskell.Lib.Logic as Logic
import qualified Hydra.Overlay.Haskell.Lib.Optionals as Optionals
import qualified Hydra.Overlay.Haskell.Lib.Sets as Sets
import qualified Hydra.Packaging as Packaging
import qualified Hydra.Parsing as Parsing
import qualified Hydra.Paths as Paths
import qualified Hydra.Query as Query
import qualified Hydra.Rdf.Serde as Serde
import qualified Hydra.Rdf.Syntax as Syntax
import qualified Hydra.Rdf.Utils as Utils
import qualified Hydra.Regex as Regex
import qualified Hydra.Relational as Relational
import qualified Hydra.Shacl.Model as ShaclModel
import qualified Hydra.System as System
import qualified Hydra.Tabular as Tabular
import qualified Hydra.Testing as Testing
import qualified Hydra.Time as Time
import qualified Hydra.Topology as Topology
import qualified Hydra.Typed as Typed
import qualified Hydra.Typing as Typing
import qualified Hydra.Util as Util
import qualified Hydra.Validation as Validation
import qualified Hydra.Variants as Variants
import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
import qualified Data.Scientific as Sci

-- | Create a boolean literal node
booleanNode :: Bool -> Syntax.Node
booleanNode b =
    Syntax.NodeLiteral (Syntax.Literal {
      Syntax.literalLexicalForm = (Logic.ifElse b "true" "false"),
      Syntax.literalDatatypeIri = (xsd "boolean"),
      Syntax.literalLanguageTag = Nothing})

-- | Serialize a CommonConstraint to triples
commonConstraintToTriples :: Syntax.Resource -> ShaclModel.CommonConstraint -> [Syntax.Triple]
commonConstraintToTriples subj cc =
    case cc of
      ShaclModel.CommonConstraintDatatype v0 -> [
        tripleRII subj (sh "datatype") v0]
      ShaclModel.CommonConstraintClass _ -> []
      ShaclModel.CommonConstraintNodeKind v0 -> [
        tripleRII subj (sh "nodeKind") (nodeKindToIri v0)]
      ShaclModel.CommonConstraintProperty v0 -> Lists.concat (Lists.map (propertyRefToTriples subj) (Sets.toList v0))
      ShaclModel.CommonConstraintMaxInclusive v0 -> [
        tripleRIN subj (sh "maxInclusive") (Syntax.NodeLiteral v0)]
      ShaclModel.CommonConstraintMinInclusive v0 -> [
        tripleRIN subj (sh "minInclusive") (Syntax.NodeLiteral v0)]
      ShaclModel.CommonConstraintMaxExclusive v0 -> [
        tripleRIN subj (sh "maxExclusive") (Syntax.NodeLiteral v0)]
      ShaclModel.CommonConstraintMinExclusive v0 -> [
        tripleRIN subj (sh "minExclusive") (Syntax.NodeLiteral v0)]
      ShaclModel.CommonConstraintMaxLength v0 -> [
        tripleRIN subj (sh "maxLength") (integerNode v0)]
      ShaclModel.CommonConstraintMinLength v0 -> [
        tripleRIN subj (sh "minLength") (integerNode v0)]
      ShaclModel.CommonConstraintPattern v0 ->
        let regex_ = ShaclModel.patternRegex v0
            flags_ = ShaclModel.patternFlags v0
        in (Lists.concat [
          [
            tripleRIN subj (sh "pattern") (stringNode regex_)],
          (Optionals.match flags_ [] (\f -> [
            tripleRIN subj (sh "flags") (stringNode f)]))])
      ShaclModel.CommonConstraintClosed v0 -> [
        tripleRIN subj (sh "closed") (booleanNode (ShaclModel.closedIsClosed v0))]
      ShaclModel.CommonConstraintHasValue v0 -> Lists.map (\n -> tripleRIN subj (sh "hasValue") n) (Sets.toList v0)
      ShaclModel.CommonConstraintIn v0 -> Lists.map (\n -> tripleRIN subj (sh "in") n) v0
      ShaclModel.CommonConstraintNode v0 -> Lists.concat (Lists.map (\ref -> (\x -> case x of
        ShaclModel.ReferenceNamed v1 -> [
          tripleRII subj (sh "node") v1]
        _ -> []) ref) (Sets.toList v0))
      ShaclModel.CommonConstraintNot v0 -> Lists.concat (Lists.map (\ref -> (\x -> case x of
        ShaclModel.ReferenceNamed v1 -> [
          tripleRII subj (sh "not") v1]
        _ -> []) ref) (Sets.toList v0))
      ShaclModel.CommonConstraintAnd v0 -> Lists.concat (Lists.map (\ref -> (\x -> case x of
        ShaclModel.ReferenceNamed v1 -> [
          tripleRII subj (sh "and") v1]
        _ -> []) ref) (Sets.toList v0))
      ShaclModel.CommonConstraintOr v0 -> Lists.concat (Lists.map (\ref -> (\x -> case x of
        ShaclModel.ReferenceNamed v1 -> [
          tripleRII subj (sh "or") v1]
        _ -> []) ref) (Sets.toList v0))
      ShaclModel.CommonConstraintXone v0 -> Lists.concat (Lists.map (\ref -> (\x -> case x of
        ShaclModel.ReferenceNamed v1 -> [
          tripleRII subj (sh "xone") v1]
        _ -> []) ref) (Sets.toList v0))
      ShaclModel.CommonConstraintEquals _ -> []
      ShaclModel.CommonConstraintDisjoint _ -> []
      ShaclModel.CommonConstraintLanguageIn _ -> []

-- | Serialize CommonProperties to triples
commonPropertiesToTriples :: Syntax.Resource -> ShaclModel.CommonProperties -> [Syntax.Triple]
commonPropertiesToTriples subj cp =
    Lists.concat [
      Lists.concat (Lists.map (commonConstraintToTriples subj) (Sets.toList (ShaclModel.commonPropertiesConstraints cp))),
      (Optionals.match (ShaclModel.commonPropertiesDeactivated cp) [] (\b -> [
        tripleRIN subj (sh "deactivated") (booleanNode b)])),
      (Lists.concat (Lists.map (\n -> [
        tripleRIN subj (sh "targetNode") (iriOrLiteralToNode n)]) (Sets.toList (ShaclModel.commonPropertiesTargetNode cp))))]

-- | Serialize a Definition<Shape> to triples
definitionToTriples :: ShaclModel.Definition ShaclModel.Shape -> [Syntax.Triple]
definitionToTriples d =

      let iri_ = ShaclModel.definitionIri d
          shape = ShaclModel.definitionTarget d
      in case shape of
        ShaclModel.ShapeNode v0 -> nodeShapeToTriples iri_ v0
        ShaclModel.ShapeProperty v0 -> propertyShapeToTriples (iriResource iri_) v0

-- | Create an integer literal node
integerNode :: Integer -> Syntax.Node
integerNode n =
    Syntax.NodeLiteral (Syntax.Literal {
      Syntax.literalLexicalForm = (Literals.showBigint n),
      Syntax.literalDatatypeIri = (xsd "integer"),
      Syntax.literalLanguageTag = Nothing})

-- | Create an IRI node
iriNode :: Syntax.Iri -> Syntax.Node
iriNode i = Syntax.NodeIri i

-- | Convert an IriOrLiteral to an RDF Node
iriOrLiteralToNode :: Syntax.IriOrLiteral -> Syntax.Node
iriOrLiteralToNode il =
    case il of
      Syntax.IriOrLiteralIri v0 -> Syntax.NodeIri v0
      Syntax.IriOrLiteralLiteral v0 -> Syntax.NodeLiteral v0

-- | Create an IRI resource
iriResource :: Syntax.Iri -> Syntax.Resource
iriResource i = Syntax.ResourceIri i

-- | Convert a NodeKind to its SHACL IRI
nodeKindToIri :: ShaclModel.NodeKind -> Syntax.Iri
nodeKindToIri nk =
    case nk of
      ShaclModel.NodeKindBlankNode -> sh "BlankNode"
      ShaclModel.NodeKindIri -> sh "IRI"
      ShaclModel.NodeKindLiteral -> sh "Literal"
      ShaclModel.NodeKindBlankNodeOrIri -> sh "BlankNodeOrIRI"
      ShaclModel.NodeKindBlankNodeOrLiteral -> sh "BlankNodeOrLiteral"
      ShaclModel.NodeKindIriOrLiteral -> sh "IRIOrLiteral"

-- | Serialize a NodeShape to triples
nodeShapeToTriples :: Syntax.Iri -> ShaclModel.NodeShape -> [Syntax.Triple]
nodeShapeToTriples iri_ ns_ =
    Lists.concat [
      [
        tripleIII iri_ (rdf "type") (sh "NodeShape"),
        (tripleIII iri_ (sh "targetClass") iri_)],
      (commonPropertiesToTriples (iriResource iri_) (ShaclModel.nodeShapeCommon ns_))]

-- | Serialize a property shape reference (may be inline or named)
propertyRefToTriples :: Syntax.Resource -> ShaclModel.Reference ShaclModel.PropertyShape -> [Syntax.Triple]
propertyRefToTriples subj ref =
    (\x -> case x of
      ShaclModel.ReferenceNamed v0 -> [
        tripleRII subj (sh "property") v0]
      ShaclModel.ReferenceDefinition v0 ->
        let iri_ = ShaclModel.definitionIri v0
            ps = ShaclModel.definitionTarget v0
        in (Lists.concat [
          [
            tripleRII subj (sh "property") iri_],
          (propertyShapeToTriples (iriResource iri_) ps)])
      ShaclModel.ReferenceAnonymous _ -> []) ref

-- | Serialize a PropertyShapeConstraint to triples
propertyShapeConstraintToTriples :: Syntax.Resource -> ShaclModel.PropertyShapeConstraint -> [Syntax.Triple]
propertyShapeConstraintToTriples subj psc =
    case psc of
      ShaclModel.PropertyShapeConstraintMinCount v0 -> [
        tripleRIN subj (sh "minCount") (integerNode v0)]
      ShaclModel.PropertyShapeConstraintMaxCount v0 -> [
        tripleRIN subj (sh "maxCount") (integerNode v0)]
      ShaclModel.PropertyShapeConstraintLessThan _ -> []
      ShaclModel.PropertyShapeConstraintLessThanOrEquals _ -> []
      ShaclModel.PropertyShapeConstraintUniqueLang v0 -> [
        tripleRIN subj (sh "uniqueLang") (booleanNode v0)]
      ShaclModel.PropertyShapeConstraintQualifiedValueShape _ -> []

-- | Serialize a PropertyShape to triples, given a subject resource (may be blank node)
propertyShapeToTriples :: Syntax.Resource -> ShaclModel.PropertyShape -> [Syntax.Triple]
propertyShapeToTriples subj ps =
    Lists.concat [
      [
        tripleRII subj (rdf "type") (sh "PropertyShape"),
        (tripleRII subj (sh "path") (ShaclModel.propertyShapePath ps))],
      (commonPropertiesToTriples subj (ShaclModel.propertyShapeCommon ps)),
      (Lists.concat (Lists.map (propertyShapeConstraintToTriples subj) (Sets.toList (ShaclModel.propertyShapeConstraints ps)))),
      (Optionals.match (ShaclModel.propertyShapeOrder ps) [] (\n -> [
        tripleRIN subj (sh "order") (integerNode n)]))]

-- | Construct an IRI in the RDF namespace
rdf :: String -> Syntax.Iri
rdf local = Utils.rdfIri local

-- | Construct an IRI in the SHACL namespace
sh :: String -> Syntax.Iri
sh local = Utils.iri "http://www.w3.org/ns/shacl#" local

-- | Convert a ShapesGraph to N-Triples string
shapesGraphToNtriples :: ShaclModel.ShapesGraph -> String
shapesGraphToNtriples sg =

      let triples = shapesGraphToTriples sg
          descs = Lists.map (\t -> tripleToDescription t) triples
      in (Serde.rdfGraphToNtriples (Utils.descriptionsToGraph descs))

-- | Convert a ShapesGraph to RDF triples
shapesGraphToTriples :: ShaclModel.ShapesGraph -> [Syntax.Triple]
shapesGraphToTriples sg = Lists.concat (Lists.map (\d -> definitionToTriples d) (Sets.toList (ShaclModel.unShapesGraph sg)))

-- | Create a string literal node
stringNode :: String -> Syntax.Node
stringNode s =
    Syntax.NodeLiteral (Syntax.Literal {
      Syntax.literalLexicalForm = s,
      Syntax.literalDatatypeIri = (xsd "string"),
      Syntax.literalLanguageTag = Nothing})

-- | Create a triple from IRI subject, IRI predicate, and IRI object
tripleIII :: Syntax.Iri -> Syntax.Iri -> Syntax.Iri -> Syntax.Triple
tripleIII s p o =
    Syntax.Triple {
      Syntax.tripleSubject = (iriResource s),
      Syntax.triplePredicate = p,
      Syntax.tripleObject = (iriNode o)}

-- | Create a triple from IRI subject, IRI predicate, and node object
tripleIIN :: Syntax.Iri -> Syntax.Iri -> Syntax.Node -> Syntax.Triple
tripleIIN s p o =
    Syntax.Triple {
      Syntax.tripleSubject = (iriResource s),
      Syntax.triplePredicate = p,
      Syntax.tripleObject = o}

-- | Create a triple from resource subject, IRI predicate, and IRI object
tripleRII :: Syntax.Resource -> Syntax.Iri -> Syntax.Iri -> Syntax.Triple
tripleRII s p o =
    Syntax.Triple {
      Syntax.tripleSubject = s,
      Syntax.triplePredicate = p,
      Syntax.tripleObject = (iriNode o)}

-- | Create a triple from resource subject, IRI predicate, and node object
tripleRIN :: Syntax.Resource -> Syntax.Iri -> Syntax.Node -> Syntax.Triple
tripleRIN s p o =
    Syntax.Triple {
      Syntax.tripleSubject = s,
      Syntax.triplePredicate = p,
      Syntax.tripleObject = o}

-- | Convert a single triple to a description (one triple per description)
tripleToDescription :: Syntax.Triple -> Syntax.Description
tripleToDescription t =

      let subj = Syntax.tripleSubject t
      in Syntax.Description {
        Syntax.descriptionSubject = (Utils.resourceToNode subj),
        Syntax.descriptionGraph = (Syntax.Graph (Sets.singleton t))}

-- | Construct an IRI in the XML Schema namespace
xsd :: String -> Syntax.Iri
xsd local = Utils.xmlSchemaDatatypeIri local