Menu

[r12]: / trunk / py_top_module / top / owl-reasoner.trd  Maximize  Restore  History

Download this file

1519 lines (1254 with data), 66.8 kB

############################################################################
# owl-reasoner.trd
#
############################################################################


############################################################################
# include section
#
# Include the meta meta model which defines the owl: and rdf: resources
# name that may be used in this file.
############################################################################
# *MD Omitted the included due to path issue when deployed with apache (defect)
# *include-file* "top/meta_meta_model.trd"

############################################################################
# schema section
#
# *MD File top/meta_meta_model.trd included here to avoid to use the include directive
############################################################################
*schema-begin*

    #
    # owl namespace
    #
    
    owl:AllDifferent                 = resource("owl:AllDifferent")
    owl:AnnotationProperty           = resource("owl:AnnotationProperty")
    owl:Class                        = resource("owl:Class")
    owl:DataRange                    = resource("owl:DataRange")
    owl:DeprecatedClass              = resource("owl:DeprecatedClass")
    owl:DeprecatedProperty           = resource("owl:DeprecatedProperty")
    owl:DatatypeProperty             = resource("owl:DatatypeProperty")
    owl:FunctionalProperty           = resource("owl:FunctionalProperty")
    owl:InverseFunctionalProperty    = resource("owl:InverseFunctionalProperty")
    owl:Nothing                      = resource("owl:Nothing")
    owl:ObjectProperty               = resource("owl:ObjectProperty")
    owl:Ontology                     = resource("owl:Ontology")
    owl:OntologyProperty             = resource("owl:OntologyProperty")
    owl:Restriction                  = resource("owl:Restriction")
    owl:SymmetricProperty            = resource("owl:SymmetricProperty")
    owl:Thing                        = resource("owl:Thing")
    owl:TransitiveProperty           = resource("owl:TransitiveProperty")

    owl:allValuesFrom                = resource("owl:allValuesFrom")
    owl:backwardCompatibleWith       = resource("owl:backwardCompatibleWith")
    owl:cardinality                  = resource("owl:cardinality")
    owl:complementOf                 = resource("owl:complementOf")
    owl:differentFrom                = resource("owl:differentFrom")
    owl:disjointWith                 = resource("owl:disjointWith")
    owl:distinctMembers              = resource("owl:distinctMembers")
    owl:equivalentClass              = resource("owl:equivalentClass")
    owl:equivalentProperty           = resource("owl:equivalentProperty")
    owl:hasValue                     = resource("owl:hasValue")
    owl:imports                      = resource("owl:imports")
    owl:incompatibleWith             = resource("owl:incompatibleWith")
    owl:intersectionOf               = resource("owl:intersectionOf")
    owl:inverseOf                    = resource("owl:inverseOf")
    owl:maxCardinality               = resource("owl:maxCardinality")
    owl:minCardinality               = resource("owl:minCardinality")
    owl:onProperty                   = resource("owl:onProperty")
    owl:oneOf                        = resource("owl:oneOf")
    owl:priorVersion                 = resource("owl:priorVersion")
    owl:sameAs                       = resource("owl:sameAs")
    owl:someValuesFrom               = resource("owl:someValuesFrom")
    owl:unionOf                      = resource("owl:unionOf")
    owl:versionInfo                  = resource("owl:versionInfo")


    #
    # rdf/rdfs namespace
    #
    
    rdf:Description                  = resource("rdf:Description")
    rdf:Property                     = resource("rdf:Property")
    rdf:type                         = resource("rdf:type")

    rdfs:Class                       = resource("rdfs:Class")
    rdfs:Datatype                    = resource("rdfs:Datatype")
    rdfs:comment                     = resource("rdfs:comment")
    rdfs:domain                      = resource("rdfs:domain")
    rdfs:range                       = resource("rdfs:range")
    rdfs:subClassOf                  = resource("rdfs:subClassOf")
    rdfs:subPropertyOf               = resource("rdfs:subPropertyOf")


    #
    # top namespace
    #
    
    top:cardinality_gate             = resource("top:cardinality_gate")
    top:consistent_on                = resource("top:consistent_on")
    top:distinct                     = resource("top:distinct")
    top:inherited_sub_class_of       = resource("top:inherited_sub_class_of")
    top:invalid_property             = resource("top:invalid_property")
    top:invalid_transitive_property  = resource("top:invalid_transitive_property")
    top:is_domain_class              = resource("top:is_domain_class")
    top:label                        = resource("top:label")
    top:not_all_value_on             = resource("top:not_all_value_on")
    top:not_empty_set                = resource("top:not_empty_set")
    top:not_subset_of                = resource("top:not_subset_of")
    top:propertyError                = resource("top:propertyError")
    top:same_as                      = resource("top:same_as")
    xsd:float                        = resource("xsd:float")


    true                             = bool("true")
    false                            = bool("false")

*schema-end*
############################################################################


############################################################################
# knowledge base section
#
############################################################################
*knowledge-base-begin*
    
    default-explain         = true
    default-optimization    = true
    default-lookup-index    = true
    max-rule-visit          = 50000

*knowledge-base-end*
############################################################################


