@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix nif:   <http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

nif:ValidUrlShape
    a sh:NodeShape ;
    sh:targetClass nif:String ;
    sh:message "R010. Instances of nif:String should have a valid URI" ;
    sh:pattern """^(?:(?:[A-Za-z][+-.\\w^_]*:/{2})?(?:\\S+(?::\\S*)?@)?(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))(?::\\d{2,5})?(?:/\\S*)?)$""" ;
    sh:flags "i" .

nif:ReferenceContextShape
    a sh:NodeShape ;
    sh:targetClass nif:String ;
    sh:message "A nif:String that is not a nif:Context should have a nif:referenceContext property with one nif:Context as object" ;
    sh:or (
        [
            sh:path nif:referenceContext ;
            sh:maxCount 1 ;
            sh:minCount 1 ;
            sh:class nif:Context ;
        ]
        [
            sh:class nif:Context;
        ]
    ) .

nif:StringShape
    a sh:NodeShape ;
    sh:message "R011. A nif:OffsetBasedString must have exactly one nif:beginIndex and one nif:endIndex" ;
    sh:targetClass nif:Context ;
    sh:property [
        sh:order 2;
        sh:path nif:beginIndex ;
        sh:lessThan nif:endIndex ;
        sh:maxCount 1 ;
        sh:minCount 1 ;
        sh:datatype xsd:nonNegativeInteger ;
    ] ;
    sh:property [
        sh:order 1;
        sh:path nif:endIndex ;
        sh:maxCount 1 ;
        sh:minCount 1 ;
        sh:datatype xsd:nonNegativeInteger ;
    ] .

nif:OffsetBasedStringShape
    a sh:NodeShape ;
    sh:targetClass nif:OffsetBasedString ;
    sh:message "R008. Instances of nif:OffsetBasedString should have a URI pattern conforming to the pattern '#offset_{beginIndex}_{endIndex*}'" ;
    sh:pattern "#offset\\_\\d+\\_\\d*\\b" ;
    sh:flags "i" .

nif:ContextShape
    a sh:NodeShape ;
    sh:targetClass nif:Context ;
    sh:property [
        sh:order 1;
        sh:path nif:isString ;
        sh:maxCount 1 ;
        sh:minCount 1 ;
        sh:datatype xsd:string ; 
    ] ;
    sh:sparql [
		a sh:SPARQLConstraint ; 
        sh:order 2;
		sh:message "R015. nif:beginIndex and nif:endIndex should match the number of word positions in nif:isString" ;
        sh:prefixes nif: ;
		sh:select """
            PREFIX nif: <http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#>
			SELECT $this
			WHERE {
                $this nif:isString ?string .
                $this nif:beginIndex ?beginIndex .
                $this nif:endIndex ?endIndex .
                filter ( strlen(str(?string)) != ?endIndex || ?beginIndex != 0)
			}
			""" ;
	] .

