From c5ec8c290f0297b0676647c7d3c62eb819d1e637 Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Tue, 28 Apr 2026 21:32:25 +0100 Subject: [PATCH] RDF syntax for SHACL Rules --- .../rules-rdf-syntax/rdf-syntax-shapes.ttl | 236 ++++++++++++++ shacl12-rules/rules-rdf-syntax/rules-ns.ttl | 162 ++++++++++ .../rules-rdf-syntax/rules-targets.ttl | 13 + .../rules-rdf-syntax/test-elements.ttl | 187 ++++++++++++ shacl12-rules/rules-rdf-syntax/test-rules.ttl | 287 ++++++++++++++++++ shacl12-rules/rules-rdf-syntax/test-terms.ttl | 102 +++++++ .../rules-rdf-syntax/test-triples.ttl | 135 ++++++++ 7 files changed, 1122 insertions(+) create mode 100644 shacl12-rules/rules-rdf-syntax/rdf-syntax-shapes.ttl create mode 100644 shacl12-rules/rules-rdf-syntax/rules-ns.ttl create mode 100644 shacl12-rules/rules-rdf-syntax/rules-targets.ttl create mode 100644 shacl12-rules/rules-rdf-syntax/test-elements.ttl create mode 100644 shacl12-rules/rules-rdf-syntax/test-rules.ttl create mode 100644 shacl12-rules/rules-rdf-syntax/test-terms.ttl create mode 100644 shacl12-rules/rules-rdf-syntax/test-triples.ttl diff --git a/shacl12-rules/rules-rdf-syntax/rdf-syntax-shapes.ttl b/shacl12-rules/rules-rdf-syntax/rdf-syntax-shapes.ttl new file mode 100644 index 00000000..0f1d96f9 --- /dev/null +++ b/shacl12-rules/rules-rdf-syntax/rdf-syntax-shapes.ttl @@ -0,0 +1,236 @@ +PREFIX rdf: +PREFIX rdfs: +PREFIX xsd: + +PREFIX sparql: +PREFIX sh: +PREFIX srl: +PREFIX srl-sh: +PREFIX shnex: + +#### RDF Term and variables. + +## Variables + +srl-sh:variableShape rdf:type sh:NodeShape ; + sh:property + [ + sh:path srl:varName ; + sh:datatype xsd:string ; + sh:minCount 1 ; + sh:maxCount 1 ; + ] . + +## RDF Terms (blank nodes exclude syntax usage e.g. as variables) + +srl-sh:termShape rdf:type sh:NodeShape ; + sh:name "RDF Term" ; + sh:xone ( + srl-sh:blankNodeDataShape + [ sh:nodeKind sh:IRI ] + [ sh:nodeKind sh:Literal ] + [ sh:nodeKind sh:TripleTerm ] + ) . + +srl-sh:blankNodeDataShape rdf:type sh:NodeShape ; + sh:nodeKind sh:BlankNode ; + sh:not srl-sh:variableShape ; + . + +srl-sh:varOrTermShape rdf:type sh:NodeShape ; + sh:name "VarOrTerm" ; + sh:xone ( [ sh:node srl-sh:variableShape ] + [ sh:node srl-sh:termShape ] + ) . + +srl-sh:varOrIRIShape rdf:type sh:NodeShape ; + sh:name "VarOrIRI" ; + sh:xone ( [ sh:node srl-sh:variableShape ] + [ sh:nodeKind sh:IRI ] + ) . + +srl-sh:blankNodeOrIRIShape rdf:type sh:NodeShape ; + sh:name "IRIorBlankNode" ; + sh:xone ( [ sh:nodeKind sh:BlankNode ] + [ sh:nodeKind sh:IRI ] + ) . + +#### Triples + +## Symmetric RDF Triple including variables. +srl-sh:tripleShape rdf:type sh:NodeShape ; + sh:property + [ sh:path srl:subject ; + sh:name "Triple subject" ; + sh:minCount 1 ; + sh:maxCount 1 ; + sh:node srl-sh:varOrTermShape + ] ; + sh:property + [ sh:path srl:predicate ; + sh:name "Triple predicate" ; + sh:minCount 1 ; + sh:maxCount 1 ; + sh:node srl-sh:varOrIRIShape + ] ; + sh:property + [ sh:path srl:object ; + sh:name "Triple object" ; + sh:minCount 1 ; + sh:maxCount 1 ; + sh:node srl-sh:varOrTermShape + ] ; + . + +## Triple pattern (body) + +srl-sh:triplePatternShape rdf:type sh:NodeShape ; + sh:node srl-sh:tripleShape ; + . + +# Triple template (head) +srl-sh:tripleTemplateShape rdf:type sh:NodeShape ; + sh:node srl-sh:tripleShape ; + . + +## Triple Data (DATA) + +srl-sh:tripleDataShape rdf:type sh:NodeShape ; + sh:property + [ sh:path srl:subject ; + sh:name "Data triple subject" ; + sh:minCount 1 ; + sh:maxCount 1 ; + sh:node srl-sh:termShape + ] ; + sh:property + [ sh:path srl:predicate ; + sh:name "Data triple predicate" ; + sh:minCount 1 ; + sh:maxCount 1 ; + sh:nodeKind sh:IRI + ] ; + sh:property + [ sh:path srl:object ; + sh:name "Data triple object" ; + sh:minCount 1 ; + sh:maxCount 1 ; + sh:node srl-sh:termShape + ] ; + . + +#### Expressions + +srl-sh:expressionShape rdf:type sh:NodeShape ; + ## if [ srl:expr [ ...] ] +## sh:property +## [ sh:path srl:expr ; +## sh:minCount 1; +## sh:maxCount 1 ; +## ] ; + . + +srl-sh:filterElementShape rdf:type sh:NodeShape ; + sh:property + [ sh:path srl:filter ; + sh:node srl-sh:expressionShape ; + sh:minCount 1 ; + sh:maxCount 1 ; + ]; + . + +srl-sh:assignmentElementShape rdf:type sh:NodeShape ; + sh:property + [ sh:path srl:assign ; + sh:minCount 1; + sh:maxCount 1; + sh:property + [ sh:path srl:assignVar ; + sh:node srl-sh:variableShape ; + sh:minCount 1; + sh:maxCount 1; + ]; + sh:property + [ sh:path srl:assignValue ; + sh:node srl-sh:expressionShape ; + sh:minCount 1 ; + sh:maxCount 1 ; + ]; + ]; + . + +srl-sh:negationElementBodyShape rdf:type sh:NodeShape ; + sh:xone ( + srl-sh:triplePatternShape + srl-sh:filterElementShape + ) . + +srl-sh:negationElementShape rdf:type sh:NodeShape ; + sh:property + [ sh:path srl:not ; + sh:memberShape srl-sh:negationElementBodyShape ; + sh:minCount 1 ; + sh:maxCount 1 ; + ] . + +#### DATA + +## In data blocks, allow triple terms for data triples. + +srl-sh:dataBlockItemShape rdf:type sh:NodeShape ; + sh:xone ( + srl-sh:tripleDataShape + [ sh:nodeKind sh:TripleTerm ] + ) . + +srl-sh:dataBlockShape rdf:type sh:NodeShape ; + sh:property [ + sh:path srl:data ; + sh:memberShape srl-sh:dataBlockItemShape ; + ] . + +### Rule Elements + +srl-sh:ruleBodyElement rdf:type sh:NodeShape ; + sh:xone ( srl-sh:triplePatternShape + srl-sh:filterElementShape + srl-sh:assignmentElementShape + srl-sh:negationElementShape + ) . + +srl-sh:ruleHeadElement rdf:type sh:NodeShape ; + sh:node srl-sh:tripleTemplateShape + . + +#### Rule Shape + +srl-sh:ruleHeadShape rdf:type sh:NodeShape ; + sh:property + [ sh:path srl:head ; + sh:memberShape srl-sh:ruleHeadElement ; + sh:maxCount 1; + sh:minCount 1; + ] . + +srl-sh:ruleBodyShape rdf:type sh:NodeShape ; + sh:property + [ sh:path srl:body ; + sh:memberShape srl-sh:ruleBodyElement; + sh:maxCount 1; + sh:minCount 1; + ] . + +srl-sh:ruleShape rdf:type sh:NodeShape ; + sh:node srl-sh:ruleHeadShape ; + sh:node srl-sh:ruleBodyShape ; + . + +#### Rule Set + +srl-sh:ruleSetShape rdf:type sh:NodeShape ; + sh:node srl-sh:dataBlockShape ; + sh:property + [ sh:path srl:rules ; + sh:memberShape srl-sh:ruleShape + ]; + . diff --git a/shacl12-rules/rules-rdf-syntax/rules-ns.ttl b/shacl12-rules/rules-rdf-syntax/rules-ns.ttl new file mode 100644 index 00000000..b33600bb --- /dev/null +++ b/shacl12-rules/rules-rdf-syntax/rules-ns.ttl @@ -0,0 +1,162 @@ +PREFIX ex: + +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX srl: +PREFIX owl: +PREFIX dc: + +<> a owl:Ontology ; + dc:title "The SHACL Rules Language Vocabulary (SRL)" ; + dc:date "2026-12-31" ; + dc:description "This is the RDF Schema for SHACL Rules." ; + rdfs:seeAlso . + +#### SHACL Rules Syntax + +## -- Classes + +srl:RuleSet rdf:type rdfs:Class ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "Rule Set" ; + rdfs:comment "The class of rule sets." . + +srl:Rule rdf:type rdfs:Class ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "A SHACL Rule" ; + rdfs:comment "The class of SHACL Rules." . + +## -- Properties + +srl:rules rdf:type rdf:Property ; + rdfs:domain srl:RuleSet ; + # range - list of rules + rdfs:isDefinedBy srl: ; + rdfs:label "Rules of a Rule Set" ; + rdfs:comment "The list of rules of the rule set." . + +srl:data rdf:type rdf:Property ; + rdfs:domain srl:RuleSet ; + # range - list + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "Data" ; + rdfs:comment "The list of data of the rule set." . + +srl:head rdf:type rdf:Property ; + rdfs:domain srl:Rule ; + # range - list of triple templates + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "Rule head" ; + rdfs:comment "The consequent of a rule." . + +srl:body rdf:type rdf:Property ; + rdfs:domain srl:Rule ; + # range : list of rule elements + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "Rule body" ; + rdfs:comment "The antecedent of a rule." . + +## -- Rule Body + +srl:RuleElement rdf:type rdfs:Class ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "A SHACL Rule Element" ; + rdfs:comment "The class of SHACL Rule Elements." . + +srl:TriplePattern rdf:type rdfs:Class ; + rdfs:subClassOf srl:RuleElement ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "A SHACL Rule Element" ; + rdfs:comment "The class of triple patterns." . + +srl:CondidtionElement rdf:type rdfs:Class ; + rdfs:subClassOf srl:RuleElement ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "A SHACL Rule condition element" ; + rdfs:comment "The class of SHACL condition elements." . + +srl:AssignmentElement rdf:type rdfs:Class ; + rdfs:subClassOf srl:RuleElement ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "A SHACL Rule assignment element" ; + rdf:comment "The class of SHACL assignment elements." . + +srl:NegationElement rdf:type rdfs:Class ; + rdfs:subClassOf srl:RuleElement ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "A SHACL Rule negation element" ; + rdf:comment "The class of SHACL negation elements." . + +## ---- + +srl:filter rdf:type rdf:Property ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "filter" ; + rdfs:comment "A filter rule element" . + +## @@Remove +srl:assign rdf:type rdf:Property ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "assign" ; + rdfs:comment "An asssignment rule element" . + + +srl:assignVar rdf:type rdf:Property ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "assignment variable" ; + rdfs:comment "The variable of an assignment" . + +srl:assignValue rdf:type rdf:Property ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "addignment value" ; + rdfs:comment "The value or expression for an assignment" . + +srl:not rdf:type rdf:Property ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "negation rule element" ; + rdfs:comment "A negation rule element" . + +## ---- + +srl:subject rdf:type rdf:Property ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Resource ; + rdfs:label "subject" ; + rdfs:comment "The subject of a triple, triple pattern or triple template." . + +srl:predicate rdf:type rdf:Property ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Resource ; + rdfs:label "predicate" ; + rdfs:comment "The predicate of a triple, triple pattern or triple template." . + +srl:object rdf:type rdf:Property ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Resource ; + rdfs:label "object" ; + rdfs:comment "The object of a triple, triple pattern or triple template." . + +srl:varName rdf:type rdf:Property ; + rdfs:isDefinedBy srl: ; + rdfs:isDefinedBy ; + rdfs:label "name of a variable" ; + rdfs:comment "Name of a variable name." . diff --git a/shacl12-rules/rules-rdf-syntax/rules-targets.ttl b/shacl12-rules/rules-rdf-syntax/rules-targets.ttl new file mode 100644 index 00000000..6639f1b1 --- /dev/null +++ b/shacl12-rules/rules-rdf-syntax/rules-targets.ttl @@ -0,0 +1,13 @@ +PREFIX rdf: +PREFIX rdfs: + +PREFIX sh: +PREFIX srl: +PREFIX srl-sh: +PREFIX owl: + +<> owl:imports <./rdf-syntax-shapes.ttl> . + +## Target to validate all SHACL rule sets in the data graph. +[] sh:targetClass srl:RuleSet; + sh:node srl-sh:ruleSetShape . diff --git a/shacl12-rules/rules-rdf-syntax/test-elements.ttl b/shacl12-rules/rules-rdf-syntax/test-elements.ttl new file mode 100644 index 00000000..d48d4602 --- /dev/null +++ b/shacl12-rules/rules-rdf-syntax/test-elements.ttl @@ -0,0 +1,187 @@ +PREFIX : + +PREFIX rdf: +PREFIX rdfs: +PREFIX xsd: + +PREFIX sh: +PREFIX srl: +PREFIX srl-sh: +PREFIX sparql: +PREFIX owl: + +[] owl:imports . + +## srl-sh:expressionShape + +:ExpressionTestGood + sh:targetClass :TestExpressionGood ; + sh:property [ sh:path :test; sh:node srl-sh:expressionShape ] + . + +:ExpressionTestBad + sh:targetClass :TestExpressionBad; + sh:not :ExpressionTestGood + . + +## -- + +:expr-test1 rdf:type :TestExpressionGood ; + :test true . + +:expr-test2 rdf:type :TestExpressionGood ; + :test [ sparql:add (1 2 ) ] + . + +## srl-sh:filterShape + +:FilterElementTestGood + sh:targetClass :TestFilterElementGood ; + sh:property [ sh:path :test; sh:node srl-sh:filterElementShape ] + . + +:FilterElementTestBad + sh:targetClass :TestFilterElementBad; + sh:not :FilterElementTestGood + . +## -- + +:filterGood-test1 rdf:type :TestFilterElementGood ; + :test [ srl:filter true ] . + +:filterBad-test1 rdf:type :TestFilterElementBad ; + :test [ ] . + +:filterBad-test2 rdf:type :TestFilterElementBad ; + :test [ :other 123 ] . + +## srl-sh:assignmentElementShape + +:AssignmentTestGood + sh:targetClass :TestAssignmentGood ; + sh:property [ sh:path :test; sh:node srl-sh:assignmentElementShape ] + . + +:AssignmentTestBad + sh:targetClass :TestAssignmentBad; + sh:not :AssignmentTestGood; + . + +## -- + +:assignmentGood-test1 rdf:type :TestAssignmentGood ; + :test [ + srl:assign [ + srl:assignValue "ABC" ; + srl:assignVar [ srl:varName "X" ] + ] + ] . + +:assignmentBad-test1 rdf:type :TestAssignmentBad ; + :test [ + srl:assign [ + srl:assignValue "ABC" ; + ] + ] . + +:assignmentBad-test2 rdf:type :TestAssignmentBad ; + :test [ + srl:assign [ + srl:assignVar [ srl:varName "X" ] + ] + ] . + +:assignmentBad-test3 rdf:type :TestAssignmentBad ; + :test [ + srl:assign [ + srl:assignValue "ABC" ; + srl:assignVar [ srl:varName "X" ] ; + srl:assignVar [ srl:varName "Y" ] ; + ] + ] . + +:assignmentBad-test4 rdf:type :TestAssignmentBad ; + :test [ + srl:assign [ + srl:assignValue "ABC" ; + srl:assignValue "123" ; + srl:assignVar [ srl:varName "X" ] ; + ] + ] . + +:assignmentBad-test5 rdf:type :TestAssignmentBad ; + :test [ + srl:assign [ ] + ] . + +:assignmentBad-test6 rdf:type :TestAssignmentBad ; + :test [ + ] . + +:assignmentBad-test7 rdf:type :TestAssignmentBad ; + :test [ + srl:assign [ + srl:assignValue "ABC" ; + srl:assignVar [ srl:varName "X" ] ; + ] ; + srl:assign [ + srl:assignValue "123" ; + srl:assignVar [ srl:varName "Y" ] ; + ] ; + ] . + +## srl-sh:negationElementShape + +:NegationElementTestGood + sh:targetClass :TestNegationElementGood ; + sh:property [ sh:path :test; sh:node srl-sh:negationElementShape ] + . + +:NegationElementTestBad + sh:targetClass :TestNegationElementBad; + sh:not :NegationElementTestGood + . + +## -- + +:negationGood-test1 rdf:type :TestNegationElementGood; + :test [ + srl:not ( + ) + ] . + +:negationGood-test2 rdf:type :TestNegationElementGood; + :test [ + srl:not ( + [ + srl:subject [ srl:varName "s" ] ; + srl:predicate :p ; + srl:object [ srl:varName "o" ] ; + ] + [ + srl:filter [ + sparql:less-than ( + [ srl:varName "o" ] + 18 + ) + ] + ] + ) + ] . + +:negationBad-test1 rdf:type :TestNegationElementBad; + :test [ + srl:not ( + [ + srl:object [ srl:varName "o" ]; + srl:predicate :p; + srl:subject [ srl:varName "s" ] + ] + [ + srl:assign [ + srl:assignValue 18 ; + srl:assignVar [ srl:varName "o" ] + ] + ] + ) + ] . diff --git a/shacl12-rules/rules-rdf-syntax/test-rules.ttl b/shacl12-rules/rules-rdf-syntax/test-rules.ttl new file mode 100644 index 00000000..3f59ec5b --- /dev/null +++ b/shacl12-rules/rules-rdf-syntax/test-rules.ttl @@ -0,0 +1,287 @@ +PREFIX : + +PREFIX rdf: +PREFIX rdfs: +PREFIX xsd: + +PREFIX sh: +PREFIX srl: +PREFIX srl-sh: +PREFIX shnex: +PREFIX sparql: +PREFIX owl: + +[] owl:imports . + +## srl-sh:ruleShape + +:RuleTestGood + sh:targetClass :TestRuleGood ; + sh:property [ sh:path :test; sh:node srl-sh:ruleShape ] + . + +:RuleTestBad + sh:targetClass :TestRuleBad ; + sh:not :RuleTestGood + . + +## -- + +:ruleGood-test1 rdf:type :TestRuleGood ; + :test [ + srl:body () ; + srl:head () ; + ] . + +:ruleGood-test2 rdf:type :TestRuleGood ; + :test [ + srl:head ( + [ srl:subject [ srl:varName "s" ] ; + srl:predicate :p; + srl:object :o + ] ) ; + srl:body ( + [ srl:subject [ srl:varName "s" ] ; + srl:predicate [ srl:varName "p" ] ; + srl:object [ srl:varName "o" ] ; + ] ) ; + ] . + +## Longer test + +:rule1 + srl:body ( + [ + srl:subject [ srl:varName "s" ] ; + srl:predicate [ srl:varName "p" ] ; + srl:object [ srl:varName "o" ] ; + ] + [ + srl:assign [ + srl:assignValue "ABC" ; + srl:assignVar [ srl:varName "X" ] + ] + ] + [ srl:filter true ] + [ + srl:not ( + [ srl:filter false ] + [ srl:subject :s ; srl:predicate :p; srl:object :o ;] + ) + ] + ) ; + srl:head ( + [ + srl:subject [ srl:varName "s" ] ; + srl:predicate [ srl:varName "p" ] ; + srl:object [ srl:varName "o" ] ; + ] + ) ; + . + +:ruleGood-test3 rdf:type :TestRuleGood ; + :test :rule1 . + +:ruleBad-test1 rdf:type :TestRuleBad ; + :test [ + srl:body () ; + ] . + +:ruleBad-test2 rdf:type :TestRuleBad ; + :test [ + srl:head () ; + ] . + +## srl-sh:dataBlockShape + +:DataBlockTestGood + sh:targetClass :TestDataBlockGood ; + sh:property [ sh:path :test; sh:node srl-sh:dataBlockShape ] + . + +:DataBlockTestBad + sh:targetClass :TestDataBlockBad ; + sh:not :DataBlockTestGood + . + +:dataBlockGood-test1 rdf:type :TestDataBlockGood ; + :test [ + srl:data ( ) + ] . + +:dataBlockGood-test2 rdf:type :TestDataBlockGood ; + :test [ + srl:data ( + [ srl:subject :s ; srl:predicate :p ; srl:object :o ] + ) + ] . + +:dataBlockGood-test3 rdf:type :TestDataBlockGood ; + :test [ + srl:data ( + [ srl:subject :s ; srl:predicate :p ; srl:object :o ] + [ srl:subject :x ; srl:predicate :y ; srl:object :z ] + ) + ] . + +:dataBlockGood-test3 rdf:type :TestDataBlockGood ; + :test [ + srl:data ( + <<( :s :p :o )>> + ) + ] . + +## srl-sh:ruleSetShape + +:RuleSetTestGood + sh:targetClass :TestRuleSetGood ; + sh:property [ sh:path :test; sh:node srl-sh:ruleSetShape ] + . + +:RuleSetTestBad + sh:targetClass :TestRuleSetBad; + sh:not :RuleSetTestGood + . + +## -- + +:ruleSetGood-test1 rdf:type :TestRuleSetGood ; + :test :ruleSet-1 . + + +## ------------------------- + +:ruleSet-1 + rdf:type srl:RuleSet; + srl:data ( + [ + srl:subject :s ; + srl:predicate :p ; + srl:object :o + ] + <<( :s :p :o )>> + ); + srl:rules ( + [ + rdf:type srl:Rule; + srl:body ( + [ + srl:object :o; + srl:predicate :p; + srl:subject [ srl:varName "x" ] + ] + ); + srl:head ( + [ + srl:object :o; + srl:predicate :q; + srl:subject [ srl:varName "x" ] + ] + ) + ] + [ + rdf:type srl:Rule; + srl:body ( + [ + srl:object :o1; + srl:predicate :p; + srl:subject [ srl:varName "x" ] + ] + [ + srl:object :o2; + srl:predicate :p; + srl:subject [ srl:varName "x" ] + ] + ); + srl:head ( + [ + srl:object :o; + srl:predicate :q; + srl:subject [ srl:varName "x" ] + ] + ) + ] + [ + rdf:type srl:Rule; + srl:body ( + [ + srl:object [ srl:varName "o" ]; + srl:predicate :p; + srl:subject [ srl:varName "x" ] + ] + [ + srl:filter [ + sparql:less-than ( + [ shnex:var "o" ] + 18 + ) + ] + ] + ); + srl:head ( + [ + srl:object :o; + srl:predicate :q; + srl:subject [ srl:varName "x" ] + ] + ) + ] + [ + rdf:type srl:Rule; + srl:body ( + [ + srl:object :o; + srl:predicate :p; + srl:subject [ srl:varName "x" ] + ] + [ + srl:assign [ + srl:assignValue 18 ; + srl:assignVar [ srl:varName "o" ] + ] + ] + ); + srl:head ( + [ + srl:object [ srl:varName "o" ]; + srl:predicate :q; + srl:subject [ srl:varName "x" ] + ] + ) + ] + [ + rdf:type srl:Rule; + srl:body ( + [ + srl:object :o; + srl:predicate :p; + srl:subject [ srl:varName "x" ] + ] + [ + srl:not ( + [ + srl:object [ srl:varName "o" ]; + srl:predicate :p; + srl:subject [ srl:varName "s" ] + ] + [ + srl:filter [ + sparql:less-than ( + [ shnex:var "o" ] + 18 + ) + ] + ] + ) + ] + ); + srl:head ( + [ + srl:object [ srl:varName "o" ]; + srl:predicate :q; + srl:subject [ srl:varName "x" ] + ] + ) + ] + ); +. diff --git a/shacl12-rules/rules-rdf-syntax/test-terms.ttl b/shacl12-rules/rules-rdf-syntax/test-terms.ttl new file mode 100644 index 00000000..3a408d61 --- /dev/null +++ b/shacl12-rules/rules-rdf-syntax/test-terms.ttl @@ -0,0 +1,102 @@ +PREFIX : + +PREFIX rdf: +PREFIX rdfs: +PREFIX xsd: + +PREFIX sh: +PREFIX srl: +PREFIX srl-sh: +PREFIX shnex: +PREFIX sparql: +PREFIX owl: + +[] owl:imports . + + +## RDF Terms + +:rdfTermTestGood + sh:targetClass :TestTermGood ; + sh:property [ sh:path :test; sh:node srl-sh:termShape ] + . + +:rdfTermTestBad + sh:targetClass :TestTermBad ; + sh:not :rdfTermTestGood + . + +:term-test1 rdf:type :TestTermGood ; + :test :iri . + +:term-test2 rdf:type :TestTermGood ; + :test "literal" . + +:term-test3 rdf:type :TestTermGood ; + :test [] . + +:term-test4 rdf:type :TestTermGood ; + :test <<( :s :p :o )>> . + +## @@add +## srl-sh:blankNodeDataShape rdf:type sh:NodeShape ; +## sh:nodeKind sh:BlankNode ; +## sh:not srl-sh:variableShape ; +## . + +## @@add +## srl-sh:varOrIRIShape + +## @@add +## srl-sh:blankNodeOrIRIShape + + + + +## Variables + +:variablesTestGood + sh:targetClass :TestVariableGood ; + sh:property [ sh:path :test; sh:node srl-sh:variableShape ] + . + +:variablesTestBad + sh:targetClass :TestVariableBad ; + sh:not :variablesTestGood ; + . + +:var-test1 rdf:type :TestVariableGood ; + :test [ srl:varName "x" ] . + +:var-test2 rdf:type :TestVariableBad ; + :test [ ] . + +:var-test3 rdf:type :TestVariableBad ; + :test [ srl:varName "x" ; srl:varName "y" ] . + +## Variable or term + +:rdfVarOrTermTestGood + sh:targetClass :TestVarOrTermGood ; + sh:property [ sh:path :test; sh:node srl-sh:varOrTermShape ] + . + +:rdfVarOrTermTestBad + sh:targetClass :TestVarOrTermBad ; + sh:not :rdVarOrTermGood ; + . + +:varOrTerm1-test rdf:type :TestVarOrTermGood ; + :test [ srl:varName "x" ] . + +:varOrTerm2-test rdf:type :TestVarOrTermGood ; + :test "x" . + +:varOrTerm3-test rdf:type :TestVarOrTermGood ; + :test :iri . + +:varOrTerm4-test rdf:type :TestVarOrTermGood ; + :test [ ] . + +:varOrTerm5-test rdf:type :TestVarOrTermGood ; + :test [ :notAVariable true ] . diff --git a/shacl12-rules/rules-rdf-syntax/test-triples.ttl b/shacl12-rules/rules-rdf-syntax/test-triples.ttl new file mode 100644 index 00000000..c412cb9e --- /dev/null +++ b/shacl12-rules/rules-rdf-syntax/test-triples.ttl @@ -0,0 +1,135 @@ +PREFIX : + +PREFIX rdf: +PREFIX rdfs: +PREFIX xsd: + +PREFIX sh: +PREFIX srl: +PREFIX srl-sh: +PREFIX shnex: +PREFIX sparql: +PREFIX owl: + +[] owl:imports . + +#### RDF Triples, patterns and template + +## srl-sh:tripleDataShape + +:tripleDataGood + sh:targetClass :TestTripleDataGood ; + sh:property [ sh:path :test; sh:node srl-sh:tripleDataShape ] + . + +:tripleDataTestBad + sh:targetClass :TestTripleDataBad; + sh:not :tripleDataGood + . + +## -- + +:tripleData-test1 rdf:type :TestTripleDataGood; + :test [ + srl:subject :s ; + srl:predicate :p ; + srl:object :o ; + ] . + +:tripleData-test2 rdf:type :TestTripleDataGood; + :test [ + srl:subject [] ; + srl:predicate :p ; + srl:object <<( :x :y 123 )>> + ] . + +## @@ variables inside triple terms are bad. + +:tripleDataBad-test1 rdf:type :TestTripleDataBad; + :test [ + srl:subject [ srl:varName "s" ]; + srl:predicate :p ; + srl:object :o + ] . + +:tripleDataBad-test2 rdf:type :TestTripleDataBad; + :test [ + srl:subject :s ; + srl:predicate [] ; + srl:object :o + ] . + +## This is "good" -- symmetric RDF +:tripleDataSym-test1 rdf:type :TestTripleDataGood; + :test [ + srl:subject "literal" ; + srl:predicate :p ; + srl:object :o + ] . + +## srl-sh:triplePatternShape + +:triplePatternGood + sh:targetClass :TestTriplePatternGood ; + sh:property [ sh:path :test; sh:node srl-sh:triplePatternShape ] + . + +:triplePatternTestBad + sh:targetClass :TestTriplePatternBad; + sh:not :triplePatternGood + . + +## -- + +:triplePattern-test1 rdf:type :TestTriplePatternGood; + :test [ + srl:subject :s ; + srl:predicate :p ; + srl:object :o ; + ] . + +## @@ Fixme. +## :triplePattern-test2 rdf:type :TestTriplePatternGood; +## :test [ +## srl:subject :s ; +## srl:predicate :p ; +## srl:object <<( [ srl:varName "x" ] :y 123 )>> +## ] . + +:triplePattern-test3 rdf:type :TestTriplePatternGood; + :test [ + srl:subject [ srl:varName "s" ]; + srl:predicate [ srl:varName "p" ]; + srl:object [ srl:varName "o" ]; + ] . + +## srl-sh:tripleTemplateShape + +:tripleTemplateGood + rdf:type :est ; + sh:targetClass :TestTripleTemplateGood ; + sh:property [ sh:path :test; sh:node srl-sh:tripleTemplateShape ] + . + +:tripleTemplateTestBad + sh:targetClass :TestTripleTemplateBad; + sh:not :tripleTemplateGood + . + +## -- + +:tripleTermplate-test1 rdf:type :TestTripleTemplateGood ; + :test [ + srl:subject [ srl:varName "s" ]; + srl:predicate [ srl:varName "p" ]; + srl:object [ srl:varName "o" ]; + ] + . + +:tripleTermplateBad-test1 rdf:type :TestTripleTemplateBad ; + :test [ + srl:subject [ srl:varName "s" ]; + srl:predicate "literal" ; + srl:object [ srl:varName "o" ]; + ] + .