PREFIX afn:  <http://jena.hpl.hp.com/ARQ/function#>
PREFIX arg:  <http://spinrdf.org/arg#>
PREFIX fn:   <http://www.w3.org/2005/xpath-functions#>
PREFIX owl:  <http://www.w3.org/2002/07/owl#>
PREFIX rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX sp:   <http://spinrdf.org/sp#>
PREFIX spif: <http://spinrdf.org/spif#>
PREFIX spin: <http://spinrdf.org/spin#>
PREFIX spl:  <http://spinrdf.org/spl#>
PREFIX xsd:  <http://www.w3.org/2001/XMLSchema#>

spl:Attribute  rdf:type     spin:ConstructTemplate;
        rdfs:comment        "Defines an \"attribute\" of a class. Attribute definitions bundle common modeling patterns known from object-oriented languages like UML. Each attribute can have min and max cardinality, a value type and a default value. The attribute links a class with one RDF property. This template should be used as spin:constraints on a class to make sure that classes meet the expected cardinalities and valueType constraints.\nIf a model wants to use spl:defaultValue, then it should instantiate the spl:ConstructDefaultValues as a spin:constructor at some root class, such as rdfs:Resource.";
        rdfs:label          "Attribute";
        rdfs:subClassOf     spin:ConstructTemplates;
        spin:body           [ rdf:type  sp:Construct;
                              sp:text   "PREFIX  xsd:  <http://www.w3.org/2001/XMLSchema#>\n  PREFIX  rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n  PREFIX  rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n  PREFIX spin: <http://spinrdf.org/spin#>\n\n  CONSTRUCT {\n      _:b0 a spin:ConstraintViolation .\n      _:b0 spin:violationRoot ?this .\n      _:b0 spin:violationPath ?predicate .\n      _:b0 spin:violationValue ?value .\n  }\n  WHERE\n    {   { SELECT  (count(*) AS ?cardinality)\n          WHERE\n            { ?this  ?predicate  ?value\n              FILTER bound(?minCount)\n            }\n          HAVING ( ?cardinality < ?minCount )\n        }\n      UNION\n        { { SELECT  (count(*) AS ?cardinality)\n            WHERE\n              { ?this  ?predicate  ?value\n                FILTER bound(?maxCount)\n              }\n            HAVING ( ?cardinality > ?maxCount )\n          }\n        }\n      UNION\n        { ?this  ?predicate  ?value\n          FILTER ( isURI(?value) || isBlank(?value) )\n          FILTER bound(?valueType)\n          FILTER NOT EXISTS { ?value  a  ?class .\n                              ?class (rdfs:subClassOf)* ?valueType\n                            }\n        }\n      UNION\n        { ?this  ?predicate  ?value\n          FILTER isLiteral(?value)\n          FILTER bound(?valueType)\n          BIND(datatype(?value) AS ?datatype)\n          FILTER ( ! ( ( ?datatype IN (?valueType, rdfs:Literal) ) || ( ( ( ! bound(?datatype) ) || ( ?datatype = rdf:langString ) ) && ( ?valueType = xsd:string ) ) ) )\n        }\n    }"
                            ];
        spin:constraint     [ rdf:type       spl:Argument;
                              rdfs:comment   "the type that all values of the property must have";
                              spl:optional   true;
                              spl:predicate  spl:valueType;
                              spl:valueType  rdfs:Class
                            ];
        spin:constraint     [ rdf:type       spl:Argument;
                              rdfs:comment   "the default value of the attribute";
                              spl:optional   true;
                              spl:predicate  spl:defaultValue
                            ];
        spin:constraint     [ rdf:type       spl:Argument;
                              rdfs:comment   "a comment describing the meaning of this attribute";
                              spl:optional   true;
                              spl:predicate  rdfs:comment;
                              spl:valueType  xsd:string
                            ];
        spin:constraint     [ rdf:type       spl:Argument;
                              rdfs:comment   "the RDF property holding the attribute value";
                              spl:predicate  spl:predicate;
                              spl:valueType  rdf:Property
                            ];
        spin:constraint     [ rdf:type       spl:Argument;
                              rdfs:comment   "the maximum number of values permitted for the property";
                              spl:optional   true;
                              spl:predicate  spl:maxCount;
                              spl:valueType  xsd:integer
                            ];
        spin:constraint     [ rdf:type       spl:Argument;
                              rdfs:comment   "the minimum number of values permitted for the property";
                              spl:optional   true;
                              spl:predicate  spl:minCount;
                              spl:valueType  xsd:integer
                            ];
        spin:labelTemplate  "Attribute {?predicate} : {?valueType} [{?minCount},{?maxCount}]" .

xsd:boolean  rdf:type  rdfs:Class .

xsd:string  rdf:type  rdfs:Class .

spl:predicate  rdf:type     rdf:Property;
        rdfs:label          "predicate";
        rdfs:subPropertyOf  sp:arg .

rdfs:Resource  rdf:type  rdfs:Class .

rdfs:comment  rdf:type  rdfs:Class , rdf:Property .

spl:optional  rdf:type      rdf:Property;
        rdfs:label          "optional";
        rdfs:range          xsd:boolean;
        rdfs:subPropertyOf  sp:arg .

