Chris.Holt@newcastle.ac.uk (Chris Holt) (02/11/91)
bertrand@eiffel.UUCP (Bertrand Meyer) writes: [about the example of:] > VEHICLE DRIVER > ^ ^ > | | > | | > | | > | | > TRUCK PROFESSIONAL_DRIVER I start from the (generally accepted?) idea that an object comprises a (possibly structured) value, together with operations that may take that value as an argument to return a result. Note that as far as I am concerned, the result is a *different* object. Thus, given the value 2 and the operations pred and succ, the result of applying succ yields the object (3, pred, succ). Objects are partially ordered, both by value and by operations. One might say that the cross-product of two objects is "greater" than either; taking the union of two objects yields a "greater" object; and adding an operation to an object yields a "greater" object. Given an object that is the union of others, adding an operation to any component yields a "greater" object; this corresponds to extending the domain of that operation. A type is a union of objects, in this fashion. The rectangle/polygon relation thus has 4 components: 1. Rect = union of rectangles, none of which have AddVertex as an operation. 2. Rect+ = union of rectangles, all of which have AddVertex. 3. Poly = union of polygons, none of which have AddVertex. 4. Poly+ = union of polygons, all of which have AddVertex. I.e. Poly+ / \ / \ Poly Rect+ \ / \ / Rect Note that there are many intermediate types; also, Rect+ isn't closed under AddVertex. The declaration/association of a variable with a type is an assertion that throughout the scope of that variable, its use returns a value of the given type. Thus, where P+, P, R+, and R are the obvious variables, and SubAddVertex and AddAddVertex coerce the types (e.g. SubAddVertex maps Poly+ -> Poly), we have: P+ := AddAddVertex(P) -- adding the operation P+ := R+ -- since a value in Rect+ must be in Poly+ R+ := P+ -- works only if P+ holds a rectangle R+ := AddAddVertex(R) -- adding the operation P := R -- since a value in Rect must be in Poly P := SubAddVertex(R+) -- removing the operation R+ := AddAddVertex(P) -- works only if P holds a rectangle etc. Back to Trucks, Vehicles, Professional_Drivers, and Drivers: As noted, we have Trucks < Vehicles Professional_Drivers < Drivers Given that: >In class VEHICLE there is a procedure > register (d: DRIVER) is > -- Register `d' as driver of current vehicle > do > ... > end -- register This would suggest to me that there is a type Driven_Vehicles such that register : Vehicles x Drivers -> Driven_Vehicles, and Vehicles < Driven_Vehicles Drivers < Driven_Vehicles. Then the operation register is associated with both Vehicles and Drivers. This operation has a sub-operation, sub_register, that is exactly like register except that it only operates on the particular sub-domains: sub_register : Trucks x Professional_Drivers -> Driven_Trucks. One might then define an operator coercion Extend, such that Extend(sub_register) = register, or one might make this coercion implicit. In fact, one might avoid the need for sub_register as a separate function, by being more finicky about the domains of register: register: (Trucks x Professional_Drivers -> Driven_Trucks) U (Vehicles-Trucks x Drivers -> Driven_Non-trucks). Then, register(Truck,Non-professional_Driver) is undefined, and returns a bottom value. > Any theoretician willing to stand up >for the practical consequences of his mathematical models? I don't know if this counts, but it seems consistent to me. :-) ----------------------------------------------------------------------------- Chris.Holt@newcastle.ac.uk Computing Lab, U of Newcastle upon Tyne, UK ----------------------------------------------------------------------------- "[War's] glory is all moonshine... War is hell." - General Sherman, 1879