PREFIX rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs:    <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd:     <http://www.w3.org/2001/XMLSchema#>

PREFIX sparql:  <http://www.w3.org/ns/sparql#>
PREFIX sh:      <http://www.w3.org/ns/shacl#>
PREFIX srl:     <http://www.w3.org/ns/shacl-rules#>
PREFIX srl-sh:  <http://www.w3.org/ns/shacl-rules-shapes#>
PREFIX shnex:   <http://www.w3.org/ns/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
      ];
    .
