POSC Specifications
Version 3.0
Epicentre Modeling Methodology

Meta Type Syntax

Introduction

This document defines a set of extensions to the EXPRESS Version 1 specification for the purpose of supporting a meta type. A meta type declaration specifies a template for a related set of attributes and for the rules that constrain the attributes within the context of the meta type. The specification is patterned after ENTITY (without an inverse clause) but it also allows a constrained (i.e., only simple types) variation of a FUNCTION style parameter list. This is comparable to the behavior of REAL, BINARY and STRING that have predefined parameters. While an entity is intended to represent some real world object, a meta type is intended to represent data that is not visible outside the context of a parent entity. That is, a meta type instance cannot exist except as a direct or indirect child of an entity instance. The intended behavior is comparable to replicating the elements into the owning entity as individual attributes with appropriately qualified names and with appropriate domain rules. The semantically explicit constraints provided by the meta type are much simpler than would be required if using only domain rules. The term element is used in order to avoid confusion with an entity attribute.

EXPRESS Syntax

The rules and restrictions on the meta components are intended to be consistent with the behavior of entity components. Those rules will not be recast in modified form (e.g., by substituting meta type for entity and element for attribute). Only points of behavioral difference will be enumerated.

Meta Type

Syntax:

--- | meta_decl = meta_head meta_body END_META_TYPE ';' .
--- | meta_head = META_TYPE meta_id [ meta_parameter_list ] [ meta_subsuper ] ';' .
--- | meta_parameter_list = '('  meta_formal_parameter { ';'  
                            meta_formal_parameter } ')' .
--- | meta_body = { meta_element } [ meta_derive_clause ] [ meta_unique_clause ] 
                  [ where_clause ] .
--- | meta_formal_parameter = meta_parameter_id  { ',' meta_parameter_id } ':' 
                              simple_types .
--- | meta_parameter_id = simple_id .
--- | meta_id = simple_id .
315 | where_clause = WHERE domain_rule ';' { domain_rule ';' } .
--- | meta_reference = meta_ref [ actual_parameter_list ] .
157 | actual_parameter_list = '(' parameter { ',' parameter } ')' .
--- | meta_ref = meta_id .

Rules and Restrictions

  1. The number and type of the actual parameters shall agree with the formal parameters defined for that meta type.
  2. Parameters can only be referenced as parameters to functions or other types or as part of a WHERE expression.
  3. A formal parameter list can only be specified once within a supertype/subtype hierarchy. That is, a meta type which has a formal parameter list cannot also inherit one.
  4. Meta types are nestable. That is, an element within a meta type may have a base type which is itself a meta type.
  5. Meta types may be recursive. That is, within a hierarchical nesting of meta types, a meta type may encounter itself. Infinite recursion is not allowed.

Meta Element

Syntax:

--- | meta_element = meta_elem_decl { ',' meta_elem_decl } ':' [ OPTIONAL ] 
                     base_type ';' .
--- | meta_elem_decl = meta_elem_id | meta_qualified_elem .
--- | meta_elem_id = simple_id .
--- | meta_qualified_elem = SELF meta_group_qualifier meta_elem_qualifier .
--- | meta_group_qualifier = '\' meta_ref .
--- | meta_elem_qualifier = '.' meta_element_ref .
--- | meta_element_ref = meta_id . 

Rules and Restrictions

  1. A unique aggregate (e.g., a SET) of meta types requires knowledge of uniqueness within the meta type. If a UNIQUE rule is not defined within the meta type then all elements of the meta type must be compared. Note that all meta type instances in the aggregate will inherently be different instances.

Meta Supertypes and Subtypes

Syntax:

