PREFIX st:   <http://ns.inria.fr/sparql-template/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX fun: <http://w3id.org/sparql-generate/fn/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX obo: <http://purl.obolibrary.org/obo/>
PREFIX swrl: <http://www.w3.org/2003/11/swrl#>
PREFIX prov: <http://www.w3.org/ns/prov#>
 
BASE <https://saref.etsi.org/documentation/>

# See https://www.w3.org/TR/owl2-quick-reference/#Properties

TEMPLATE  <term/propertyDescription.rqg>( ?property ) {

  # named object property
  TEMPLATE {
    "<a href='{?property}' title='{ st:call-template( <term/label.rqg>, ?property ) }: {?commentStr}'>{fun:prefixedIRI(?property)}</a>"
    "<sup title='{ fun:property(<en.properties>, 'objectproperty') }' class='type-op'>op</sup>"
  }
  WHERE {
    FILTER(ISURI(?property))
    ?property a owl:ObjectProperty ;
    OPTIONAL { ?property rdfs:comment ?comment }
    FILTER (?property != owl:topObjectProperty)
    FILTER (?property != owl:bottomObjectProperty)
    BIND( IF(BOUND(?comment), ?comment, "<<no comment>>") AS ?commentStr )
  } LIMIT 1 .

  # universal object property
  TEMPLATE {
    "<a href='{ ?property }' title='{?property}'>{fun:prefixedIRI(?property)}</a>"
    "<sup title='{ fun:property(<en.properties>, 'objectproperty') }' class='type-op'>op</sup>"
  } WHERE {
    FILTER (?property = owl:topObjectProperty)
  } .

  # empty object property
  TEMPLATE {
    "<a href='{?property}' title='{?property}'>{fun:prefixedIRI(?property)}</a>"
    "<sup title='{ fun:property(<en.properties>, 'objectproperty') }' class='type-op'>op</sup>"
  } WHERE {
    FILTER (?property = owl:bottomObjectProperty)
  } .

  # inverse property
  TEMPLATE {
    "(<span class='logic'>inverse of</span> "
    TEMPLATE <term/propertyDescription.rqg>( ?inverse ) .
    ")"
  } 
  WHERE {
    FILTER(ISBLANK(?property))
    ?property owl:inverseOf ?inverse .
  } .

  # named data property
  TEMPLATE {
    "<a href='{ ?property }' title='{ st:call-template( <ontology/label.rqg>, ?onto,  ?property ) }: {?commentStr}'>{fun:prefixedIRI(?property)}</a>"
    "<sup title='{ fun:property(<en.properties>, 'dataproperty') }' class='type-dp'>dp</sup>"
  }
  WHERE {
    FILTER(ISURI(?property))
    ?property a owl:DatatypeProperty
    OPTIONAL { ?property rdfs:comment ?comment }
    FILTER (?property != owl:topDataProperty)
    FILTER (?property != owl:bottomDataProperty)
    BIND( IF(BOUND(?comment), ?comment, "<<no comment>>") AS ?commentStr )
  } LIMIT 1 .

  # universal data property
  TEMPLATE {
    "<a href='{?property}' title='{?property}'>{fun:prefixedIRI(?property)}</a>"
    "<sup title='{ fun:property(<en.properties>, 'dataproperty') }' class='type-dp'>dp</sup>"
  } WHERE {
    FILTER (?property = owl:topDataProperty)
  } .

  # empty data property
  TEMPLATE {
    "<a href='{?property}' title='{?property}'>{fun:prefixedIRI(?property)}</a>"
    "<sup title='{ fun:property(<en.properties>, 'dataproperty') }' class='type-dp'>dp</sup>"
  } WHERE {
    FILTER (?property = owl:bottomDataProperty)
  } .

  # fallback
  TEMPLATE {
    "<a href='{?property}' title='{?property}'>{fun:prefixedIRI(?property)}</a><strong>Warning: property not declared</strong>"
  } 
  WHERE {
    FILTER(ISURI(?property))
    FILTER( NOT EXISTS {?property a owl:ObjectProperty } ) .
    FILTER( NOT EXISTS {?property a owl:DatatypeProperty } ) .
    FILTER (?property != owl:topObjectProperty)
    FILTER (?property != owl:bottomObjectProperty)
    FILTER (?property != owl:topDataProperty)
    FILTER (?property != owl:bottomDataProperty)
  } .

}