############################################################################
# knowledge rules section
#
############################################################################
*knowledge-rules-begin*

    # ///////////////////////////////////////////////////////////////////
    # LOGICAL CONSEQUENCES APPLICABLE TO CLASSES.
    # ///////////////////////////////////////////////////////////////////


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # rdfs:subClassOf
    #
    # This applies to classes.
    # ///////////////////////////////////////////////////////////////////

    #
    # rdfs:subClassOf is transitive: (A < B) and (B < C) => (A < C)
    #
    [n=rule_inherited_base_class2, s=100]:                              \
        (?c1 rdfs:subClassOf ?c2).                                      \
        (?c2 rdfs:subClassOf ?c3).                                      \
        [?c1 different_from ?c3]                                        \
        ->                                                              \
        (?c1 rdfs:subClassOf ?c3)


    #
    # Ensure all classes (owl:Class) are rdfs:subClassOf owl:Thing.
    #
    [n=rule_sub_class_thing, s=80]:                                     \
        (?c1 rdf:type owl:Class).                                       \
        [((?c1 different_from owl:Thing) and                            \
          (?c1 exist_not rdfs:subClassOf))]                             \
        ->                                                              \
        (?c1 rdfs:subClassOf owl:Thing)


    #
    # Ensure all owl:Restriction are rdfs:subClassOf owl:Thing.
    #
    [n=rule_class_restriction, s=100]:                                  \
        (?c1 rdf:type owl:Restriction)                                  \
        ->                                                              \
        (?c1 rdfs:subClassOf owl:Thing)


    #
    # In OWL DL an individual can never be at the same time a class: 
    # classes and individuals form disjoint domains.
    # 
    [n=err_rule_individuals_and_classes, s=100]:                        \
        (?c2 rdf:type owl:Class).                                       \
        (?s1 rdf:type owl:Class).                                       \
        (?s1 rdf:type ?c2)                                              \
        ->                                                              \
        (?s1 rdf:type owl:Nothing)


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:equivalentClass
    #
    # Note: owl:equivalentClass is asserted rather than inferred. 
    # The basic construct is owl:subClassOf. 
    # Do not infer owl:equivalentClass from classes that are mutually
    # owl:subClassOf each other this would lead to cycling for inconsistent
    # models.
    # This applies to classes.
    # ///////////////////////////////////////////////////////////////////

    #
    # owl:equivalentClass is symetric: (A = B) => (B = A)
    #
    [n=rule_symetry_of_equ_class, s=100]:                               \
        (?c1 owl:equivalentClass ?c2)                                   \
        ->                                                              \
        (?c2 owl:equivalentClass ?c1)


    #
    # owl:equivalentClass is transitive: (A = B) ^ (B = C) => (A = C)
    #
    [n=rule_trans_of_equ_class, s=100]:                                 \
        (?c1 owl:equivalentClass ?c2).                                  \
        (?c2 owl:equivalentClass ?c3).                                  \
        [(?c1 different_from ?c3)]                                      \
        ->                                                              \
        (?c1 owl:equivalentClass ?c3)


    #
    # owl:equivalentClass subsume each other: (A = B) => (A < B) and (B < A)
    #
    [n=rule_subsume_equ_class, s=100]:                                  \
        (?c1 owl:equivalentClass ?c2)                                   \
        ->                                                              \
        (?c1 rdfs:subClassOf ?c2)


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:intersectionOf
    #
    # This applies to classes.
    # ///////////////////////////////////////////////////////////////////

    #
    # owl:intersectionOf is used in covering axiom:
    #   (A = (B ^ C)) => (A < B) and (A < C)
    #
    [n=rule_intersect_axiom1, s=100]:                                   \
        (?c1 owl:intersectionOf ?c2)                                    \
        ->                                                              \
        (?c1 rdfs:subClassOf ?c2)


    #
    # Determine that a class is a subset of a class defined by the 
    # conjuction of some of it's base classes:
    #   (A = (A1 ^ A2...An)) and (B < A1) ... (B < An) => (B < A)
    #
    # This rule determine the sets that are different.
    #
    [n=rule_intersect_axiom2, s=95, o=f]:                               \
        (?A owl:intersectionOf ?A1).                                    \
        (?B rdfs:subClassOf ?A1).                                       \
        [?A different_from ?B].                                         \
        (?A owl:intersectionOf ?A2).                                    \
        [?A1 different_from ?A2].                                       \
        not(?B rdfs:subClassOf ?A2)                                     \
        ->                                                              \
        (?B top:not_subset_of ?A)


    # 
    # Determine that a class is a subset of a class defined by the 
    # conjuction of some of it's base classes:
    #   (A = (A1 ^ A2...An)) and (B < A1) ... (B < An) => (B < A)
    #
    # Assume that (B < A) unless proven otherwise.
    #
    [n=rule_intersect_axiom3, s=85, o=f]:                               \
        (?A owl:intersectionOf ?A1).                                    \
        (?B rdfs:subClassOf ?A1).                                       \
        [?A different_from ?B)].                                        \
        not(?B top:not_subset_of ?A)                                    \
        ->                                                              \
        (?B rdfs:subClassOf ?A)


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:unionOf
    #
    # This applies to classes.
    # ///////////////////////////////////////////////////////////////////

    #
    # owl:unionOf is used in covering axiom. 
    #   (A = (B | C)) => (B < A) and (C < A)
    #
    [n=rule_union_axiom1, s=100]:                                       \
        (?c1 owl:unionOf ?c2)                                           \
        ->                                                              \
        (?c2 rdfs:subClassOf ?c1)


    #
    # A disjuction of classes contained in a disjuction of a greater 
    # number of classes is a subset:
    #   (A = (A1 | A2...An)) and (B = (A1 | A2...Am)) and (m <= n) => (B < A)
    #
    # This rule proves that (B = (A1 | A2...Am)) does not hold;
    # i.e., that A does not have all classes in the union of B.
    #
    [n=rule_union_axiom2, s=110]:                                       \
        (?B owl:unionOf ?a1).                                           \
        (?A rdf:type owl:Class).                                        \
        [(?A different_from ?B) and (?A exist owl:unionOf)].            \
        not(?A owl:unionOf ?a1)                                         \
        ->                                                              \
        (?B top:not_subset_of ?A)


    # 
    # A disjuction of classes contained in a disjuction of a greater 
    # number of classes is a subset:
    #   (A = (A1 | A2...An)) and (B = (A1 | A2...Am)) and (m <= n) => (B < A)
    #
    # Assume (B < A) unless proven otherwise.
    #
    [n=rule_union_axiom3, s=90]:                                        \
        (?A rdf:type owl:Class).                                        \
        [?A exist owl:unionOf].                                         \
        (?B rdf:type owl:Class).                                        \
        [(?A different_from ?B) and (?B exist owl:unionOf)].            \
        not(?B top:not_subset_of ?A)                                    \
        ->                                                              \
        (?B rdfs:subClassOf ?A)


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:disjointWith
    #
    # This applies to classes.
    # ///////////////////////////////////////////////////////////////////

    #
    # owl:disjointWith is symetric: (A != B) => (B != A)
    #
    [n=rule_symetry_of_disjoint_class, s=100]:                          \
        (?A owl:disjointWith ?B)                                        \
        ->                                                              \
        (?B owl:disjointWith ?A)


    #
    # A class is disjoint with subclasses of it's disjoint class: 
    #   (A != B) and (C < B) => (A != C)
    #
    [n=rule_disjoint_class1, s=100]:                                    \
        (?A owl:disjointWith ?B).                                       \
        (?C rdfs:subClassOf ?B)                                         \
        ->                                                              \
        (?A owl:disjointWith ?C)


    #
    # Subclasses of disjoint classes are disjoint: 
    #   (A != B) and (C < A) and (D < B) => (C != D)
    #
    [n=rule_disjoint_class2, s=100]:                                    \
        (?A owl:disjointWith ?B).                                       \
        (?C rdfs:subClassOf ?A).                                        \
        (?D rdfs:subClassOf ?B)                                         \
        ->                                                              \
        (?C owl:disjointWith ?D)


    #
    # A class subclass of 2 disjoint classes is owl:Nothing:
    #   (A < B) and (A < C) and (B != C) => (A < 0)
    #
    [n=err_rule_sub_class_of_disjoint_classes, s=100]:                  \
        (?A rdfs:subClassOf ?B).                                        \
        (?A rdfs:subClassOf ?C).                                        \
        [?B different_from ?C].                                         \
        (?B owl:disjointWith ?C)                                        \
        ->                                                              \
        (?A rdfs:subClassOf owl:Nothing)
    

    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:complementOf
    #
    # This applies to classes.
    # ///////////////////////////////////////////////////////////////////
    
    #
    # owl:complementOf is symetric: (A ~= B) => (B ~= A)
    #
    [n=rule_complement_class1, s=100]:                                  \
        (?A owl:complementOf ?B)                                        \
        ->                                                              \
        (?B owl:complementOf ?A)


    #
    # Complement classes are disjoint: (A ~= B) => (A != B)
    #
    [n=rule_complement_class2, s=100]:                                  \
        (?A owl:complementOf ?B)                                        \
        ->                                                              \
        (?A owl:disjointWith ?B)


    #
    # A class can have only one complement class: 
    #   (A ~= B) and (B ~= C) => (A = C)
    #
    [n=rule_complement_class3, s=100]:                                  \
        (?A owl:complementOf ?B).                                       \
        (?B owl:complementOf ?C).                                       \
        [?A different_from ?C]                                          \
        ->                                                              \
        (?A owl:equivalentClass ?C)


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:oneOf
    # (used for class expression as enumerated set.)
    #
    # owl:oneOf is used in covering axiom where all possible 
    # individuals are named.
    #
    # Set A subsume set B if all individuals in set B are included in set A.
    # This consider individuals that are equivalents (owl:sameAs)
    # This applies to classes.
    # ///////////////////////////////////////////////////////////////////

    #
    # Individuals that are equivalent are in same enumerated sets: 
    #   (a < A) and (a = b) => (b < A)
    #
    [n=rule_oneof_util1, s=120]:                                        \
        (?c1 owl:oneOf ?o1).                                            \
        (?o1 owl:sameAs ?o2)                                            \
        ->                                                              \
        (?c1 owl:oneOf ?o2)


    #
    # An enumerated class not the subset of it's super-class must
    # be empty:
    #   (A < B) and (a1 < A) and not(a1 < B) => (A < 0)
    # 
    #
    [n=err_rule_oneof_axiom4, s=100]:                                   \
        (?A rdfs:subClassOf ?B).                                        \
        (?A top:not_subset_of ?B)                                       \
        ->                                                              \
        (?A rdfs:subClassOf owl:Nothing)


    #
    # Empty enumerated set must have it's enumerated individuals
    # of type Nothing:
    #   (A < 0) and (a1 < A)  => (a1 < 0)
    # 
    #
    [n=err_rule_oneof_axiom5, s=100]:                                   \
        (?A rdfs:subClassOf owl:Nothing).                               \
        (?A owl:oneOf ?a1)                                              \
        ->                                                              \
        (?a1 rdf:type owl:Nothing)


    #
    # This rule determine the sets that are different.
    #
    [n=rule_oneof_axiom1, s=105]:                                       \
        (?c1 owl:oneOf ?o1).                                            \
        (?c2 rdf:type owl:Class).                                       \
        [(?c1 different_from ?c2) and (?c2 exist owl:oneOf)].           \
        not(?c2 owl:oneOf ?o1)                                          \
        ->                                                              \
        (?c1 top:not_subset_of ?c2)


    # 
    # Assume sets having oneOf construct are equivalent by default.
    # The rule above will prove otherwise if needed.
    #   all(a < A) and (a < B) => (A < B)
    #
    [n=rule_oneof_axiom2, s=100]:                                       \
        (?c1 rdf:type owl:Class).                                       \
        [?c1 exist owl:oneOf].                                          \
        (?c2 rdf:type owl:Class).                                       \
        [(?c1 different_from ?c2) and (?c2 exist owl:oneOf)].           \
        not(?c1 top:not_subset_of ?c2)                                  \
        ->                                                              \
        (?c1 rdfs:subClassOf ?c2)


    # 
    # Two sets known to be equivalent must have their members
    # pair-wise equivalent unless known to be different.
    #   (A = B) and (a < A) and (b < B) and not(a != b) => (a = b)
    #
    [n=rule_oneof_axiom3, s=110]:                                       \
        (?c1 owl:oneOf ?o1).                                            \
        (?c2 owl:oneOf ?o2).                                            \
        [(?c1 different_from ?c2) and (?o1 different_from ?o2)].        \
        (?c1 owl:equivalentClass ?c2).                                  \
        not(?o1 owl:differentFrom ?o2).                                 \
        not(?c1 top:not_subset_of ?c2)                                  \
        ->                                                              \
        (?o1 owl:sameAs ?o2)


    # ///////////////////////////////////////////////////////////////////
    # Sets with all members of rdf:type owl:Nothing are empty.
    # Empty sets extend owl:Nothing.
    #
    # This applies to classes.
    # ///////////////////////////////////////////////////////////////////
    
    #
    # Rule to identify sets that are not empty.
    #
    [n=rule_not_empty_set, s=40]:                                       \
        (?c1 owl:oneOf ?o1).                                            \
        not(?o1 rdf:type owl:Nothing)                                   \
        ->                                                              \
        (?c1 top:not_empty_set true)


    #
    # Assume enumerated sets to be empty unless proof of otherwise.
    #
    [n=err_rule_empty_set, s=30]:                                       \
        (?c1 rdf:type owl:Class).                                       \
        [?c1 exist owl:oneOf].                                          \
        not(?c1 top:not_empty_set true)                                 \
        ->                                                              \
        (?c1 rdfs:subClassOf owl:Nothing)


    # ///////////////////////////////////////////////////////////////////
    # LOGICAL CONSEQUENCES APPLICABLE TO INDIVIDUALS.
    # ///////////////////////////////////////////////////////////////////


    # ///////////////////////////////////////////////////////////////////
    # Infer class membership of individuals based on class hierarchy.
    #
    # This applies to individuals.
    # ///////////////////////////////////////////////////////////////////
    
    #
    # Individuals must have rdf:type as specified by class hierarchy: 
    #   (a < A) and (A < B) => (a < B)
    #
    [n=rule_ind_membership1, s=50]:                                     \
        (?s1 rdf:type ?c1).                                             \
        (?c1 rdfs:subClassOf ?c2)                                       \
        ->                                                              \
        (?s1 rdf:type ?c2)


    #
    # Individuals member of two classes that are disjoint must be owl:Nothing: 
    #   (a < A) and (a < B) and (A != B) => (a < 0)
    #
    [n=err_rule_ind_membership2, s=50]:                                 \
        (?s1 rdf:type ?c1).                                             \
        (?s1 rdf:type ?c2).                                             \
        [?c1 different_from ?c2].                                       \
        (?c1 owl:disjointWith ?c2)                                      \
        ->                                                              \
        (?s1 rdf:type owl:Nothing)


    #
    # Individual can only be same and different from another one if it is owl:Nothing:
    #   (a = b) and (a != b) => (a < 0)
    #
    [n=err_rule_ind_membership3, s=50]:                                 \
        (?a owl:sameAs ?b).                                             \
        (?a owl:differentFrom ?b).                                      \
        [?a different_from ?b]                                          \
        ->                                                              \
        (?a rdf:type owl:Nothing)


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:sameAs
    #
    # owl:sameAs is used for constructing enumerated sets.
    # This applies to individuals.
    # ///////////////////////////////////////////////////////////////////

    #
    # owl:sameAs is symetric: (a = b) => (b = a)
    #
    [n=rule_symetry_of_same_as, s=120]:                                 \
        (?s1 owl:sameAs ?s2)                                            \
        ->                                                              \
        (?s2 owl:sameAs ?s1)


    #
    # owl:sameAs is transitive: (a = b) and (b = c) => (a = c)
    #
    [n=rule_trans_of_same_as, s=120]:                                   \
        (?s1 owl:sameAs ?s2).                                           \
        (?s2 owl:sameAs ?s3).                                           \
        [?s1 different_from ?s3]                                        \
        ->                                                              \
        (?s1 owl:sameAs ?s3)


    #
    # owl:sameAs individuals have same type:
    #   (a = b) and (a < A) => (b < A)
    #
    [n=rule_same_as_type1, s=100]:                                      \
        (?a owl:sameAs ?b).                                             \
        (?a rdf:type ?A)                                                \
        ->                                                              \
        (?b rdf:type ?A)


    #
    # SameAs individuals participate in same relations: 
    #   (x = y) and P(x, z) => P(y, z)
    #
    [n=rule_same_prop1, s=100]:                                         \
        (?p rdfs:subClassOf rdf:Property).                              \
        (?x owl:sameAs ?y).                                             \
        (?x ?p ?z).                                                     \
        [?z different_from ?y]                                          \
        ->                                                              \
        (?y ?p ?z)


    #
    # SameAs individuals participate in same relations: 
    #   (z = z1) and P(x, z) => P(x, z1)
    #
    [n=rule_same_prop2, s=100]:                                         \
        (?p rdfs:subClassOf rdf:Property).                              \
        (?z owl:sameAs ?z1).                                            \
        (?x ?p ?z).                                                     \
        [?x different_from ?z1]                                         \
        ->                                                              \
        (?x ?p ?z1)


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:differentFrom
    #
    # owl:differentFrom is used for constructing enumerated sets.
    # This applies to individuals.
    # ///////////////////////////////////////////////////////////////////

    #
    # owl:differentFrom is symetric: (a != b) => (b != a)
    #
    [n=rule_symetry_of_different_from, s=120]:                          \
        (?s1 owl:differentFrom ?s2)                                     \
        ->                                                              \
        (?s2 owl:differentFrom ?s1)


    #
    # Same individuals have common different individuals: 
    #   (a = b) and (b != c) => (a != c)
    #
    [n=rule_trans_of_different_from, s=120]:                            \
        (?a owl:sameAs ?b).                                             \
        (?b owl:differentFrom ?c).                                      \
        [?a different_from ?c]                                          \
        ->                                                              \
        (?a owl:differentFrom ?c)

    #
    # owl:distinctMembers is syntactic sugar to owl:differentFrom
    #
    [n=rule_distinct_memb_axiom, s=120]:                                \
        (?c1 owl:distinctMembers ?s1).                                  \
        (?c1 owl:distinctMembers ?s2).                                  \
        [?s1 different_from ?s2]                                        \
        ->                                                              \
        (?s1 owl:differentFrom ?s2)


    # ///////////////////////////////////////////////////////////////////
    # LOGICAL CONSEQUENCES APPLICABLE TO PROPERTIES.
    # ///////////////////////////////////////////////////////////////////

    #
    # Detect error in property semantic
    #
    [n=rule_err_prop1, s=100]:                                          \
        (?p1 rdf:type owl:DatatypeProperty).                            \
        (?p1 rdf:type owl:ObjectProperty)                               \
        ->                                                              \
        (?p1 top:propertyError top:invalid_property)


    #
    # Detect error in property range
    #
    [n=rule_err_prop_disjoint_range1, s=100]:                           \
        (?p1 rdfs:range ?c1).                                           \
        (?p1 rdfs:range ?c2).                                           \
        [?c1 different_from ?c2].                                       \
        (?c1 owl:disjointWith ?c2)                                      \
        ->                                                              \
        (?p1 top:propertyError top:invalid_property)


    #
    # Detect error in property domain
    #
    [n=rule_err_prop_disjoint_domain1, s=100]:                          \
        (?p1 rdfs:domain ?c1).                                          \
        (?p1 rdfs:domain ?c2).                                          \
        [?c1 different_from ?c2].                                       \
        (?c1 owl:disjointWith ?c2)                                      \
        ->                                                              \
        (?p1 top:propertyError top:invalid_property)


    # ///////////////////////////////////////////////////////////////////
    # Ensure to have both owl:ObjectProperty and owl:DatatypeProperty 
    # subclasses of the RDF class rdf:Property.
    #
    # This applies to properties.
    # ///////////////////////////////////////////////////////////////////
    #
    [n=rule_prop1, s=120]:                                              \
        (?p1 rdf:type owl:ObjectProperty)                               \
        ->                                                              \
        (?p1 rdfs:subClassOf rdf:Property)


    [n=rule_prop2, s=120]:                                              \
        (?p1 rdf:type owl:DatatypeProperty)                             \
        ->                                                              \
        (?p1 rdfs:subClassOf rdf:Property)


    #
    # Subject must be of type specified by the property domain: 
    #   P(x, y) and (P domain C) => (x < C)
    #
    [n=rule_prop3, s=120]:                                              \
        (?s ?p ?o).                                                     \
        (?p rdfs:domain ?d)                                             \
        ->                                                              \
        (?s rdf:type ?d)


    #
    # Object must be of type specified by the property range: 
    #   P(x, y) and (P range C) => (y < C)
    #
    [n=rule_prop4, s=120]:                                              \
        (?s ?p ?o).                                                     \
        (?p rdfs:range ?d)                                              \
        ->                                                              \
        (?o rdf:type ?d)


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # rdfs:subPropertyOf
    #
    # This applies to properties.
    # ///////////////////////////////////////////////////////////////////

    #
    # In OWL DL the subject and object of a subproperty (rdfs:subPropertyOf) statement must be either both 
    # datatype properties or both object properties.
    #
    [n=rule_sub_prop11, s=120]:                                         \
        (?p1 rdfs:subPropertyOf ?p2).                                   \
        (?p2 rdf:type owl:ObjectProperty)                               \
        ->                                                              \
        (?p1 rdf:type owl:ObjectProperty)


    [n=rule_sub_prop12, s=120]:                                         \
        (?p1 rdfs:subPropertyOf ?p2).                                   \
        (?p2 rdf:type owl:DatatypeProperty)                             \
        ->                                                              \
        (?p1 rdf:type owl:DatatypeProperty)


    #
    # rdfs:subPropertyOf have domain of parent property
    # Subproperty must have sub-domain parent property: 
    #   (P1 < P2) and (P1 domain C1) and (P2 domain C2) => (P1 domain (C1 ^ C2)) 
    #
    [n=rule_sub_prop2, s=120]:                                          \
        (?p1 rdfs:subPropertyOf ?p2).                                   \
        (?p2 rdfs:domain ?d)                                            \
        ->                                                              \
        (?p1 rdfs:domain ?d)


    #
    # rdfs:subPropertyOf have range of parent property
    # Subproperty must have sub-range of parent property:
    #  (P1 < P2) and (P1 range C1) and (P2 range C2) => (P1 range (C1 ^ C2))
    #
    [n=rule_sub_prop3, s=120]:                                          \
        (?p1 rdfs:subPropertyOf ?p2).                                   \
        (?p2 rdfs:range ?d)                                             \
        ->                                                              \
        (?p1 rdfs:range ?d)
    
    
    #
    # Transitivity of subproperty relation: (P1 < P2) and (P2 < P3) => (P1 < P3)
    #
    [n=rule_sub_prop4, s=120]:                                          \
        (?p1 rdfs:subPropertyOf ?p2).                                   \
        (?p2 rdfs:subPropertyOf ?p3).                                   \
        [?p1 different_from ?p3]                                        \
        ->                                                              \
        (?p1 rdfs:subPropertyOf ?p3)


    [n=rule_sub_prop5, s=120]:                                          \
        (?p1 rdfs:subPropertyOf ?p2).                                   \
        (?p2 top:propertyError ?x)                                      \
        ->                                                              \
        (?p1 top:propertyError ?x)


    #
    # Inheritance of properties: P1(x, y) and (P1 < P2) => P2(x, y)
    #
    [n=rule_sub_prop6, s=100]:                                          \
        (?p1 rdfs:subPropertyOf ?p2).                                   \
        (?x ?p1 ?y)                                                     \
        ->                                                              \
        (?x ?p2 ?y)


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:equivalentProperty
    #
    # This applies to properties.
    # ///////////////////////////////////////////////////////////////////
    
    #
    # owl:equivalentProperty is symetric
    #
    [n=rule_sym_equivalent_prop1, s=120]:                               \
        (?p1 owl:equivalentProperty ?p2)                                \
        ->                                                              \
        (?p2 owl:equivalentProperty ?p1)


    #
    # owl:equivalentProperty is transitive
    #
    [n=rule_trans_equivalent_prop1, s=120]:                             \
        (?p1 owl:equivalentProperty ?p2).                               \
        (?p2 owl:equivalentProperty ?p3).                               \
        [?p1 different_from ?p3]                                        \
        ->                                                              \
        (?p1 owl:equivalentProperty ?p3)


    #
    # owl:equivalentProperty have same domain
    #
    [n=rule_domain_equivalent_prop1, s=120]:                            \
        (?p1 owl:equivalentProperty ?p2).                               \
        (?p2 rdfs:domain ?d)                                            \
        ->                                                              \
        (?p1 rdfs:domain ?d)


    #
    # owl:equivalentProperty have same range
    #
    [n=rule_range_equivalent_prop1, s=120]:                             \
        (?p1 owl:equivalentProperty ?p2).                               \
        (?p2 rdfs:range ?d)                                             \
        ->                                                              \
        (?p1 rdfs:range ?d)


    #
    # owl:equivalentProperty have same "property extension"
    #   (P1 = P2) => (P1 < P2) and (P2 < P1)
    #
    [n=rule_equivalent_prop1, s=120]:                                   \
        (?P1 owl:equivalentProperty ?P2)                                \
        ->                                                              \
        (?P1 rdfs:subPropertyOf ?P2).                                   \
        (?P2 rdfs:subPropertyOf ?P1)


    #
    # owl:equivalentProperty have same "property extension"
    #   (P1 < P2) and (P2 < P1) => (P1 = P2)
    #
    [n=rule_equivalent_prop2, s=120]:                                   \
        (?P1 rdfs:subPropertyOf ?P2).                                   \
        (?P2 rdfs:subPropertyOf ?P1)                                    \
        ->                                                              \
        (?P1 owl:equivalentProperty ?P2)


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:inverseOf
    #
    # This applies to properties.
    # ///////////////////////////////////////////////////////////////////
    
    #
    # owl:inverseOf is symetric and is applicable only to owl:ObjectProperty.
    #
    [n=rule_sym_inverse_prop1, s=120]:                                  \
        (?p1 owl:inverseOf ?p2)                                         \
        ->                                                              \
        (?p2 owl:inverseOf ?p1).                                        \
        (?p1 rdf:type owl:ObjectProperty)


    #
    # owl:inverseOf have domain and range interchanged
    #
    [n=rule_domain_inverse_prop1, s=120]:                               \
        (?p1 owl:inverseOf ?p2).                                        \
        (?p2 rdfs:domain ?c)                                            \
        ->                                                              \
        (?p1 rdfs:range ?c)


    [n=rule_range_inverse_prop1, s=120]:                                \
        (?p1 owl:inverseOf ?p2).                                        \
        (?p2 rdfs:range ?c)                                             \
        ->                                                              \
        (?p1 rdfs:domain ?c)


    #
    # P1 owl:inverseOf P2: P1(x, y) => P2(y, x)
    #
    [n=rule_pair_inverse_prop1, s=100]:                                 \
        (?p1 owl:inverseOf ?p2).                                        \
        (?s ?p1 ?o)                                                     \
        ->                                                              \
        (?o ?p2 ?s)


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:FunctionalProperty
    #
    # This applies to properties.
    # ///////////////////////////////////////////////////////////////////
    
    #
    # owl:FunctionalProperty can have only one value
    #
    [n=rule_functional_prop1, s=120]:                                   \
        (?p1 rdf:type owl:FunctionalProperty).                          \
        (?s ?p1 ?o1).                                                   \
        (?s ?p1 ?o2).                                                   \
        [?o1 different_from ?o2]                                        \
        ->                                                              \
        (?o1 owl:sameAs ?o2)


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:InverseFunctionalProperty
    #
    # This applies to properties.
    # ///////////////////////////////////////////////////////////////////
    
    #
    # owl:InverseFunctionalProperty is owl:ObjectProperty
    #
    [n=rule_inv_funct_prop1, s=120]:                                    \
        (?p1 rdf:type owl:InverseFunctionalProperty)                    \
        ->                                                              \
        (?p1 rdf:type owl:ObjectProperty)                               \
    
    #
    # owl:InverseFunctionalProperty can have only one subject
    #   P(x1, y) and P(x2, y) => (x1 = x2)
    #
    [n=rule_inv_funct_prop2, s=120]:                                    \
        (?p1 rdf:type owl:InverseFunctionalProperty).                   \
        (?s1 ?p1 ?o).                                                   \
        (?s2 ?p1 ?o).                                                   \
        [?s1 different_from ?s2]                                        \
        ->                                                              \
        (?s1 owl:sameAs ?s2)


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:TransitiveProperty
    #
    # This applies to properties.
    # ///////////////////////////////////////////////////////////////////
    
    #
    # owl:TransitiveProperty is owl:ObjectProperty
    #
    [n=rule_trans_prop1, s=120]:                                        \
        (?p1 rdf:type owl:TransitiveProperty)                           \
        ->                                                              \
        (?p1 rdf:type owl:ObjectProperty)


    #
    # owl:TransitiveProperty: P(x, y) ^ P(y, z) => P(x, z)
    #
    [n=rule_trans_prop2, s=120]:                                        \
        (?p1 rdf:type owl:TransitiveProperty).                          \
        (?s1 ?p1 ?s2).                                                  \
        (?s2 ?p1 ?s3).                                                  \
        [?s1 different_from ?s3]                                        \
        ->                                                              \
        (?s1 ?p1 ?s3)


    #
    # owl:TransitiveProperty cannot have global cardinality constraints,
    # nor it's superproperty, it's inverse, and the inverse of it's superproperty.
    #
    [n=rule_trans_prop3, s=120]:                                        \
        (?p1 rdf:type owl:TransitiveProperty).                          \
        (?p1 rdf:type owl:FunctionalProperty)                           \
        ->                                                              \
        (?p1 top:propertyError top:invalid_transitive_property)


    [n=rule_trans_prop4, s=120]:                                        \
        (?p1 rdf:type owl:TransitiveProperty).                          \
        (?p1 rdf:type owl:InverseFunctionalProperty)                    \
        ->                                                              \
        (?p1 top:propertyError top:invalid_transitive_property)


    [n=rule_trans_prop5, s=120]:                                        \
        (?p1 rdf:type owl:TransitiveProperty).                          \
        (?p1 rdfs:subPropertyOf ?p2).                                   \
        (?p2 rdf:type owl:FunctionalProperty)                           \
        ->                                                              \
        (?p1 top:propertyError top:invalid_transitive_property)


    [n=rule_trans_prop6, s=120]:                                        \
        (?p1 rdf:type owl:TransitiveProperty).                          \
        (?p1 rdfs:subPropertyOf ?p2).                                   \
        (?p2 rdf:type owl:InverseFunctionalProperty)                    \
        ->                                                              \
        (?p1 top:propertyError top:invalid_transitive_property)


    [n=rule_trans_prop7, s=120]:                                        \
        (?p1 rdf:type owl:TransitiveProperty).                          \
        (?p1 owl:inverseOf ?p2).                                        \
        (?p2 rdf:type owl:FunctionalProperty)                           \
        ->                                                              \
        (?p1 top:propertyError top:invalid_transitive_property)


    [n=rule_trans_prop8, s=120]:                                        \
        (?p1 rdf:type owl:TransitiveProperty).                          \
        (?p1 owl:inverseOf ?p2).                                        \
        (?p2 rdf:type owl:InverseFunctionalProperty)                    \
        ->                                                              \
        (?p1 top:propertyError top:invalid_transitive_property)


    [n=rule_trans_prop9, s=120]:                                        \
        (?p1 rdf:type owl:TransitiveProperty).                          \
        (?p1 rdfs:subPropertyOf ?p2).                                   \
        (?p2 owl:inverseOf ?p3).                                        \
        (?p3 rdf:type owl:FunctionalProperty)                           \
        ->                                                              \
        (?p1 top:propertyError top:invalid_transitive_property)


    [n=rule_trans_prop10, s=120]:                                       \
        (?p1 rdf:type owl:TransitiveProperty).                          \
        (?p1 rdfs:subPropertyOf ?p2).                                   \
        (?p2 owl:inverseOf ?p3).                                        \
        (?p3 rdf:type owl:InverseFunctionalProperty)                    \
        ->                                                              \
        (?p1 top:propertyError top:invalid_transitive_property)


    #
    # The superproperty of a transitive property is also a transitive property.
    #
    [n=rule_trans_prop11, s=120]:                                       \
        (?p1 rdf:type owl:TransitiveProperty).                          \
        (?p1 rdfs:subPropertyOf ?p2)                                    \
        ->                                                              \
        (?p2 rdf:type owl:TransitiveProperty)

    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:SymmetricProperty
    #
    # This applies to properties.
    # ///////////////////////////////////////////////////////////////////
    
    #
    # owl:SymmetricProperty is owl:ObjectProperty
    #
    [n=rule_symetric_prop1, s=120]:                                     \
        (?p1 rdf:type owl:SymmetricProperty)                            \
        ->                                                              \
        (?p1 rdf:type owl:ObjectProperty)


    #
    # owl:SymmetricProperty: P(x, y) => P(y, x)
    #
    [n=rule_symetric_prop2, s=120]:                                     \
        (?p1 rdf:type owl:SymmetricProperty).                           \
        (?x ?p1 ?y)                                                     \
        ->                                                              \
        (?y ?p1 ?x)


    #
    # The domain and range of a symmetric property are the same.
    #
    [n=rule_symetric_prop3, s=120]:                                     \
        (?p1 rdf:type owl:SymmetricProperty).                           \
        (?p1 rdfs:domain ?c)                                            \
        ->                                                              \
        (?p1 rdfs:range ?c)


    #
    # The domain and range of a symmetric property are the same.
    #
    [n=rule_symetric_prop4, s=120]:                                     \
        (?p1 rdf:type owl:SymmetricProperty).                           \
        (?p1 rdfs:range ?c)                                             \
        ->                                                              \
        (?p1 rdfs:domain ?c)


    # ///////////////////////////////////////////////////////////////////
    # LOGICAL CONSEQUENCES APPLICABLE TO PROPERTY RESTRICTION.
    # ///////////////////////////////////////////////////////////////////


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:allValuesFrom
    #
    # This applies to classes.
    # ///////////////////////////////////////////////////////////////////

    #
    # owl:allValuesFrom: Class where all individuals for which all values 
    # of the property under consideration are either members of the 
    # class extension of the class description or are data values within 
    # the specified data range:
    #   P all-values-from Y, for X: all y: P(x, y) and (y < Y) => (x < X) 
    #
    # Assume all values will satisfy the condition, those who don't
    # will be weed out.
    #
    [n=rule_all_value_from1, s=60]:                                     \
        (?c1 owl:allValuesFrom ?c2).                                    \
        (?c1 owl:onProperty ?p).                                        \
        (?o rdf:type ?c2).                                              \
        (?s ?p ?o).                                                     \
        not(?s top:not_all_value_on ?p)                                 \
        ->                                                              \
        (?s rdf:type ?c1)


    #
    # Weed out those who don't meet the criteria.
    #
    [n=rule_all_value_from2, s=70]:                                     \
        (?c1 owl:allValuesFrom ?c2).                                    \
        (?c1 owl:onProperty ?p).                                        \
        (?s ?p ?o).                                                     \
        not(?o rdf:type ?c2)                                            \
        ->                                                              \
        (?s top:not_all_value_on ?p)


    #
    # owl:allValuesFrom: Analogous to the universal (for-all) quantifier 
    # of Predicate logic:
    #   P all-values-from C: P(x, y) => (y < C)
    #
    [n=rule_all_value_from3, s=120]:                                    \
        (?c1 owl:allValuesFrom ?c2).                                    \
        (?c1 owl:onProperty ?p).                                        \
        (?s rdf:type ?c1).                                              \
        (?s ?p ?o)                                                      \
        ->                                                              \
        (?o rdf:type ?c2)


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:someValuesFrom
    #
    # This applies to classes.
    # ///////////////////////////////////////////////////////////////////

    #
    # owl:someValuesFrom: Describes a class of all individuals for which 
    # at least one value of the property concerned is an instance of the 
    # class description or a data value in the data range:
    #   P some-values-from Y, for X: exist y: P(x, y) and (y < Y) => (x < X)
    #
    [n=rule_some_value_from1, s=90]:                                    \
        (?c1 owl:someValuesFrom ?c2).                                   \
        (?c1 owl:onProperty ?p).                                        \
        (?o rdf:type ?c2).                                              \
        (?s ?p ?o)                                                      \
        ->                                                              \
        (?s rdf:type ?c1)


    #
    # owl:someValuesFrom: Analogous to the existential quantifier of Predicate logic;
    # for each instance of the class that is being defined, 
    # there exists at least one value for P that fulfills the constraint:
    #   P some-values-from Y, for X: (x < X) => P(x, y) and (y < Y) [exist at least one y]
    #
    # Note: The enforcement here is reduced to determine whether
    #       the individual is consistent or not with the restriction.
    #
    [n=rule_some_value_from2, s=80]:                                    \
        (?c1 owl:someValuesFrom ?c2).                                   \
        (?c1 owl:onProperty ?p).                                        \
        (?s rdf:type ?c1).                                              \
        (?s ?p ?o).                                                     \
        (?o rdf:type ?c2)                                               \
        ->                                                              \
        (?s top:consistent_on ?p)
    
    
    #
    # Assume individuals are not consistent, 
    # those who are will be weed out.
    #
    [n=err_rule_some_value_from3, s=50]:                                \
        (?c1 owl:someValuesFrom ?c2).                                   \
        (?c1 owl:onProperty ?p).                                        \
        (?s rdf:type ?c1).                                              \
        not(?s top:consistent_on ?p)                                    \
        ->                                                              \
        (?s rdf:type owl:Nothing)


    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:hasValue
    #
    # This applies to classes.
    # ///////////////////////////////////////////////////////////////////

    #
    # owl:hasValue: Describes a class of all individuals for which the 
    # property concerned has at least one value semantically equal to y:
    #   P has_value y, for X: P(x, y) => (x < X)
    #
    [n=rule_has_value1, s=100]:                                         \
        (?c1 owl:hasValue ?y).                                          \
        (?c1 owl:onProperty ?p).                                        \
        (?s ?p ?y)                                                      \
        ->                                                              \
        (?s rdf:type ?c1)


    #
    # All member of the described class must have at least one value 
    # sematically equal to y:
    #   P has_value y, for X: (x < X) => P(x, y)
    #
    [n=rule_has_value2, s=100]:                                         \
        (?c1 owl:hasValue ?y).                                          \
        (?c1 owl:onProperty ?p).                                        \
        (?s rdf:type ?c1)                                               \
        ->                                                              \
        (?s ?p ?y)


    #
    # When the property concerned is a Transitive Property, 
    # then this class may be subclass to another one describing the 
    # set of individual with value obtained from transitivity:
    #   P has-value y, for X: as P(X, y)
    #   P is-transitive:
    #   P has-value y2, for X2: as P(X2, y2)
    #       P(X, y) and P(X2, y2) and P(y, y2) => (X < X2)
    #
    [n=rule_has_value3, s=100]:                                         \
        (?c1 owl:hasValue ?y1).                                         \
        (?c1 owl:onProperty ?P).                                        \
        (?P rdf:type owl:TransitiveProperty).                           \
        (?c2 owl:hasValue ?y2).                                         \
        (?c2 owl:onProperty ?P).                                        \
        [?c1 different_from ?c2].                                       \
        (?y1 ?P ?y2)                                                    \
        ->                                                              \
        (?c1 rdfs:subClassOf ?c2)
    
    
    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:maxCardinality
    #
    # This applies to classes.
    # ///////////////////////////////////////////////////////////////////

    #
    # Describes a class of all individuals that have at most N semantically distinct values 
    # (individuals or data values) for the property concerned, where N is the value of the 
    # cardinality constraint.
    #
    
    #
    # Identify the individuals: for X: (#P(x, y) .le. n) => (x < X)
    #
    [n=rule_max_cardinality1, s=5, o=f]:                                \
        (?s top:cardinality_gate true).                                 \
        (?C owl:maxCardinality ?N).                                     \
        (?C owl:onProperty ?P).                                         \
        (?s ?P ?o).                                                     \
        [?s test_max_cardinality ?C]                                    \
        ->                                                              \
        (?s rdf:type ?C)

    
    #
    # Validate restriction: for X: (x < X) and not(#P(x, y) .le. n) => (x < 0)
    #
    [n=err_rule_max_cardinality2, s=5, o=f]:                            \
        (?s top:cardinality_gate true).                                 \
        (?C owl:maxCardinality ?N).                                     \
        (?s rdf:type ?C).                                               \
        [not (?s test_max_cardinality ?C)]                              \
        ->                                                              \
        (?s rdf:type owl:Nothing)
    
    
    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:minCardinality
    #
    # This applies to classes.
    # ///////////////////////////////////////////////////////////////////

    #
    # Describes a class of all individuals that have at least N semantically distinct values 
    # (individuals or data values) for the property concerned, where N is the value of the 
    # cardinality constraint.
    #
    
    #
    # Identify the individuals: for X: (#P(x, y) .ge. n) => (x < X)
    #
    [n=rule_min_cardinality1, s=5, o=f]:                                \
        (?s top:cardinality_gate true).                                 \
        (?C owl:minCardinality ?N).                                     \
        (?C owl:onProperty ?P).                                         \
        (?s ?P ?o).                                                     \
        [?s test_min_cardinality ?C]                                    \
        ->                                                              \
        (?s rdf:type ?C)

    
    #
    # Validate restriction: for X: (x < X) and not(#P(x, y) .ge. n) => (x < 0)
    #
    [n=err_rule_min_cardinality2, s=5, o=f]:                            \
        (?s top:cardinality_gate true).                                 \
        (?C owl:minCardinality ?N).                                     \
        (?s rdf:type ?C).                                               \
        [not (?s test_min_cardinality ?C)]                              \
        ->                                                              \
        (?s rdf:type owl:Nothing)
    
    
    # ///////////////////////////////////////////////////////////////////
    # Apply logical consequences of
    # owl:cardinality
    #
    # This applies to classes.
    # ///////////////////////////////////////////////////////////////////

    #
    # Describes a class of all individuals that have exacly N semantically distinct values 
    # (individuals or data values) for the property concerned, where N is the value of the 
    # cardinality constraint.
    #
    
    #
    # Identify the individuals: for X: (#P(x, y) .eq. n) => (x < X)
    #
    [n=rule_cardinality1, s=5, o=f]:                                    \
        (?s top:cardinality_gate true).                                 \
        (?C owl:cardinality ?N).                                        \
        (?C owl:onProperty ?P).                                         \
        (?s ?P ?o).                                                     \
        [?s test_cardinality ?C]                                        \
        ->                                                              \
        (?s rdf:type ?C)

    
    #
    # Validate restriction: for X: (x < X) and not(#P(x, y) .eq. n) => (x < 0)
    #
    [n=err_rule_cardinality2, s=5, o=f]:                                \
        (?s top:cardinality_gate true).                                 \
        (?C owl:cardinality ?N).                                        \
        (?s rdf:type ?C).                                               \
        [not (?s test_cardinality ?C)]                                  \
        ->                                                              \
        (?s rdf:type owl:Nothing)

    
    #
    # Gate to avoid rules to fires too early
    #
    [n=rule_gate_cardinality1, s=5, o=f]:                               \
        (?C owl:maxCardinality ?N).                                     \
        (?s rdf:type ?C)                                                \
        ->                                                              \
        (?s top:cardinality_gate true)

    [n=rule_gate_cardinality2, s=5, o=f]:                               \
        (?C owl:maxCardinality ?N).                                     \
        (?C owl:onProperty ?P).                                         \
        (?s ?P ?o)                                                      \
        ->                                                              \
        (?s top:cardinality_gate true)

    [n=rule_gate_cardinality3, s=5, o=f]:                               \
        (?C owl:minCardinality ?N).                                     \
        (?s rdf:type ?C)                                                \
        ->                                                              \
        (?s top:cardinality_gate true)

    [n=rule_gate_cardinality4, s=5, o=f]:                               \
        (?C owl:minCardinality ?N).                                     \
        (?C owl:onProperty ?P).                                         \
        (?s ?P ?o)                                                      \
        ->                                                              \
        (?s top:cardinality_gate true)

    [n=rule_gate_cardinality5, s=5, o=f]:                               \
        (?C owl:cardinality ?N).                                        \
        (?s rdf:type ?C)                                                \
        ->                                                              \
        (?s top:cardinality_gate true)

    [n=rule_gate_cardinality6, s=5, o=f]:                               \
        (?C owl:cardinality ?N).                                        \
        (?C owl:onProperty ?P).                                         \
        (?s ?P ?o)                                                      \
        ->                                                              \
        (?s top:cardinality_gate true)


    

    #####################################################################
    #####################################################################
    #####################################################################
    # ///////////////////////////////////////////////////////////////////
    # query du jour. . .to avoid recompilation of unit test. . .
    #
    # ///////////////////////////////////////////////////////////////////
    q_du_jour1:                                                         \
        SELECT * FROM                                                   \
        (?u top:propertyError ?x)


    q_du_jour2:                                                         \
        SELECT * FROM                                                   \
        (?u rdfs:subClassOf owl:Nothing)


    q_du_jour3:                                                         \
        SELECT * FROM                                                   \
        (?u ?v ?w).                                                     \
        [((?v same_as rdfs:subClassOf) and                              \
         ((is_resource ?u) and (is_resource ?w)))]


    q_du_jour4:                                                         \
        SELECT * FROM                                                   \
        (?u rdfs:subClassOf rdf:Property).                              \
        (?u ?v ?w)


*knowledge-rules-end*
############################################################################

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.