<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE rdf:RDF [
    <!ENTITY rdf   "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <!ENTITY rdfs  "http://www.w3.org/2000/01/rdf-schema#">
    <!ENTITY owl   "http://www.w3.org/2002/07/owl#">
    <!ENTITY xsd   "http://www.w3.org/2001/XMLSchema#">
    <!ENTITY sswap "http://sswapmeet.sswap.info/sswap/">
]>

<rdf:RDF
    xmlns:rdf   = "&rdf;"
    xmlns:rdfs  = "&rdfs;"
    xmlns:owl   = "&owl;"
    xmlns:xsd   = "&xsd;"
    xmlns:sswap = "&sswap;"
    xmlns       = "&sswap;"
>

    <!-- Read in the SSWAP protocol to define all SSWAP terms -->
    <owl:Ontology rdf:about="&sswap;owlOntology">
        <owl:imports rdf:resource="&sswap;owlOntology"/>
    </owl:Ontology>

    <!-- Define this term using OWL + SSWAP semantics -->
    <owl:Class rdf:about="&sswap;Provider">

        <!-- Declare simple subsumption relations -->
        <rdfs:subClassOf rdf:resource="&sswap;SSWAP"/>

        <!-- Declare necessary conditions (i.e., subClassOf ) -->
        <!--
             These are essentially *optional* properties, so an
             individual may belong to this class and not have
             these properties instantiated.

             The cardinality constraints do not constrain how many
             instances of the property can exist, but it does allow
             a reasoner to infer how many semantically distinct
             objects (values) exist.  In the case of an
             owl:DatatypeProperty and an owl:maxCardinality = 1,
             it essentially means that if a value is defined, then
             it is the only allowed valued.  (Two semantically
             distinct values [e.g., 1 and 2] would yield the
             ontology inconsistent.
        -->

        <!-- None or one sswap:aboutURI predicates -->
        <rdfs:subClassOf>
            <owl:Restriction>
                <owl:onProperty>
                    <owl:DatatypeProperty rdf:about="&sswap;aboutURI"/>
                </owl:onProperty>
                <owl:maxCardinality rdf:datatype="&xsd;nonNegativeInteger">1</owl:maxCardinality>
            </owl:Restriction>
        </rdfs:subClassOf>

        <!-- None or one sswap:metadata predicates -->
        <rdfs:subClassOf>
            <owl:Restriction>
                <owl:onProperty>
                    <owl:DatatypeProperty rdf:about="&sswap;metadata"/>
                </owl:onProperty>
                <owl:maxCardinality rdf:datatype="&xsd;nonNegativeInteger">1</owl:maxCardinality>
            </owl:Restriction>
        </rdfs:subClassOf>

        <!-- None or one sswap:oneLineDescription predicates -->
        <rdfs:subClassOf>
            <owl:Restriction>
                <owl:onProperty>
                    <owl:DatatypeProperty rdf:about="&sswap;oneLineDescription"/>
                </owl:onProperty>
                <owl:maxCardinality rdf:datatype="&xsd;nonNegativeInteger">1</owl:maxCardinality>
            </owl:Restriction>
        </rdfs:subClassOf>

        <!-- Any number of sswap:providesResource predicates -->
        <!-- This offers no new logical restrictions, but it identifies
             sswap:providesResource as an optional property.
        -->
        <rdfs:subClassOf>
            <owl:Restriction>
                <owl:onProperty>
                    <owl:ObjectProperty rdf:about="&sswap;providesResource"/>
                </owl:onProperty>
                <owl:minCardinality rdf:datatype="&xsd;nonNegativeInteger">0</owl:minCardinality>
            </owl:Restriction>
        </rdfs:subClassOf>

        <!-- Declare necessary and sufficient conditions (i.e., equivalentClass) -->
        <!--
            The <owl:allValuesFrom> lets a reasoner infer the class of the
            object of the restricted property.  In this case, the property
            sswap:providesResource points from an individual of this class
            (sswap:Provirder) to an individual of rdf:type sswap:Resource.

	    This model identifies *required* properties, so an individual of
            this class must have these properties.
        -->

        <owl:equivalentClass>
            <owl:Class>
                <owl:intersectionOf rdf:parseType="Collection">

                    <!-- Must have exactly one name -->
                    <owl:Restriction>
                        <owl:onProperty>
                            <owl:DatatypeProperty rdf:about="&sswap;name"/>
                        </owl:onProperty>
                        <owl:cardinality rdf:datatype="&xsd;nonNegativeInteger">1</owl:cardinality>
                    </owl:Restriction>

                    <!-- sswap:providesResource must point to to a sswap:Resource for
                         an individual to belong to this class.
                    -->
                    <owl:Restriction>
                        <owl:onProperty>
                            <owl:ObjectProperty rdf:about="&sswap;providesResource"/>
                        </owl:onProperty>
                        <owl:allValuesFrom>
                            <owl:Class rdf:about="&sswap;Resource"/>
                        </owl:allValuesFrom>
                    </owl:Restriction>

                    <!-- Exactly zero sswap:providedBy properties  -->
		            <!--
                         Without a statement such as this a reasoner would
                         infer that sswap:Resource would is an owl:subClassOf
                         sswap:Provider.  The statements below avert that
                         conclusion, yielding sswap:Provider and sswap:Resource
                         sibling classes.
                    -->
                    <owl:Restriction>
                        <owl:onProperty>
                            <owl:ObjectProperty rdf:about="&sswap;providedBy"/>
                        </owl:onProperty>
                        <owl:cardinality rdf:datatype="&xsd;nonNegativeInteger">0</owl:cardinality>
                    </owl:Restriction>

                </owl:intersectionOf>
            </owl:Class>
        </owl:equivalentClass>

        <!-- Belonging to this class preclude belonging to these classes, and vice-versa -->
        <owl:disjointWith>
            <owl:Class rdf:about="&sswap;Graph"/>
        </owl:disjointWith>

        <!-- Self-documenting comment about this term -->
        <rdfs:comment rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
            >A required class. This class designates the provider of one or more resources. Providers claim ownership of resources and are anticipated to be associated with actual organizations such as W3C, NCBI, etc.  Providers may state that they provide multiple resources by using multiple providesResource properties.

It is expected that the provider description will be in its own file, separate from the Resource Description Graphs.

Required predicates:
	name

Optional predicates:
	aboutURI
	metadata
	oneLineDescription
	providesResource

The owl:Restriction on sswap:providedBy refines the class definition so as to prohibit the reasoner from otherwise incorrectly infering that swap;Provider is a rdfs:subClassOf sswap:Resource. sswap:providedBy is not a valid predicate for a sswap:Provider. See sswap:Resource for notes on sswap:providesResource and sswap:providedBy.</rdfs:comment>

    </owl:Class>

</rdf:RDF>

