MathStructures.mesa
Copyright © 1989 by Xerox Corporation. All rights reserved.
Arnon, August 28, 1989 1:42:36 pm PDT
DIRECTORY
SafeStorage,
IO,
Atom,
Rope,
Basics,
MathObjects;
MathStructures: CEDAR DEFINITIONS
= BEGIN
Types From Referenced Interfaces
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
Object: TYPE = MathObjects.Object;
MethodDictionary: TYPE = MathObjects.MethodDictionary;
Structure Types
By a "Structure:" we mean a Domain, View, or Category (as distinct from an "Element" of some Domain or View).
Category: TYPE = Object;
Domain: TYPE = Object;
View: TYPE = Object;
We expect that .class of an "Element" is a Domain or View, .class of a Domain or View is a Category, and .class of a Category is a special global system Object Categories (= set of all Categories; implemented much like any other Structure).
The .class of any Element, Domain, View, or Category Object is assumed to have a $flavor method that will report that Object's flavor. The special Object Categories should never be manipulated by anyone other than the system, so there should be no need to report its flavor (which we can regard either as undefined, or as "meta").
Also, the .class of any Element, Domain, View, or Category Object is assumed to have a $methods method, which can report all the methods (i.e. the "MethodDictionary", whatever it is), of that class. This $methods "selector" is the one and only means by which a client or user gets access to a class's MethodDictionary (although there could be distinct client and user versions of the method).
We expect that the .data field of a Element, Domain, View, or Category Object will record optional structure-specific data, e.g. a View should save its "underlying" Domain, Domains and Categories may have "properties", e.g. we may attach axioms to a Category.
When a Domain or View or Category is instantiated, we get a link Domain/View -> Category via the .class field. This is an instance of the "isAnElementOf" relation that in general we want an Object's .class field to express. In this case it may be of use for inheritance, in that Domains can "inherit" methods from a Category they belong to. However, we view it as merely a particular favored "basic" inheritance relation. In general, (multiple) inheritance is supported via the global Domain and Category lattices, that record all "isASubsetOf" relations among Domains and Categories, respectively. There is a certain consistency assumed between these lattices and the capabilities of the Domains and Categories involved in them. If we are trying to recast (an element of) Domain or Category S as (an element of) S', and if there is path from S to S' in the global lattice, then we assume that by (e.g. depth-first or breadth-first) search of the Widen or Narrow (depending on the direction of the path) edges rooted at S', we will find a "path" of procs which can be composed to actually do the recasting. Thus in general, the "transitive closure" of the Widen or Narrow "edges" rooted at a Structure S comprise a subgraph of one of the global lattices. The possible partiality of this subgraph is the major reason for the use of the global lattices: they give us a single place to express the full multiplicity of relationships among the Structures that are their nodes.
Note that a Domain's .class field creates one, and only one, link between the Domain and Category lattices. We can, if appropriate, put in more such links (in a sense, this is the whole point of Views). Thus in fact, the Domain and Category lattices are linked, and can be thought of as a single lattice.
A Domain should always be able to make a View of itself as a member of its category. This should normally be straightforward: the Category methods should be a subset of the Domain methods, with identical names. We may even go so far as to say that the elements of Categories ARE Views; setting the Class field of a Domain to point to a Category is just a "lazy" binding; it is becomes meaningful when we create the View of the Domain as a member of that Category.
Given a category C, a View V that is a member of C, and a (direct) supercategory C' of C, C should always know how to create a new View V' which is a View of V as a member of C'. This will typically involve retaining a subset of V's methods, and possibly giving some of them new names. We call this capability the "ViewWiden" method of C'. If C is not a direct subcategory of C', then we simply compose the ViewWiden methods along a chain of intermediate subcategories.
Perhaps in general, Widen and Narrow procs should not reside in Structures; they are more properly thought of as labels on edges in the global lattices. Hence when a Domain is instantiated, it should
1) create a node for itself in the Domain lattice
2) identify (Narrow and Widen) edges in the Domain lattice of which its a vertex, and provide a proc for each such edge. There should be a precedence ordering among the Narrow edges, and among the Widen edges, to guide searches.
3) provide at least one link (edge) from itself as a node in the Domain lattice, to a node of the Category lattice, together with a ViewAs proc for each such edge. Its .class field is one such link (except does not provide the ViewAs proc per se). Again, there should be a precedence ordering among these edges.
When a Category is instantiated, it should
1) create a node for itself in the Category lattice
2) identify (Widen) edges in the Category lattice of which its a vertex, and provide a proc for each such edge. (Narrow procs seem impossible for Categories; e.g. for Ring -> ID, how do you give a proc that determines whether a given Ring has zero divisors?). There should be an ordering among these Widen edges.
Some global proces may, from time to time, crawl over all links from the Domain lattice into the Category lattice, and update the aggregate of all "back" links from nodes of the Category lattice to nodes of the Domain lattice. This can be regarded as system data, namely the ability to report all currently instantiated Domains that can be viewed as elements of a particular Category (transitive closure in the Category graph should of course be used to generate the full such list).
There should be allowance for "equipotent" nodes in (at least) the Domain lattice, typically arising from Domains which are multiple representations for the same mathematical domain. Each such pair can be both "widened" and "narrowed" to each other.
END.