<?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;Resource">

        <!-- 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:inputURI predicates -->
        <rdfs:subClassOf>
            <owl:Restriction>
                <owl:onProperty>
                    <owl:DatatypeProperty rdf:about="&sswap;inputURI"/>
                </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>

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

        <!-- Declare necessary and sufficient conditions (i.e., equivalentClass) -->
        <!--
        The pattern below of using both <owl:allValuesFrom> and
        <owl:someValuesFrom> is a type of Qualified Cardinality Restriction
        (QCR).  The cardinality restriction is on this *class* definition,
        instead of (globally) on a property, as would be such if using
        <owl:cardinality>, <owl:minCardinality>, or <owl:maxCardinality>.

        The <owl:allValuesFrom> lets a reasoner infer the class of the object
        of the restricted property.  In this case, the property
        sswap:operatesOn points from an individual of this class
        (sswap:Resource) to an individual of rdf:type sswap:Graph.

        The <owl:someValuesFrom> lets a reasoner infer that if the property
        does indeed point to an individual of the named class, then there must
        be at least one such relation.  In this case, we're using the same
        property and class as used for <owl:allValuesFrom> as part the class
        definition, so the result is a cardinality constraint that an
        individual of sswap:Resource *must* have at least one sswap:operatesOn
       	property pointing to a sswap:Graph.

        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>

                    <!-- Must have one or more sswap:operatesOn predicates -->
                    <owl:Restriction>
                        <owl:onProperty>
                            <owl:ObjectProperty rdf:about="&sswap;operatesOn"/>
                        </owl:onProperty>
                        <owl:allValuesFrom>
                            <owl:Class rdf:about="&sswap;Graph"/>
                        </owl:allValuesFrom>
                    </owl:Restriction>

                    <owl:Restriction>
                        <owl:onProperty>
                            <owl:ObjectProperty rdf:about="&sswap;operatesOn"/>
                        </owl:onProperty>
                        <owl:someValuesFrom>
                            <owl:Class rdf:about="&sswap;Graph"/>
                        </owl:someValuesFrom>
                    </owl:Restriction>

                    <!-- Must have exactly one sswap:providedBy, pointing to
                         an individual of type sswap:Provider.
                    -->
                    <owl:Restriction>
                        <owl:onProperty>
                            <owl:ObjectProperty rdf:about="&sswap;providedBy"/>
                        </owl:onProperty>
                        <owl:allValuesFrom>
                            <owl:Class rdf:about="&sswap;Provider"/>
                        </owl:allValuesFrom>
                    </owl:Restriction>

                    <owl:Restriction>
                        <owl:onProperty>
                            <owl:ObjectProperty rdf:about="&sswap;providedBy"/>
                        </owl:onProperty>
                        <owl:cardinality rdf:datatype="&xsd;nonNegativeInteger">1</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="&xsd;string"
        >A required class. This class designates the semantically described resource. Resources that "do things," for example, transform input (sswap:Subject) to output (sswap:Object) are commonly called services. Resources may also be web pages, ontologies, etc.  A
sswap:Resource sswap:operatesOn one or more sswap:Graphs, where the sswap:Graph acts as a data structure containing the
mapping of some input (sswap:Subject) to some output (sswap:Object).

All sswap:Resource(s) have a sswap:Provider (indicated by the sswap:providedBy predicate) which claims ownership of the resource
(reciprocated by the sswap:providesResource predicate).  If the resource's URL is a lexical sub-path of the provider, then the provider does not
have to reciprocate the sswap:providesResource claim; but if the resource is claiming ownership by a provider whose URL is not a
lexical sub-path, then the provider must explicitly reciprocate the claim with by using sswap:providesResource.  Similarly, if a provider claims a
resource which is not in a sub-path, then the resource must reciprocate the claim.

Required predicates:
	name
	operatesOn
	providedBy

Optional predicates:
	aboutURI
	inputURI
	metadata
	oneLineDescription
	outputURI</rdfs:comment>

    </owl:Class>

</rdf:RDF>
