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#>
PREFIX iter: <http://w3id.org/sparql-generate/iter/>
PREFIX schema: <http://schema.org/>

BASE <https://saref.etsi.org/documentation/>
 
TEMPLATE <term/dataProperty.rqg>( ?dp ) {

  # See https://www.w3.org/TR/owl2-quick-reference/#Properties 
  # Data Property Axioms 
  "\n<div class='description'><dl>" BOX {

    # functional property
    TEMPLATE {
      "\n<p><strong>{ fun:property(<en.properties>, 'hascharacteristics') }:</strong>"
      fun:property(<en.properties>, 'functional')
      "</p>"
    } WHERE {
      ?dp a owl:FunctionalProperty .
    } .

    # equivalent properties
    TEMPLATE {
      before = "\n<dt>{ fun:property(<en.properties>, 'hasequivalentproperties') }</dt><dd>" ;
        TEMPLATE <term/propertyDescription.rqg>( ?dp2 ) . 
      ; separator = ", "
      ; after = "</dd>"
    } DISTINCT WHERE {
      { ?dp owl:equivalentProperty ?dp2 }
      UNION
      { ?dp2 owl:equivalentProperty ?dp }
    } .

    # hassuperproperties
    TEMPLATE {
      before = "\n<dt>{ fun:property(<en.properties>, 'hassuperproperties') }</dt><dd>" ;
        TEMPLATE <term/propertyDescription.rqg>( ?dp2 ) . 
      ; separator = ", "
      ; after = "</dd>"
    } DISTINCT WHERE {
      ?dp rdfs:subPropertyOf ?dp2
    } .

    # hassubproperties
    TEMPLATE {
      before = "\n<dt>{ fun:property(<en.properties>, 'hassubproperties') }</dt><dd>" ;
        TEMPLATE <term/propertyDescription.rqg>( ?dp2 ) . 
      ; separator = ", "
      ; after = "</dd>"
    } DISTINCT WHERE {
      ?dp2 rdfs:subPropertyOf ?dp
    } .

    # property domain
    TEMPLATE {
      before = "\n<dt>{ fun:property(<en.properties>, 'hasdomain') }</dt><dd>" ;
        TEMPLATE <term/classDescription.rqg>( ?c , true ) . 
      ; separator = ", "
      ; after = "</dd>"
    } DISTINCT WHERE {
      ?dp rdfs:domain ?c
    } .

    # property domain includes
    TEMPLATE {
      before = "\n<dt>{ fun:property(<en.properties>, 'domainIncludes') }</dt><dd>" ;
        TEMPLATE <term/classDescription.rqg>( ?c , true ) . 
      ; separator = ", "
      ; after = "</dd>"
    } DISTINCT WHERE {
      ?dp schema:domainIncludes ?c
    } .

    # property range
    TEMPLATE {
      before = "\n<dt>{ fun:property(<en.properties>, 'hasrange') }</dt><dd>" ;
        TEMPLATE <term/dataRangeDescription.rqg>( ?c ) . 
      ; separator = ", "
      ; after = "</dd>"
    } DISTINCT WHERE {
      ?dp rdfs:range ?c
    } .

    # property range includes
    TEMPLATE {
      before = "\n<dt>{ fun:property(<en.properties>, 'rangeIncludes') }</dt><dd>" ;
        TEMPLATE <term/dataRangeDescription.rqg>( ?c ) . 
      ; separator = ", "
      ; after = "</dd>"
    } DISTINCT WHERE {
      ?dp schema:rangeIncludes ?c
    } .

    # disjoint properties
    TEMPLATE {
      before = "\n<dt>{ fun:property(<en.properties>, 'isdisjointwith') }</dt><dd>" ;
        TEMPLATE <term/propertyDescription.rqg>( ?dp2 ) . 
      ; separator = ", "
      ; after = "</dd>"
    } DISTINCT WHERE {
      { ?dp owl:propertyDisjointWith ?dp2 }
      UNION
      { ?dp2 owl:propertyDisjointWith ?dp }
    } .

  } "\n</dl></div>"

}