Cardinality Restrictions

By looking at attribute usage and element occurrence we can derive the appropriate OWL cardinality restrictions. Cardinality restrictions are derived from occurrence constraints on particles. For straightforward content there is almost a direct mapping from occurrences to cardinality. Elements occur once by default, and attributes are optional. We can also change minOccurs and maxOccurs on an element and this will be directly reflected in the OWL cardinality constraint. However, this belies a significant difference between occurrence constraints and cardinality restrictions. An occurrence constraint in XML schema refers to the occurrence of content at a given lexical position in the document. Similar content may occur at different positions within the same particle. In contrast, Cardinality restrictions limit the total number of appearances of a property in the context of a given class.

The following example shows how cardinality restrictions are derived from occurrence constraints on complex content. The content of the 'all' compositor and sub-element 'foo' occur once by default. The maximum number of occurrences of 'bar' is unbounded. By default, the use of attribute 'baz' is optional.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example.org/" xmlns="http://example.org/">
        <xs:element name="foo" type="xs:string"/>
        <xs:element name="bar" type="xs:string"/>
        
        <xs:complexType name="Foobar">
                <xs:all>
                        <xs:element ref="foo"/>
                        <xs:element ref="bar" maxOccurs="unbounded"/>
                </xs:all>
                <xs:attribute name="baz" type="xs:string"/>
        </xs:complexType>

</xs:schema>

Cardinality restrictions only constrain the number of occurences of a property in the context of a given class. They don't affect global property definitions. Property 'foo' is restricted to a cardinality of 1, while property 'bar' has a minimum cardinality of 1 (the maximum is unlimited). The optional attribute 'baz' has a maximum cardinality of 1 - occurring at most once. Note also, that because 'baz' is a locally defined attribute, it alone has an additional value constraint. The type of 'baz' is local to the class, whereas the ranges of 'foo' and 'bar' are globally defined.

# Base: http://example.org/cardinality1.owl
@prefix ns1:     <http://example.org/> .
@prefix xs:      <http://www.w3.org/2001/XMLSchema> .
@prefix ns2:     <http://example.org/def/> .
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix daml:    <http://www.daml.org/2001/03/daml+oil#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xs_:     <http://www.w3.org/2001/XMLSchema#> .
@prefix :        <#> .
@prefix owl:     <http://www.w3.org/2002/07/owl#> .

ns1:Foobar
      a       owl:Class ;
      rdfs:subClassOf
              [ a       owl:Restriction ;
                owl:maxCardinality "1"^^xs_:int ;
                owl:onProperty ns2:baz
              ] ;
      rdfs:subClassOf
              [ a       owl:Restriction ;
                owl:minCardinality "1"^^xs_:int ;
                owl:onProperty ns1:bar
              ] ;
      rdfs:subClassOf
              [ a       owl:Restriction ;
                owl:allValuesFrom xs_:string ;
                owl:onProperty ns2:baz
              ] ;
      rdfs:subClassOf
              [ a       owl:Restriction ;
                owl:cardinality "1"^^xs_:int ;
                owl:onProperty ns1:foo
              ] .

ns1:bar
      a       owl:DatatypeProperty , rdf:Property ;
      rdfs:range xs_:string .

ns1:foo
      a       owl:DatatypeProperty , rdf:Property ;
      rdfs:range xs_:string .

ns2:baz
      a       owl:DatatypeProperty , rdf:Property .

<>    a       owl:Ontology .

An occurrence constraint in XML schema refers to the occurrence of content at a particular lexical position in the document. Similar content may occur at a different position within the same particle. This is demonstrated in the following example, where a single element 'foo' may be followed (in sequence) by yet another element 'foo'. Because these are both properties of the same resource we calculate the cardinality of 'foo' by summing repeated occurrences.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example.org/" xmlns="http://example.org/">       
        <xs:element name="foo" type="xs:string"/>
        
        <xs:element name="foofoo">
                <xs:complexType>
                        <xs:sequence>
                                <xs:element ref="foo" />
                                <xs:element ref="foo" />
                        </xs:sequence>
                </xs:complexType>
        </xs:element>

</xs:schema>

Summing the occurrences of 'foo' makes for a cardinality of 2, right? Wrong. The OWL below has a maximum cardinality of 2, but a minimum cardinality of 1.

# Base: http://example.org/cardinality2.owl
@prefix ns1:     <http://example.org/> .
@prefix xs:      <http://www.w3.org/2001/XMLSchema> .
@prefix ns2:     <http://example.org/def/> .
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix daml:    <http://www.daml.org/2001/03/daml+oil#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xs_:     <http://www.w3.org/2001/XMLSchema#> .
@prefix :        <#> .
@prefix owl:     <http://www.w3.org/2002/07/owl#> .

<>    a       owl:Ontology .