--- | meta_subsuper = [ meta_super_constraint ] [ meta_sub_declaration ] .
--- | meta_sub_declaration = SUBTYPE OF '(' meta_ref { ',' meta_ref } ')' .
--- | meta_super_constraint = meta_abstract_super_decl | meta_super_rule .
--- | meta_abstract_super_decl = ABSTRACT SUPERTYPE [ meta_subtype_constraint ] . 
--- | meta_subtype_constraint = 'OF' '(' meta_super_expression ')' .
--- | meta_super_expression = ONEOF '(' meta_ref { ',' meta_ref } ')' . 
--- | meta_super_rule = SUPERTYPE meta_subtype_constraint .

Rules and Restrictions:

  1. Supertype is constrained to ONEOF behavior but the syntax is constructed in a manner such that ANDOR and AND could be added in a backward compatible manner.

Meta Derived Element

Syntax:

--- | meta_derive_clause = DERIVE meta_derived_elem { meta_derived_elem } .
--- | meta_derived_elem = meta_elem_decl ':' base_type ':=' expression ';' .

Meta Unique Rule

Syntax:

--- | meta_unique_clause = UNIQUE meta_unique_rule ';' { 
                           meta_unique_rule ';' } .
--- | meta_unique_rule = [ label ':' ] meta_referenced_elem { ',' 
                         meta_referenced_elem } .
--- | meta_referenced_elem = meta_element_ref | meta_qualified_elem .

Rules and Restrictions

  1. Uniqueness spans some collection of meta type instances. This will typically be an aggregate of a meta type. Within the collection, the named element, or combination of elements, shall be different throughout.
  2. If a meta type has a uniqueness clause, then a non-unique aggregate of that meta type cannot be declared.

Meta Path

A meta path expands certain usages of entity_ref. A meta path is an ordered collection of named nodes along a hierarchical path that starts at an entity instance. A meta path may represent a collection of meta type instances but each node in the path only represents a single instance from among the instances available at that point in the hierarchy. The path qualifier allows an interior node in the path (i.e., an element of the collection) to be referenced.

Syntax:

--- | meta_path = entity_ref '.' attribute_ref { '.' meta_element_ref } .
--- | meta_path_qualifier = '[' ( meta_path | entity_ref |
                            ( attribute_ref { '.' meta_element_ref } ) | 
                            ( meta_element_ref { '.' meta_element_ref } ) ) ']' .

Rules and Restrictions

  1. Each node in the path must represent a compound type (i.e., meta type or entity). The first node in the path represents an entity instance (chosen from the available collection of entity instances). The second and subsequent nodes in the path must represent a meta type instance. The terminating node in the meta path must represent an instance from an aggregate of meta type instances. The only exception is when used as the base type of an inverse.
  2. The type of the meta path is the type of the terminating meta type.
  3. The path qualifier must be unique within the context of the path. If a name is not unique within the path then the name must be prefixed until the node is uniquely identified. The final name in the list represents the referenced node. If a non-unique name is specified, then the first occurrence of that name in the path will be assumed (this assumption is required so the first node in the path can be referenced).

Express Modifications

The following modifications integrate the new syntax into the existing Express syntax. The extensions are displayed in bold.

Syntax:

171 | base_type = aggregation_types | simple_types | named_types | 
                  meta_path .
189 | declaration = entity_decl | function_decl | procedure_decl | type_decl | 
                    meta_decl .
234 | inverse_attr = attribute_decl ';' [ ( SET | BAG ) [ bound_spec ] OF ] 
                     ( entity_ref FOR attribute_ref | 
                     meta_path FOR meta_element_ref ) ';' .
245 | named_types = entity_ref | type_ref | meta_reference .
246 | named_type_or_rename = ( entity_ref | type_ref | meta_ref ) 
                             [ AS ( entity_id | type_id | meta_id ) ] .
261 | qualifiable_factor = attribute_ref | constant_factor | function_call |
                           general_ref | population | meta_element_ref .
263 | qualifier = attribute_qualifier | group_qualifier | index_qualifier | 
                  meta_elem_qualifier | meta_group_qualifier | 
                  meta_path_qualifier .
