 Volz *et al.* (2003) claims that, "the unrestricted use of cardinality constraints cannot be supported efficiently in Logic Programming environments..." It is true that, in theory, there are an unlimited number of cardinality constraints that the developer could impose. However, we can extend SWORIER's system design (from Figure 2) by introducing a new module, as shown in Figure 3. Any cardinality constraints found in the ontologies are sent to this *Cardinality Rules* module, which produces one or two Prolog rules for each constraint. Since there are a finite number of cardinality constraints in any ontologies, it is possible to develop all and only the necessary cardinality rules, and thus, the problem is tractable. 

 An example cardinality constraint is expressed by the OWL code in Table 11a, which says that every theater object is described by exactly one individual. For this constraint, it is necessary to generate two rules, one testing to make sure that there is no more than one individual, and the other checking that there is at least one individual that satisfies the restriction. We have two options for the first rule: 1) If two different individuals are found that both describe the same theater object, we could report an error to the developer, as in Section 4.6, or 2) we could enforce the constraint with the rule in which says that if any theater object is described by two individuals, then those two individuals must be equivalent. For the second rule, there are three options: 1) If a theater object exists that is not described by any individuals, we could report an error to the developer, as in Section 4.6, 2) the constraint could be enforced by skolemization, which was explained in Section 4.7, or 3) the problem could be fixed by adding new facts to the knowledge base. The last option is demonstrated in Table 11c, where the Prolog predicate, gensym, sets I3 to a new unique constant, and the assert predicate adds the required fact to the knowledge base. (The query, enforceConstraints, would be run offline in order to create all of the required facts.)

![0_image_0.png](0_image_0.png)