ns1:foofoo
      a       owl:ObjectProperty ;
      rdfs:range
              [ a       owl:Class ;
                rdfs:subClassOf
                        [ a       owl:Restriction ;
                          owl:maxCardinality "2"^^xs_:int ;
                          owl:onProperty ns1:foo
                        ] ;
                rdfs:subClassOf
                        [ a       owl:Restriction ;
                          owl:minCardinality "1"^^xs_:int ;
                          owl:onProperty ns1:foo
                        ]
              ] .

ns1:foo
      a       owl:DatatypeProperty , rdf:Property ;
      rdfs:range xs_:string .

There is an edge case where there may be two occurrences of 'foo' but only one distinct property/value pair. This happens if both occurrences have the same literal value, as demonstrated below. Both occurrences map to the same statement [ ns1:foo "foo"^^xs_:string ] (with the same subject). Because these are logical statements it makes no difference how many times they are asserted, it amounts to saying the same thing twice. The actual cardinality of 'foo' in this case is 1. Because of this, the minimum cardinality of any datatype property will never exceed 1.

<?xml version="1.0" encoding="UTF-8"?>
<foofoo xmlns="http://example.org/">
        <foo>foo</foo>
        <foo>foo</foo>
</foofoo>

The two elements above amount to saying the same thing twice.

# Base: http://example.org/cardinality2.xml
@prefix ns1:     <http://example.org/> .
@prefix xs:      <http://www.w3.org/2001/XMLSchema> .
@prefix ns2:     <http://example.org/def/> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xs_:     <http://www.w3.org/2001/XMLSchema#> .
@prefix :        <#> .

<>    ns1:foofoo
              [ ns1:foo "foo"^^xs_:string
              ] .

Does this mean we lose information and can't achieve the reverse mapping back into RDF? If the number of times something was asserted is significant we have to record the sequence in which they occur. The example below shows how each occurrence of the element has been reified, making each an objectified resource in its own right, with its own identity. Each reified 'foo' is added to the object (of 'foofoo') as an rdf:Seq in their correct lexical order. With this additional metadata we see that there are two identical statements. This sequencing information is viewed as a data-structuring issue and is not modelled ontologically.

# Base: http://example.org/cardinality2a.xml
@prefix ns1:     <http://example.org/> .
@prefix xs:      <http://www.w3.org/2001/XMLSchema> .
@prefix ns2:     <http://example.org/def/> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xs_:     <http://www.w3.org/2001/XMLSchema#> .
@prefix :        <#> .

<>    ns1:foofoo _:b1 .

_:b1  a       rdf:Seq ;
      rdf:_1  [ a       rdf:Statement ;
                rdf:object "foo"^^xs_:string ;
                rdf:predicate ns1:foo ;
                rdf:subject _:b1
              ] ;
      rdf:_2  [ a       rdf:Statement ;
                rdf:object "foo"^^xs_:string ;
                rdf:predicate ns1:foo ;
                rdf:subject _:b1
              ] ;
      ns1:foo "foo"^^xs_:string .

Compositors like sequence, choice, all (and group references) are not directly represented in OWL because they are concerned with the lexical form of a document. However, their effect is to modulate the occurrences of elements within a particle. Like elements the maximum is set by maxOccurs, and the minimum by minOccurs. With nested compositors, the cardinality is calculated by multiplying nested elements by the occurrence constraints on the compositor. By default, the sequence compositor has a minimum and maximum factor of 1. The choice compositor has a maximum factor of 1, but an overriding minimum factor of 0 because all but one of its elements will not occur at all.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://example.org/" xmlns="http://example.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:element name="foo" type="xs:string"/>
        <xs:element name="bar" type="xs:string"/>
        <!-- minimum cardinality of 0 for each choice -->
        <xs:complexType name="Foobar" mixed="true">
                <xs:sequence maxOccurs="2">
                        <xs:choice maxOccurs="2">
                                <xs:element ref="foo"/>
                                <xs:element ref="bar" maxOccurs="unbounded"/>
                        </xs:choice>
                </xs:sequence>
        </xs:complexType>
</xs:schema>

The minimum cardinality of both 'foo' and 'bar' is 1*0*1 = 0. The maximum cardinality of both 'foo' and 'bar' is 2*2*1 = 4.

# Base: http://example.org/cardinality3.owl
@prefix ns1:     <http://example.org/> .
@prefix xs:      <http://www.w3.org/2001/XMLSchema> .
@prefix ns2:     <http://example.org/def/> .
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix daml:    <http://www.daml.org/2001/03/daml+oil#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xs_:     <http://www.w3.org/2001/XMLSchema#> .
@prefix :        <#> .
@prefix owl:     <http://www.w3.org/2002/07/owl#> .

<>    a       owl:Ontology .

ns1:Foobar
      a       owl:Class ;
      rdfs:subClassOf
              [ a       owl:Restriction ;
                owl:maxCardinality "4"^^xs_:int ;
                owl:onProperty ns1:foo
              ] .

ns1:bar
      a       owl:DatatypeProperty , rdf:Property ;
      rdfs:range xs_:string .