275 | resource_ref = constant_ref | entity_ref | function_ref | procedure_ref | 
                     type_ref | meta_ref .
309 | underlying_type = constructed_types | aggregation_types | simple_types | 
                        type_ref | meta_reference .

Rules and Restrictions

  1. For an inverse attribute, the terminating node in the meta path does not have to be an aggregate (i.e., it can have an implied upper bound of one).

Real World Example

This example captures the logical content of the OpenGis Well Known Binary (WKB) data structure. The byte order has been excluded since it is an artifact of the physical implementation.

   META_TYPE Point;
      x, y : REAL(10);
   END_META_TYPE;
   
   META_TYPE LinearRing;
      points : LIST[2:?] OF Point
      (*The first point is topologically connected to the last point.*);
   END_META_TYPE;
   
   META_TYPE WKBGeometry ABSTRACT SUPERTYPE OF ( ONEOF
     (WKBPoint, WKBLineString, WKBPolygon, WKBGeometryCollection,
      WKBMultiPoint, WKBMultiLineString, WKBMultiPolygon) );
   END_META_TYPE;
   
   META_TYPE WKBPoint SUBTYPE OF (WKBGeometry);
      point : Point;
   END_META_TYPE;
   
   META_TYPE WKBLineString SUBTYPE OF (WKBGeometry);
      points : LIST[2:?] OF Point;
   END_META_TYPE;
   
   META_TYPE WKBPolygon SUBTYPE OF (WKBGeometry);
      rings : LIST[1:?] OF LinearRing
      (*The first ring is the outer boundary.*);
   END_META_TYPE;
   
   META_TYPE WKBMultiPoint SUBTYPE OF (WKBGeometry);
      wkbPoints : SET[1:?] OF WKBPoint;
   END_META_TYPE;
   
   META_TYPE WKBMultiLineString SUBTYPE OF (WKBGeometry);
      wkbLineStrings : SET[1:?] OF WKBLineString;
   END_META_TYPE;
   
   META_TYPE WKBMultiPolygon SUBTYPE OF (WKBGeometry);
      wkbPolygons : SET[1:?] OF WKBPolygon;
   END_META_TYPE;
   
   META_TYPE WKBGeometryCollection SUBTYPE OF (WKBGeometry);
      wkbGeometries : SET[1:?] OF WKBGeometry;
   END_META_TYPE;

Conversion to standard EXPRESS

A schema that has been produced using the meta type syntax can be projected into an alternative schema that conforms to EXPRESS Version 1 syntax. The resulting alternative schema should be semantically equivalent to the original schema. That is, it should be possible to store the same information in either variant without loss of business semantics.

Convert to Entity

The simplest way to create a schema conforming to EXPRESS Version 1 syntax is to mechanically:

  1. Change META_TYPE to ENTITY.
  2. Convert formal meta type parameters to attributes of the new entity.
  3. Delete parameters from meta type invocations (these will now be entity invocations). This information will become attribute values in the referenced entity instance.
  4. Convert all inverse attributes with the same meta path and attribute to a single inverse attribute.
  5. Replace all meta paths with the type of the terminating collection.
  6. Properly qualify all domain rules that contain meta paths.

While a schema produced in this manner will be syntactically correct, it will be semantically incomplete because it will lack the ability to insure that each entity instance of a former meta type is only referenced from one parent. In order to make the resulting model semantically complete, the new entity must be modified by:

  1. Creating an inverse attribute for each invocation of the meta type (i.e., the new entity). The upper bound for the aggregate must be one.
  2. Creating a mandatory select one domain rule on the new inverse attributes. This insures that the meta type instance is only referenced from one parent.
  3. Adding the new inverse attributes to any existing uniqueness clause.
  4. Adding a domain rule to insure that the proper parameter values have been instantiated for each instantiated inverse. Alternatively, this can be added to the calling entity.
  5. A non-unique aggregate of a meta type that does not have an inherent uniqueness constraint will require the addition of an aggregate index attribute that must be added to the uniqueness clause of the new entity. Again, this is to insure that an instance can only be referenced once.

