views:

184

answers:

6

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 ?

+1  A: 

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.

anthares
No, subclassing doesn't work that way in Python. An instance of a subclass doesn't create or contain an instance of the superclass.
Thomas Wouters
it kind of make sense... if I hear what you are saying, it's because you have code to execute, while OWL is only related to description of logic relationships among entities. in the latter case, mutual subclassing does not introduce any ambiguity, it will just be handled at the logical level.
Stefano Borini
+7  A: 

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 and object. object is an instance of type, and type is a subclass of object. And of course, type is also an instance of type (since it's a subclass of object). 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.

Thomas Wouters
You are indicating that no consistent ruleset for mutual inheritance exists. Can you elaborate why that is so?
bayer
I don't intend to indicate that. A consistent ruleset for MI does exist. Python follows the C3 algorithm for MI. A MI hierarchy is basically flattened to create a sensible (and predictable) MRO. C3 forbids ambiguous situations, however, like inheritance cycles and inconsistent baseclass ordering between baseclasses.
Thomas Wouters
C3 algorithm... hmmm... I feel so ignorant, so often :( googling...
Stefano Borini
http://www.python.org/download/releases/2.2.3/descrintro/ is a good resource.
Thomas Wouters
A: 

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.

bayer
+2  A: 

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"

unutbu
+2  A: 

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.

S.Lott
What I am doing right now is that I am describing entities according to an ontology. These entities are mapped to classes. Of course, if the ontology contains mutual subclasses I cannot map those owl classes to program classes. I know that I am using the wrong approach, but at the moment, with the resources I have, the constraints I have and the time I have, it's the best I can do. Fortunately, I have no such cases, and my ontology is simple, so I can produce the class mapping by hand.
Stefano Borini
Most times we define our entities and ontology *outside* our code. We write our code to reason about the entities using the ontology rules to classify the entities. Your fundamental question stems from observing that an Ontology richer than an OO programming language. This points up the problem of trying to generate code from ontology. Generating code from ontology can **only** be done by using the ontology to guide to reasoning as you create code.
S.Lott
Thank you @S.Lott, your comment was very interesting.
Stefano Borini
+1  A: 

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.

Phil M