hydra-rdf 0.17.4 → 0.17.5
raw patch · 6 files changed
+427/−15 lines, 6 filesdep ~hydra-kernelPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: hydra-kernel
API changes (from Hackage documentation)
+ Hydra.Rdf.ShaclRdf: booleanNode :: Bool -> Node
+ Hydra.Rdf.ShaclRdf: commonConstraintToTriples :: Resource -> CommonConstraint -> [Triple]
+ Hydra.Rdf.ShaclRdf: commonPropertiesToTriples :: Resource -> CommonProperties -> [Triple]
+ Hydra.Rdf.ShaclRdf: definitionToTriples :: Definition Shape -> [Triple]
+ Hydra.Rdf.ShaclRdf: integerNode :: Integer -> Node
+ Hydra.Rdf.ShaclRdf: iriNode :: Iri -> Node
+ Hydra.Rdf.ShaclRdf: iriOrLiteralToNode :: IriOrLiteral -> Node
+ Hydra.Rdf.ShaclRdf: iriResource :: Iri -> Resource
+ Hydra.Rdf.ShaclRdf: nodeKindToIri :: NodeKind -> Iri
+ Hydra.Rdf.ShaclRdf: nodeShapeToTriples :: Iri -> NodeShape -> [Triple]
+ Hydra.Rdf.ShaclRdf: propertyRefToTriples :: Resource -> Reference PropertyShape -> [Triple]
+ Hydra.Rdf.ShaclRdf: propertyShapeConstraintToTriples :: Resource -> PropertyShapeConstraint -> [Triple]
+ Hydra.Rdf.ShaclRdf: propertyShapeToTriples :: Resource -> PropertyShape -> [Triple]
+ Hydra.Rdf.ShaclRdf: rdf :: String -> Iri
+ Hydra.Rdf.ShaclRdf: sh :: String -> Iri
+ Hydra.Rdf.ShaclRdf: shapesGraphToNtriples :: ShapesGraph -> String
+ Hydra.Rdf.ShaclRdf: shapesGraphToTriples :: ShapesGraph -> [Triple]
+ Hydra.Rdf.ShaclRdf: stringNode :: String -> Node
+ Hydra.Rdf.ShaclRdf: tripleIII :: Iri -> Iri -> Iri -> Triple
+ Hydra.Rdf.ShaclRdf: tripleIIN :: Iri -> Iri -> Node -> Triple
+ Hydra.Rdf.ShaclRdf: tripleRII :: Resource -> Iri -> Iri -> Triple
+ Hydra.Rdf.ShaclRdf: tripleRIN :: Resource -> Iri -> Node -> Triple
+ Hydra.Rdf.ShaclRdf: tripleToDescription :: Triple -> Description
+ Hydra.Rdf.ShaclRdf: xsd :: String -> Iri
Files
- CHANGELOG.md +125/−0
- hydra-rdf.cabal +4/−3
- src/main/haskell/Hydra/Rdf/Serde.hs +1/−1
- src/main/haskell/Hydra/Rdf/ShaclRdf.hs +289/−0
- src/main/haskell/Hydra/Rdf/Utils.hs +1/−1
- src/main/haskell/Hydra/Shacl/Coder.hs +7/−10
CHANGELOG.md view
@@ -15,6 +15,131 @@ --- +## [0.17.5] - 2026-08-19++Point release on the 0.17.x line. Two language-surface changes lead: sum-type eliminators unify on+`match` (scrutinee-first), and the primitive set is tentatively finalized — `strings.lines`/`unlines`+are removed in favour of `hydra.formatting` term helpers. A symlink-aware filesystem family lands+across all ten hosts, and Hydra's own build system continues its migration into Hydra.++**Backward-incompatible.** The `cases` -> `match` rename and the `strings.lines`/`unlines` removal+both change the published kernel surface. Code written against 0.17.4 that uses `Optionals.cases`+or `strings.lines`/`strings.unlines` must be updated.++### Highlights++- **Sum-type eliminators unify on `match`** ([#615](https://github.com/CategoricalData/hydra/issues/615)):+ the `cases`/`match` helper pair is flipped to a single scrutinee-first `match` convention across the+ Haskell, Java, Python, and Scala DSLs, the `optionals.cases` -> `optionals.match` kernel primitive,+ and the corresponding implementations in TypeScript and all four Lisp dialects.+- **Primitive set tentatively finalized** ([#417](https://github.com/CategoricalData/hydra/issues/417)):+ `strings.lines` and `strings.unlines` are removed as primitives; their semantics are preserved as+ `hydra.formatting.lines`/`unlines` term helpers, with overlay implementations dropped across all ten+ hosts and callers repointed.+- **Symlink-aware filesystem primitives** ([#666](https://github.com/CategoricalData/hydra/issues/666)):+ `status(followLinks)`, `createSymlink`, and `readSymlink` land with native implementations for every+ host — Haskell, Java, Python, Scala, TypeScript, Clojure, Common Lisp, Scheme, and Emacs Lisp.+- **Build system promotion continues** ([#416](https://github.com/CategoricalData/hydra/issues/416)):+ adds `hydra.build.walk` extension-glob helpers (`extensionOf`/`filterByExtension`/`matchesExtension`)+ and `hydra.build.comparereportlogic`, a set of pure snapshot-compare decision helpers.++### Bug fixes++- **`math.range` was inclusive of both bounds** ([#647](https://github.com/CategoricalData/hydra/issues/647)),+ silently fabricating an extra element in index arithmetic.+- **Java coder TCO-`cases` codegen** dropped enclosing-method type parameters from union-variant casts+ (found via [#666](https://github.com/CategoricalData/hydra/issues/666)).+- **`ShaclRdf` promoted to a DSL module** ([#652](https://github.com/CategoricalData/hydra/issues/652))+ so the SHACL pipeline works outside Haskell.+- **Cold-seed shim portability**: the R22 bootstrap shim used GNU-only `\+` and `\b`, which fail under+ BSD `sed` on macOS ([#417](https://github.com/CategoricalData/hydra/issues/417)).+- **Bootstrap Haskell target missing `unix`**: the demo's static `package.yaml` was not updated when+ `System.Posix.Files` entered the kernel overlay, breaking every `*-to-haskell` bootstrap cell+ ([#670](https://github.com/CategoricalData/hydra/issues/670)).+- **Bootstrap comparison scored Scala and TypeScript cells as passing without comparing anything**:+ `compare_output`'s target switch was missing both languages, so the baseline path was malformed,+ every file counted as "no baseline found", and a zero-file comparison reported `pass`. A Scala or+ TypeScript *target* cell could never fail ([#671](https://github.com/CategoricalData/hydra/issues/671)).++### Known issues++- A pre-#630 post-generation text pass rewrites `hydra.lib.<sub>` -> `hydra.overlay.<lang>.lib.<sub>`+ in generated **doc comments** as well as code, because its quote-prefix guard does not recognize+ mid-sentence prose references. Affects two kernel doc strings in `src/main`+ (`hydra.error.system`, `hydra.error.packaging`) plus ~20 generated docstrings in the test tree;+ cosmetic only, no behavioral impact. Tracked as part of+ [#633](https://github.com/CategoricalData/hydra/issues/633).+- Bootstrap comparison diff detail is not persisted to the run directory+ ([#671](https://github.com/CategoricalData/hydra/issues/671)).++---++## [0.17.4] - 2026-08-09++Point release on the 0.17.x line. Fixes an inference bug that mis-typed generated Java and Python for+`readFile`, adds the `divide` primitive, and restores `hydra-ext` to the published package set. Release+validation also surfaced a family of pre-existing cross-host code-generation defects — none of which the+per-host CI jobs can catch, because only the bootstrap exercises one host generating *another*.++### Highlights++- **Output-only nominal generalization fixed** ([#637](https://github.com/CategoricalData/hydra/issues/637),+ with [#638](https://github.com/CategoricalData/hydra/issues/638) /+ [#639](https://github.com/CategoricalData/hydra/issues/639) /+ [#640](https://github.com/CategoricalData/hydra/issues/640)): a nominal type appearing only in the+ *output* position of a primitive's signature was generalized to a free type variable instead of resolving+ as nominal, mis-typing the generated Java and Python for `readFile`. Also widens universe closure and adds+ a `kernelTypeUniverse` helper, an effect DSL builder, and `effects`/`files`/`text`/`system` lib wrappers.+- **`divide` primitive** ([#317](https://github.com/CategoricalData/hydra/issues/317)): now present in the+ published kernel. This also clears the cold-clone dangle, since a cold seed against published 0.17.4+ resolves `DefMath.divide`.+- **`hydra-ext` republished** ([#636](https://github.com/CategoricalData/hydra/issues/636)): back in the+ published set after its absence from 0.17.1–0.17.3, shipping to Hackage and PyPI.++### Bug fixes++- **Overlay-lib redirection skipped for the Haskell target**+ ([#630](https://github.com/CategoricalData/hydra/issues/630)):+ the Java, Python, Scheme, Clojure and Common Lisp heads resolved the overlay lib directory using an+ all-lowercase path and did not lower-case the names they scanned. Haskell's overlay tree is capitalized+ (`Hydra/Overlay/Haskell/Lib/`), so every `hydra.lib.*` redirect silently failed and the generated Haskell+ imported `Hydra.Lib.*` instead of `Hydra.Overlay.Haskell.Lib.*`, producing hundreds of type errors. The+ defect was invisible on case-sensitive filesystems, where the failed directory check falls back to a+ hard-coded list that happens to be correct. The Python head carried *two* independent copies of this scan;+ only the one in `generation.py` feeds the Haskell coder.+- **Lisp-as-host bootstrap** ([#520](https://github.com/CategoricalData/hydra/issues/520),+ [#630](https://github.com/CategoricalData/hydra/issues/630)): the four Lisp head decode drivers called+ `from_json` with a stale 4-argument signature, and the Lisp bootstrap-driver coders were not pre-bound with+ `overlaySubs`.+- **Python-as-host dropped the `Graph` argument** ([#630](https://github.com/CategoricalData/hydra/issues/630)):+ `overlaySubs` was not threaded into the Python head's `write_*` wrappers.+- **Clojure `resolve-coder` and `decimal-to-float32`**+ ([#630](https://github.com/CategoricalData/hydra/issues/630)): a stray parenthesis closed a `case` early,+ making an unsupported-default block run unconditionally; and `(float (.doubleValue ...))` threw on+ `Float.MAX_VALUE`, now saturating via `(.floatValue (bigdec x))`.+- **Cold-seeder failed on macOS** ([#630](https://github.com/CategoricalData/hydra/issues/630)): the #376+ cold seeder used a bare `sed -i -e`, which is GNU-only and aborts immediately under BSD `sed`.++### Release engineering++- **Review checkpoint before Maven Central publishes**+ ([#591](https://github.com/CategoricalData/hydra/issues/591)): `HYDRA_JAVA_PUBLISH_HOLD=1` uploads the+ aggregated Java deployment as `USER_MANAGED`, so it validates and then holds for review instead of+ publishing automatically. This mirrors `HYDRA_SCALA_PUBLISH_HOLD` and makes an upload reversible — a held+ deployment can be dropped, whereas an automatic one cannot be undone.++### Known issues++- **`hydra-ext` is not published to Maven Central**+ ([#643](https://github.com/CategoricalData/hydra/issues/643)): it does not compile for the Java target,+ because the visitor-pattern inner interface the Java coder emits collides with the enclosing `Visitor`+ type in `hydra.cpp.syntax`. Only Java is affected; the Python coder emits sibling classes rather than+ nested ones. ext ships to Hackage and PyPI at 0.17.4 and is expected to rejoin the Java set once fixed.+- **TypeScript no longer self-hosts**+ ([#642](https://github.com/CategoricalData/hydra/issues/642)): the TypeScript host's JSON decoder fails to+ decode most of the kernel, so `typescript-as-host` code generation is broken. No published artifact is+ affected — `dist/typescript` is generated by the Haskell host and passes its test suite.+ ## [0.17.3] - 2026-08-01 Point release on the 0.17.x line, focused on **release-artifact integrity**. The 0.17.2 release shipped
hydra-rdf.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.39.1.+-- This file has been generated from package.yaml by hpack version 0.38.1. -- -- see: https://github.com/sol/hpack name: hydra-rdf-version: 0.17.4+version: 0.17.5 synopsis: Hydra's RDF/SHACL/OWL model and coder support description: Hydra is an implementation of the LambdaGraph data model, which takes advantage of an isomorphism between labeled hypergraphs and typed lambda calculus: in Hydra, "graphs are programs, and programs are graphs". RDF support for Hydra category: Data@@ -31,6 +31,7 @@ Hydra.Dsl.Shacl.Model Hydra.Owl.Syntax Hydra.Rdf.Serde+ Hydra.Rdf.ShaclRdf Hydra.Rdf.Syntax Hydra.Rdf.Utils Hydra.Shacl.Coder@@ -45,6 +46,6 @@ build-depends: base >=4.19.0 && <4.22 , containers >=0.6.7 && <0.8- , hydra-kernel ==0.17.4+ , hydra-kernel ==0.17.5 , scientific >=0.3.7 && <0.4 default-language: Haskell2010
src/main/haskell/Hydra/Rdf/Serde.hs view
@@ -109,7 +109,7 @@ (escapeLiteralString lex), "\""]) suffix =- Optionals.cases lang (Serialization.noSep [+ Optionals.match lang (Serialization.noSep [ Serialization.cst "^^", (iriToExpr dt)]) languageTagToExpr in (Serialization.noSep [
+ src/main/haskell/Hydra/Rdf/ShaclRdf.hs view
@@ -0,0 +1,289 @@+-- 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
src/main/haskell/Hydra/Rdf/Utils.hs view
@@ -167,7 +167,7 @@ local_ = Util.qualifiedNameLocal qualName in (Syntax.Iri (Strings.concat [ "urn:",- (Optionals.cases gname "" Packaging.unModuleName),+ (Optionals.match gname "" Packaging.unModuleName), "#", (Formatting.decapitalize local_), (Formatting.capitalize (Core.unName fname))]))
src/main/haskell/Hydra/Shacl/Coder.hs view
@@ -43,6 +43,7 @@ import qualified Hydra.Rdf.Utils as Utils import qualified Hydra.Regex as Regex import qualified Hydra.Relational as Relational+import qualified Hydra.Rewriting as Rewriting import qualified Hydra.Shacl.Model as ShaclModel import qualified Hydra.Strip as Strip import qualified Hydra.System as System@@ -132,7 +133,7 @@ Syntax.Description { Syntax.descriptionSubject = (Syntax.NodeIri (Syntax.Iri "http://www.w3.org/1999/02/22-rdf-syntax-ns#nil")), Syntax.descriptionGraph = (Syntax.Graph Sets.empty)}],- cx0)) (Optionals.cases (Lists.uncons terms) (Right ([], cx0)) (\p ->+ cx0)) (Optionals.match (Lists.uncons terms) (Right ([], cx0)) (\p -> let pair1 = Utils.nextBlankNode cx0 node1 = Pairs.first pair1 cx1 = Pairs.second pair1@@ -202,13 +203,9 @@ in (Eithers.map (\_dr -> ( Lists.concat2 (Utils.forObjects subject (Utils.keyIri _ks) (Utils.subjectsOf (Pairs.first _dr))) (Utils.triplesOf (Pairs.first _dr)), (Pairs.second _dr))) (encodeTerm node2 (Pairs.second kv) cx2 g)))) cx (Maps.toList v0))- Core.TermWrap v0 -> Eithers.map (\_dr ->- let descs = Pairs.first _dr- cx1 = Pairs.second _dr- in (- Optionals.withDefault descs (Optionals.map (\p -> Lists.cons (withType (Core.wrappedTermTypeName v0) (Pairs.first p)) (Pairs.second p)) (Lists.uncons descs)),- cx1)) (encodeTerm subject (Core.wrappedTermBody v0) cx g)- Core.TermOptional v0 -> Optionals.cases v0 (Right ([], cx)) (\_inner -> encodeTerm subject _inner cx g)+ Core.TermWrap v0 -> encodeTerm subject (Rewriting.wrapTermToRecord (Core.wrappedTermTypeName v0) (Core.wrappedTermBody v0)) cx g+ Core.TermOptional v0 -> Optionals.match v0 (Right ([], cx)) (\_inner -> encodeTerm subject _inner cx g)+ Core.TermUnit -> Right ([], cx) Core.TermRecord v0 -> let rname = Core.recordTypeName v0 fields = Core.recordFields v0@@ -245,7 +242,7 @@ Core.TypeLiteral v0 -> Right (encodeLiteralType v0) Core.TypeMap _ -> any Core.TypePair _ -> any- Core.TypeWrap _ -> any+ Core.TypeWrap v0 -> encodeType tname (Rewriting.wrapTypeToRecord v0) cx Core.TypeRecord v0 -> Eithers.map (\_props -> common [ ShaclModel.CommonConstraintProperty (Sets.fromList (Lists.map (\_p -> ShaclModel.ReferenceDefinition _p) _props))]) (Eithers.mapList (\_pair -> encodeFieldType tname (Just (Pairs.first _pair)) (Pairs.second _pair) cx) (Lists.zip (Lists.map (\_i -> Literals.int32ToBigint _i) (Math.range 0 (Lists.length v0))) v0)) Core.TypeSet _ -> any@@ -266,7 +263,7 @@ -- | Fold over a list, accumulating results and threading context through each step foldAccumResult :: (t0 -> t1 -> Either t2 (t3, t0)) -> t0 -> [t1] -> Either t2 ([t3], t0) foldAccumResult f cx xs =- Optionals.cases (Lists.uncons xs) (Right ([], cx)) (\p -> Eithers.bind (f cx (Pairs.first p)) (\_r -> Eithers.map (\_rest -> (Lists.cons (Pairs.first _r) (Pairs.first _rest), (Pairs.second _rest))) (foldAccumResult f (Pairs.second _r) (Pairs.second p))))+ Optionals.match (Lists.uncons xs) (Right ([], cx)) (\p -> Eithers.bind (f cx (Pairs.first p)) (\_r -> Eithers.map (\_rest -> (Lists.cons (Pairs.first _r) (Pairs.first _rest), (Pairs.second _rest))) (foldAccumResult f (Pairs.second _r) (Pairs.second p)))) -- | Construct a SHACL node shape from a list of common constraints node :: [ShaclModel.CommonConstraint] -> ShaclModel.Shape