<http://spinrdf.org/spl>
        rdf:type         owl:Ontology;
        rdfs:comment     "A collection of generally useful SPARQL functions (expressed as SPIN functions), and SPIN templates. Also provides a top-level classification of functions, and definitions of the standard SPARQL functions.";
        rdfs:label       "SPIN Standard Library";
        owl:imports      <http://spinrdf.org/spin>;
        owl:versionInfo  "1.4.2" .

spl:maxCount  rdf:type      rdf:Property;
        rdfs:subPropertyOf  spl:count .

spl:minCount  rdf:type      rdf:Property;
        rdfs:subPropertyOf  spl:count .

rdf:Property  rdf:type  rdfs:Class .

spl:defaultValue  rdf:type  rdf:Property;
        rdfs:label          "default value";
        rdfs:subPropertyOf  sp:arg .

spl:valueType  rdf:type     rdf:Property;
        rdfs:label          "value type";
        rdfs:subPropertyOf  sp:arg .

rdfs:Class  rdf:type  rdfs:Class .

spl:Argument  rdf:type      spin:ConstructTemplate;
        rdfs:comment        "Provides metadata about an argument of a SPIN Function or Template. Arguments wrap a given rdf:Property (predicate) and specify its value type and whether the argument is optional. When used as spin:constraint, the body of this template will verify that a non-optional value exists and that it has the specified value type. Arguments that have been declared spl:optional true become optional if the type of ?this is spl:UnionTemplate. ";
        rdfs:label          "Argument";
        rdfs:subClassOf     spin:ConstructTemplates;
        spin:body           [ rdf:type  sp:Construct;
                              sp:text   "PREFIX  xsd:  <http://www.w3.org/2001/XMLSchema#>\nPREFIX  afn:  <http://jena.apache.org/ARQ/function#>\nPREFIX  rdfs: <http://www.w3.org/2000/01/rdf-schema#>\nPREFIX  rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\nPREFIX  spin: <http://spinrdf.org/spin#>\n\nCONSTRUCT \n  { \n    _:c0 a spin:ConstraintViolation .\n    _:c0 spin:violationRoot ?this .\n    _:c0 spin:violationPath ?predicate .\n    _:c0 spin:violationValue ?value .\n    _:c0 rdfs:label ?label .\n  }\nWHERE\n  {   { FILTER ( ( ! bound(?optional) ) || ( ?optional = false ) )\n        FILTER NOT EXISTS { ?this  ?predicate  ?value }\n        # FILTER isIRI(?this)\n        BIND(concat(\"Missing value for argument \", afn:localname(?predicate)) AS ?label)\n      }\n    UNION\n      { FILTER bound(?valueType)\n          { ?this  ?predicate  ?value\n            # FILTER isIRI(?this)\n            FILTER ( isURI(?value) || isBlank(?value) )\n            FILTER bound(?valueType)\n            FILTER ( ( ?valueType != rdfs:Resource ) || isLiteral(?value) )\n            FILTER NOT EXISTS { ?value  a  ?class .\n                                ?class (rdfs:subClassOf)* ?valueType\n                              }\n          }\n        UNION\n          { ?this  ?predicate  ?value\n            # FILTER isIRI(?this)\n            FILTER isLiteral(?value)\n            FILTER bound(?valueType)\n            FILTER ( ( ?valueType != rdfs:Resource ) || isLiteral(?value) )\n            BIND(datatype(?value) AS ?datatype)\n            FILTER ( ! ( ( ?datatype IN (?valueType, rdfs:Literal) ) || ( ( ( ! bound(?datatype) ) || ( ?datatype = rdf:langString ) ) && ( ?valueType = xsd:string ) ) ) )\n          }\n        BIND(concat(\"Incorrect type of argument \", afn:localname(?predicate), \" (expected: \", afn:localname(?valueType), \")\") AS ?label)\n      }\n  }"
                            ];
        spin:constraint     [ rdf:type       spl:Argument;
                              rdfs:comment   "indicates whether the argument is optional";
                              spl:optional   true;
                              spl:predicate  spl:optional;
                              spl:valueType  xsd:boolean
                            ];
        spin:constraint     [ rdf:type       spl:Argument;
                              rdfs:comment   "the default value for the argument";
                              spl:optional   true;
                              spl:predicate  spl:defaultValue
                            ];
        spin:constraint     [ rdf:type       spl:Argument;
                              rdfs:comment   "the property holding the values of each function call";
                              spl:predicate  spl:predicate;
                              spl:valueType  rdf:Property
                            ];
        spin:constraint     [ rdf:type       spl:Argument;
                              rdfs:comment   "the value type of the argument";
                              spl:optional   true;
                              spl:predicate  spl:valueType;
                              spl:valueType  rdfs:Class
                            ];
        spin:constraint     [ rdf:type       spl:Argument;
                              rdfs:comment   "a comment describing the argument";
                              spl:optional   true;
                              spl:predicate  rdfs:comment;
                              spl:valueType  xsd:string
                            ];
        spin:labelTemplate  "Argument {?predicate} : {?valueType}" .

xsd:integer  rdf:type  rdfs:Class .