ns1:foo
      a       owl:DatatypeProperty , rdf:Property ;
      rdfs:range xs_:string .

Another feature that will affect cardinality is the appearance of an xs:any wild-card. We have to count how many of these could match other elements in the particle and increment their cardinalities accordingly. The schema below includes an element 'foo' followed by a selection of xs:any elements that may, in principle, match yet another occurrence of 'foo'. We count how many of these may match 'foo' and increment its min and max cardinalities. The last two xs:any cannot match 'foo'. The 'foo' element is defined in the target namespace, but '#other' will only match an element in another namespace, while '#local' will only match a local, unqualified element.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
        targetNamespace="http://example.org/" xmlns="http://example.org/">
        
        <xs:element name="foo" type="xs:string"/>

        <!-- element foo has max cardinality 4 -->
        <xs:complexType name="Any">
                <xs:sequence>
                        <xs:element ref="foo" />
                        <xs:any namespace="http://example.org"/>
                        <xs:any namespace="##any"/>
                        <xs:any namespace="##targetNamespace"/>
                        <xs:any namespace="##other"/>
                        <xs:any namespace="##local"/>
                </xs:sequence>
        </xs:complexType>
        
</xs:schema>

As for other properties that may potentially match xs:any, there are no specific restrictions that can be derived from the schema. In an open-world we may pass over them in silence.

# Base: http://example.org/cardinality4.owl
@prefix ns1:     <http://example.org/> .
@prefix xs:      <http://www.w3.org/2001/XMLSchema> .
@prefix ns2:     <http://example.org/def/> .
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix daml:    <http://www.daml.org/2001/03/daml+oil#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xs_:     <http://www.w3.org/2001/XMLSchema#> .
@prefix :        <#> .
@prefix owl:     <http://www.w3.org/2002/07/owl#> .

ns1:foo
      a       owl:DatatypeProperty , rdf:Property ;
      rdfs:range xs_:string .

ns1:Any
      a       owl:Class ;
      rdfs:subClassOf
              [ a       owl:Restriction ;
                owl:minCardinality "1"^^xs_:int ;
                owl:onProperty ns1:foo
              ] ;
      rdfs:subClassOf
              [ a       owl:Restriction ;
                owl:maxCardinality "4"^^xs_:int ;
                owl:onProperty ns1:foo
              ] .

<>    a       owl:Ontology .

The final feature relevant to cardinality is the use of substitution groups.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
        targetNamespace="http://example.org/" xmlns="http://example.org/" >
        
        <xs:element name="foo" />       
        <xs:element name="bar" substitutionGroup="foo" />
        <xs:element name="foobar" type="Foobar" />
        
        <xs:complexType name="Foobar">
                <xs:sequence>
                        <xs:element ref="foo" />
                        <xs:element ref="bar" />
                </xs:sequence>
        </xs:complexType>

</xs:schema>

The member element 'bar' can substitute for the head element 'foo', so the content may include up to 2 'bar's (we assume there may be other potential sub-properties that could also substitute for 'foo'). Conversely, as 'bar' is a sub-property of 'foo' each 'bar' statement implies a 'foo' statement. There are therefore up to 2 'foo's. Ordinarily, we might conclude that exactly two 'foo's are implied, but there is again the possibility that we might have two identical literal values.

# Base: http://example.org/substitution.owl
@prefix ns1:     <http://example.org/> .
@prefix xs:      <http://www.w3.org/2001/XMLSchema> .
@prefix ns2:     <http://example.org/def/> .
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix daml:    <http://www.daml.org/2001/03/daml+oil#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xs_:     <http://www.w3.org/2001/XMLSchema#> .
@prefix :        <#> .
@prefix owl:     <http://www.w3.org/2002/07/owl#> .

ns1:Foobar
      a       owl:Class ;
      rdfs:subClassOf
              [ a       owl:Restriction ;
                owl:maxCardinality "2"^^xs_:int ;
                owl:onProperty ns1:foo
              ] ;
      rdfs:subClassOf
              [ a       owl:Restriction ;
                owl:minCardinality "1"^^xs_:int ;
                owl:onProperty ns1:foo
              ] ;
      rdfs:subClassOf
              [ a       owl:Restriction ;
                owl:minCardinality "1"^^xs_:int ;
                owl:onProperty ns1:bar
              ] ;
      rdfs:subClassOf
              [ a       owl:Restriction ;
                owl:maxCardinality "2"^^xs_:int ;
                owl:onProperty ns1:bar
              ] .

<>    a       owl:Ontology .

ns1:bar
      a       rdf:Property ;
      rdfs:subPropertyOf ns1:foo .

ns1:foobar
      a       owl:ObjectProperty ;
      rdfs:range ns1:Foobar .

ns1:foo
      a       rdf:Property .

Generated on Mon Jun 18 16:02:37 2007 for Gloze by  doxygen 1.5.0