For example, the following extended EXPRESS snippet:

   ENTITY ent; 
      first  : val_pair(6);
      second : OPTIONAL SET[0:?] OF val_pair(9); 
      inflection : OPTIONAL ent.second
      (*The inflection point in the set. In a true real world example of an
      inflection point, the aggregate on second would need to be some form of 
      a LIST. However, for this example, the SET aggregate was chosen 
      in order to demonstrate that SET must sometimes be projected as LIST.*);
   WHERE
      inflection_valid  : inflection[ent] :=: self;
   END_ENTITY;

   ENTITY unit_of_measure; 
      identifier  : string;
   INVERSE
      valpair_first  : SET[0:?] OF ent.first FOR uom; 
      valpair_second : SET[0:?] OF ent.second FOR uom; 
   END_ENTITY;

   META_TYPE val_pair ( precision : INTEGER ); 
      elem1 : REAL(precision);
      elem2 : REAL(precision); 
      uom   : unit_of_measure; 
   UNIQUE
     si: elem1;
   WHERE
      pre: precision > 0;
      val: elem1 > elem2; 
   END_META_TYPE;

Is intended to be semantically equivalent to the following standard EXPRESS.

   ENTITY ent; 
      first : val_pair; 
      second: OPTIONAL SET[0:?] OF val_pair; 
      inflection : OPTIONAL val_pair;
   WHERE
      inflection_valid  : NOT EXISTS (inflection) OR 
                          (EXISTS(inflection.ent_second) AND 
                           (inflection.ent_second :=: self);
   END_ENTITY;

   ENTITY unit_of_measure; 
      identifier  : string;
   INVERSE
      valpair :  SET[0:?] OF val_pair FOR uom;
   END_ENTITY;

   ENTITY val_pair; 
      precision : INTEGER; 
      elem1     : REAL(precision);
      elem2     : REAL(precision); 
      uom       : unit_of_measure; 
   INVERSE
      ent_first  : SET[0:1] OF ent FOR first;
      ent_second : SET[0:1] OF ent FOR second;
   UNIQUE
     si: elem1, ent_first, ent_second;
   WHERE 
      val : elem1 > elem2;
      mse : EXISTS(ent_first) XOR EXISTS(ent_second)
        (*One or the other, but not both must be given.*);
      pre : (EXISTS(ent_first)  AND (precision=6)) OR
            (EXISTS(ent_second) AND (precision=9));
   END_ENTITY;

Convert to Attribute

Alternatively, the meta type pattern can be replicated as attributes and domain rules in the invoking entity with appropriately qualified names. For an aggregate of a meta type, either:

  1. Convert each individual element of the meta type to a LIST of the underlying type. The list is necessary in order to align the element tuples. If any of the elements are optional then either:
  2. Or assume an upper bound of the aggregate and create individual attribute sets for each position in the aggregate. For example, if the expected upper bound of the above SET were 2, then 2 triplets of elem1,elem2,uom attributes would be created (e.g., second1_elem1, second1_elem2, second1_uom, second2_elem1, second2_elem2, second2_uom).

For meta paths to an aggregate of meta type, a pair of attributes will be required. One attribute will point to the instance and one attribute will indicate the element in the aggregate.

For example, the following is also semantically equivalent to the above extended EXPRESS snippet. The precision parameter does not need to be checked because it was logically checked at the time of replication. While the schema retains the business semantics of the original schema, some of the modeling logic has been moved to the application software (e.g., that the elements of the LISTs should be aligned).

   ENTITY ent; 
      first_elem1    : REAL(6);
      first_elem2    : REAL(6);
      first_uom      : unit_of_measure;
      second_elem1   : OPTIONAL LIST[0:?] OF UNIQUE REAL(9)
        (*Unique because SET is unique.*);
      second_elem2   : OPTIONAL LIST[0:?] OF        REAL(9)
        (*Non-unique because it was not part of the uniqueness clause.*);
      second_uom     : OPTIONAL LIST[0:?] OF        unit_of_measure;  
      inflection_idx : OPTIONAL INTEGER
        (*A second attribute that points to this instance is not needed.*);
   WHERE
      first_valid      : first_elem1 > first_elem2;
      second_valid     : val_pair_list_valid (second_elem1, second_elem2, second_uom);
      inflection_valid : EXISTS(second_elem1) OR 
                         (EXISTS(second_elem1)=EXISTS(inflection_idx));
   END_ENTITY;

   ENTITY unit_of_measure; 
      identifier  : string;
   INVERSE
      valpair_first  : SET[0:?] OF ent FOR first_uom; 
      valpair_second : BAG[0:?] OF ent FOR second_uom;
   END_ENTITY;

   FUNCTION val_pair_list_valid (elem1 : LIST[0:?] OF REAL;
                                 elem2 : LIST[0:?] OF REAL;
                                 uom   : LIST[0:?] OF unit_of_measure) : BOOLEAN;
   -- Return FALSE if the list of val_pair elements is not valid.
     IF ( EXISTS(elem1) OR EXISTS(elem2) OR EXISTS(uom) ) THEN
       IF ( (NOT EXISTS(elem1)) OR (NOT EXISTS(elem2)) OR (NOT EXISTS(uom)) ) THEN
       -- All must be given.
         RETURN (FALSE);
       END_IF;
       IF ( (LOINDEX(elem1)<>LOINDEX(elem2)) OR
            (HIINDEX(elem1)<>HIINDEX(elem2)) OR
            (LOINDEX(elem1)<>LOINDEX(uom)) OR
            (HIINDEX(elem1)<>HIINDEX(uom)) ) THEN
       -- Must have a one-to-one correspondence.
         RETURN (FALSE);
       END_IF;
       REPEAT i := LOINDEX(elem1) TO HIINDEX(elem1);
         IF ( NOT(elem1[i] > elem2[i]) ) THEN
         -- Element 1 must be greater than element 2.
           RETURN (FALSE);
         END_IF;
       END_REPEAT;
     END_IF;
     RETURN (TRUE);
   END_FUNCTION;

Convert to Entity and/or Attribute

A third option is a combination of the previous two conversion techniques. For example, convert the relatively simple meta types to attributes and convert the more complex meta types to entities. Within the same projected model, the same simple meta type might sometimes be converted to attributes and sometimes be converted to an entity (e.g., for an aggregate).

Other Thoughts

An entity is a compound type that is inherently a collection (of instances) with visibility within the context of a schema. A meta type is a compound type that is inherently singular and has visibility within the context of a parent entity. A nested entity could be defined as a variation of these two concepts. Namely, a compound type that is inherently a collection but with visibility within the context of a parent entity. It would allow an inverse clause but not a parameter list. A nested entity would inherently be defined within the context of a single parent (i.e., it could only be invoked once and thus could not be recursive).

With three almost identical data structures, these concepts could be better integrated by eliminating any distinction between explicit attribute and meta element. This would be easier to do if the meta path concept was generalized into an instance path where an entity type could exist at any point in the path. The instance path would basically replace entity_ref in attributes and selects. An upside to this is that it would allow business semantics to be explicitly assigned to an element of an aggregate. These semantics would represent membership in the aggregate rather than being a fundamental characteristic of the instance.

These concepts could become extremely powerful mechanisms if officially incorporated into EXPRESS because they would allow support for user defined types and for hierarchical models. A hierarchical model is most useful for data that is not intended to be visible outside the context of a parent. An example would be the information contained within a graphical image of an object.


Copyright 2001 POSC. All rights reserved.