Look at this picture.
This is not what object-oriented programming is about. OOP is not about some kind of universal classification mechanism.
The Circle-Elipse discussion pops up on OOP lists more than once a year. The problem is that OOP is not supposed to resolve all knowledge representation issues. There is no OOP notation that can be used to represent all relationships I can imagine.
OOP is about computation, and so a Rectangle class in Smalltalk is not a "Rectangle" by the mathematical definition. The class Rectangle is a solution to a problem that is narrower than the mathematical definition.
OOP is a tool for solving computational problems, and so in any given system it may serve my purposes to have more than one kind of Rectangle class (in Smalltalk, I'd use namespaces to refer to specific classes). I would implement each class to solve a specific problem.
Whether or not I make some class named Circle be a subclass of some class named Elipse should be a decision made within the context of a specific computational problem.
So we should put this discussion to rest and deal with the real problem of OOP: even as a computational notation, modern OOPs are by and large too complex. They make us say more than is necessary to solve most problems they're applied to. Forget the Elipse-Circle discussion. There are real problems to deal with.