Complex question I assume, but studying OWL opened a new perspective to live, the universe and everything. I'm going philosophical here.
I am trying to achieve a class C which is subclass of B which in turn is subclass of C. Just for fun, you know...
So here it is
>>> class A(object): pass
...
>>> class B(A): pass
...
>>> class C(B): pass
...
>>> B.__bases__
(<class '__main__.A'>,)
>>> B.__bases__ = (C,)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: a __bases__ item causes an inheritance cycle
>>>
clearly, python is smart and forbids this. However, in OWL it is possible to define two classes to be mutual subclasses. The question is: what is the mind boggling explanation why this is allowed in OWL (which is not a programming language) and disallowed in programming languages ?
Python doesn't allow it because there is no sensible way to do it. You could invent arbitrary rules about how to handle such a case (and perhaps some languages do), but since there is no actual gain in doing so, Python refuses to guess. Classes are required to have a stable, predictable method resolution order for a number of reasons, and so weird, unpredictable or surprising MROs are not allowed.
That said, there is a special case in Python:
type
andobject
.object
is an instance oftype
, andtype
is a subclass ofobject
. And of course,type
is also an instance oftype
(since it's a subclass ofobject
). This might be why OWL allows it: you need to start a class/metaclass hierarchy in some singularity, if you want everything to be an object and all objects to have a class.I'm sure someone can up with an example where this makes sense. However, I guess this restriction is easier and not less powerful.
Eg, Let's say class A holds fields a and b. Class C holds b and c. Then the view on things from C would be: A.a, C.b, C.c and the view from A would be: A.a, A.b, C.c.
Just moving b into a common base class is far easier to understand and implement, though.
The MRO scheme implemented in Python (as of 2.3) forbids cyclic subclassing. Valid MRO's are guaranteed to satisfy "local precedence" and "monotonicity". Cyclic subclassing would break monotonicity.
This issue is discussed in the section entitled "Bad Method Resolution Orders"
For a semantic reasoner, if A is a subclass of B, and B is a subclass of A, then the classes can be considered equivalent. They are not the "same", but from a reasoning perspective, if I can reason an individual is (or is not) a member of the class A, I can reason the individual is (or is not) a member of the class B. The classes A and B are semantically equivalent, which is what you were able to express with OWL.
I think the answer is "When you construct class C ... it must create instance of class B .. which must create instance of class C ... and so on" This will never end. This is forbidden in most languages (in fact i don't know other case). You can only create an object with a 'reference' to other object that can be initially null.
Part of this "disconnect" is because OWL describes an open world ontology. An Ontology has little or nothing to do with a program, other than a program can manipulate an ontology.
Trying to relate OWL concepts to programming languages is like trying to relate A Pianist and A Piano Sonata.
The sonata doesn't really have a concrete manifestion until someone is playing it -- ideally a Pianist, but not necessarily. Until it's being played, it's just potential relationships among notes manifested as sounds. When it's being played, some of actual relationships will be relevant to you, the listener. Some won't be relevant to the listener.