POSC Specifications Version 3.0 |
Epicentre Modeling Methodology |
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.
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.
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 . |
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 . |
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 . |
Syntax: --- | meta_derive_clause = DERIVE meta_derived_elem { meta_derived_elem } . --- | meta_derived_elem = meta_elem_decl ':' base_type ':=' expression ';' . |
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 . |
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 } ) ) ']' . |
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 . |
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;
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.
The simplest way to create a schema conforming to EXPRESS Version 1 syntax is to mechanically:
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:
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;
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:
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;
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).
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.