1SCHEMA engineering_properties_schema;
2(* ***********************************
3Constants in the schema engineering_properties_schema
4*********************************** *)
5
6
7   CONSTANT
8      dummy_gri : geometric_representation_item := representation_item('') || geometric_representation_item();
9      schema_prefix : STRING := 'ENGINEERING_PROPERTIES_SCHEMA.';
10      the_booleans : elementary_space := make_elementary_space(es_booleans);
11      the_empty_maths_tuple : maths_tuple := [];
12      the_empty_space : finite_space := make_finite_space([]);
13      the_complex_numbers : elementary_space := make_elementary_space(es_complex_numbers);
14      the_generics : elementary_space := make_elementary_space(es_generics);
15      the_integers : elementary_space := make_elementary_space(es_integers);
16      the_logicals : elementary_space := make_elementary_space(es_logicals);
17      the_numbers : elementary_space := make_elementary_space(es_numbers);
18      the_reals : elementary_space := make_elementary_space(es_reals);
19      the_strings : elementary_space := make_elementary_space(es_strings);
20      the_zero_tuple_space : listed_product_space := make_listed_product_space([]);
21      the_complex_tuples : extended_tuple_space := make_extended_tuple_space(the_zero_tuple_space, the_complex_numbers);
22      the_integer_tuples : extended_tuple_space := make_extended_tuple_space(the_zero_tuple_space, the_integers);
23      the_neg1_one_interval : finite_real_interval := make_finite_real_interval(-1.00000, closed, 1.00000, closed);
24      the_nonnegative_reals : real_interval_from_min := make_real_interval_from_min(0.00000, closed);
25      the_real_tuples : extended_tuple_space := make_extended_tuple_space(the_zero_tuple_space, the_reals);
26      the_binarys : elementary_space := make_elementary_space(es_binarys);
27      the_maths_spaces : elementary_space := make_elementary_space(es_maths_spaces);
28      the_neghalfpi_halfpi_interval : finite_real_interval := make_finite_real_interval(-0.500000 * 3.14159, closed, 0.500000 * 3.14159, closed);
29      the_negpi_pi_interval : finite_real_interval := make_finite_real_interval(-3.14159, open, 3.14159, closed);
30      the_tuples : extended_tuple_space := make_extended_tuple_space(the_zero_tuple_space, the_generics);
31      the_zero_pi_interval : finite_real_interval := make_finite_real_interval(0.00000, closed, 3.14159, closed);
32   END_CONSTANT;
33
34
35(* ***********************************
36Entities in the schema engineering_properties_schema
37*********************************** *)
38
39   ENTITY SQL_mappable_defined_function
40   ABSTRACT SUPERTYPE
41   SUBTYPE OF (defined_function);
42   END_ENTITY;
43
44   ENTITY abs_function
45   SUBTYPE OF (unary_function_call);
46   END_ENTITY;
47
48   ENTITY absorbed_dose_measure_with_unit
49   SUBTYPE OF (measure_with_unit);
50   WHERE
51      WR1:
52         'ENGINEERING_PROPERTIES_SCHEMA.ABSORBED_DOSE_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
53   END_ENTITY;
54
55   ENTITY absorbed_dose_unit
56   SUBTYPE OF (derived_unit);
57   WHERE
58      WR1:
59         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.gray);
60   END_ENTITY;
61
62	ENTITY si_absorbed_dose_unit
63     SUBTYPE OF (absorbed_dose_unit,si_unit);
64  WHERE
65    WR1: SELF\si_unit.name = si_unit_name.gray;
66    WR2: NOT EXISTS(SELF\derived_unit.name);
67  END_ENTITY;
68
69   ENTITY abstracted_expression_function
70   SUBTYPE OF (maths_function, quantifier_expression);
71   DERIVE
72      SELF\quantifier_expression.variables : LIST [1:?] OF UNIQUE generic_variable := remove_first(SELF\multiple_arity_generic_expression.operands);
73      expr : generic_expression := SELF\multiple_arity_generic_expression.operands[1];
74   WHERE
75      WR1:
76         SIZEOF(QUERY (operand <* SELF\multiple_arity_generic_expression.operands| NOT has_values_space(operand))) = 0;
77   END_ENTITY;
78
79   ENTITY acceleration_measure_with_unit
80   SUBTYPE OF (measure_with_unit);
81   WHERE
82      WR1:
83         'ENGINEERING_PROPERTIES_SCHEMA.ACCELERATION_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
84   END_ENTITY;
85
86   ENTITY acceleration_unit
87   SUBTYPE OF (derived_unit);
88   WHERE
89      WR1:
90         derive_dimensional_exponents(SELF) = dimensional_exponents(1.00000, 0.00000, -2.00000, 0.00000, 0.00000, 0.00000, 0.00000);
91   END_ENTITY;
92
93   ENTITY acos_function
94   SUBTYPE OF (unary_function_call);
95   END_ENTITY;
96
97   ENTITY action;
98      name : label;
99      description : OPTIONAL text;
100      chosen_method : action_method;
101   DERIVE
102      id : identifier := get_id_value(SELF);
103   WHERE
104      WR1:
105         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ID_ATTRIBUTE.IDENTIFIED_ITEM')) <= 1;
106   END_ENTITY;
107
108   ENTITY action_assignment
109   ABSTRACT SUPERTYPE;
110      assigned_action : action;
111   DERIVE
112      role : object_role := get_role(SELF);
113   WHERE
114      WR1:
115         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ROLE_ASSOCIATION.ITEM_WITH_ROLE')) <= 1;
116   END_ENTITY;
117
118   ENTITY action_directive;
119      name : label;
120      description : OPTIONAL text;
121      analysis : text;
122      comment : text;
123      requests : SET [1:?] OF versioned_action_request;
124   END_ENTITY;
125   ENTITY action_method;
126      name : label;
127      description : OPTIONAL text;
128      consequence : text;
129      purpose : text;
130   END_ENTITY;
131
132   ENTITY action_method_relationship;
133      name : label;
134      description : OPTIONAL text;
135      relating_method : action_method;
136      related_method : action_method;
137   END_ENTITY;
138
139   ENTITY action_method_with_associated_documents
140   SUBTYPE OF (action_method);
141      documents : SET [1:?] OF document;
142   END_ENTITY;
143
144   ENTITY action_method_with_associated_documents_constrained
145   SUBTYPE OF (action_method_with_associated_documents);
146      usage_constraints : SET [1:?] OF document_usage_constraint;
147   WHERE
148      WR1:
149         SIZEOF(QUERY (item <* usage_constraints| NOT (item.source IN SELF\action_method_with_associated_documents.documents))) = 0;
150   END_ENTITY;
151
152   ENTITY action_property;
153      name : label;
154      description : text;
155      definition : characterized_action_definition;
156   END_ENTITY;
157
158   ENTITY action_property_relationship;
159      name : label;
160      description : text;
161      relating_action_property : action_property;
162      related_action_property : action_property;
163   WHERE
164      WR1:
165         relating_action_property :<>: related_action_property;
166   END_ENTITY;
167
168   ENTITY action_property_representation;
169      name : label;
170      description : text;
171      property : action_property;
172      representation : representation;
173   END_ENTITY;
174
175   ENTITY action_relationship;
176      name : label;
177      description : OPTIONAL text;
178      relating_action : action;
179      related_action : action;
180   END_ENTITY;
181
182   ENTITY action_request_assignment
183   ABSTRACT SUPERTYPE;
184      assigned_action_request : versioned_action_request;
185   DERIVE
186      role : object_role := get_role(SELF);
187   WHERE
188      WR1:
189         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ROLE_ASSOCIATION.ITEM_WITH_ROLE')) <= 1;
190   END_ENTITY;
191
192   ENTITY action_request_solution;
193     method : action_method;
194      request : versioned_action_request;
195   DERIVE
196      description : text := get_description_value(SELF);
197      name : label := get_name_value(SELF);
198   WHERE
199      WR1:
200         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
201      WR2:
202         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'NAME_ATTRIBUTE.NAMED_ITEM')) <= 1;
203   END_ENTITY;
204
205   ENTITY action_resource;
206      name : label;
207      description : OPTIONAL text;
208      usage : SET [1:?] OF supported_item;
209      kind : action_resource_type;
210   END_ENTITY;
211
212   ENTITY action_resource_relationship;
213      name : label;
214      description : OPTIONAL text;
215      relating_resource : action_resource;
216      related_resource : action_resource;
217   END_ENTITY;
218
219   ENTITY action_resource_requirement;
220      name : label;
221      description : text;
222      kind : resource_requirement_type;
223      OPERATIONS : SET [1:?] OF characterized_action_definition;
224   END_ENTITY;
225
226   ENTITY action_resource_requirement_relationship;
227      name : label;
228      description : text;
229      relating_action_resource_requirement : action_resource_requirement;
230      related_action_resource_requirement : action_resource_requirement;
231   WHERE
232      WR1:
233         relating_action_resource_requirement :<>: related_action_resource_requirement;
234   END_ENTITY;
235
236   ENTITY action_resource_type;
237      name : label;
238   END_ENTITY;
239
240   ENTITY action_status;
241      status : label;
242      assigned_action : executed_action;
243   END_ENTITY;
244
245   ENTITY address;
246      internal_location : OPTIONAL label;
247      street_number : OPTIONAL label;
248      street : OPTIONAL label;
249      postal_box : OPTIONAL label;
250      town : OPTIONAL label;
251      region : OPTIONAL label;
252      postal_code : OPTIONAL label;
253      country : OPTIONAL label;
254      facsimile_number : OPTIONAL label;
255      telephone_number : OPTIONAL label;
256      electronic_mail_address : OPTIONAL label;
257      telex_number : OPTIONAL label;
258   DERIVE
259      name : label := get_name_value(SELF);
260      url : identifier := get_id_value(SELF);
261   WHERE
262      WR1:
263         ((((((((((EXISTS(internal_location) OR EXISTS(street_number)) OR EXISTS(street)) OR EXISTS(postal_box)) OR EXISTS(town)) OR EXISTS(region)) OR EXISTS(postal_code)) OR EXISTS(country)) OR EXISTS(facsimile_number)) OR EXISTS(telephone_number)) OR EXISTS(electronic_mail_address)) OR EXISTS(telex_number);
264   END_ENTITY;
265
266   ENTITY amount_of_substance_measure_with_unit
267   SUBTYPE OF (measure_with_unit);
268   WHERE
269      WR1:
270         'ENGINEERING_PROPERTIES_SCHEMA.AMOUNT_OF_SUBSTANCE_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
271   END_ENTITY;
272
273   ENTITY amount_of_substance_unit
274   SUBTYPE OF (named_unit);
275   WHERE
276      WR1:
277         ((((((SELF\named_unit.dimensions.length_exponent = 0.00000) AND (SELF\named_unit.dimensions.mass_exponent = 0.00000)) AND (SELF\named_unit.dimensions.time_exponent = 0.00000)) AND (SELF\named_unit.dimensions.electric_current_exponent = 0.00000)) AND (SELF\named_unit.dimensions.thermodynamic_temperature_exponent = 0.00000)) AND (SELF\named_unit.dimensions.amount_of_substance_exponent = 1.00000)) AND (SELF\named_unit.dimensions.luminous_intensity_exponent = 0.00000);
278   END_ENTITY;
279
280   ENTITY and_expression
281   SUBTYPE OF (multiple_arity_boolean_expression);
282   END_ENTITY;
283
284   ENTITY angular_location
285   SUBTYPE OF (dimensional_location);
286      angle_selection : angle_relator;
287   END_ENTITY;
288
289   ENTITY angular_size
290   SUBTYPE OF (dimensional_size);
291      angle_selection : angle_relator;
292   END_ENTITY;
293
294   ENTITY angularity_tolerance
295   SUBTYPE OF (geometric_tolerance_with_datum_reference);
296   WHERE
297      WR1:
298         SIZEOF(SELF\geometric_tolerance_with_datum_reference.datum_system) < 3;
299   END_ENTITY;
300
301   ENTITY apex
302   SUBTYPE OF (derived_shape_aspect);
303   END_ENTITY;
304
305   ENTITY application_context;
306      application : label;
307   DERIVE
308      description : text := get_description_value(SELF);
309      id : identifier := get_id_value(SELF);
310   INVERSE
311      context_elements : SET [1:?] OF application_context_element FOR frame_of_reference;
312   WHERE
313      WR1:
314         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
315      WR2:
316         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ID_ATTRIBUTE.IDENTIFIED_ITEM')) <= 1;
317   END_ENTITY;
318
319   ENTITY application_context_element
320   SUPERTYPE OF (ONEOF(product_concept_context, product_context, product_definition_context));
321      name : label;
322      frame_of_reference : application_context;
323   END_ENTITY;
324
325   ENTITY application_context_relationship;
326      name : label;
327      description : OPTIONAL text;
328      relating_context : application_context;
329      related_context : application_context;
330   END_ENTITY;
331
332   ENTITY application_defined_function
333   SUBTYPE OF (maths_function);
334      explicit_domain : tuple_space;
335      explicit_range : tuple_space;
336      parameters : LIST OF maths_value;
337   WHERE
338      WR1:
339         expression_is_constant(explicit_domain);
340      WR2:
341         expression_is_constant(explicit_range);
342   END_ENTITY;
343
344   ENTITY applied_action_assignment
345   SUBTYPE OF (action_assignment);
346      item : action_item;
347   END_ENTITY;
348
349   ENTITY applied_action_request_assignment
350   SUBTYPE OF (action_request_assignment);
351      item : action_request_item;
352   END_ENTITY;
353
354   ENTITY applied_approval_assignment
355   SUBTYPE OF (approval_assignment);
356      item : approval_item;
357   END_ENTITY;
358
359   ENTITY applied_certification_assignment
360   SUBTYPE OF (certification_assignment);
361      item : certification_item;
362   END_ENTITY;
363
364   ENTITY applied_contract_assignment
365   SUBTYPE OF (contract_assignment);
366      item : contract_item;
367   END_ENTITY;
368
369   ENTITY applied_date_and_time_assignment
370   SUBTYPE OF (date_and_time_assignment);
371      item : date_and_time_item;
372   END_ENTITY;
373
374   ENTITY applied_date_assignment
375   SUBTYPE OF (date_assignment);
376      item : date_item;
377   END_ENTITY;
378
379   ENTITY applied_document_reference
380   SUBTYPE OF (document_reference);
381      item : document_item;
382   END_ENTITY;
383
384   ENTITY applied_document_usage_contraint_assignment
385   SUBTYPE OF (document_usage_constraint_assignment);
386      item : document_item;
387   END_ENTITY;
388
389   ENTITY applied_effectivity_assignment
390   SUBTYPE OF (effectivity_assignment);
391      item : effectivity_item;
392   END_ENTITY;
393
394   ENTITY applied_event_occurrence_assignment
395   SUBTYPE OF (event_occurrence_assignment);
396      item : event_occurred_item;
397   END_ENTITY;
398
399   ENTITY applied_external_identification_assignment
400   SUBTYPE OF (external_identification_assignment);
401      items : SET [1:?] OF external_identification_item;
402   WHERE
403      WR1:
404         NOT (SELF.role.name = 'version') OR item_correlation(SELF.items, [ 'EXTERNALLY_DEFINED_CLASS', 'EXTERNALLY_DEFINED_ENGINEERING_PROPERTY' ]);
405   END_ENTITY;
406
407   ENTITY applied_group_assignment
408   SUBTYPE OF (group_assignment);
409      items : SET [1:?] OF groupable_item;
410   END_ENTITY;
411
412   ENTITY applied_identification_assignment
413   SUBTYPE OF (identification_assignment);
414      item : identification_item;
415   END_ENTITY;
416
417   ENTITY applied_location_assignment
418   SUBTYPE OF (location_assignment);
419      item : location_item;
420   END_ENTITY;
421
422   ENTITY applied_location_representation_assignment
423   SUBTYPE OF (location_representation_assignment);
424      item : location_representation_item;
425   END_ENTITY;
426
427   ENTITY applied_organization_assignment
428   SUBTYPE OF (organization_assignment);
429      item : organization_item;
430   END_ENTITY;
431
432   ENTITY applied_organizational_project_assignment
433   SUBTYPE OF (organizational_project_assignment);
434      item : SET [1:?] OF organizational_project_item;
435   END_ENTITY;
436
437   ENTITY applied_person_and_organization_assignment
438   SUBTYPE OF (person_and_organization_assignment);
439      item : person_and_organization_item;
440   END_ENTITY;
441
442   ENTITY applied_person_assignment
443   SUBTYPE OF (person_assignment);
444      item : person_item;
445   END_ENTITY;
446   ENTITY applied_qualification_assignment
447   SUBTYPE OF (qualification_type_assignment);
448      item : qualification_item;
449   END_ENTITY;
450
451   ENTITY applied_security_classification_assignment
452   SUBTYPE OF (security_classification_assignment);
453      item : SET [1:?] OF security_classified_item;
454   END_ENTITY;
455
456   ENTITY applied_state_observed_assignment
457   SUBTYPE OF (state_observed_assignment);
458      item : state_observed_item;
459   END_ENTITY;
460
461   ENTITY applied_state_type_assignment
462   SUBTYPE OF (state_type_assignment);
463      item : state_item;
464   END_ENTITY;
465
466   ENTITY applied_time_interval_assignment
467   SUBTYPE OF (time_interval_assignment);
468      item : time_interval_item;
469   END_ENTITY;
470
471   ENTITY approval;
472      status : approval_status;
473      level : label;
474   END_ENTITY;
475
476   ENTITY approval_assignment
477   ABSTRACT SUPERTYPE;
478      assigned_approval : approval;
479   DERIVE
480      role : object_role := get_role(SELF);
481   WHERE
482      WR1:
483         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ROLE_ASSOCIATION.ITEM_WITH_ROLE')) <= 1;
484   END_ENTITY;
485
486   ENTITY approval_date_time;
487      date_time : date_time_select;
488      dated_approval : approval;
489   DERIVE
490      role : object_role := get_role(SELF);
491   WHERE
492      WR1:
493         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ROLE_ASSOCIATION.ITEM_WITH_ROLE')) <= 1;
494   END_ENTITY;
495
496   ENTITY approval_person_organization;
497      person_organization : person_organization_select;
498      authorized_approval : approval;
499      role : approval_role;
500   END_ENTITY;
501
502   ENTITY approval_relationship;
503      name : label;
504      description : OPTIONAL text;
505      relating_approval : approval;
506      related_approval : approval;
507   END_ENTITY;
508
509   ENTITY approval_role;
510      role : label;
511   DERIVE
512      description : text := get_description_value(SELF);
513   WHERE
514      WR1:
515         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
516   END_ENTITY;
517
518   ENTITY approval_status;
519      name : label;
520   END_ENTITY;
521
522   ENTITY area_measure_with_unit
523   SUBTYPE OF (measure_with_unit);
524   WHERE
525      WR1:
526         'ENGINEERING_PROPERTIES_SCHEMA.AREA_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
527   END_ENTITY;
528
529   ENTITY area_unit
530   SUBTYPE OF (derived_unit);
531   WHERE
532      WR1:
533         derive_dimensional_exponents(SELF) = dimensional_exponents(2.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000);
534   END_ENTITY;
535
536   ENTITY ascribable_state;
537      name : label;
538      description : OPTIONAL text;
539      pertaining_state_type : state_type;
540      ascribed_state_observed : state_observed;
541   END_ENTITY;
542   ENTITY ascribable_state_relationship;
543      name : label;
544      description : OPTIONAL text;
545      relating_ascribable_state : ascribable_state;
546      related_ascribable_state : ascribable_state;
547   END_ENTITY;
548
549   ENTITY asin_function
550   SUBTYPE OF (unary_function_call);
551   END_ENTITY;
552
553   ENTITY atan_function
554   SUBTYPE OF (binary_function_call);
555   END_ENTITY;
556
557   ENTITY atom_based_literal
558   SUBTYPE OF (generic_literal);
559      lit_value : atom_based_value;
560   END_ENTITY;
561
562   ENTITY attribute_classification_assignment
563   ABSTRACT SUPERTYPE;
564      assigned_class : group;
565      attribute_name : label;
566      role : classification_role;
567   END_ENTITY;
568
569   ENTITY attribute_language_assignment
570   SUBTYPE OF (attribute_classification_assignment);
571      items : SET [1:?] OF attribute_language_item;
572   DERIVE
573      language : label := SELF\attribute_classification_assignment.assigned_class.name;
574   WHERE
575      WR1:
576         SELF\attribute_classification_assignment.role.name IN [ 'primary', 'translated' ];
577      WR2:
578         'ENGINEERING_PROPERTIES_SCHEMA.' + 'LANGUAGE' IN TYPEOF(SELF\attribute_classification_assignment.assigned_class);
579   END_ENTITY;
580
581   ENTITY attribute_value_assignment
582   ABSTRACT SUPERTYPE;
583      attribute_name : label;
584      attribute_value : attribute_type;
585      role : attribute_value_role;
586   END_ENTITY;
587
588   ENTITY attribute_value_role;
589      name : label;
590      description : OPTIONAL text;
591   END_ENTITY;
592
593   ENTITY axis1_placement
594   SUBTYPE OF (placement);
595      axis : OPTIONAL direction;
596   DERIVE
597      z : direction := NVL(normalise(axis), dummy_gri || direction([ 0.00000, 0.00000, 1.00000 ]));
598   WHERE
599      WR1:
600         SELF\geometric_representation_item.dim = 3;
601   END_ENTITY;
602
603   ENTITY axis2_placement_2d
604   SUBTYPE OF (placement);
605      ref_direction : OPTIONAL direction;
606   DERIVE
607      p : LIST [2:2] OF direction := build_2axes(ref_direction);
608   WHERE
609      WR1:
610         SELF\geometric_representation_item.dim = 2;
611   END_ENTITY;
612
613   ENTITY axis2_placement_3d
614   SUBTYPE OF (placement);
615      axis : OPTIONAL direction;
616      ref_direction : OPTIONAL direction;
617   DERIVE
618      p : LIST [3:3] OF direction := build_axes(axis, ref_direction);
619   WHERE
620      WR1:
621         SELF\placement.location.dim = 3;
622      WR2:
623         NOT EXISTS(axis) OR (axis.dim = 3);
624      WR3:
625         NOT EXISTS(ref_direction) OR (ref_direction.dim = 3);
626      WR4:
627         (NOT EXISTS(axis) OR NOT EXISTS(ref_direction)) OR (cross_product(axis, ref_direction).magnitude > 0.00000);
628   END_ENTITY;
629
630   ENTITY b_spline_basis
631   SUBTYPE OF (maths_function, generic_literal);
632      degree : nonnegative_integer;
633      repeated_knots : LIST [2:?] OF REAL;
634   DERIVE
635      order : positive_integer := degree + 1;
636      num_basis : positive_integer := SIZEOF(repeated_knots) - order;
637   WHERE
638      WR1:
639         num_basis >= order;
640      WR2:
641         nondecreasing(repeated_knots);
642      WR3:
643         repeated_knots[order] < repeated_knots[(num_basis + 1)];
644   END_ENTITY;
645
646   ENTITY b_spline_function
647   SUBTYPE OF (maths_function, unary_generic_expression);
648      SELF\unary_generic_expression.operand : maths_function;
649      basis : LIST [1:?] OF b_spline_basis;
650   DERIVE
651      coef : maths_function := SELF\unary_generic_expression.operand;
652   WHERE
653      WR1:
654         function_is_table(coef);
655      WR2:
656         (space_dimension(coef.range) = 1) AND (number_superspace_of(factor1(coef.range)) = the_reals);
657      WR3:
658         SIZEOF(basis) <= SIZEOF(shape_of_array(coef));
659      WR4:
660         compare_basis_and_coef(basis, coef);
661   END_ENTITY;
662
663   ENTITY banded_matrix
664   SUBTYPE OF (linearized_table_function);
665      default_entry : maths_value;
666      below : INTEGER;
667      above : INTEGER;
668      order : ordering_type;
669   WHERE
670      WR1:
671         SIZEOF(SELF\explicit_table_function.shape) = 2;
672      WR2:
673         -below <= above;
674      WR3:
675         member_of(default_entry, factor1(SELF\linearized_table_function.source.range));
676   END_ENTITY;
677
678   ENTITY basic_sparse_matrix
679   SUBTYPE OF (explicit_table_function, multiple_arity_generic_expression);
680      SELF\multiple_arity_generic_expression.operands : LIST [3:3] OF maths_function;
681      default_entry : maths_value;
682      order : ordering_type;
683   DERIVE
684      index : maths_function := SELF\multiple_arity_generic_expression.operands[1];
685      loc : maths_function := SELF\multiple_arity_generic_expression.operands[2];
686      val : maths_function := SELF\multiple_arity_generic_expression.operands[3];
687   WHERE
688      WR1:
689         function_is_1d_table(index);
690      WR2:
691         function_is_1d_table(loc);
692      WR3:
693         function_is_1d_table(val);
694      WR4:
695         check_sparse_index_domain(index.domain, index_base, shape, order);
696      WR5:
697         check_sparse_index_to_loc(index.range, loc.domain);
698      WR6:
699         loc.domain = val.domain;
700      WR7:
701         check_sparse_loc_range(loc.range, index_base, shape, order);
702      WR8:
703         member_of(default_entry, val.range);
704   END_ENTITY;
705
706   ENTITY binary_boolean_expression
707   ABSTRACT SUPERTYPE OF (ONEOF(xor_expression, equals_expression))
708   SUBTYPE OF (boolean_expression, binary_generic_expression);
709   END_ENTITY;
710
711   ENTITY binary_function_call
712   ABSTRACT SUPERTYPE OF (atan_function)
713   SUBTYPE OF (binary_numeric_expression);
714   END_ENTITY;
715
716   ENTITY binary_generic_expression
717   ABSTRACT SUPERTYPE
718   SUBTYPE OF (generic_expression);
719      operands : LIST [2:2] OF generic_expression;
720   END_ENTITY;
721
722   ENTITY binary_literal
723   SUBTYPE OF (generic_literal);
724      lit_value : BINARY;
725   END_ENTITY;
726
727   ENTITY binary_numeric_expression
728   ABSTRACT SUPERTYPE OF (ONEOF(minus_expression, div_expression, mod_expression, power_expression, binary_function_call))
729   SUBTYPE OF (numeric_expression, binary_generic_expression);
730      SELF\binary_generic_expression.operands : LIST [2:2] OF numeric_expression;
731   END_ENTITY;
732
733   ENTITY block_volume
734   SUBTYPE OF (volume);
735      position : axis2_placement_3d;
736      x : positive_length_measure;
737      y : positive_length_measure;
738      z : positive_length_measure;
739   END_ENTITY;
740
741   ENTITY boolean_defined_function
742   ABSTRACT SUPERTYPE
743   SUBTYPE OF (defined_function, boolean_expression);
744   END_ENTITY;
745
746   ENTITY boolean_expression
747   ABSTRACT SUPERTYPE OF (ONEOF(simple_boolean_expression, unary_boolean_expression, binary_boolean_expression, multiple_arity_boolean_expression, comparison_expression, interval_expression, boolean_defined_function))
748   SUBTYPE OF (expression);
749   END_ENTITY;
750
751   ENTITY boolean_literal
752   SUBTYPE OF (simple_boolean_expression, generic_literal);
753      the_value : BOOLEAN;
754   END_ENTITY;
755
756   ENTITY boolean_variable
757   SUBTYPE OF (simple_boolean_expression, variable);
758   END_ENTITY;
759
760   ENTITY bound_variable_semantics
761   SUBTYPE OF (variable_semantics);
762   END_ENTITY;
763
764   ENTITY calendar_date
765   SUBTYPE OF (date);
766      day_component : day_in_month_number;
767      month_component : month_in_year_number;
768   WHERE
769      WR1:
770         valid_calendar_date(SELF);
771   END_ENTITY;
772
773   ENTITY capacitance_measure_with_unit
774   SUBTYPE OF (measure_with_unit);
775   WHERE
776      WR1:
777         'ENGINEERING_PROPERTIES_SCHEMA.CAPACITANCE_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
778   END_ENTITY;
779
780   ENTITY capacitance_unit
781   SUBTYPE OF (derived_unit);
782   WHERE
783      WR1:
784         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.farad);
785   END_ENTITY;
786
787	ENTITY si_capacitance_unit
788     SUBTYPE OF (capacitance_unit,si_unit);
789  WHERE
790    WR1: SELF\si_unit.name = si_unit_name.farad;
791    WR2: NOT EXISTS(SELF\derived_unit.name);
792  END_ENTITY;
793
794   ENTITY cartesian_complex_number_region
795   SUBTYPE OF (maths_space, generic_literal);
796      real_constraint : real_interval;
797      imag_constraint : real_interval;
798   WHERE
799      WR1:
800         ((min_exists(real_constraint) OR max_exists(real_constraint)) OR min_exists(imag_constraint)) OR max_exists(imag_constraint);
801   END_ENTITY;
802
803   ENTITY cartesian_point
804   SUPERTYPE OF (ONEOF(cylindrical_point, polar_point, spherical_point))
805   SUBTYPE OF (point);
806      coordinates : LIST [1:3] OF length_measure;
807   END_ENTITY;
808
809   ENTITY cartesian_transformation_operator
810   SUPERTYPE OF (cartesian_transformation_operator_3d)
811   SUBTYPE OF (geometric_representation_item, functionally_defined_transformation);
812      axis1 : OPTIONAL direction;
813      axis2 : OPTIONAL direction;
814      local_origin : cartesian_point;
815      scale : OPTIONAL REAL;
816   DERIVE
817      scl : REAL := NVL(scale, 1.00000);
818   WHERE
819      WR1:
820         scl > 0.00000;
821   END_ENTITY;
822
823   ENTITY cartesian_transformation_operator_3d
824   SUBTYPE OF (cartesian_transformation_operator);
825      axis3 : OPTIONAL direction;
826   DERIVE
827      u : LIST [3:3] OF direction := base_axis(3, SELF\cartesian_transformation_operator.axis1, SELF\cartesian_transformation_operator.axis2, axis3);
828   WHERE
829      WR1:
830         SELF\geometric_representation_item.dim = 3;
831   END_ENTITY;
832
833   ENTITY celsius_temperature_measure_with_unit
834   SUBTYPE OF (measure_with_unit);
835   WHERE
836      WR1:
837         'ENGINEERING_PROPERTIES_SCHEMA.THERMODYNAMIC_TEMPERATURE_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
838   END_ENTITY;
839
840   ENTITY centre_of_symmetry
841   SUBTYPE OF (derived_shape_aspect);
842   WHERE
843      WR1:
844         SIZEOF(QUERY (sadr <* SELF\derived_shape_aspect.deriving_relationships| NOT ('ENGINEERING_PROPERTIES_SCHEMA.SYMMETRIC_SHAPE_ASPECT' IN TYPEOF(sadr\shape_aspect_relationship.related_shape_aspect)))) = 0;
845   END_ENTITY;
846
847   ENTITY certification;
848      name : label;
849      purpose : text;
850      kind : certification_type;
851   END_ENTITY;
852
853   ENTITY certification_assignment
854   ABSTRACT SUPERTYPE;
855      assigned_certification : certification;
856   DERIVE
857      role : object_role := get_role(SELF);
858   WHERE
859      WR1:
860         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ROLE_ASSOCIATION.ITEM_WITH_ROLE')) <= 1;
861   END_ENTITY;
862
863   ENTITY certification_type;
864      description : label;
865   END_ENTITY;
866
867   ENTITY characterized_object;
868      name : label;
869      description : OPTIONAL text;
870   END_ENTITY;
871
872   ENTITY circle
873   SUBTYPE OF (conic);
874      radius : positive_length_measure;
875   END_ENTITY;
876
877   ENTITY class
878   SUBTYPE OF (group);
879   END_ENTITY;
880
881   ENTITY classification_assignment
882   ABSTRACT SUPERTYPE;
883      assigned_class : group;
884      role : classification_role;
885   END_ENTITY;
886
887   ENTITY classification_role;
888      name : label;
889      description : OPTIONAL text;
890   END_ENTITY;
891
892   ENTITY coaxiality_tolerance
893   SUBTYPE OF (geometric_tolerance_with_datum_reference);
894   WHERE
895      WR1:
896         SIZEOF(SELF\geometric_tolerance_with_datum_reference.datum_system) <= 2;
897   END_ENTITY;
898
899   ENTITY comparison_equal
900   SUBTYPE OF (comparison_expression);
901   END_ENTITY;
902
903   ENTITY comparison_expression
904   ABSTRACT SUPERTYPE OF (ONEOF(comparison_equal, comparison_greater, comparison_greater_equal, comparison_less, comparison_less_equal, comparison_not_equal, like_expression))
905   SUBTYPE OF (boolean_expression, binary_generic_expression);
906      SELF\binary_generic_expression.operands : LIST [2:2] OF expression;
907   WHERE
908      WR1:
909         (('ENGINEERING_PROPERTIES_SCHEMA.NUMERIC_EXPRESSION' IN TYPEOF(SELF\binary_generic_expression.operands[1])) AND ('ENGINEERING_PROPERTIES_SCHEMA.NUMERIC_EXPRESSION' IN TYPEOF(SELF\binary_generic_expression.operands[2])) OR ('ENGINEERING_PROPERTIES_SCHEMA.BOOLEAN_EXPRESSION' IN TYPEOF(SELF\binary_generic_expression.operands[1])) AND ('ENGINEERING_PROPERTIES_SCHEMA.BOOLEAN_EXPRESSION' IN TYPEOF(SELF\binary_generic_expression.operands[2]))) OR ('ENGINEERING_PROPERTIES_SCHEMA.STRING_EXPRESSION' IN TYPEOF(SELF\binary_generic_expression.operands[1])) AND ('ENGINEERING_PROPERTIES_SCHEMA.STRING_EXPRESSION' IN TYPEOF(SELF\binary_generic_expression.operands[2]));
910   END_ENTITY;
911
912   ENTITY comparison_greater
913   SUBTYPE OF (comparison_expression);
914   END_ENTITY;
915
916   ENTITY comparison_greater_equal
917   SUBTYPE OF (comparison_expression);
918   END_ENTITY;
919
920   ENTITY comparison_less
921   SUBTYPE OF (comparison_expression);
922   END_ENTITY;
923
924   ENTITY comparison_less_equal
925   SUBTYPE OF (comparison_expression);
926   END_ENTITY;
927
928   ENTITY comparison_not_equal
929   SUBTYPE OF (comparison_expression);
930   END_ENTITY;
931
932   ENTITY complex_number_literal
933   SUBTYPE OF (generic_literal);
934      real_part : REAL;
935      imag_part : REAL;
936   END_ENTITY;
937
938   ENTITY composite_shape_aspect
939   SUBTYPE OF (shape_aspect);
940   INVERSE
941      component_relationships : SET [2:?] OF shape_aspect_relationship FOR relating_shape_aspect;
942   END_ENTITY;
943
944   ENTITY compound_representation_item
945   SUBTYPE OF (representation_item);
946      item_element : compound_item_definition;
947   END_ENTITY;
948
949   ENTITY concat_expression
950   SUBTYPE OF (string_expression, multiple_arity_generic_expression);
951      SELF\multiple_arity_generic_expression.operands : LIST [2:?] OF string_expression;
952   END_ENTITY;
953
954   ENTITY concentricity_tolerance
955   SUBTYPE OF (geometric_tolerance_with_datum_reference);
956   WHERE
957      WR1:
958         SIZEOF(SELF\geometric_tolerance_with_datum_reference.datum_system) = 1;
959   END_ENTITY;
960
961   ENTITY concurrent_action_method
962   SUBTYPE OF (action_method_relationship);
963   END_ENTITY;
964
965   ENTITY conductance_measure_with_unit
966   SUBTYPE OF (measure_with_unit);
967   WHERE
968      WR1:
969         'ENGINEERING_PROPERTIES_SCHEMA.CONDUCTANCE_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
970   END_ENTITY;
971
972   ENTITY conductance_unit
973   SUBTYPE OF (derived_unit);
974   WHERE
975      WR1:
976         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.siemens);
977   END_ENTITY;
978
979	ENTITY si_conductance_unit
980     SUBTYPE OF (conductance_unit,si_unit);
981  WHERE
982    WR1: SELF\si_unit.name = si_unit_name.siemens;
983    WR2: NOT EXISTS(SELF\derived_unit.name);
984  END_ENTITY;
985
986   ENTITY configuration_design;
987      configuration : configuration_item;
988      design : configuration_design_item;
989   DERIVE
990      name : label := get_name_value(SELF);
991      description : text := get_description_value(SELF);
992   UNIQUE
993      UR1 : configuration, design;
994   WHERE
995      WR1:
996         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'NAME_ATTRIBUTE.NAMED_ITEM')) <= 1;
997      WR2:
998         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
999   END_ENTITY;
1000
1001   ENTITY configuration_item;
1002      id : identifier;
1003      name : label;
1004      description : OPTIONAL text;
1005      item_concept : product_concept;
1006      purpose : OPTIONAL label;
1007   END_ENTITY;
1008
1009   ENTITY conic
1010   SUPERTYPE OF (ONEOF(circle, ellipse, hyperbola, parabola))
1011   SUBTYPE OF (curve);
1012      position : axis2_placement;
1013   END_ENTITY;
1014
1015   ENTITY conical_surface
1016   SUBTYPE OF (elementary_surface);
1017      radius : length_measure;
1018      semi_angle : plane_angle_measure;
1019   WHERE
1020      WR1:
1021         radius >= 0.00000;
1022   END_ENTITY;
1023
1024   ENTITY constant_function
1025   SUBTYPE OF (maths_function, generic_literal);
1026      sole_output : maths_value;
1027      source_of_domain : maths_space_or_function;
1028   WHERE
1029      WR1:
1030         no_cyclic_domain_reference(source_of_domain, [ SELF ]);
1031      WR2:
1032         expression_is_constant(domain_from(source_of_domain));
1033   END_ENTITY;
1034
1035   ENTITY context_dependent_action_method_relationship;
1036      name : label;
1037      relating_relationship : action_method_relationship;
1038      related_relationship : action_method_relationship;
1039   UNIQUE
1040      UR1 : relating_relationship, related_relationship;
1041   WHERE
1042      WR1:
1043         relating_relationship.relating_method :=: related_relationship.relating_method;
1044   END_ENTITY;
1045
1046   ENTITY context_dependent_action_relationship;
1047      name : label;
1048      relating_relationship : action_relationship;
1049      related_relationship : action_relationship;
1050   UNIQUE
1051      UR1 : relating_relationship, related_relationship;
1052   WHERE
1053      WR1:
1054         relating_relationship.relating_action :=: related_relationship.relating_action;
1055   END_ENTITY;
1056
1057   ENTITY context_dependent_shape_representation;
1058      representation_relation : shape_representation_relationship;
1059      represented_product_relation : product_definition_shape;
1060   DERIVE
1061      description : text := get_description_value(SELF);
1062      name : label := get_name_value(SELF);
1063   WHERE
1064      WR1:
1065         'ENGINEERING_PROPERTIES_SCHEMA.PRODUCT_DEFINITION_RELATIONSHIP' IN TYPEOF(SELF.represented_product_relation.definition);
1066      WR2:
1067         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
1068      WR3:
1069         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'NAME_ATTRIBUTE.NAMED_ITEM')) <= 1;
1070   END_ENTITY;
1071
1072   ENTITY context_dependent_unit
1073   SUBTYPE OF (named_unit);
1074      name : label;
1075   END_ENTITY;
1076
1077   ENTITY contract;
1078      name : label;
1079      purpose : text;
1080      kind : contract_type;
1081   END_ENTITY;
1082
1083   ENTITY contract_assignment
1084   ABSTRACT SUPERTYPE;
1085      assigned_contract : contract;
1086   DERIVE
1087      role : object_role := get_role(SELF);
1088   WHERE
1089      WR1:
1090         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ROLE_ASSOCIATION.ITEM_WITH_ROLE')) <= 1;
1091   END_ENTITY;
1092
1093   ENTITY contract_relationship;
1094      id : identifier;
1095      name : label;
1096      description : OPTIONAL text;
1097      relating_contract : contract;
1098      related_contract : contract;
1099   END_ENTITY;
1100
1101   ENTITY contract_type;
1102      description : label;
1103   END_ENTITY;
1104
1105   ENTITY conversion_based_unit
1106   SUBTYPE OF (named_unit);
1107      name : label;
1108      conversion_factor : measure_with_unit;
1109   DERIVE
1110      SELF\named_unit.dimensions : dimensional_exponents := derive_dimensional_exponents(conversion_factor\measure_with_unit.unit_component);
1111   END_ENTITY;
1112
1113   ENTITY coordinated_universal_time_offset;
1114      hour_offset : INTEGER;
1115      minute_offset : OPTIONAL INTEGER;
1116      sense : ahead_or_behind;
1117   DERIVE
1118      actual_minute_offset : INTEGER := NVL(minute_offset, 0);
1119   WHERE
1120      WR1:
1121         (0 <= hour_offset) AND (hour_offset < 24);
1122      WR2:
1123         (0 <= actual_minute_offset) AND (actual_minute_offset <= 59);
1124      WR3:
1125         NOT (((hour_offset <> 0) OR (actual_minute_offset <> 0)) AND (sense = exact));
1126   END_ENTITY;
1127
1128   ENTITY cos_function
1129   SUBTYPE OF (unary_function_call);
1130   END_ENTITY;
1131
1132   ENTITY curve
1133   SUPERTYPE OF (ONEOF(line, conic))
1134   SUBTYPE OF (geometric_representation_item);
1135   END_ENTITY;
1136
1137   ENTITY cylindrical_point
1138   SUBTYPE OF (cartesian_point);
1139      r : length_measure;
1140      theta : plane_angle_measure;
1141      z : length_measure;
1142   DERIVE
1143      SELF\cartesian_point.coordinates : LIST [1:3] OF length_measure := [ r * COS(theta), r * SIN(theta), z ];
1144   WHERE
1145      WR1:
1146         r >= 0.00000;
1147   END_ENTITY;
1148
1149   ENTITY cylindrical_surface
1150   SUBTYPE OF (elementary_surface);
1151      radius : positive_length_measure;
1152   END_ENTITY;
1153
1154   ENTITY cylindrical_volume
1155   SUBTYPE OF (volume);
1156      position : axis2_placement_3d;
1157      radius : positive_length_measure;
1158      height : positive_length_measure;
1159   END_ENTITY;
1160
1161   ENTITY cylindricity_tolerance
1162   SUBTYPE OF (geometric_tolerance);
1163   WHERE
1164      WR1:
1165         NOT ('ENGINEERING_PROPERTIES_SCHEMA.' + 'GEOMETRIC_TOLERANCE_WITH_DATUM_REFERENCE' IN TYPEOF(SELF));
1166   END_ENTITY;
1167
1168   ENTITY data_environment;
1169      name : label;
1170      description : text;
1171      elements : SET [1:?] OF property_definition_representation;
1172   END_ENTITY;
1173
1174   ENTITY data_environment_relationship;
1175      name : label;
1176      description : text;
1177      relating_data_environment : data_environment;
1178      related_data_environment : data_environment;
1179   END_ENTITY;
1180
1181   ENTITY date
1182   SUPERTYPE OF (ONEOF(calendar_date, ordinal_date, week_of_year_and_day_date, year_month));
1183      year_component : year_number;
1184   END_ENTITY;
1185
1186   ENTITY date_and_time;
1187      date_component : date;
1188      time_component : local_time;
1189   END_ENTITY;
1190
1191   ENTITY date_and_time_assignment
1192   ABSTRACT SUPERTYPE;
1193      assigned_date_and_time : date_and_time;
1194      role : date_time_role;
1195   END_ENTITY;
1196
1197   ENTITY date_assignment
1198   ABSTRACT SUPERTYPE;
1199      assigned_date : date;
1200      role : date_role;
1201   END_ENTITY;
1202
1203   ENTITY date_role;
1204      name : label;
1205   DERIVE
1206      description : text := get_description_value(SELF);
1207   WHERE
1208      WR1:
1209         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
1210   END_ENTITY;
1211
1212   ENTITY date_time_role;
1213      name : label;
1214   DERIVE
1215      description : text := get_description_value(SELF);
1216   WHERE
1217      WR1:
1218         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
1219   END_ENTITY;
1220
1221   ENTITY dated_effectivity
1222   SUBTYPE OF (effectivity);
1223      effectivity_end_date : OPTIONAL date_time_or_event_occurrence;
1224      effectivity_start_date : date_time_or_event_occurrence;
1225   END_ENTITY;
1226
1227   ENTITY datum
1228   SUBTYPE OF (shape_aspect);
1229      identification : identifier;
1230   INVERSE
1231      established_by_relationships : SET [1:?] OF shape_aspect_relationship FOR related_shape_aspect;
1232   WHERE
1233      WR1:
1234         SIZEOF(QUERY (x <* SELF\datum.established_by_relationships| (SIZEOF(TYPEOF(x\shape_aspect_relationship.relating_shape_aspect) * [ 'ENGINEERING_PROPERTIES_SCHEMA.DATUM_FEATURE', 'ENGINEERING_PROPERTIES_SCHEMA.DATUM_TARGET' ]) <> 1))) = 0;
1235   END_ENTITY;
1236
1237   ENTITY datum_feature
1238   SUBTYPE OF (shape_aspect);
1239   INVERSE
1240      feature_basis_relationship : shape_aspect_relationship FOR relating_shape_aspect;
1241   WHERE
1242      WR1:
1243         SIZEOF(QUERY (sar <* bag_to_set(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.SHAPE_ASPECT_RELATIONSHIP.' + 'RELATING_SHAPE_ASPECT'))| NOT ('ENGINEERING_PROPERTIES_SCHEMA.DATUM' IN TYPEOF(sar\shape_aspect_relationship.related_shape_aspect)))) = 0;
1244      WR2:
1245         SELF\shape_aspect.product_definitional = TRUE;
1246   END_ENTITY;
1247
1248   ENTITY datum_reference;
1249      precedence : INTEGER;
1250      referenced_datum : datum;
1251   WHERE
1252      WR1:
1253         precedence > 0;
1254   END_ENTITY;
1255
1256   ENTITY datum_target
1257   SUBTYPE OF (shape_aspect);
1258      target_id : identifier;
1259   INVERSE
1260      target_basis_relationship : shape_aspect_relationship FOR relating_shape_aspect;
1261   WHERE
1262      WR1:
1263         SIZEOF(QUERY (sar <* bag_to_set(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.SHAPE_ASPECT_RELATIONSHIP.' + 'RELATING_SHAPE_ASPECT'))| NOT ('ENGINEERING_PROPERTIES_SCHEMA.DATUM' IN TYPEOF(sar\shape_aspect_relationship.related_shape_aspect)))) = 0;
1264      WR2:
1265         SELF\shape_aspect.product_definitional = TRUE;
1266   END_ENTITY;
1267
1268   ENTITY defined_function
1269   ABSTRACT SUPERTYPE OF (ONEOF(numeric_defined_function, string_defined_function, boolean_defined_function) ANDOR SQL_mappable_defined_function);
1270   END_ENTITY;
1271
1272   ENTITY definite_integral_expression
1273   SUBTYPE OF (quantifier_expression);
1274      lower_limit_neg_infinity : BOOLEAN;
1275      upper_limit_pos_infinity : BOOLEAN;
1276   DERIVE
1277      integrand : generic_expression := SELF\multiple_arity_generic_expression.operands[1];
1278      variable_of_integration : maths_variable := SELF\multiple_arity_generic_expression.operands[2];
1279      SELF\quantifier_expression.variables : LIST [1:1] OF UNIQUE generic_variable := [ variable_of_integration ];
1280   WHERE
1281      WR1:
1282         has_values_space(integrand);
1283      WR2:
1284         space_is_continuum(values_space_of(integrand));
1285      WR3:
1286         definite_integral_expr_check(SELF\multiple_arity_generic_expression.operands, lower_limit_neg_infinity, upper_limit_pos_infinity);
1287   END_ENTITY;
1288
1289   ENTITY definite_integral_function
1290   SUBTYPE OF (maths_function, unary_generic_expression);
1291      SELF\unary_generic_expression.operand : maths_function;
1292      variable_of_integration : input_selector;
1293      lower_limit_neg_infinity : BOOLEAN;
1294      upper_limit_pos_infinity : BOOLEAN;
1295   DERIVE
1296      integrand : maths_function := SELF\unary_generic_expression.operand;
1297   WHERE
1298      WR1:
1299         space_is_continuum(integrand.range);
1300      WR2:
1301         definite_integral_check(integrand.domain, variable_of_integration, lower_limit_neg_infinity, upper_limit_pos_infinity);
1302   END_ENTITY;
1303
1304   ENTITY dependent_variable_definition
1305   SUBTYPE OF (unary_generic_expression);
1306      name : label;
1307      description : text;
1308   END_ENTITY;
1309
1310   ENTITY derived_shape_aspect
1311   SUPERTYPE OF (ONEOF(apex, centre_of_symmetry, geometric_alignment, geometric_intersection, parallel_offset, perpendicular_to, extension, tangent))
1312   SUBTYPE OF (shape_aspect);
1313   INVERSE
1314      deriving_relationships : SET [1:?] OF shape_aspect_relationship FOR relating_shape_aspect;
1315   WHERE
1316      WR1:
1317         SIZEOF(QUERY (dr <* SELF\derived_shape_aspect.deriving_relationships| NOT ('ENGINEERING_PROPERTIES_SCHEMA.' + 'SHAPE_ASPECT_DERIVING_RELATIONSHIP' IN TYPEOF(dr)))) = 0;
1318   END_ENTITY;
1319
1320   ENTITY derived_unit
1321   SUPERTYPE OF (ONEOF(absorbed_dose_unit, acceleration_unit, radioactivity_unit, area_unit, capacitance_unit, dose_equivalent_unit, electric_charge_unit, conductance_unit, electric_potential_unit, energy_unit, magnetic_flux_density_unit, force_unit, frequency_unit, illuminance_unit, inductance_unit, magnetic_flux_unit, power_unit, pressure_unit, resistance_unit, volume_unit));
1322      elements : SET [1:?] OF derived_unit_element;
1323   DERIVE
1324      name : label := get_name_value(SELF);
1325   WHERE
1326      WR1:
1327         (SIZEOF(elements) > 1) OR (SIZEOF(elements) = 1) AND (elements[1].exponent <> 1.00000);
1328      WR2:
1329         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'NAME_ATTRIBUTE.NAMED_ITEM')) <= 1;
1330   END_ENTITY;
1331
1332   ENTITY derived_unit_element;
1333      unit : named_unit;
1334      exponent : REAL;
1335   END_ENTITY;
1336
1337   ENTITY description_attribute;
1338      attribute_value : text;
1339      described_item : description_attribute_select;
1340   END_ENTITY;
1341
1342   ENTITY descriptive_representation_item
1343   SUBTYPE OF (representation_item);
1344      description : text;
1345   END_ENTITY;
1346
1347  ENTITY dimension_related_tolerance_zone_element;
1348      related_dimension : dimensional_location;
1349      related_element : tolerance_zone_definition;
1350   END_ENTITY;
1351
1352   ENTITY dimensional_characteristic_representation;
1353      dimension : dimensional_characteristic;
1354      representation : shape_dimension_representation;
1355   END_ENTITY;
1356
1357   ENTITY dimensional_exponents;
1358      length_exponent : REAL;
1359      mass_exponent : REAL;
1360      time_exponent : REAL;
1361      electric_current_exponent : REAL;
1362      thermodynamic_temperature_exponent : REAL;
1363      amount_of_substance_exponent : REAL;
1364      luminous_intensity_exponent : REAL;
1365   END_ENTITY;
1366
1367   ENTITY dimensional_location
1368   SUPERTYPE OF (ONEOF(angular_location, dimensional_location_with_path))
1369  	SUBTYPE OF (shape_aspect_relationship);
1370   END_ENTITY;
1371
1372   ENTITY dimensional_location_with_path
1373   SUBTYPE OF (dimensional_location);
1374      path : shape_aspect;
1375   END_ENTITY;
1376
1377   ENTITY dimensional_size
1378   SUPERTYPE OF (ONEOF(angular_size, dimensional_size_with_path));
1379      applies_to : shape_aspect;
1380      name : label;
1381   WHERE
1382      WR1:
1383         applies_to.product_definitional = TRUE;
1384   END_ENTITY;
1385
1386   ENTITY dimensional_size_with_path
1387   SUBTYPE OF (dimensional_size);
1388      path : shape_aspect;
1389   END_ENTITY;
1390
1391   ENTITY direction
1392   SUBTYPE OF (geometric_representation_item);
1393      direction_ratios : LIST [2:3] OF REAL;
1394   WHERE
1395      WR1:
1396         SIZEOF(QUERY (tmp <* direction_ratios| (tmp <> 0.00000))) > 0;
1397   END_ENTITY;
1398
1399   ENTITY div_expression
1400   SUBTYPE OF (binary_numeric_expression);
1401   END_ENTITY;
1402
1403   ENTITY document;
1404      id : identifier;
1405      name : label;
1406      description : OPTIONAL text;
1407      kind : document_type;
1408   INVERSE
1409      representation_types : SET [0:?] OF document_representation_type FOR represented_document;
1410   END_ENTITY;
1411
1412   ENTITY document_product_association;
1413      name : label;
1414      description : OPTIONAL text;
1415      relating_document : document;
1416      related_product : product_or_formation_or_definition;
1417   END_ENTITY;
1418
1419   ENTITY document_reference
1420   ABSTRACT SUPERTYPE;
1421      assigned_document : document;
1422      source : label;
1423   DERIVE
1424      role : object_role := get_role(SELF);
1425   WHERE
1426      WR1:
1427         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ROLE_ASSOCIATION.ITEM_WITH_ROLE')) <= 1;
1428   END_ENTITY;
1429
1430   ENTITY document_relationship;
1431      name : label;
1432      description : OPTIONAL text;
1433      relating_document : document;
1434      related_document : document;
1435   END_ENTITY;
1436
1437   ENTITY document_representation_type;
1438      name : label;
1439      represented_document : document;
1440   END_ENTITY;
1441
1442   ENTITY document_type;
1443      product_data_type : label;
1444   END_ENTITY;
1445
1446   ENTITY document_usage_constraint;
1447      source : document;
1448      subject_element : label;
1449      subject_element_value : text;
1450   END_ENTITY;
1451
1452   ENTITY document_usage_constraint_assignment
1453   ABSTRACT SUPERTYPE;
1454      assigned_document_usage : document_usage_constraint;
1455      role : document_usage_role;
1456   END_ENTITY;
1457
1458   ENTITY document_usage_role;
1459      name : label;
1460      description : OPTIONAL text;
1461   END_ENTITY;
1462
1463   ENTITY dose_equivalent_measure_with_unit
1464   SUBTYPE OF (measure_with_unit);
1465   WHERE
1466      WR1:
1467         'ENGINEERING_PROPERTIES_SCHEMA.DOSE_EQUIVALENT_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
1468   END_ENTITY;
1469
1470   ENTITY dose_equivalent_unit
1471   SUBTYPE OF (derived_unit);
1472   WHERE
1473      WR1:
1474         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.sievert);
1475   END_ENTITY;
1476
1477	ENTITY si_dose_equivalent_unit
1478     SUBTYPE OF (dose_equivalent_unit,si_unit);
1479  WHERE
1480    WR1: SELF\si_unit.name = si_unit_name.sievert;
1481    WR2: NOT EXISTS(SELF\derived_unit.name);
1482  END_ENTITY;
1483
1484   ENTITY effectivity
1485   SUPERTYPE OF (ONEOF(serial_numbered_effectivity, dated_effectivity, time_interval_based_effectivity));
1486      id : identifier;
1487   DERIVE
1488      name : label := get_name_value(SELF);
1489      description : text := get_description_value(SELF);
1490   WHERE
1491      WR1:
1492         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'NAME_ATTRIBUTE.NAMED_ITEM')) <= 1;
1493      WR2:
1494         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
1495   END_ENTITY;
1496
1497   ENTITY effectivity_assignment
1498   ABSTRACT SUPERTYPE;
1499      assigned_effectivity : effectivity;
1500   DERIVE
1501      role : object_role := get_role(SELF);
1502   WHERE
1503      WR1:
1504         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ROLE_ASSOCIATION.ITEM_WITH_ROLE')) <= 1;
1505   END_ENTITY;
1506
1507   ENTITY effectivity_relationship;
1508      name : label;
1509      description : OPTIONAL text;
1510      related_effectivity : effectivity;
1511      relating_effectivity : effectivity;
1512   END_ENTITY;
1513
1514   ENTITY electric_charge_measure_with_unit
1515   SUBTYPE OF (measure_with_unit);
1516   WHERE
1517      WR1:
1518         'ENGINEERING_PROPERTIES_SCHEMA.ELECTRIC_CHARGE_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
1519   END_ENTITY;
1520
1521   ENTITY electric_charge_unit
1522   SUBTYPE OF (derived_unit);
1523   WHERE
1524      WR1:
1525         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.coulomb);
1526   END_ENTITY;
1527
1528	ENTITY si_electric_charge_unit
1529     SUBTYPE OF (electric_charge_unit,si_unit);
1530  WHERE
1531    WR1: SELF\si_unit.name = si_unit_name.coulomb;
1532    WR2: NOT EXISTS(SELF\derived_unit.name);
1533  END_ENTITY;
1534
1535   ENTITY electric_current_measure_with_unit
1536   SUBTYPE OF (measure_with_unit);
1537   WHERE
1538      WR1:
1539         'ENGINEERING_PROPERTIES_SCHEMA.ELECTRIC_CURRENT_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
1540   END_ENTITY;
1541
1542   ENTITY electric_current_unit
1543   SUBTYPE OF (named_unit);
1544   WHERE
1545      WR1:
1546         ((((((SELF\named_unit.dimensions.length_exponent = 0.00000) AND (SELF\named_unit.dimensions.mass_exponent = 0.00000)) AND (SELF\named_unit.dimensions.time_exponent = 0.00000)) AND (SELF\named_unit.dimensions.electric_current_exponent = 1.00000)) AND (SELF\named_unit.dimensions.thermodynamic_temperature_exponent = 0.00000)) AND (SELF\named_unit.dimensions.amount_of_substance_exponent = 0.00000)) AND (SELF\named_unit.dimensions.luminous_intensity_exponent = 0.00000);
1547   END_ENTITY;
1548
1549   ENTITY electric_potential_measure_with_unit
1550   SUBTYPE OF (measure_with_unit);
1551   WHERE
1552      WR1:
1553         'ENGINEERING_PROPERTIES_SCHEMA.ELECTRIC_POTENTIAL_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
1554   END_ENTITY;
1555
1556   ENTITY electric_potential_unit
1557   SUBTYPE OF (derived_unit);
1558   WHERE
1559      WR1:
1560         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.volt);
1561   END_ENTITY;
1562
1563	ENTITY si_electric_potential_unit
1564     SUBTYPE OF (electric_potential_unit,si_unit);
1565  WHERE
1566    WR1: SELF\si_unit.name = si_unit_name.volt;
1567    WR2: NOT EXISTS(SELF\derived_unit.name);
1568  END_ENTITY;
1569
1570   ENTITY elementary_function
1571   SUBTYPE OF (maths_function, generic_literal);
1572      func_id : elementary_function_enumerators;
1573   END_ENTITY;
1574
1575   ENTITY elementary_space
1576   SUBTYPE OF (maths_space, generic_literal);
1577      space_id : elementary_space_enumerators;
1578   END_ENTITY;
1579
1580   ENTITY elementary_surface
1581   SUPERTYPE OF (ONEOF(plane, cylindrical_surface, conical_surface, spherical_surface))
1582   SUBTYPE OF (surface);
1583      position : axis2_placement_3d;
1584   END_ENTITY;
1585
1586   ENTITY ellipse
1587   SUBTYPE OF (conic);
1588      semi_axis_1 : positive_length_measure;
1589      semi_axis_2 : positive_length_measure;
1590   END_ENTITY;
1591
1592   ENTITY energy_measure_with_unit
1593   SUBTYPE OF (measure_with_unit);
1594   WHERE
1595      WR1:
1596         'ENGINEERING_PROPERTIES_SCHEMA.ENERGY_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
1597   END_ENTITY;
1598
1599   ENTITY energy_unit
1600   SUBTYPE OF (derived_unit);
1601   WHERE
1602      WR1:
1603         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.joule);
1604   END_ENTITY;
1605
1606	ENTITY si_energy_unit
1607     SUBTYPE OF (energy_unit,si_unit);
1608  WHERE
1609    WR1: SELF\si_unit.name = si_unit_name.joule;
1610    WR2: NOT EXISTS(SELF\derived_unit.name);
1611  END_ENTITY;
1612
1613   ENTITY environment;
1614      syntactic_representation : generic_variable;
1615      semantics : variable_semantics;
1616   END_ENTITY;
1617
1618   ENTITY equals_expression
1619   SUBTYPE OF (binary_boolean_expression);
1620   END_ENTITY;
1621
1622   ENTITY event_occurrence;
1623      id : identifier;
1624      name : label;
1625      description : OPTIONAL text;
1626   END_ENTITY;
1627
1628   ENTITY event_occurrence_assignment
1629   ABSTRACT SUPERTYPE;
1630      assigned_event_occurrence : event_occurrence;
1631      role : event_occurrence_role;
1632   END_ENTITY;
1633
1634   ENTITY event_occurrence_role;
1635      name : label;
1636      description : OPTIONAL text;
1637   END_ENTITY;
1638
1639   ENTITY executed_action
1640   SUBTYPE OF (action);
1641   END_ENTITY;
1642
1643   ENTITY exp_function
1644   SUBTYPE OF (unary_function_call);
1645   END_ENTITY;
1646
1647   ENTITY expanded_uncertainty
1648   SUBTYPE OF (standard_uncertainty);
1649      coverage_factor : REAL;
1650   END_ENTITY;
1651
1652   ENTITY explicit_table_function
1653   ABSTRACT SUPERTYPE OF (ONEOF(listed_real_data, listed_integer_data, listed_logical_data, listed_string_data, listed_complex_number_data, listed_data, externally_listed_data, linearized_table_function, basic_sparse_matrix))
1654   SUBTYPE OF (maths_function);
1655      index_base : zero_or_one;
1656      shape : LIST [1:?] OF positive_integer;
1657   END_ENTITY;
1658
1659   ENTITY expression
1660   ABSTRACT SUPERTYPE OF (ONEOF(numeric_expression, boolean_expression, string_expression))
1661   SUBTYPE OF (generic_expression);
1662   END_ENTITY;
1663
1664   ENTITY expression_denoted_function
1665   SUBTYPE OF (maths_function, unary_generic_expression);
1666   DERIVE
1667      expr : generic_expression := SELF\unary_generic_expression.operand;
1668   WHERE
1669      WR1:
1670         schema_prefix + 'FUNCTION_SPACE' IN TYPEOF(values_space_of(expr));
1671   END_ENTITY;
1672
1673   ENTITY extended_tuple_space
1674   SUBTYPE OF (maths_space, generic_literal);
1675      base : product_space;
1676      extender : maths_space;
1677   WHERE
1678      WR1:
1679         expression_is_constant(base) AND expression_is_constant(extender);
1680      WR2:
1681         no_cyclic_space_reference(SELF, []);
1682      WR3:
1683         extender <> the_empty_space;
1684   END_ENTITY;
1685
1686   ENTITY extension
1687   SUBTYPE OF (derived_shape_aspect);
1688   WHERE
1689      WR1:
1690         SIZEOF(SELF\derived_shape_aspect.deriving_relationships) = 1;
1691   END_ENTITY;
1692
1693   ENTITY external_identification_assignment
1694   ABSTRACT SUPERTYPE
1695   SUBTYPE OF (identification_assignment);
1696      source : external_source;
1697   END_ENTITY;
1698
1699   ENTITY external_referent_assignment
1700   ABSTRACT SUPERTYPE;
1701      assigned_name : label;
1702   DERIVE
1703      role : object_role := get_role(SELF);
1704   UNIQUE
1705      UR1 : assigned_name;
1706   WHERE
1707      WR1:
1708         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ROLE_ASSOCIATION.ITEM_WITH_ROLE')) <= 1;
1709   END_ENTITY;
1710
1711   ENTITY external_source;
1712      source_id : source_item;
1713   DERIVE
1714      description : text := get_description_value(SELF);
1715   WHERE
1716      WR1:
1717         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
1718   END_ENTITY;
1719
1720   ENTITY external_source_relationship;
1721      name : label;
1722      description : OPTIONAL text;
1723      relating_source : external_source;
1724      related_source : external_source;
1725   END_ENTITY;
1726
1727   ENTITY externally_defined_action_property
1728   SUBTYPE OF (action_property, externally_defined_item);
1729   END_ENTITY;
1730
1731   ENTITY externally_defined_class
1732   SUBTYPE OF (class, externally_defined_item);
1733   END_ENTITY;
1734
1735   ENTITY externally_defined_engineering_property
1736   SUBTYPE OF (material_property, externally_defined_item);
1737   END_ENTITY;
1738
1739   ENTITY externally_defined_item;
1740      item_id : source_item;
1741      source : external_source;
1742   END_ENTITY;
1743
1744   ENTITY externally_defined_item_relationship;
1745      name : label;
1746      description : OPTIONAL text;
1747      relating_item : externally_defined_item;
1748      related_item : externally_defined_item;
1749   END_ENTITY;
1750
1751   ENTITY externally_listed_data
1752   SUBTYPE OF (explicit_table_function, generic_literal, externally_defined_item);
1753      value_range : maths_space;
1754   WHERE
1755      WR1:
1756         expression_is_constant(value_range);
1757   END_ENTITY;
1758
1759   ENTITY finite_function
1760   SUBTYPE OF (maths_function, generic_literal);
1761      pairs : SET [1:?] OF LIST [2:2] OF maths_value;
1762   WHERE
1763      WR1:
1764         VALUE_UNIQUE(list_selected_components(pairs, 1));
1765   END_ENTITY;
1766
1767   ENTITY finite_integer_interval
1768   SUBTYPE OF (maths_space, generic_literal);
1769      min : INTEGER;
1770      max : INTEGER;
1771   DERIVE
1772      size : positive_integer := max - min + 1;
1773   WHERE
1774      WR1:
1775         min <= max;
1776   END_ENTITY;
1777
1778   ENTITY finite_real_interval
1779   SUBTYPE OF (maths_space, generic_literal);
1780      min : REAL;
1781      min_closure : open_closed;
1782      max : REAL;
1783      max_closure : open_closed;
1784   WHERE
1785      WR1:
1786         min < max;
1787   END_ENTITY;
1788
1789   ENTITY finite_space
1790   SUBTYPE OF (maths_space, generic_literal);
1791      members : SET OF maths_value;
1792   WHERE
1793      WR1:
1794         VALUE_UNIQUE(members);
1795      WR2:
1796         SIZEOF(QUERY (expr <* QUERY (member <* members| ('ENGINEERING_PROPERTIES_SCHEMA.GENERIC_EXPRESSION' IN TYPEOF(member)))| NOT expression_is_constant(expr))) = 0;
1797      WR3:
1798         no_cyclic_space_reference(SELF, []);
1799   END_ENTITY;
1800
1801   ENTITY flatness_tolerance
1802   SUBTYPE OF (geometric_tolerance);
1803   WHERE
1804      WR1:
1805         NOT ('ENGINEERING_PROPERTIES_SCHEMA.' + 'GEOMETRIC_TOLERANCE_WITH_DATUM_REFERENCE' IN TYPEOF(SELF));
1806   END_ENTITY;
1807
1808   ENTITY force_measure_with_unit
1809   SUBTYPE OF (measure_with_unit);
1810   WHERE
1811      WR1:
1812         'ENGINEERING_PROPERTIES_SCHEMA.FORCE_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
1813   END_ENTITY;
1814
1815   ENTITY force_unit
1816   SUBTYPE OF (derived_unit);
1817   WHERE
1818      WR1:
1819         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.newton);
1820   END_ENTITY;
1821
1822	ENTITY si_force_unit
1823     SUBTYPE OF (force_unit,si_unit);
1824  WHERE
1825    WR1: SELF\si_unit.name = si_unit_name.newton;
1826    WR2: NOT EXISTS(SELF\derived_unit.name);
1827  END_ENTITY;
1828
1829   ENTITY format_function
1830   SUBTYPE OF (string_expression, binary_generic_expression);
1831   DERIVE
1832      value_to_format : generic_expression := SELF\binary_generic_expression.operands[1];
1833      format_string : generic_expression := SELF\binary_generic_expression.operands[2];
1834   WHERE
1835      WR1:
1836         ('ENGINEERING_PROPERTIES_SCHEMA.NUMERIC_EXPRESSION' IN TYPEOF(value_to_format)) AND ('ENGINEERING_PROPERTIES_SCHEMA.STRING_EXPRESSION' IN TYPEOF(format_string));
1837   END_ENTITY;
1838
1839   ENTITY founded_item;
1840   END_ENTITY;
1841
1842   ENTITY free_variable_semantics
1843   SUBTYPE OF (variable_semantics);
1844   END_ENTITY;
1845
1846	ENTITY frequency_measure_with_unit
1847   SUBTYPE OF (measure_with_unit);
1848   WHERE
1849      WR1:
1850         'ENGINEERING_PROPERTIES_SCHEMA.FREQUENCY_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
1851   END_ENTITY;
1852
1853   ENTITY frequency_unit
1854   SUBTYPE OF (derived_unit);
1855   WHERE
1856      WR1:
1857         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.hertz);
1858   END_ENTITY;
1859
1860	ENTITY si_frequency_unit
1861     SUBTYPE OF (frequency_unit,si_unit);
1862  WHERE
1863    WR1: SELF\si_unit.name = si_unit_name.hertz;
1864    WR2: NOT EXISTS(SELF\derived_unit.name);
1865  END_ENTITY;
1866
1867   ENTITY function_application
1868   SUBTYPE OF (multiple_arity_generic_expression);
1869      func : maths_function_select;
1870      arguments : LIST [1:?] OF maths_expression;
1871   DERIVE
1872      SELF\multiple_arity_generic_expression.operands : LIST [2:?] OF generic_expression := [ convert_to_maths_function(func) ] + convert_to_operands(arguments);
1873   WHERE
1874      WR1:
1875         function_applicability(func, arguments);
1876   END_ENTITY;
1877
1878   ENTITY function_space
1879   SUBTYPE OF (maths_space, generic_literal);
1880      domain_constraint : space_constraint_type;
1881      domain_argument : maths_space;
1882      range_constraint : space_constraint_type;
1883      range_argument : maths_space;
1884   WHERE
1885      WR1:
1886         expression_is_constant(domain_argument) AND expression_is_constant(range_argument);
1887      WR2:
1888         (domain_argument <> the_empty_space) AND (range_argument <> the_empty_space);
1889      WR3:
1890         (domain_constraint <> sc_member) OR NOT member_of(the_empty_space, domain_argument);
1891      WR4:
1892         (range_constraint <> sc_member) OR NOT member_of(the_empty_space, range_argument);
1893      WR5:
1894         NOT (any_space_satisfies(domain_constraint, domain_argument) AND any_space_satisfies(range_constraint, range_argument));
1895   END_ENTITY;
1896
1897   ENTITY functionally_defined_transformation;
1898      name : label;
1899      description : OPTIONAL text;
1900   END_ENTITY;
1901
1902   ENTITY general_linear_function
1903   SUBTYPE OF (maths_function, unary_generic_expression);
1904      SELF\unary_generic_expression.operand : maths_function;
1905      sum_index : one_or_two;
1906   DERIVE
1907      mat : maths_function := SELF\unary_generic_expression.operand;
1908   WHERE
1909      WR1:
1910         function_is_2d_table(mat);
1911      WR2:
1912         (space_dimension(mat.range) = 1) AND subspace_of_es(factor1(mat.range), es_numbers);
1913   END_ENTITY;
1914
1915   ENTITY general_property;
1916      id : identifier;
1917      name : label;
1918      description : OPTIONAL text;
1919   END_ENTITY;
1920
1921   ENTITY generic_expression
1922   ABSTRACT SUPERTYPE OF (ONEOF(simple_generic_expression, unary_generic_expression, binary_generic_expression, multiple_arity_generic_expression));
1923   WHERE
1924      WR1:
1925         is_acyclic(SELF);
1926   END_ENTITY;
1927
1928   ENTITY generic_literal
1929   ABSTRACT SUPERTYPE
1930   SUBTYPE OF (simple_generic_expression);
1931   END_ENTITY;
1932
1933   ENTITY generic_variable
1934   ABSTRACT SUPERTYPE
1935   SUBTYPE OF (simple_generic_expression);
1936   INVERSE
1937      interpretation : environment FOR syntactic_representation;
1938   END_ENTITY;
1939
1940   ENTITY geometric_alignment
1941   SUBTYPE OF (derived_shape_aspect);
1942   WHERE
1943      WR1:
1944         SIZEOF(SELF\derived_shape_aspect.deriving_relationships) > 1;
1945   END_ENTITY;
1946
1947   ENTITY geometric_intersection
1948   SUBTYPE OF (derived_shape_aspect);
1949   WHERE
1950      WR1:
1951         SIZEOF(SELF\derived_shape_aspect.deriving_relationships) > 1;
1952   END_ENTITY;
1953
1954   ENTITY geometric_representation_context
1955   SUBTYPE OF (representation_context);
1956      coordinate_space_dimension : dimension_count;
1957   END_ENTITY;
1958
1959   ENTITY geometric_representation_item
1960   SUPERTYPE OF (ONEOF(point, direction, vector, placement, cartesian_transformation_operator, curve, surface, volume))
1961   SUBTYPE OF (representation_item);
1962   DERIVE
1963      dim : dimension_count := dimension_of(SELF);
1964   WHERE
1965      WR1:
1966         SIZEOF(QUERY (using_rep <* using_representations(SELF)| NOT ('ENGINEERING_PROPERTIES_SCHEMA.GEOMETRIC_REPRESENTATION_CONTEXT' IN TYPEOF(using_rep.context_of_items)))) = 0;
1967   END_ENTITY;
1968
1969   ENTITY geometric_tolerance;
1970      name : label;
1971      description : text;
1972      magnitude : measure_with_unit;
1973      toleranced_shape_aspect : shape_aspect;
1974   WHERE
1975      WR1:
1976         ('NUMBER' IN TYPEOF(magnitude\measure_with_unit.value_component)) AND (magnitude\measure_with_unit.value_component >= 0.00000);
1977   END_ENTITY;
1978
1979   ENTITY geometric_tolerance_relationship;
1980      name : label;
1981      description : text;
1982      relating_geometric_tolerance : geometric_tolerance;
1983      related_geometric_tolerance : geometric_tolerance;
1984   END_ENTITY;
1985
1986   ENTITY geometric_tolerance_with_datum_reference
1987   SUBTYPE OF (geometric_tolerance);
1988      datum_system : SET [1:?] OF datum_reference;
1989   END_ENTITY;
1990
1991   ENTITY geometric_tolerance_with_defined_unit
1992   SUBTYPE OF (geometric_tolerance);
1993      unit_size : measure_with_unit;
1994   WHERE
1995      WR1:
1996         ('NUMBER' IN TYPEOF(unit_size\measure_with_unit.value_component)) AND (unit_size\measure_with_unit.value_component > 0.00000);
1997   END_ENTITY;
1998
1999   ENTITY global_uncertainty_assigned_context
2000   SUBTYPE OF (representation_context);
2001      uncertainty : SET [1:?] OF uncertainty_measure_with_unit;
2002   END_ENTITY;
2003
2004   ENTITY global_unit_assigned_context
2005   SUBTYPE OF (representation_context);
2006      units : SET [1:?] OF unit;
2007   END_ENTITY;
2008
2009   ENTITY group;
2010      name : label;
2011      description : OPTIONAL text;
2012   DERIVE
2013      id : identifier := get_id_value(SELF);
2014   WHERE
2015      WR1:
2016         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ID_ATTRIBUTE.IDENTIFIED_ITEM')) <= 1;
2017   END_ENTITY;
2018
2019   ENTITY group_assignment
2020   ABSTRACT SUPERTYPE;
2021      assigned_group : group;
2022   DERIVE
2023      role : object_role := get_role(SELF);
2024   WHERE
2025      WR1:
2026         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ROLE_ASSOCIATION.ITEM_WITH_ROLE')) <= 1;
2027   END_ENTITY;
2028
2029   ENTITY group_relationship;
2030      name : label;
2031      description : OPTIONAL text;
2032      relating_group : group;
2033      related_group : group;
2034   END_ENTITY;
2035
2036   ENTITY homogeneous_linear_function
2037   SUBTYPE OF (maths_function, unary_generic_expression);
2038      SELF\unary_generic_expression.operand : maths_function;
2039      sum_index : one_or_two;
2040   DERIVE
2041      mat : maths_function := SELF\unary_generic_expression.operand;
2042   WHERE
2043      WR1:
2044         function_is_2d_table(mat);
2045      WR2:
2046         (space_dimension(mat.range) = 1) AND subspace_of_es(factor1(mat.range), es_numbers);
2047   END_ENTITY;
2048
2049   ENTITY hyperbola
2050   SUBTYPE OF (conic);
2051      semi_axis : positive_length_measure;
2052      semi_imag_axis : positive_length_measure;
2053   END_ENTITY;
2054
2055   ENTITY id_attribute;
2056      attribute_value : identifier;
2057      identified_item : id_attribute_select;
2058   END_ENTITY;
2059
2060   ENTITY identification_assignment
2061   ABSTRACT SUPERTYPE;
2062      assigned_id : identifier;
2063      role : identification_role;
2064   END_ENTITY;
2065
2066   ENTITY identification_assignment_relationship;
2067      name : label;
2068      description : OPTIONAL text;
2069      relating_identification_assignment : identification_assignment;
2070      related_identification_assignment : identification_assignment;
2071   END_ENTITY;
2072
2073   ENTITY identification_role;
2074      name : label;
2075      description : OPTIONAL text;
2076   END_ENTITY;
2077
2078   ENTITY illuminance_measure_with_unit
2079   SUBTYPE OF (measure_with_unit);
2080   WHERE
2081      WR1:
2082         'ENGINEERING_PROPERTIES_SCHEMA.ILLUMINANCE_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
2083   END_ENTITY;
2084
2085   ENTITY illuminance_unit
2086   SUBTYPE OF (derived_unit);
2087   WHERE
2088      WR1:
2089         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.lux);
2090   END_ENTITY;
2091
2092	ENTITY si_illuminance_unit
2093     SUBTYPE OF (illuminance_unit,si_unit);
2094  WHERE
2095    WR1: SELF\si_unit.name = si_unit_name.lux;
2096    WR2: NOT EXISTS(SELF\derived_unit.name);
2097  END_ENTITY;
2098
2099   ENTITY imported_curve_function
2100   SUBTYPE OF (maths_function, generic_literal);
2101      geometry : curve;
2102      parametric_domain : tuple_space;
2103   WHERE
2104      WR1:
2105         expression_is_constant(parametric_domain);
2106   END_ENTITY;
2107
2108   ENTITY imported_point_function
2109   SUBTYPE OF (maths_function, generic_literal);
2110      geometry : point;
2111   END_ENTITY;
2112
2113   ENTITY imported_surface_function
2114   SUBTYPE OF (maths_function, generic_literal);
2115      geometry : surface;
2116      parametric_domain : tuple_space;
2117   WHERE
2118      WR1:
2119         expression_is_constant(parametric_domain);
2120   END_ENTITY;
2121
2122   ENTITY imported_volume_function
2123   SUBTYPE OF (maths_function, generic_literal);
2124      geometry : volume;
2125      parametric_domain : tuple_space;
2126   WHERE
2127      WR1:
2128         expression_is_constant(parametric_domain);
2129   END_ENTITY;
2130
2131   ENTITY index_expression
2132   SUBTYPE OF (string_expression, binary_generic_expression);
2133   DERIVE
2134      operand : generic_expression := SELF\binary_generic_expression.operands[1];
2135      index : generic_expression := SELF\binary_generic_expression.operands[2];
2136   WHERE
2137      WR1:
2138         ('ENGINEERING_PROPERTIES_SCHEMA.STRING_EXPRESSION' IN TYPEOF(operand)) AND ('ENGINEERING_PROPERTIES_SCHEMA.NUMERIC_EXPRESSION' IN TYPEOF(index));
2139      WR2:
2140         is_int_expr(index);
2141   END_ENTITY;
2142
2143   ENTITY inductance_measure_with_unit
2144   SUBTYPE OF (measure_with_unit);
2145   WHERE
2146      WR1:
2147         'ENGINEERING_PROPERTIES_SCHEMA.INDUCTANCE_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
2148   END_ENTITY;
2149
2150   ENTITY inductance_unit
2151   SUBTYPE OF (derived_unit);
2152   WHERE
2153      WR1:
2154         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.henry);
2155   END_ENTITY;
2156
2157	 ENTITY si_inductance_unit
2158     SUBTYPE OF (inductance_unit,si_unit);
2159  WHERE
2160    WR1: SELF\si_unit.name = si_unit_name.henry;
2161    WR2: NOT EXISTS(SELF\derived_unit.name);
2162  END_ENTITY;
2163
2164   ENTITY int_literal
2165   SUBTYPE OF (literal_number);
2166      SELF\literal_number.the_value : INTEGER;
2167   END_ENTITY;
2168
2169   ENTITY int_numeric_variable
2170   SUBTYPE OF (numeric_variable);
2171   END_ENTITY;
2172
2173   ENTITY int_value_function
2174   SUBTYPE OF (value_function);
2175   END_ENTITY;
2176
2177   ENTITY integer_defined_function
2178   ABSTRACT SUPERTYPE
2179   SUBTYPE OF (numeric_defined_function);
2180   END_ENTITY;
2181
2182   ENTITY integer_interval_from_min
2183   SUBTYPE OF (maths_space, generic_literal);
2184      min : INTEGER;
2185   END_ENTITY;
2186
2187   ENTITY integer_interval_to_max
2188   SUBTYPE OF (maths_space, generic_literal);
2189      max : INTEGER;
2190   END_ENTITY;
2191
2192   ENTITY integer_tuple_literal
2193   SUBTYPE OF (generic_literal);
2194      lit_value : LIST [1:?] OF INTEGER;
2195   END_ENTITY;
2196
2197   ENTITY interval_expression
2198   SUBTYPE OF (boolean_expression, multiple_arity_generic_expression);
2199   DERIVE
2200      interval_low : generic_expression := SELF\multiple_arity_generic_expression.operands[1];
2201      interval_item : generic_expression := SELF\multiple_arity_generic_expression.operands[2];
2202      interval_high : generic_expression := SELF\multiple_arity_generic_expression.operands[3];
2203   WHERE
2204      WR1:
2205         (('ENGINEERING_PROPERTIES_SCHEMA.EXPRESSION' IN TYPEOF(interval_low)) AND ('ENGINEERING_PROPERTIES_SCHEMA.EXPRESSION' IN TYPEOF(interval_item))) AND ('ENGINEERING_PROPERTIES_SCHEMA.EXPRESSION' IN TYPEOF(interval_high));
2206      WR2:
2207         (('ENGINEERING_PROPERTIES_SCHEMA.STRING_EXPRESSION' IN TYPEOF(SELF.interval_low)) AND ('ENGINEERING_PROPERTIES_SCHEMA.STRING_EXPRESSION' IN TYPEOF(SELF.interval_high))) AND ('ENGINEERING_PROPERTIES_SCHEMA.STRING_EXPRESSION' IN TYPEOF(SELF.interval_item)) OR (('ENGINEERING_PROPERTIES_SCHEMA.STRING_EXPRESSION' IN TYPEOF(SELF.interval_low)) AND ('ENGINEERING_PROPERTIES_SCHEMA.NUMERIC_EXPRESSION' IN TYPEOF(SELF.interval_item))) AND ('ENGINEERING_PROPERTIES_SCHEMA.NUMERIC_EXPRESSION' IN TYPEOF(SELF.interval_high));
2208   END_ENTITY;
2209
2210   ENTITY item_defined_transformation;
2211      name : label;
2212      description : OPTIONAL text;
2213      transform_item_1 : representation_item;
2214      transform_item_2 : representation_item;
2215   END_ENTITY;
2216
2217   ENTITY item_identified_representation_usage;
2218      name : label;
2219      description : OPTIONAL text;
2220      definition : represented_definition;
2221      used_representation : representation;
2222      identified_item : representation_item;
2223   WHERE
2224      WR1:
2225         SELF.used_representation IN using_representations(SELF.identified_item);
2226   END_ENTITY;
2227
2228   ENTITY language
2229   SUBTYPE OF (group);
2230   WHERE
2231      WR1:
2232         (SIZEOF(QUERY (ca <* USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'CLASSIFICATION_ASSIGNMENT.' + 'ASSIGNED_CLASS')| ('ENGINEERING_PROPERTIES_SCHEMA.' + 'LANGUAGE_ASSIGNMENT' IN TYPEOF(ca)))) > 0) OR (SIZEOF(QUERY (aca <* USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ATTRIBUTE_CLASSIFICATION_ASSIGNMENT.' + 'ASSIGNED_CLASS')| ('ENGINEERING_PROPERTIES_SCHEMA.' + 'ATTRIBUTE_LANGUAGE_ASSIGNMENT' IN TYPEOF(aca)))) > 0);
2233   END_ENTITY;
2234
2235   ENTITY language_assignment
2236   SUBTYPE OF (classification_assignment);
2237      items : SET [1:?] OF language_item;
2238   WHERE
2239      WR1:
2240         'ENGINEERING_PROPERTIES_SCHEMA.' + 'LANGUAGE' IN TYPEOF(SELF.assigned_class);
2241      WR2:
2242         SELF.role.name = 'language';
2243      WR3:
2244         SIZEOF(SELF.items) = SIZEOF(QUERY (i <* SELF.items| ('ENGINEERING_PROPERTIES_SCHEMA.' + 'REPRESENTATION' IN TYPEOF(i)) AND (i\representation.name = 'document content')));
2245   END_ENTITY;
2246
2247   ENTITY length_function
2248   SUBTYPE OF (numeric_expression, unary_generic_expression);
2249      SELF\unary_generic_expression.operand : string_expression;
2250   END_ENTITY;
2251
2252   ENTITY length_measure_with_unit
2253   SUBTYPE OF (measure_with_unit);
2254   WHERE
2255      WR1:
2256         'ENGINEERING_PROPERTIES_SCHEMA.LENGTH_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
2257   END_ENTITY;
2258
2259   ENTITY length_unit
2260   SUBTYPE OF (named_unit);
2261   WHERE
2262      WR1:
2263         ((((((SELF\named_unit.dimensions.length_exponent = 1.00000) AND (SELF\named_unit.dimensions.mass_exponent = 0.00000)) AND (SELF\named_unit.dimensions.time_exponent = 0.00000)) AND (SELF\named_unit.dimensions.electric_current_exponent = 0.00000)) AND (SELF\named_unit.dimensions.thermodynamic_temperature_exponent = 0.00000)) AND (SELF\named_unit.dimensions.amount_of_substance_exponent = 0.00000)) AND (SELF\named_unit.dimensions.luminous_intensity_exponent = 0.00000);
2264   END_ENTITY;
2265
2266   ENTITY like_expression
2267   SUBTYPE OF (comparison_expression);
2268   WHERE
2269      WR1:
2270         ('ENGINEERING_PROPERTIES_SCHEMA.STRING_EXPRESSION' IN TYPEOF(SELF\comparison_expression.operands[1])) AND ('ENGINEERING_PROPERTIES_SCHEMA.STRING_EXPRESSION' IN TYPEOF(SELF\comparison_expression.operands[2]));
2271   END_ENTITY;
2272
2273   ENTITY limits_and_fits;
2274      form_variance : label;
2275      zone_variance : label;
2276      grade : label;
2277      source : text;
2278   END_ENTITY;
2279
2280   ENTITY line
2281   SUBTYPE OF (curve);
2282      pnt : cartesian_point;
2283      dir : vector;
2284   WHERE
2285      WR1:
2286         dir.dim = pnt.dim;
2287   END_ENTITY;
2288
2289   ENTITY linearized_table_function
2290   SUPERTYPE OF (ONEOF(standard_table_function, regular_table_function, triangular_matrix, symmetric_matrix, banded_matrix))
2291   SUBTYPE OF (explicit_table_function, unary_generic_expression);
2292      SELF\unary_generic_expression.operand : maths_function;
2293      first : INTEGER;
2294   DERIVE
2295      source : maths_function := SELF\unary_generic_expression.operand;
2296   WHERE
2297      WR1:
2298         function_is_1d_array(source);
2299      WR2:
2300         member_of(first, source.domain);
2301   END_ENTITY;
2302
2303   ENTITY listed_complex_number_data
2304   SUBTYPE OF (explicit_table_function, generic_literal);
2305      values : LIST [2:?] OF REAL;
2306   DERIVE
2307      SELF\explicit_table_function.shape : LIST [1:?] OF positive_integer := [ SIZEOF(values) DIV 2 ];
2308   WHERE
2309      WR1:
2310         NOT ODD(SIZEOF(values));
2311   END_ENTITY;
2312
2313   ENTITY listed_data
2314   SUBTYPE OF (explicit_table_function, generic_literal);
2315      values : LIST [1:?] OF maths_value;
2316      value_range : maths_space;
2317   DERIVE
2318      SELF\explicit_table_function.shape : LIST [1:?] OF positive_integer := [ SIZEOF(values) ];
2319   WHERE
2320      WR1:
2321         expression_is_constant(value_range);
2322      WR2:
2323         SIZEOF(QUERY (val <* values| NOT member_of(val, value_range))) = 0;
2324   END_ENTITY;
2325
2326   ENTITY listed_integer_data
2327   SUBTYPE OF (explicit_table_function, generic_literal);
2328      values : LIST [1:?] OF INTEGER;
2329   DERIVE
2330      SELF\explicit_table_function.shape : LIST [1:?] OF positive_integer := [ SIZEOF(values) ];
2331   END_ENTITY;
2332
2333   ENTITY listed_logical_data
2334   SUBTYPE OF (explicit_table_function, generic_literal);
2335      values : LIST [1:?] OF LOGICAL;
2336   DERIVE
2337      SELF\explicit_table_function.shape : LIST [1:?] OF positive_integer := [ SIZEOF(values) ];
2338   END_ENTITY;
2339
2340   ENTITY listed_product_space
2341   SUBTYPE OF (maths_space, generic_literal);
2342      factors : LIST OF maths_space;
2343   WHERE
2344      WR1:
2345         SIZEOF(QUERY (space <* factors| NOT expression_is_constant(space))) = 0;
2346      WR2:
2347         no_cyclic_space_reference(SELF, []);
2348      WR3:
2349         NOT (the_empty_space IN factors);
2350   END_ENTITY;
2351
2352   ENTITY listed_real_data
2353   SUBTYPE OF (explicit_table_function, generic_literal);
2354      values : LIST [1:?] OF REAL;
2355   DERIVE
2356      SELF\explicit_table_function.shape : LIST [1:?] OF positive_integer := [ SIZEOF(values) ];
2357   END_ENTITY;
2358
2359   ENTITY listed_string_data
2360   SUBTYPE OF (explicit_table_function, generic_literal);
2361      values : LIST [1:?] OF STRING;
2362   DERIVE
2363      SELF\explicit_table_function.shape : LIST [1:?] OF positive_integer := [ SIZEOF(values) ];
2364   END_ENTITY;
2365
2366   ENTITY literal_number
2367   ABSTRACT SUPERTYPE OF (ONEOF(int_literal, real_literal))
2368   SUBTYPE OF (simple_numeric_expression, generic_literal);
2369      the_value : NUMBER;
2370   END_ENTITY;
2371
2372   ENTITY local_time;
2373      hour_component : hour_in_day;
2374      minute_component : OPTIONAL minute_in_hour;
2375      second_component : OPTIONAL second_in_minute;
2376      zone : coordinated_universal_time_offset;
2377   WHERE
2378      WR1:
2379         valid_time(SELF);
2380   END_ENTITY;
2381
2382   ENTITY location;
2383      id : identifier;
2384      name : label;
2385      description : OPTIONAL text;
2386   END_ENTITY;
2387
2388   ENTITY location_assignment
2389   ABSTRACT SUPERTYPE;
2390      id : identifier;
2391      name : label;
2392      description : OPTIONAL text;
2393      assigned_location : location;
2394      role : location_role;
2395   END_ENTITY;
2396
2397   ENTITY location_relationship;
2398      id : identifier;
2399      name : label;
2400      description : OPTIONAL text;
2401      relating_location : location;
2402      related_location : location;
2403   END_ENTITY;
2404
2405   ENTITY location_representation_assignment
2406   ABSTRACT SUPERTYPE;
2407      id : identifier;
2408      name : label;
2409      description : OPTIONAL text;
2410      represented_location : location;
2411      role : location_representation_role;
2412   END_ENTITY;
2413
2414   ENTITY location_representation_role;
2415      id : identifier;
2416      name : label;
2417      description : OPTIONAL text;
2418   END_ENTITY;
2419
2420   ENTITY location_role;
2421      id : identifier;
2422      name : label;
2423      description : OPTIONAL text;
2424   END_ENTITY;
2425
2426   ENTITY log10_function
2427   SUBTYPE OF (unary_function_call);
2428   END_ENTITY;
2429
2430   ENTITY log2_function
2431   SUBTYPE OF (unary_function_call);
2432   END_ENTITY;
2433
2434   ENTITY log_function
2435   SUBTYPE OF (unary_function_call);
2436   END_ENTITY;
2437
2438   ENTITY logical_literal
2439   SUBTYPE OF (generic_literal);
2440      lit_value : LOGICAL;
2441   END_ENTITY;
2442
2443   ENTITY luminous_flux_measure_with_unit
2444   SUBTYPE OF (measure_with_unit);
2445   WHERE
2446      WR1:
2447         'ENGINEERING_PROPERTIES_SCHEMA.LUMINOUS_FLUX_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
2448   END_ENTITY;
2449
2450   ENTITY luminous_flux_unit
2451   SUBTYPE OF (named_unit);
2452   WHERE
2453      WR1:
2454         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.lumen);
2455   END_ENTITY;
2456
2457   ENTITY luminous_intensity_measure_with_unit
2458   SUBTYPE OF (measure_with_unit);
2459   WHERE
2460      WR1:
2461         'ENGINEERING_PROPERTIES_SCHEMA.LUMINOUS_INTENSITY_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
2462   END_ENTITY;
2463
2464   ENTITY luminous_intensity_unit
2465   SUBTYPE OF (named_unit);
2466   WHERE
2467      WR1:
2468         ((((((SELF\named_unit.dimensions.length_exponent = 0.00000) AND (SELF\named_unit.dimensions.mass_exponent = 0.00000)) AND (SELF\named_unit.dimensions.time_exponent = 0.00000)) AND (SELF\named_unit.dimensions.electric_current_exponent = 0.00000)) AND (SELF\named_unit.dimensions.thermodynamic_temperature_exponent = 0.00000)) AND (SELF\named_unit.dimensions.amount_of_substance_exponent = 0.00000)) AND (SELF\named_unit.dimensions.luminous_intensity_exponent = 1.00000);
2469   END_ENTITY;
2470
2471   ENTITY magnetic_flux_density_measure_with_unit
2472   SUBTYPE OF (measure_with_unit);
2473   WHERE
2474      WR1:
2475         'ENGINEERING_PROPERTIES_SCHEMA.MAGNETIC_FLUX_DENSITY_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
2476   END_ENTITY;
2477   ENTITY magnetic_flux_density_unit
2478   SUBTYPE OF (derived_unit);
2479   WHERE
2480      WR1:
2481         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.tesla);
2482   END_ENTITY;
2483
2484	ENTITY si_magnetic_flux_density_unit
2485     SUBTYPE OF (magnetic_flux_density_unit,si_unit);
2486  WHERE
2487    WR1: SELF\si_unit.name = si_unit_name.tesla;
2488    WR2: NOT EXISTS(SELF\derived_unit.name);
2489  END_ENTITY;
2490
2491   ENTITY magnetic_flux_measure_with_unit
2492   SUBTYPE OF (measure_with_unit);
2493   WHERE
2494      WR1:
2495         'ENGINEERING_PROPERTIES_SCHEMA.MAGNETIC_FLUX_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
2496   END_ENTITY;
2497
2498   ENTITY magnetic_flux_unit
2499   SUBTYPE OF (derived_unit);
2500   WHERE
2501      WR1:
2502         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.weber);
2503   END_ENTITY;
2504
2505	ENTITY si_magnetic_flux_unit
2506     SUBTYPE OF (magnetic_flux_unit,si_unit);
2507  WHERE
2508    WR1: SELF\si_unit.name = si_unit_name.weber;
2509    WR2: NOT EXISTS(SELF\derived_unit.name);
2510  END_ENTITY;
2511
2512   ENTITY mapped_item
2513   SUBTYPE OF (representation_item);
2514      mapping_source : representation_map;
2515      mapping_target : representation_item;
2516   WHERE
2517      WR1:
2518         acyclic_mapped_representation(using_representations(SELF), [ SELF ]);
2519   END_ENTITY;
2520
2521   ENTITY mass_measure_with_unit
2522   SUBTYPE OF (measure_with_unit);
2523   WHERE
2524      WR1:
2525         'ENGINEERING_PROPERTIES_SCHEMA.MASS_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
2526   END_ENTITY;
2527   ENTITY mass_unit
2528   SUBTYPE OF (named_unit);
2529   WHERE
2530      WR1:
2531         ((((((SELF\named_unit.dimensions.length_exponent = 0.00000) AND (SELF\named_unit.dimensions.mass_exponent = 1.00000)) AND (SELF\named_unit.dimensions.time_exponent = 0.00000)) AND (SELF\named_unit.dimensions.electric_current_exponent = 0.00000)) AND (SELF\named_unit.dimensions.thermodynamic_temperature_exponent = 0.00000)) AND (SELF\named_unit.dimensions.amount_of_substance_exponent = 0.00000)) AND (SELF\named_unit.dimensions.luminous_intensity_exponent = 0.00000);
2532   END_ENTITY;
2533
2534   ENTITY material_designation;
2535      name : label;
2536      definitions : SET [1:?] OF characterized_definition;
2537   END_ENTITY;
2538
2539   ENTITY material_designation_characterization;
2540      name : label;
2541      description : text;
2542      designation : material_designation;
2543      property : characterized_material_property;
2544   END_ENTITY;
2545
2546   ENTITY material_property
2547   SUBTYPE OF (property_definition);
2548   UNIQUE
2549      UR1 : SELF\property_definition.name, SELF\property_definition.definition;
2550   WHERE
2551      WR1:
2552         ('ENGINEERING_PROPERTIES_SCHEMA.CHARACTERIZED_OBJECT' IN TYPEOF(SELF\property_definition.definition)) OR (SIZEOF(bag_to_set(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'PROPERTY_DEFINITION_REPRESENTATION.DEFINITION')) - QUERY (temp <* bag_to_set(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'PROPERTY_DEFINITION_REPRESENTATION.DEFINITION'))| ('ENGINEERING_PROPERTIES_SCHEMA.' + 'MATERIAL_PROPERTY_REPRESENTATION' IN TYPEOF(temp)))) = 0);
2553   END_ENTITY;
2554
2555   ENTITY material_property_representation
2556   SUBTYPE OF (property_definition_representation);
2557      dependent_environment : data_environment;
2558   END_ENTITY;
2559
2560   ENTITY mathematical_description;
2561      described : maths_expression;
2562      describing : STRING;
2563      encoding : label;
2564   END_ENTITY;
2565
2566   ENTITY maths_boolean_variable
2567   SUBTYPE OF (maths_variable, boolean_variable);
2568   WHERE
2569      WR1:
2570         subspace_of_es(SELF\maths_variable.values_space, es_booleans);
2571   END_ENTITY;
2572
2573   ENTITY maths_enum_literal
2574   SUBTYPE OF (generic_literal);
2575      lit_value : maths_enum_atom;
2576   END_ENTITY;
2577
2578   ENTITY maths_function
2579   ABSTRACT SUPERTYPE OF (ONEOF(finite_function, constant_function, selector_function, elementary_function, restriction_function, repackaging_function, reindexed_array_function, series_composed_function, parallel_composed_function, explicit_table_function, homogeneous_linear_function, general_linear_function, b_spline_basis, b_spline_function, rationalize_function, partial_derivative_function, definite_integral_function, abstracted_expression_function, expression_denoted_function, imported_point_function, imported_curve_function, imported_surface_function, imported_volume_function, application_defined_function))
2580   SUBTYPE OF (generic_expression);
2581   DERIVE
2582      domain : tuple_space := derive_function_domain(SELF);
2583      range : tuple_space := derive_function_range(SELF);
2584   END_ENTITY;
2585
2586   ENTITY maths_integer_variable
2587   SUBTYPE OF (maths_variable, int_numeric_variable);
2588   WHERE
2589      WR1:
2590         subspace_of_es(SELF\maths_variable.values_space, es_integers);
2591   END_ENTITY;
2592
2593   ENTITY maths_real_variable
2594   SUBTYPE OF (maths_variable, real_numeric_variable);
2595   WHERE
2596      WR1:
2597         subspace_of_es(SELF\maths_variable.values_space, es_reals);
2598   END_ENTITY;
2599
2600   ENTITY maths_space
2601   ABSTRACT SUPERTYPE OF (ONEOF(elementary_space, finite_integer_interval, integer_interval_from_min, integer_interval_to_max, finite_real_interval, real_interval_from_min, real_interval_to_max, cartesian_complex_number_region, polar_complex_number_region, finite_space, uniform_product_space, listed_product_space, extended_tuple_space, function_space))
2602   SUBTYPE OF (generic_expression);
2603   END_ENTITY;
2604
2605   ENTITY maths_string_variable
2606   SUBTYPE OF (maths_variable, string_variable);
2607   WHERE
2608      WR1:
2609         subspace_of_es(SELF\maths_variable.values_space, es_strings);
2610   END_ENTITY;
2611
2612   ENTITY maths_tuple_literal
2613   SUBTYPE OF (generic_literal);
2614      lit_value : LIST OF maths_value;
2615   END_ENTITY;
2616
2617   ENTITY maths_value_qualification;
2618      name : label;
2619      description : text;
2620      qualified_maths_value : maths_value_with_unit;
2621      qualifiers : SET [1:?] OF value_qualifier;
2622   WHERE
2623      WR1:
2624         SIZEOF(QUERY (temp <* qualifiers| ('ENGINEERING_PROPERTIES_SCHEMA.PRECISION_QUALIFIER' IN TYPEOF(temp)))) < 2;
2625   END_ENTITY;
2626
2627   ENTITY maths_value_representation_item
2628   SUBTYPE OF (representation_item, maths_value_with_unit);
2629   END_ENTITY;
2630
2631   ENTITY maths_value_with_unit;
2632      value_component : maths_value;
2633      unit_component : unit;
2634   END_ENTITY;
2635
2636   ENTITY maths_variable
2637   SUBTYPE OF (generic_variable);
2638      values_space : maths_space;
2639      name : label;
2640   WHERE
2641      WR1:
2642         expression_is_constant(values_space);
2643   END_ENTITY;
2644
2645   ENTITY maximum_function
2646   SUBTYPE OF (multiple_arity_function_call);
2647   END_ENTITY;
2648
2649   ENTITY measure_qualification;
2650      name : label;
2651      description : text;
2652      qualified_measure : measure_with_unit;
2653      qualifiers : SET [1:?] OF value_qualifier;
2654   WHERE
2655      WR1:
2656         SIZEOF(QUERY (temp <* qualifiers| ('ENGINEERING_PROPERTIES_SCHEMA.PRECISION_QUALIFIER' IN TYPEOF(temp)))) < 2;
2657   END_ENTITY;
2658
2659   ENTITY measure_representation_item
2660   SUBTYPE OF (representation_item, measure_with_unit);
2661   END_ENTITY;
2662
2663   ENTITY measure_with_unit
2664   SUPERTYPE OF (ONEOF(length_measure_with_unit, mass_measure_with_unit, time_measure_with_unit, electric_current_measure_with_unit, thermodynamic_temperature_measure_with_unit, celsius_temperature_measure_with_unit, amount_of_substance_measure_with_unit, luminous_intensity_measure_with_unit, plane_angle_measure_with_unit, solid_angle_measure_with_unit, area_measure_with_unit, volume_measure_with_unit, ratio_measure_with_unit, acceleration_measure_with_unit, capacitance_measure_with_unit, electric_charge_measure_with_unit, conductance_measure_with_unit, electric_potential_measure_with_unit, energy_measure_with_unit, magnetic_flux_density_measure_with_unit, force_measure_with_unit, illuminance_measure_with_unit, inductance_measure_with_unit, luminous_flux_measure_with_unit, magnetic_flux_measure_with_unit, power_measure_with_unit, pressure_measure_with_unit, resistance_measure_with_unit, velocity_measure_with_unit, absorbed_dose_measure_with_unit, radioactivity_measure_with_unit, dose_equivalent_measure_with_unit));
2665      value_component : measure_value;
2666      unit_component : unit;
2667   WHERE
2668      WR1:
2669         valid_units(SELF);
2670   END_ENTITY;
2671
2672   ENTITY minimum_function
2673   SUBTYPE OF (multiple_arity_function_call);
2674   END_ENTITY;
2675
2676   ENTITY minus_expression
2677   SUBTYPE OF (binary_numeric_expression);
2678   END_ENTITY;
2679
2680   ENTITY minus_function
2681   SUBTYPE OF (unary_function_call);
2682   END_ENTITY;
2683
2684   ENTITY mod_expression
2685   SUBTYPE OF (binary_numeric_expression);
2686   END_ENTITY;
2687
2688   ENTITY modified_geometric_tolerance
2689   SUBTYPE OF (geometric_tolerance);
2690      modifier : limit_condition;
2691   END_ENTITY;
2692
2693   ENTITY mult_expression
2694   SUBTYPE OF (multiple_arity_numeric_expression);
2695   END_ENTITY;
2696
2697   ENTITY multi_language_attribute_assignment
2698   SUBTYPE OF (attribute_value_assignment);
2699      items : SET [1:?] OF multi_language_attribute_item;
2700   DERIVE
2701      language : label := get_multi_language(SELF);
2702   WHERE
2703      WR1:
2704         SELF\attribute_value_assignment.role.name = 'alternate language';
2705      WR2:
2706          (SIZEOF(USEDIN(SELF.items[1], 'ENGINEERING_PROPERTIES_SCHEMA.ATTRIBUTE_LANGUAGE_ASSIGNMENT.ITEMS')) = 1) AND (SIZEOF(QUERY (ala <* USEDIN(SELF.items[1], 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ATTRIBUTE_LANGUAGE_ASSIGNMENT.' + 'ITEMS')| (ala.attribute_name = 'attribute_value'))) = 1);
2707   END_ENTITY;
2708
2709   ENTITY multiple_arity_boolean_expression
2710   ABSTRACT SUPERTYPE OF (ONEOF(and_expression, or_expression))
2711   SUBTYPE OF (boolean_expression, multiple_arity_generic_expression);
2712      SELF\multiple_arity_generic_expression.operands : LIST [2:?] OF boolean_expression;
2713   END_ENTITY;
2714
2715   ENTITY multiple_arity_function_call
2716   ABSTRACT SUPERTYPE OF (ONEOF(maximum_function, minimum_function))
2717   SUBTYPE OF (multiple_arity_numeric_expression);
2718   END_ENTITY;
2719
2720   ENTITY multiple_arity_generic_expression
2721   ABSTRACT SUPERTYPE
2722   SUBTYPE OF (generic_expression);
2723      operands : LIST [2:?] OF generic_expression;
2724   END_ENTITY;
2725
2726   ENTITY multiple_arity_numeric_expression
2727   ABSTRACT SUPERTYPE OF (ONEOF(plus_expression, mult_expression, multiple_arity_function_call))
2728   SUBTYPE OF (numeric_expression, multiple_arity_generic_expression);
2729      SELF\multiple_arity_generic_expression.operands : LIST [2:?] OF numeric_expression;
2730   END_ENTITY;
2731
2732   ENTITY name_assignment
2733   ABSTRACT SUPERTYPE;
2734      assigned_name : label;
2735   DERIVE
2736      role : object_role := get_role(SELF);
2737   WHERE
2738      WR1:
2739         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ROLE_ASSOCIATION.ITEM_WITH_ROLE')) <= 1;
2740   END_ENTITY;
2741
2742   ENTITY name_attribute;
2743      attribute_value : label;
2744      named_item : name_attribute_select;
2745   END_ENTITY;
2746
2747   ENTITY named_unit
2748   SUPERTYPE OF (ONEOF(si_unit, conversion_based_unit, context_dependent_unit) ANDOR ONEOF(length_unit, mass_unit, time_unit, electric_current_unit, thermodynamic_temperature_unit, amount_of_substance_unit, luminous_flux_unit, luminous_intensity_unit, plane_angle_unit, solid_angle_unit, ratio_unit));
2749      dimensions : dimensional_exponents;
2750   END_ENTITY;
2751
2752   ENTITY not_expression
2753   SUBTYPE OF (unary_boolean_expression);
2754      SELF\unary_generic_expression.operand : boolean_expression;
2755   END_ENTITY;
2756
2757   ENTITY numeric_defined_function
2758   ABSTRACT SUPERTYPE OF (ONEOF(integer_defined_function, real_defined_function))
2759   SUBTYPE OF (numeric_expression, defined_function);
2760   END_ENTITY;
2761
2762   ENTITY numeric_expression
2763   ABSTRACT SUPERTYPE OF (ONEOF(simple_numeric_expression, unary_numeric_expression, binary_numeric_expression, multiple_arity_numeric_expression, length_function, value_function, numeric_defined_function))
2764   SUBTYPE OF (expression);
2765   DERIVE
2766      is_int : BOOLEAN := is_int_expr(SELF);
2767      sql_mappable : BOOLEAN := is_SQL_mappable(SELF);
2768   END_ENTITY;
2769
2770   ENTITY numeric_variable
2771   SUPERTYPE OF (ONEOF(int_numeric_variable, real_numeric_variable))
2772   SUBTYPE OF (simple_numeric_expression, variable);
2773   WHERE
2774      WR1:
2775         ('ENGINEERING_PROPERTIES_SCHEMA.INT_NUMERIC_VARIABLE' IN TYPEOF(SELF)) OR ('ENGINEERING_PROPERTIES_SCHEMA.REAL_NUMERIC_VARIABLE' IN TYPEOF(SELF));
2776   END_ENTITY;
2777
2778   ENTITY object_role;
2779      name : label;
2780      description : OPTIONAL text;
2781   END_ENTITY;
2782
2783   ENTITY odd_function
2784   SUBTYPE OF (unary_boolean_expression);
2785      SELF\unary_generic_expression.operand : numeric_expression;
2786   WHERE
2787      WR1:
2788         is_int_expr(SELF);
2789   END_ENTITY;
2790
2791   ENTITY or_expression
2792   SUBTYPE OF (multiple_arity_boolean_expression);
2793   END_ENTITY;
2794
2795   ENTITY ordinal_date
2796   SUBTYPE OF (date);
2797      day_component : day_in_year_number;
2798   WHERE
2799      WR1:
2800         NOT leap_year(SELF.year_component) AND ((1 <= day_component) AND (day_component <= 365)) OR leap_year(SELF.year_component) AND ((1 <= day_component) AND (day_component <= 366));
2801   END_ENTITY;
2802
2803   ENTITY organization;
2804      id : OPTIONAL identifier;
2805      name : label;
2806      description : OPTIONAL text;
2807   END_ENTITY;
2808
2809   ENTITY organization_assignment
2810   ABSTRACT SUPERTYPE;
2811      assigned_organization : organization;
2812      role : organization_role;
2813   END_ENTITY;
2814
2815   ENTITY organization_relationship;
2816      name : label;
2817      description : OPTIONAL text;
2818      relating_organization : organization;
2819      related_organization : organization;
2820   END_ENTITY;
2821
2822   ENTITY organization_role;
2823      name : label;
2824   DERIVE
2825      description : text := get_description_value(SELF);
2826   WHERE
2827      WR1:
2828         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
2829   END_ENTITY;
2830
2831   ENTITY organizational_address
2832   SUBTYPE OF (address);
2833      organizations : SET [1:?] OF organization;
2834      description : OPTIONAL text;
2835   END_ENTITY;
2836
2837   ENTITY organizational_project;
2838      name : label;
2839      description : OPTIONAL text;
2840      responsible_organizations : SET [1:?] OF organization;
2841   DERIVE
2842      id : identifier := get_id_value(SELF);
2843   WHERE
2844      WR1:
2845         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ID_ATTRIBUTE.IDENTIFIED_ITEM')) <= 1;
2846   END_ENTITY;
2847
2848   ENTITY organizational_project_assignment
2849   ABSTRACT SUPERTYPE;
2850      assigned_organizational_project : organizational_project;
2851      role : organizational_project_role;
2852   END_ENTITY;
2853
2854   ENTITY organizational_project_relationship;
2855      name : label;
2856      description : OPTIONAL text;
2857      relating_organizational_project : organizational_project;
2858      related_organizational_project : organizational_project;
2859   END_ENTITY;
2860
2861   ENTITY organizational_project_role;
2862      name : label;
2863      description : OPTIONAL text;
2864   END_ENTITY;
2865
2866   ENTITY oriented_surface
2867   SUBTYPE OF (surface);
2868      orientation : BOOLEAN;
2869   END_ENTITY;
2870
2871   ENTITY parabola
2872   SUBTYPE OF (conic);
2873      focal_dist : length_measure;
2874   WHERE
2875      WR1:
2876         focal_dist <> 0.00000;
2877   END_ENTITY;
2878
2879   ENTITY parallel_composed_function
2880   SUBTYPE OF (maths_function, multiple_arity_generic_expression);
2881      source_of_domain : maths_space_or_function;
2882      prep_functions : LIST [1:?] OF maths_function;
2883      final_function : maths_function_select;
2884   DERIVE
2885      SELF\multiple_arity_generic_expression.operands : LIST [2:?] OF generic_expression := convert_to_operands_prcmfn(source_of_domain, prep_functions, final_function);
2886   WHERE
2887      WR1:
2888         no_cyclic_domain_reference(source_of_domain, [ SELF ]);
2889      WR2:
2890         expression_is_constant(domain_from(source_of_domain));
2891      WR3:
2892         parallel_composed_function_domain_check(domain_from(source_of_domain), prep_functions);
2893      WR4:
2894         parallel_composed_function_composability_check(prep_functions, final_function);
2895   END_ENTITY;
2896
2897   ENTITY parallel_offset
2898   SUBTYPE OF (derived_shape_aspect);
2899      offset : measure_with_unit;
2900   WHERE
2901      WR1:
2902         SIZEOF(SELF\derived_shape_aspect.deriving_relationships) = 1;
2903   END_ENTITY;
2904
2905   ENTITY parallelism_tolerance
2906   SUBTYPE OF (geometric_tolerance_with_datum_reference);
2907   WHERE
2908      WR1:
2909         SIZEOF(SELF\geometric_tolerance_with_datum_reference.datum_system) < 3;
2910   END_ENTITY;
2911
2912   ENTITY parametric_representation_context
2913   SUBTYPE OF (representation_context);
2914   END_ENTITY;
2915
2916   ENTITY partial_derivative_expression
2917   SUBTYPE OF (unary_generic_expression);
2918      d_variables : LIST [1:?] OF maths_variable;
2919      extension : extension_options;
2920   DERIVE
2921      derivand : generic_expression := SELF\unary_generic_expression.operand;
2922   WHERE
2923      WR1:
2924         has_values_space(derivand);
2925      WR2:
2926         space_is_continuum(values_space_of(derivand));
2927      WR3:
2928         SIZEOF(QUERY (vbl <* d_variables| NOT subspace_of(values_space_of(vbl), the_reals) AND NOT subspace_of(values_space_of(vbl), the_complex_numbers))) = 0;
2929   END_ENTITY;
2930
2931   ENTITY partial_derivative_function
2932   SUBTYPE OF (maths_function, unary_generic_expression);
2933      SELF\unary_generic_expression.operand : maths_function;
2934      d_variables : LIST [1:?] OF input_selector;
2935      extension : extension_options;
2936   DERIVE
2937      derivand : maths_function := SELF\unary_generic_expression.operand;
2938   WHERE
2939      WR1:
2940         space_is_continuum(derivand.range);
2941      WR2:
2942         partial_derivative_check(derivand.domain, d_variables);
2943   END_ENTITY;
2944
2945   ENTITY perpendicular_to
2946   SUBTYPE OF (derived_shape_aspect);
2947   WHERE
2948      WR1:
2949         SIZEOF(SELF\derived_shape_aspect.deriving_relationships) = 1;
2950   END_ENTITY;
2951
2952   ENTITY perpendicularity_tolerance
2953   SUBTYPE OF (geometric_tolerance_with_datum_reference);
2954   WHERE
2955      WR1:
2956         SIZEOF(SELF\geometric_tolerance_with_datum_reference.datum_system) <= 3;
2957   END_ENTITY;
2958
2959   ENTITY person;
2960      id : identifier;
2961      last_name : OPTIONAL label;
2962      first_name : OPTIONAL label;
2963      middle_names : OPTIONAL LIST [1:?] OF label;
2964      prefix_titles : OPTIONAL LIST [1:?] OF label;
2965      suffix_titles : OPTIONAL LIST [1:?] OF label;
2966   WHERE
2967      WR1:
2968         EXISTS(last_name) OR EXISTS(first_name);
2969   END_ENTITY;
2970
2971   ENTITY person_and_organization;
2972      the_person : person;
2973      the_organization : organization;
2974   DERIVE
2975      name : label := get_name_value(SELF);
2976      description : text := get_description_value(SELF);
2977   WHERE
2978      WR1:
2979         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'NAME_ATTRIBUTE.NAMED_ITEM')) <= 1;
2980      WR2:
2981         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
2982   END_ENTITY;
2983
2984   ENTITY person_and_organization_assignment
2985   ABSTRACT SUPERTYPE;
2986      assigned_person_and_organization : person_and_organization;
2987      role : person_and_organization_role;
2988   END_ENTITY;
2989
2990   ENTITY person_and_organization_role;
2991      name : label;
2992   DERIVE
2993      description : text := get_description_value(SELF);
2994   WHERE
2995      WR1:
2996         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
2997   END_ENTITY;
2998
2999   ENTITY person_assignment
3000   ABSTRACT SUPERTYPE;
3001      assigned_person : person;
3002      role : person_role;
3003   END_ENTITY;
3004
3005   ENTITY person_role;
3006      name : label;
3007   DERIVE
3008      description : text := get_description_value(SELF);
3009   WHERE
3010      WR1:
3011         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
3012   END_ENTITY;
3013
3014   ENTITY person_type;
3015      id : identifier;
3016      name : label;
3017      description : OPTIONAL text;
3018   END_ENTITY;
3019
3020   ENTITY person_type_definition;
3021      id : identifier;
3022      name : label;
3023      description : OPTIONAL text;
3024      formation : person_type_definition_formation;
3025   END_ENTITY;
3026
3027   ENTITY person_type_definition_formation;
3028      id : identifier;
3029      name : label;
3030      description : OPTIONAL text;
3031      of_person_type : person_type;
3032   END_ENTITY;
3033
3034   ENTITY person_type_definition_relationship;
3035      id : identifier;
3036      name : label;
3037      description : OPTIONAL text;
3038      relating_person_type_definition : person_type_definition;
3039      related_person_type_definition : person_type_definition;
3040   END_ENTITY;
3041
3042   ENTITY personal_address
3043   SUBTYPE OF (address);
3044      people : SET [1:?] OF person;
3045      description : OPTIONAL text;
3046   END_ENTITY;
3047
3048   ENTITY placement
3049   SUPERTYPE OF (ONEOF(axis1_placement, axis2_placement_2d, axis2_placement_3d))
3050   SUBTYPE OF (geometric_representation_item);
3051      location : cartesian_point;
3052   END_ENTITY;
3053
3054   ENTITY plane
3055   SUBTYPE OF (elementary_surface);
3056   END_ENTITY;
3057
3058   ENTITY plane_angle_measure_with_unit
3059   SUBTYPE OF (measure_with_unit);
3060   WHERE
3061      WR1:
3062         'ENGINEERING_PROPERTIES_SCHEMA.PLANE_ANGLE_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
3063   END_ENTITY;
3064
3065   ENTITY plane_angle_unit
3066   SUBTYPE OF (named_unit);
3067   WHERE
3068      WR1:
3069         ((((((SELF\named_unit.dimensions.length_exponent = 0.00000) AND (SELF\named_unit.dimensions.mass_exponent = 0.00000)) AND (SELF\named_unit.dimensions.time_exponent = 0.00000)) AND (SELF\named_unit.dimensions.electric_current_exponent = 0.00000)) AND (SELF\named_unit.dimensions.thermodynamic_temperature_exponent = 0.00000)) AND (SELF\named_unit.dimensions.amount_of_substance_exponent = 0.00000)) AND (SELF\named_unit.dimensions.luminous_intensity_exponent = 0.00000);
3070   END_ENTITY;
3071
3072   ENTITY plus_expression
3073   SUBTYPE OF (multiple_arity_numeric_expression);
3074   END_ENTITY;
3075
3076   ENTITY plus_minus_tolerance;
3077      range : tolerance_method_definition;
3078      toleranced_dimension : dimensional_characteristic;
3079   UNIQUE
3080      UR1 : toleranced_dimension;
3081   END_ENTITY;
3082
3083   ENTITY point
3084   SUPERTYPE OF (ONEOF(cartesian_point, point_on_curve, point_on_surface, point_in_volume))
3085   SUBTYPE OF (geometric_representation_item);
3086   END_ENTITY;
3087
3088   ENTITY point_in_volume
3089   SUBTYPE OF (point);
3090      basis_volume : volume;
3091      point_parameter_u : parameter_value;
3092      point_parameter_v : parameter_value;
3093      point_parameter_w : parameter_value;
3094   END_ENTITY;
3095
3096   ENTITY point_on_curve
3097   SUBTYPE OF (point);
3098      basis_curve : curve;
3099      point_parameter : parameter_value;
3100   END_ENTITY;
3101
3102   ENTITY point_on_surface
3103   SUBTYPE OF (point);
3104      basis_surface : surface;
3105      point_parameter_u : parameter_value;
3106      point_parameter_v : parameter_value;
3107   END_ENTITY;
3108
3109   ENTITY polar_complex_number_region
3110   SUBTYPE OF (maths_space, generic_literal);
3111      centre : complex_number_literal;
3112      distance_constraint : real_interval;
3113      direction_constraint : finite_real_interval;
3114   WHERE
3115      WR1:
3116         min_exists(distance_constraint) AND (real_min(distance_constraint) >= 0.00000);
3117      WR2:
3118         (-3.14159 <= direction_constraint.min) AND (direction_constraint.min < 3.14159);
3119      WR3:
3120         direction_constraint.max - direction_constraint.min <= 2.00000 * 3.14159;
3121      WR4:
3122         (direction_constraint.max - direction_constraint.min < 2.00000 * 3.14159) OR (direction_constraint.min_closure = open);
3123      WR5:
3124         ((direction_constraint.max - direction_constraint.min < 2.00000 * 3.14159) OR (direction_constraint.max_closure = open)) OR (direction_constraint.min = -3.14159);
3125      WR6:
3126         (((real_min(distance_constraint) > 0.00000) OR max_exists(distance_constraint)) OR (direction_constraint.max - direction_constraint.min < 2.00000 * 3.14159)) OR (direction_constraint.max_closure = open);
3127   END_ENTITY;
3128
3129   ENTITY polar_point
3130   SUBTYPE OF (cartesian_point);
3131      r : length_measure;
3132      theta : plane_angle_measure;
3133   DERIVE
3134      SELF\cartesian_point.coordinates : LIST [1:3] OF length_measure := [ r * COS(theta), r * SIN(theta) ];
3135   WHERE
3136      WR1:
3137         r >= 0.00000;
3138   END_ENTITY;
3139
3140   ENTITY position_tolerance
3141   SUBTYPE OF (geometric_tolerance);
3142   WHERE
3143      WR1:
3144         NOT ('ENGINEERING_PROPERTIES_SCHEMA.' + 'GEOMETRIC_TOLERANCE_WITH_DATUM_REFERENCE' IN TYPEOF(SELF)) OR (SIZEOF(SELF\geometric_tolerance_with_datum_reference.datum_system) <= 3);
3145   END_ENTITY;
3146
3147   ENTITY power_expression
3148   SUBTYPE OF (binary_numeric_expression);
3149   END_ENTITY;
3150
3151   ENTITY power_measure_with_unit
3152   SUBTYPE OF (measure_with_unit);
3153   WHERE
3154      WR1:
3155         'ENGINEERING_PROPERTIES_SCHEMA.POWER_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
3156   END_ENTITY;
3157
3158   ENTITY power_unit
3159   SUBTYPE OF (derived_unit);
3160   WHERE
3161      WR1:
3162         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.watt);
3163   END_ENTITY;
3164
3165	ENTITY si_power_unit
3166     SUBTYPE OF (power_unit,si_unit);
3167  WHERE
3168    WR1: SELF\si_unit.name = si_unit_name.watt;
3169    WR2: NOT EXISTS(SELF\derived_unit.name);
3170  END_ENTITY;
3171
3172   ENTITY pre_defined_item;
3173      name : label;
3174   END_ENTITY;
3175
3176   ENTITY precision_qualifier;
3177      precision_value : INTEGER;
3178   END_ENTITY;
3179
3180   ENTITY pressure_measure_with_unit
3181   SUBTYPE OF (measure_with_unit);
3182   WHERE
3183      WR1:
3184         'ENGINEERING_PROPERTIES_SCHEMA.PRESSURE_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
3185   END_ENTITY;
3186
3187   ENTITY pressure_unit
3188   SUBTYPE OF (derived_unit);
3189   WHERE
3190      WR1:
3191         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.pascal);
3192   END_ENTITY;
3193
3194	ENTITY si_pressure_unit
3195     SUBTYPE OF (pressure_unit,si_unit);
3196  WHERE
3197    WR1: SELF\si_unit.name = si_unit_name.pascal;
3198    WR2: NOT EXISTS(SELF\derived_unit.name);
3199  END_ENTITY;
3200
3201   ENTITY process_or_process_relationship_effectivity
3202   SUBTYPE OF (effectivity);
3203      effective_process_or_process_relationship : process_or_process_relationship;
3204   END_ENTITY;
3205
3206   ENTITY process_product_association;
3207      name : label;
3208      description : text;
3209      defined_product : characterized_product_definition;
3210      process : product_definition_process;
3211   END_ENTITY;
3212
3213   ENTITY process_property_association;
3214      name : label;
3215      description : text;
3216      process : property_process;
3217      property_or_shape : property_or_shape_select;
3218   END_ENTITY;
3219
3220   ENTITY product;
3221      id : identifier;
3222      name : label;
3223      description : OPTIONAL text;
3224      frame_of_reference : SET [1:?] OF product_context;
3225   END_ENTITY;
3226
3227   ENTITY product_as_individual
3228   ABSTRACT SUPERTYPE OF (ONEOF(product_as_planned, product_as_realised))
3229   SUBTYPE OF (product_definition_formation);
3230   END_ENTITY;
3231
3232   ENTITY product_as_planned
3233   SUBTYPE OF (product_as_individual);
3234   END_ENTITY;
3235
3236   ENTITY product_as_realised
3237   SUBTYPE OF (product_as_individual);
3238   END_ENTITY;
3239
3240   ENTITY product_category;
3241      name : label;
3242      description : OPTIONAL text;
3243   DERIVE
3244      id : identifier := get_id_value(SELF);
3245   WHERE
3246      WR1:
3247         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ID_ATTRIBUTE.IDENTIFIED_ITEM')) <= 1;
3248   END_ENTITY;
3249
3250   ENTITY product_category_relationship;
3251      name : label;
3252      description : OPTIONAL text;
3253      category : product_category;
3254      sub_category : product_category;
3255   WHERE
3256      WR1:
3257         acyclic_product_category_relationship(SELF, [ SELF.sub_category ]);
3258   END_ENTITY;
3259
3260   ENTITY product_concept;
3261      id : identifier;
3262      name : label;
3263      description : OPTIONAL text;
3264      market_context : product_concept_context;
3265   UNIQUE
3266      UR1 : id;
3267   END_ENTITY;
3268
3269   ENTITY product_concept_context
3270   SUBTYPE OF (application_context_element);
3271      market_segment_type : label;
3272   END_ENTITY;
3273
3274   ENTITY product_context
3275   SUBTYPE OF (application_context_element);
3276      discipline_type : label;
3277   END_ENTITY;
3278
3279   ENTITY product_definition;
3280      id : identifier;
3281      description : OPTIONAL text;
3282      formation : product_definition_formation;
3283      frame_of_reference : product_definition_context;
3284   DERIVE
3285      name : label := get_name_value(SELF);
3286   WHERE
3287      WR1:
3288         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'NAME_ATTRIBUTE.NAMED_ITEM')) <= 1;
3289   END_ENTITY;
3290
3291   ENTITY product_definition_context
3292   SUBTYPE OF (application_context_element);
3293      life_cycle_stage : label;
3294   END_ENTITY;
3295
3296   ENTITY product_definition_formation;
3297      id : identifier;
3298      description : OPTIONAL text;
3299      of_product : product;
3300   UNIQUE
3301      UR1 : id, of_product;
3302   END_ENTITY;
3303
3304   ENTITY product_definition_formation_relationship;
3305      id : identifier;
3306      name : label;
3307      description : OPTIONAL text;
3308      relating_product_definition_formation : product_definition_formation;
3309      related_product_definition_formation : product_definition_formation;
3310   END_ENTITY;
3311
3312   ENTITY product_definition_process
3313   SUBTYPE OF (action);
3314      identification : identifier;
3315   INVERSE
3316      product_definitions : SET [1:?] OF process_product_association FOR process;
3317   END_ENTITY;
3318   ENTITY product_definition_relationship;
3319      id : identifier;
3320      name : label;
3321      description : OPTIONAL text;
3322      relating_product_definition : product_definition;
3323      related_product_definition : product_definition;
3324   END_ENTITY;
3325
3326   ENTITY product_definition_shape
3327   SUBTYPE OF (property_definition);
3328   UNIQUE
3329      UR1 : SELF\property_definition.definition;
3330   WHERE
3331      WR1:         SIZEOF([ 'ENGINEERING_PROPERTIES_SCHEMA.CHARACTERIZED_PRODUCT_DEFINITION', 'ENGINEERING_PROPERTIES_SCHEMA.CHARACTERIZED_OBJECT' ] * TYPEOF(SELF\property_definition.definition)) > 0;
3332   END_ENTITY;
3333
3334   ENTITY product_definition_substitute;
3335      description : OPTIONAL text;
3336      context_relationship : product_definition_relationship;
3337      substitute_definition : product_definition;
3338   DERIVE
3339      name : label := get_name_value(SELF);
3340   WHERE
3341      WR1:
3342         context_relationship.related_product_definition :<>: substitute_definition;
3343      WR2:
3344         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'NAME_ATTRIBUTE.NAMED_ITEM')) <= 1;
3345   END_ENTITY;
3346
3347   ENTITY product_definition_with_associated_documents
3348   SUBTYPE OF (product_definition);
3349      documentation_ids : SET [1:?] OF document;
3350   END_ENTITY;
3351
3352   ENTITY product_material_composition_relationship
3353   SUBTYPE OF (product_definition_relationship);
3354      class : label;
3355      constituent_amount : SET [1:?] OF characterized_product_composition_value;
3356      composition_basis : label;
3357      determination_method : text;
3358   END_ENTITY;
3359
3360   ENTITY product_relationship;
3361      id : identifier;
3362      name : label;
3363      description : OPTIONAL text;
3364      relating_product : product;
3365      related_product : product;
3366   END_ENTITY;
3367
3368   ENTITY projected_zone_definition
3369   SUBTYPE OF (tolerance_zone_definition);
3370      projection_end : shape_aspect;
3371      projected_length : measure_with_unit;
3372   WHERE
3373      WR1:
3374         ('NUMBER' IN TYPEOF(projected_length\measure_with_unit.value_component)) AND (projected_length\measure_with_unit.value_component > 0.00000);
3375      WR2:         derive_dimensional_exponents(projected_length\measure_with_unit.unit_component) = dimensional_exponents(1, 0, 0, 0, 0, 0, 0);
3376   END_ENTITY;
3377
3378   ENTITY property_definition;
3379      name : label;
3380      description : OPTIONAL text;
3381      definition : characterized_definition;
3382   DERIVE
3383      id : identifier := get_id_value(SELF);
3384   WHERE
3385      WR1:
3386         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ID_ATTRIBUTE.IDENTIFIED_ITEM')) <= 1;
3387   END_ENTITY;
3388
3389   ENTITY property_definition_relationship;
3390      name : label;
3391      description : text;
3392      relating_property_definition : property_definition;
3393      related_property_definition : property_definition;
3394   END_ENTITY;
3395
3396   ENTITY property_definition_representation;
3397      definition : represented_definition;
3398      used_representation : representation;
3399   DERIVE
3400      description : text := get_description_value(SELF);
3401      name : label := get_name_value(SELF);
3402   WHERE
3403      WR1:
3404         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
3405      WR2:
3406         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'NAME_ATTRIBUTE.NAMED_ITEM')) <= 1;
3407   END_ENTITY;
3408
3409   ENTITY property_process
3410   SUBTYPE OF (action);
3411      identification : identifier;
3412   INVERSE
3413      properties : SET [1:?] OF process_property_association FOR process;
3414   END_ENTITY;
3415
3416   ENTITY qualification;
3417      id : identifier;
3418      name : label;
3419      description : OPTIONAL text;
3420   END_ENTITY;
3421
3422   ENTITY qualification_relationship;
3423      id : identifier;
3424      name : label;
3425      description : OPTIONAL text;
3426      relating_qualification : qualification;
3427      related_qualification : qualification;
3428   END_ENTITY;
3429
3430   ENTITY qualification_type;
3431      id : identifier;
3432      name : label;
3433      description : OPTIONAL text;
3434   END_ENTITY;
3435
3436   ENTITY qualification_type_assignment
3437   ABSTRACT SUPERTYPE;
3438      id : identifier;
3439      name : label;
3440      description : OPTIONAL text;
3441      assigned_qualification_type : qualification_type;
3442      role : qualification_type_role;
3443   END_ENTITY;
3444
3445   ENTITY qualification_type_role;
3446      id : identifier;
3447      name : label;
3448      description : OPTIONAL text;
3449   END_ENTITY;
3450
3451   ENTITY qualified_representation_item
3452   SUBTYPE OF (representation_item);
3453      qualifiers : SET [1:?] OF value_qualifier;
3454   WHERE
3455      WR1:
3456         SIZEOF(QUERY (temp <* qualifiers| ('ENGINEERING_PROPERTIES_SCHEMA.PRECISION_QUALIFIER' IN TYPEOF(temp)))) < 2;
3457   END_ENTITY;
3458
3459   ENTITY qualitative_uncertainty
3460   SUBTYPE OF (uncertainty_qualifier);
3461      uncertainty_value : text;
3462   END_ENTITY;
3463
3464   ENTITY quantifier_expression
3465   ABSTRACT SUPERTYPE
3466   SUBTYPE OF (multiple_arity_generic_expression);
3467      variables : LIST [1:?] OF UNIQUE generic_variable;
3468   WHERE
3469      WR1:
3470         SIZEOF(QUERY (vrbl <* variables| NOT (vrbl IN SELF\multiple_arity_generic_expression.operands))) = 0;
3471      WR2:
3472         SIZEOF(QUERY (vrbl <* variables| NOT (schema_prefix + 'BOUND_VARIABLE_SEMANTICS' IN TYPEOF(vrbl.interpretation.semantics)))) = 0;
3473   END_ENTITY;
3474
3475   ENTITY radioactivity_measure_with_unit
3476   SUBTYPE OF (measure_with_unit);
3477   WHERE
3478      WR1:
3479         'ENGINEERING_PROPERTIES_SCHEMA.RADIOACTIVITY_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
3480   END_ENTITY;
3481
3482   ENTITY radioactivity_unit
3483   SUBTYPE OF (derived_unit);
3484   WHERE
3485      WR1:
3486         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.becquerel);
3487   END_ENTITY;
3488
3489	ENTITY si_radioactivity_unit
3490     SUBTYPE OF (radioactivity_unit,si_unit);
3491  WHERE
3492    WR1: SELF\si_unit.name = si_unit_name.becquerel;
3493    WR2: NOT EXISTS(SELF\derived_unit.name);
3494  END_ENTITY;
3495
3496   ENTITY ratio_measure_with_unit
3497   SUBTYPE OF (measure_with_unit);
3498   WHERE
3499      WR1:
3500         'ENGINEERING_PROPERTIES_SCHEMA.RATIO_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
3501   END_ENTITY;
3502
3503   ENTITY ratio_unit
3504   SUBTYPE OF (named_unit);
3505   WHERE
3506      WR1:
3507         ((((((SELF\named_unit.dimensions.length_exponent = 0.00000) AND (SELF\named_unit.dimensions.mass_exponent = 0.00000)) AND (SELF\named_unit.dimensions.time_exponent = 0.00000)) AND (SELF\named_unit.dimensions.electric_current_exponent = 0.00000)) AND (SELF\named_unit.dimensions.thermodynamic_temperature_exponent = 0.00000)) AND (SELF\named_unit.dimensions.amount_of_substance_exponent = 0.00000)) AND (SELF\named_unit.dimensions.luminous_intensity_exponent = 0.00000);
3508   END_ENTITY;
3509
3510   ENTITY rationalize_function
3511   SUBTYPE OF (maths_function, unary_generic_expression);
3512      SELF\unary_generic_expression.operand : maths_function;
3513   DERIVE
3514      fun : maths_function := SELF\unary_generic_expression.operand;
3515   WHERE
3516      WR1:
3517         (space_dimension(fun.domain) = 1) AND (space_dimension(fun.range) = 1);
3518      WR2:
3519         number_tuple_subspace_check(factor1(fun.range));
3520      WR3:
3521         space_dimension(factor1(fun.range)) > 1;
3522   END_ENTITY;
3523
3524   ENTITY real_defined_function
3525   ABSTRACT SUPERTYPE
3526   SUBTYPE OF (numeric_defined_function);
3527   END_ENTITY;
3528
3529   ENTITY real_interval_from_min
3530   SUBTYPE OF (maths_space, generic_literal);
3531      min : REAL;
3532      min_closure : open_closed;
3533   END_ENTITY;
3534
3535   ENTITY real_interval_to_max
3536   SUBTYPE OF (maths_space, generic_literal);
3537      max : REAL;
3538      max_closure : open_closed;
3539   END_ENTITY;
3540
3541   ENTITY real_literal
3542   SUBTYPE OF (literal_number);
3543      SELF\literal_number.the_value : REAL;
3544   END_ENTITY;
3545
3546   ENTITY real_numeric_variable
3547   SUBTYPE OF (numeric_variable);
3548   END_ENTITY;
3549
3550   ENTITY real_tuple_literal
3551   SUBTYPE OF (generic_literal);
3552      lit_value : LIST [1:?] OF REAL;
3553   END_ENTITY;
3554
3555   ENTITY referenced_modified_datum
3556   SUBTYPE OF (datum_reference);
3557      modifier : limit_condition;
3558   END_ENTITY;
3559
3560   ENTITY regular_table_function
3561   SUBTYPE OF (linearized_table_function);
3562      increments : LIST [1:?] OF INTEGER;
3563   WHERE
3564      WR1:
3565         SIZEOF(increments) = SIZEOF(SELF\explicit_table_function.shape);
3566      WR2:
3567         extremal_position_check(SELF);
3568   END_ENTITY;
3569
3570   ENTITY reindexed_array_function
3571   SUBTYPE OF (maths_function, unary_generic_expression);
3572      SELF\unary_generic_expression.operand : maths_function;
3573      starting_indices : LIST [1:?] OF INTEGER;
3574   WHERE
3575      WR1:
3576         function_is_array(SELF\unary_generic_expression.operand);
3577      WR2:
3578         SIZEOF(starting_indices) = SIZEOF(shape_of_array(SELF\unary_generic_expression.operand));
3579   END_ENTITY;
3580
3581   ENTITY repackaging_function
3582   SUBTYPE OF (maths_function, unary_generic_expression);
3583      SELF\unary_generic_expression.operand : maths_function;
3584      input_repack : repackage_options;
3585      output_repack : repackage_options;
3586      selected_output : nonnegative_integer;
3587   WHERE
3588      WR1:
3589         (input_repack <> ro_wrap_as_tuple) OR (space_dimension(operand.domain) = 1) AND (schema_prefix + 'TUPLE_SPACE' IN TYPEOF(factor1(operand.domain)));
3590      WR2:
3591         (output_repack <> ro_unwrap_tuple) OR (space_dimension(operand.range) = 1) AND (schema_prefix + 'TUPLE_SPACE' IN TYPEOF(factor1(operand.range)));
3592      WR3:
3593         selected_output <= space_dimension(repackage(operand.range, output_repack));
3594   END_ENTITY;
3595
3596   ENTITY representation;
3597      name : label;
3598      items : SET [1:?] OF representation_item;
3599      context_of_items : representation_context;
3600   DERIVE
3601      id : identifier := get_id_value(SELF);
3602      description : text := get_description_value(SELF);
3603   WHERE
3604      WR1:
3605         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ID_ATTRIBUTE.IDENTIFIED_ITEM')) <= 1;
3606      WR2:
3607         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
3608   END_ENTITY;
3609
3610   ENTITY representation_context;
3611      context_identifier : identifier;
3612      context_type : text;
3613   INVERSE
3614      representations_in_context : SET [1:?] OF representation FOR context_of_items;
3615   END_ENTITY;
3616
3617   ENTITY representation_item;
3618      name : label;
3619   WHERE
3620      WR1:
3621         SIZEOF(using_representations(SELF)) > 0;
3622   END_ENTITY;
3623
3624   ENTITY representation_item_relationship;
3625      name : label;
3626      description : OPTIONAL text;
3627      relating_representation_item : representation_item;
3628      related_representation_item : representation_item;
3629   END_ENTITY;
3630
3631   ENTITY representation_map;
3632      mapping_origin : representation_item;
3633      mapped_representation : representation;
3634   INVERSE
3635      map_usage : SET [1:?] OF mapped_item FOR mapping_source;
3636   WHERE
3637      WR1:
3638         item_in_context(SELF.mapping_origin, SELF.mapped_representation.context_of_items);
3639   END_ENTITY;
3640
3641   ENTITY representation_relationship;
3642      name : label;
3643      description : OPTIONAL text;
3644      rep_1 : representation;
3645      rep_2 : representation;
3646   END_ENTITY;
3647
3648   ENTITY representation_relationship_with_transformation
3649   SUBTYPE OF (representation_relationship);
3650      transformation_operator : transformation;
3651   WHERE
3652      WR1:
3653         SELF\representation_relationship.rep_1.context_of_items :<>: SELF\representation_relationship.rep_2.context_of_items;
3654   END_ENTITY;
3655
3656   ENTITY requirement_for_action_resource
3657   SUBTYPE OF (action_resource_requirement);
3658      resources : SET [1:?] OF action_resource;
3659   END_ENTITY;
3660
3661   ENTITY resistance_measure_with_unit
3662   SUBTYPE OF (measure_with_unit);
3663   WHERE
3664      WR1:
3665         'ENGINEERING_PROPERTIES_SCHEMA.RESISTANCE_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
3666   END_ENTITY;
3667
3668   ENTITY resistance_unit
3669   SUBTYPE OF (derived_unit);
3670   WHERE
3671      WR1:
3672         derive_dimensional_exponents(SELF) = dimensions_for_si_unit(si_unit_name.ohm);
3673   END_ENTITY;
3674
3675	ENTITY si_resistance_unit
3676     SUBTYPE OF (resistance_unit,si_unit);
3677  WHERE
3678    WR1: SELF\si_unit.name = si_unit_name.ohm;
3679    WR2: NOT EXISTS(SELF\derived_unit.name);
3680  END_ENTITY;
3681
3682   ENTITY resource_property;
3683      name : label;
3684      description : text;
3685      resource : characterized_resource_definition;
3686   END_ENTITY;
3687
3688   ENTITY resource_property_relationship;
3689      name : label;
3690      description : text;
3691      relating_resource_property : resource_property;
3692      related_resource_property : resource_property;
3693   WHERE
3694      WR1:
3695         relating_resource_property :<>: related_resource_property;
3696   END_ENTITY;
3697
3698   ENTITY resource_property_representation;
3699      name : label;
3700      description : text;
3701      property : resource_property;
3702      representation : representation;
3703   END_ENTITY;
3704
3705   ENTITY resource_requirement_type;
3706      name : label;
3707      description : text;
3708   END_ENTITY;
3709
3710   ENTITY resource_requirement_type_relationship;
3711      name : label;
3712      description : text;
3713      relating_requirement_type : resource_requirement_type;
3714      related_requirement_type : resource_requirement_type;
3715   WHERE
3716      WR1:
3717         relating_requirement_type :<>: related_requirement_type;
3718   END_ENTITY;
3719
3720   ENTITY restriction_function
3721   SUBTYPE OF (maths_function, unary_generic_expression);
3722      SELF\unary_generic_expression.operand : maths_space;
3723   END_ENTITY;
3724
3725   ENTITY role_association;
3726      role : object_role;
3727      item_with_role : role_select;
3728   END_ENTITY;
3729
3730   ENTITY roundness_tolerance
3731   SUBTYPE OF (geometric_tolerance);
3732   WHERE
3733      WR1:
3734         NOT ('ENGINEERING_PROPERTIES_SCHEMA.' + 'GEOMETRIC_TOLERANCE_WITH_DATUM_REFERENCE' IN TYPEOF(SELF));
3735   END_ENTITY;
3736
3737   ENTITY runout_zone_definition
3738   SUBTYPE OF (tolerance_zone_definition);
3739      orientation : runout_zone_orientation;
3740   END_ENTITY;
3741
3742   ENTITY runout_zone_orientation;
3743      angle : measure_with_unit;
3744   END_ENTITY;
3745
3746   ENTITY runout_zone_orientation_reference_direction
3747   SUBTYPE OF (runout_zone_orientation);
3748      orientation_defining_relationship : shape_aspect_relationship;
3749   END_ENTITY;
3750
3751   ENTITY security_classification;
3752      name : label;
3753      purpose : text;
3754      security_level : security_classification_level;
3755   END_ENTITY;
3756
3757   ENTITY security_classification_assignment
3758   ABSTRACT SUPERTYPE;
3759      assigned_security_classification : security_classification;
3760   DERIVE
3761      role : object_role := get_role(SELF);
3762   WHERE
3763      WR1:
3764         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ROLE_ASSOCIATION.ITEM_WITH_ROLE')) <= 1;
3765   END_ENTITY;
3766
3767   ENTITY security_classification_level;
3768      name : label;
3769   END_ENTITY;
3770
3771   ENTITY selector_function
3772   SUBTYPE OF (maths_function, generic_literal);
3773      selector : input_selector;
3774      source_of_domain : maths_space_or_function;
3775   WHERE
3776      WR1:
3777         no_cyclic_domain_reference(source_of_domain, [ SELF ]);
3778      WR2:
3779         expression_is_constant(domain_from(source_of_domain));
3780   END_ENTITY;
3781
3782   ENTITY sequential_method
3783   SUBTYPE OF (serial_action_method);
3784      sequence_position : count_measure;
3785   END_ENTITY;
3786
3787   ENTITY serial_action_method
3788   SUBTYPE OF (action_method_relationship);
3789   END_ENTITY;
3790
3791   ENTITY serial_numbered_effectivity
3792   SUBTYPE OF (effectivity);
3793      effectivity_start_id : identifier;
3794      effectivity_end_id : OPTIONAL identifier;
3795   END_ENTITY;
3796
3797   ENTITY series_composed_function
3798   SUBTYPE OF (maths_function, multiple_arity_generic_expression);
3799      SELF\multiple_arity_generic_expression.operands : LIST [2:?] OF maths_function;
3800   WHERE
3801      WR1:
3802         composable_sequence(SELF\multiple_arity_generic_expression.operands);
3803   END_ENTITY;
3804
3805   ENTITY shape_aspect;
3806      name : label;
3807      description : OPTIONAL text;
3808      of_shape : product_definition_shape;
3809      product_definitional : LOGICAL;
3810   DERIVE
3811      id : identifier := get_id_value(SELF);
3812   WHERE
3813      WR1:
3814         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ID_ATTRIBUTE.IDENTIFIED_ITEM')) <= 1;
3815   END_ENTITY;
3816
3817   ENTITY shape_aspect_deriving_relationship
3818   SUBTYPE OF (shape_aspect_relationship);
3819   WHERE
3820      WR1:
3821         'ENGINEERING_PROPERTIES_SCHEMA.DERIVED_SHAPE_ASPECT' IN TYPEOF(SELF\shape_aspect_relationship.relating_shape_aspect);
3822   END_ENTITY;
3823
3824   ENTITY shape_aspect_relationship;
3825      name : label;
3826      description : OPTIONAL text;
3827      relating_shape_aspect : shape_aspect;
3828      related_shape_aspect : shape_aspect;
3829   DERIVE
3830      id : identifier := get_id_value(SELF);
3831   WHERE
3832      WR1:
3833         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ID_ATTRIBUTE.IDENTIFIED_ITEM')) <= 1;
3834   END_ENTITY;
3835
3836   ENTITY shape_definition_representation
3837   SUBTYPE OF (property_definition_representation);
3838   WHERE
3839      WR1:
3840         ('ENGINEERING_PROPERTIES_SCHEMA.PRODUCT_DEFINITION_SHAPE' IN TYPEOF(SELF.definition)) OR ('ENGINEERING_PROPERTIES_SCHEMA.SHAPE_DEFINITION' IN TYPEOF(SELF.definition.definition));
3841      WR2:
3842         'ENGINEERING_PROPERTIES_SCHEMA.SHAPE_REPRESENTATION' IN TYPEOF(SELF.used_representation);
3843   END_ENTITY;
3844
3845   ENTITY shape_dimension_representation
3846   SUBTYPE OF (shape_representation);
3847   WHERE
3848      WR1:
3849         SIZEOF(QUERY (temp <* SELF\representation.items| NOT ('ENGINEERING_PROPERTIES_SCHEMA.MEASURE_REPRESENTATION_ITEM' IN TYPEOF(temp)))) = 0;
3850      WR2:
3851         SIZEOF(SELF\representation.items) <= 3;
3852      WR3:
3853         SIZEOF(QUERY (pos_mri <* QUERY (real_mri <* SELF\representation.items| ('REAL' IN TYPEOF(real_mri\measure_with_unit.value_component)))| NOT (pos_mri\measure_with_unit.value_component > 0.00000))) = 0;
3854   END_ENTITY;
3855
3856   ENTITY shape_representation
3857   SUBTYPE OF (representation);
3858   END_ENTITY;
3859
3860   ENTITY shape_representation_relationship
3861   SUBTYPE OF (representation_relationship);
3862   WHERE
3863      WR1:
3864         'ENGINEERING_PROPERTIES_SCHEMA.SHAPE_REPRESENTATION' IN TYPEOF(SELF\representation_relationship.rep_1) + TYPEOF(SELF\representation_relationship.rep_2);
3865   END_ENTITY;
3866
3867   ENTITY si_unit
3868   SUBTYPE OF (named_unit);
3869      prefix : OPTIONAL si_prefix;
3870      name : si_unit_name;
3871   DERIVE
3872      SELF\named_unit.dimensions : dimensional_exponents := dimensions_for_si_unit(name);
3873   WHERE
3874      WR1:
3875         NOT (('ENGINEERING_PROPERTIES_SCHEMA.MASS_UNIT' IN TYPEOF(SELF)) AND (SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.DERIVED_UNIT_ELEMENT.UNIT')) > 0)) OR (prefix = si_prefix.kilo);
3876   END_ENTITY;
3877
3878   ENTITY simple_boolean_expression
3879   ABSTRACT SUPERTYPE OF (ONEOF(boolean_literal, boolean_variable))
3880   SUBTYPE OF (boolean_expression, simple_generic_expression);
3881   END_ENTITY;
3882
3883   ENTITY simple_generic_expression
3884   ABSTRACT SUPERTYPE OF (ONEOF(generic_literal, generic_variable))
3885   SUBTYPE OF (generic_expression);
3886   END_ENTITY;
3887
3888   ENTITY simple_numeric_expression
3889   ABSTRACT SUPERTYPE OF (ONEOF(literal_number, numeric_variable))
3890   SUBTYPE OF (numeric_expression, simple_generic_expression);
3891   END_ENTITY;
3892
3893   ENTITY simple_string_expression
3894   ABSTRACT SUPERTYPE OF (ONEOF(string_literal, string_variable))
3895   SUBTYPE OF (string_expression, simple_generic_expression);
3896   END_ENTITY;
3897
3898   ENTITY sin_function
3899   SUBTYPE OF (unary_function_call);
3900   END_ENTITY;
3901
3902   ENTITY solid_angle_measure_with_unit
3903   SUBTYPE OF (measure_with_unit);
3904   WHERE
3905      WR1:
3906         'ENGINEERING_PROPERTIES_SCHEMA.SOLID_ANGLE_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
3907   END_ENTITY;
3908
3909   ENTITY solid_angle_unit
3910   SUBTYPE OF (named_unit);
3911   WHERE
3912      WR1:
3913         ((((((SELF\named_unit.dimensions.length_exponent = 0.00000) AND (SELF\named_unit.dimensions.mass_exponent = 0.00000)) AND (SELF\named_unit.dimensions.time_exponent = 0.00000)) AND (SELF\named_unit.dimensions.electric_current_exponent = 0.00000)) AND (SELF\named_unit.dimensions.thermodynamic_temperature_exponent = 0.00000)) AND (SELF\named_unit.dimensions.amount_of_substance_exponent = 0.00000)) AND (SELF\named_unit.dimensions.luminous_intensity_exponent = 0.00000);
3914   END_ENTITY;
3915
3916   ENTITY spherical_point
3917   SUBTYPE OF (cartesian_point);
3918      r : length_measure;
3919      theta : plane_angle_measure;
3920      phi : plane_angle_measure;
3921   DERIVE
3922      SELF\cartesian_point.coordinates : LIST [1:3] OF length_measure := [ r * SIN(theta) * COS(phi), r * SIN(theta) * SIN(phi), r * COS(theta) ];
3923   WHERE
3924      WR1:
3925         r >= 0.00000;
3926   END_ENTITY;
3927
3928   ENTITY spherical_surface
3929   SUBTYPE OF (elementary_surface);
3930      radius : positive_length_measure;
3931   END_ENTITY;
3932
3933   ENTITY spherical_volume
3934   SUBTYPE OF (volume);
3935      position : axis2_placement_3d;
3936      radius : positive_length_measure;
3937   END_ENTITY;
3938
3939   ENTITY square_root_function
3940   SUBTYPE OF (unary_function_call);
3941   END_ENTITY;
3942
3943   ENTITY standard_table_function
3944   SUBTYPE OF (linearized_table_function);
3945      order : ordering_type;
3946   WHERE
3947      WR1:
3948         extremal_position_check(SELF);
3949   END_ENTITY;
3950
3951   ENTITY standard_uncertainty
3952   SUPERTYPE OF (expanded_uncertainty)
3953   SUBTYPE OF (uncertainty_qualifier);
3954      uncertainty_value : REAL;
3955   END_ENTITY;
3956
3957   ENTITY state_observed;
3958      name : label;
3959      description : OPTIONAL text;
3960   END_ENTITY;
3961
3962   ENTITY state_observed_assignment
3963   ABSTRACT SUPERTYPE;
3964      assigned_state_observed : state_observed;
3965      role : state_observed_role;
3966   END_ENTITY;
3967
3968   ENTITY state_observed_relationship;
3969      name : label;
3970      description : OPTIONAL text;
3971      relating_state_observed : SET [1:?] OF state_observed;
3972      related_state_observed : SET [1:?] OF state_observed;
3973   END_ENTITY;
3974   ENTITY state_observed_role;
3975      name : label;
3976      description : OPTIONAL text;
3977   END_ENTITY;
3978
3979   ENTITY state_type;
3980      name : label;
3981      description : OPTIONAL text;
3982   END_ENTITY;
3983
3984   ENTITY state_type_assignment
3985   ABSTRACT SUPERTYPE;
3986      assigned_state_type : state_type;
3987      role : state_type_role;
3988   END_ENTITY;
3989
3990   ENTITY state_type_relationship;
3991      name : label;
3992      description : OPTIONAL text;
3993      relating_state_type : SET [1:?] OF state_type;
3994      related_state_type : SET [1:?] OF state_type;
3995   END_ENTITY;
3996
3997   ENTITY state_type_role;
3998      name : label;
3999      description : OPTIONAL text;
4000   END_ENTITY;
4001
4002   ENTITY statistical_distribution_for_tolerance
4003   SUBTYPE OF (representation);
4004   WHERE
4005      WR1:
4006         SIZEOF(QUERY (item <* SELF\representation.items| NOT ('ENGINEERING_PROPERTIES_SCHEMA.MEASURE_REPRESENTATION_ITEM' IN TYPEOF(item)))) = 0;
4007   END_ENTITY;
4008
4009   ENTITY straightness_tolerance
4010   SUBTYPE OF (geometric_tolerance);
4011   WHERE
4012      WR1:
4013         NOT ('ENGINEERING_PROPERTIES_SCHEMA.' + 'GEOMETRIC_TOLERANCE_WITH_DATUM_REFERENCE' IN TYPEOF(SELF));
4014   END_ENTITY;
4015
4016   ENTITY strict_triangular_matrix
4017   SUBTYPE OF (triangular_matrix);
4018      main_diagonal_value : maths_value;
4019   END_ENTITY;
4020
4021   ENTITY string_defined_function
4022   ABSTRACT SUPERTYPE
4023   SUBTYPE OF (defined_function, string_expression);
4024   END_ENTITY;
4025
4026   ENTITY string_expression
4027   ABSTRACT SUPERTYPE OF (ONEOF(simple_string_expression, index_expression, substring_expression, concat_expression, format_function, string_defined_function))
4028   SUBTYPE OF (expression);
4029   END_ENTITY;
4030
4031   ENTITY string_literal
4032   SUBTYPE OF (simple_string_expression, generic_literal);
4033      the_value : STRING;
4034   END_ENTITY;
4035
4036   ENTITY string_variable
4037   SUBTYPE OF (simple_string_expression, variable);
4038   END_ENTITY;
4039
4040   ENTITY substring_expression
4041   SUBTYPE OF (string_expression, multiple_arity_generic_expression);
4042   DERIVE
4043      operand : generic_expression := SELF\multiple_arity_generic_expression.operands[1];
4044      index1 : generic_expression := SELF\multiple_arity_generic_expression.operands[2];
4045      index2 : generic_expression := SELF\multiple_arity_generic_expression.operands[3];
4046   WHERE
4047      WR1:
4048         (('ENGINEERING_PROPERTIES_SCHEMA.STRING_EXPRESSION' IN TYPEOF(operand)) AND ('ENGINEERING_PROPERTIES_SCHEMA.NUMERIC_EXPRESSION' IN TYPEOF(index1))) AND ('ENGINEERING_PROPERTIES_SCHEMA.NUMERIC_EXPRESSION' IN TYPEOF(index2));
4049      WR2:
4050         SIZEOF(SELF\multiple_arity_generic_expression.operands) = 3;
4051      WR3:
4052         is_int_expr(index1);
4053      WR4:
4054         is_int_expr(index2);
4055   END_ENTITY;
4056
4057   ENTITY surface
4058   SUPERTYPE OF (elementary_surface)
4059   SUBTYPE OF (geometric_representation_item);
4060   END_ENTITY;
4061
4062   ENTITY symmetric_banded_matrix
4063   SUBTYPE OF (symmetric_matrix);
4064      default_entry : maths_value;
4065      above : nonnegative_integer;
4066   WHERE
4067      WR1:
4068         member_of(default_entry, factor1(SELF\linearized_table_function.source.range));
4069   END_ENTITY;
4070
4071   ENTITY symmetric_matrix
4072   SUBTYPE OF (linearized_table_function);
4073      symmetry : symmetry_type;
4074      triangle : lower_upper;
4075      order : ordering_type;
4076   WHERE
4077      WR1:
4078         SIZEOF(SELF\explicit_table_function.shape) = 2;
4079      WR2:
4080         SELF\explicit_table_function.shape[1] = SELF\explicit_table_function.shape[2];
4081      WR3:
4082         NOT (symmetry = skew) OR (space_dimension(SELF\linearized_table_function.source.range) = 1) AND subspace_of_es(factor1(SELF\linearized_table_function.source.range), es_numbers);
4083      WR4:
4084         NOT ((symmetry = hermitian) OR (symmetry = skew_hermitian)) OR (space_dimension(SELF\linearized_table_function.source.range) = 1) AND subspace_of_es(factor1(SELF\linearized_table_function.source.range), es_complex_numbers);
4085   END_ENTITY;
4086
4087   ENTITY symmetric_shape_aspect
4088   SUBTYPE OF (shape_aspect);
4089   INVERSE
4090      basis_relationships : SET [1:?] OF shape_aspect_relationship FOR relating_shape_aspect;
4091   WHERE
4092      WR1:
4093         SIZEOF(QUERY (x <* SELF\symmetric_shape_aspect.basis_relationships| ('ENGINEERING_PROPERTIES_SCHEMA.CENTRE_OF_SYMMETRY' IN TYPEOF(x\shape_aspect_relationship.related_shape_aspect)))) >= 1;
4094   END_ENTITY;
4095
4096   ENTITY symmetry_tolerance
4097   SUBTYPE OF (geometric_tolerance_with_datum_reference);
4098   WHERE
4099      WR1:
4100         SIZEOF(SELF\geometric_tolerance_with_datum_reference.datum_system) <= 3;
4101   END_ENTITY;
4102
4103   ENTITY tan_function
4104   SUBTYPE OF (unary_function_call);
4105   END_ENTITY;
4106
4107   ENTITY tangent
4108   SUBTYPE OF (derived_shape_aspect);
4109   WHERE
4110      WR1:
4111         SIZEOF(SELF\derived_shape_aspect.deriving_relationships) = 1;
4112   END_ENTITY;
4113
4114   ENTITY thermodynamic_temperature_measure_with_unit
4115   SUBTYPE OF (measure_with_unit);
4116   WHERE
4117      WR1:
4118         'ENGINEERING_PROPERTIES_SCHEMA.THERMODYNAMIC_TEMPERATURE_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
4119   END_ENTITY;
4120
4121   ENTITY thermodynamic_temperature_unit
4122   SUBTYPE OF (named_unit);
4123   WHERE
4124      WR1:
4125         ((((((SELF\named_unit.dimensions.length_exponent = 0.00000) AND (SELF\named_unit.dimensions.mass_exponent = 0.00000)) AND (SELF\named_unit.dimensions.time_exponent = 0.00000)) AND (SELF\named_unit.dimensions.electric_current_exponent = 0.00000)) AND (SELF\named_unit.dimensions.thermodynamic_temperature_exponent = 1.00000)) AND (SELF\named_unit.dimensions.amount_of_substance_exponent = 0.00000)) AND (SELF\named_unit.dimensions.luminous_intensity_exponent = 0.00000);
4126   END_ENTITY;
4127
4128   ENTITY time_interval;
4129      id : identifier;
4130      name : label;
4131      description : OPTIONAL text;
4132   END_ENTITY;
4133
4134   ENTITY time_interval_assignment
4135   ABSTRACT SUPERTYPE;
4136      assigned_time_interval : time_interval;
4137      role : time_interval_role;
4138   END_ENTITY;
4139
4140   ENTITY time_interval_based_effectivity
4141   SUBTYPE OF (effectivity);
4142      effectivity_period : time_interval;
4143   END_ENTITY;
4144
4145   ENTITY time_interval_relationship;
4146      name : label;
4147      description : OPTIONAL text;
4148      relating_time_interval : time_interval;
4149      related_time_interval : time_interval;
4150   END_ENTITY;
4151
4152   ENTITY time_interval_role;
4153      name : label;
4154      description : OPTIONAL text;
4155   END_ENTITY;
4156
4157   ENTITY time_interval_with_bounds
4158   SUBTYPE OF (time_interval);
4159      primary_bound : OPTIONAL date_time_or_event_occurrence;
4160      secondary_bound : OPTIONAL date_time_or_event_occurrence;
4161      duration : OPTIONAL time_measure_with_unit;
4162   WHERE
4163      WR1:
4164         NOT (EXISTS(secondary_bound) AND EXISTS(duration));
4165      WR2:
4166         EXISTS(primary_bound) OR EXISTS(secondary_bound);
4167   END_ENTITY;
4168
4169   ENTITY time_measure_with_unit
4170   SUBTYPE OF (measure_with_unit);
4171   WHERE
4172      WR1:
4173         'ENGINEERING_PROPERTIES_SCHEMA.TIME_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
4174   END_ENTITY;
4175
4176   ENTITY time_role;
4177      name : label;
4178   DERIVE
4179      description : text := get_description_value(SELF);
4180   WHERE
4181      WR1:
4182         SIZEOF(USEDIN(SELF, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
4183   END_ENTITY;
4184
4185   ENTITY time_unit
4186   SUBTYPE OF (named_unit);
4187   WHERE
4188      WR1:
4189         ((((((SELF\named_unit.dimensions.length_exponent = 0.00000) AND (SELF\named_unit.dimensions.mass_exponent = 0.00000)) AND (SELF\named_unit.dimensions.time_exponent = 1.00000)) AND (SELF\named_unit.dimensions.electric_current_exponent = 0.00000)) AND (SELF\named_unit.dimensions.thermodynamic_temperature_exponent = 0.00000)) AND (SELF\named_unit.dimensions.amount_of_substance_exponent = 0.00000)) AND (SELF\named_unit.dimensions.luminous_intensity_exponent = 0.00000);
4190   END_ENTITY;
4191
4192   ENTITY tolerance_value;
4193      lower_bound : measure_with_unit;
4194      upper_bound : measure_with_unit;
4195   WHERE
4196      WR1:
4197         upper_bound\measure_with_unit.value_component > lower_bound\measure_with_unit.value_component;
4198      WR2:
4199         upper_bound\measure_with_unit.unit_component = lower_bound\measure_with_unit.unit_component;
4200   END_ENTITY;
4201
4202   ENTITY tolerance_with_statistical_distribution;
4203      associated_tolerance : shape_tolerance_select;
4204      tolerance_allocation : statistical_distribution_for_tolerance;
4205   END_ENTITY;
4206
4207   ENTITY tolerance_zone
4208   SUBTYPE OF (shape_aspect);
4209      defining_tolerance : SET [1:?] OF geometric_tolerance;
4210      form : tolerance_zone_form;
4211   END_ENTITY;
4212
4213   ENTITY tolerance_zone_definition
4214   SUPERTYPE OF (ONEOF(projected_zone_definition, runout_zone_definition));
4215      zone : tolerance_zone;
4216      boundaries : SET [1:?] OF shape_aspect;
4217   END_ENTITY;
4218
4219   ENTITY tolerance_zone_form;
4220      name : label;
4221   END_ENTITY;
4222
4223   ENTITY total_runout_tolerance
4224   SUBTYPE OF (geometric_tolerance_with_datum_reference);
4225   WHERE
4226      WR1:
4227         SIZEOF(SELF\geometric_tolerance_with_datum_reference.datum_system) <= 2;
4228   END_ENTITY;
4229
4230   ENTITY triangular_matrix
4231   SUBTYPE OF (linearized_table_function);
4232      default_entry : maths_value;
4233      lo_up : lower_upper;
4234      order : ordering_type;
4235   WHERE
4236      WR1:
4237         SIZEOF(SELF\explicit_table_function.shape) = 2;
4238      WR2:
4239         member_of(default_entry, SELF\maths_function.range);
4240   END_ENTITY;
4241
4242   ENTITY type_qualifier;
4243      name : label;
4244   END_ENTITY;
4245
4246   ENTITY unary_boolean_expression
4247   ABSTRACT SUPERTYPE OF (ONEOF(not_expression, odd_function))
4248   SUBTYPE OF (boolean_expression, unary_generic_expression);
4249   END_ENTITY;
4250
4251   ENTITY unary_function_call
4252   ABSTRACT SUPERTYPE OF (ONEOF(abs_function, minus_function, sin_function, cos_function, tan_function, asin_function, acos_function, exp_function, log_function, log2_function, log10_function, square_root_function))
4253   SUBTYPE OF (unary_numeric_expression);
4254   END_ENTITY;
4255
4256   ENTITY unary_generic_expression
4257   ABSTRACT SUPERTYPE
4258   SUBTYPE OF (generic_expression);
4259      operand : generic_expression;
4260   END_ENTITY;
4261
4262   ENTITY unary_numeric_expression
4263   ABSTRACT SUPERTYPE OF (unary_function_call)
4264   SUBTYPE OF (numeric_expression, unary_generic_expression);
4265      SELF\unary_generic_expression.operand : numeric_expression;
4266   END_ENTITY;
4267
4268   ENTITY uncertainty_assigned_representation
4269   SUBTYPE OF (representation);
4270      uncertainty : SET [1:?] OF uncertainty_measure_with_unit;
4271   END_ENTITY;
4272
4273   ENTITY uncertainty_measure_with_unit
4274   SUBTYPE OF (measure_with_unit);
4275      name : label;
4276      description : OPTIONAL text;
4277   WHERE
4278      WR1:
4279         valid_measure_value(SELF\measure_with_unit.value_component);
4280   END_ENTITY;
4281
4282   ENTITY uncertainty_qualifier
4283   SUPERTYPE OF (ONEOF(standard_uncertainty, qualitative_uncertainty));
4284      measure_name : label;
4285      description : text;
4286   END_ENTITY;
4287
4288   ENTITY uniform_product_space
4289   SUBTYPE OF (maths_space, generic_literal);
4290      base : maths_space;
4291      exponent : positive_integer;
4292   WHERE
4293      WR1:
4294         expression_is_constant(base);
4295      WR2:
4296         no_cyclic_space_reference(SELF, []);
4297      WR3:
4298         base <> the_empty_space;
4299   END_ENTITY;
4300
4301   ENTITY value_function
4302   SUPERTYPE OF (int_value_function)
4303   SUBTYPE OF (numeric_expression, unary_generic_expression);
4304      SELF\unary_generic_expression.operand : string_expression;
4305   END_ENTITY;
4306
4307   ENTITY value_representation_item
4308   SUBTYPE OF (representation_item);
4309      value_component : measure_value;
4310   WHERE
4311      WR1:
4312         SIZEOF(QUERY (rep <* using_representations(SELF)| NOT ('ENGINEERING_PROPERTIES_SCHEMA.GLOBAL_UNIT_ASSIGNED_CONTEXT' IN TYPEOF(rep.context_of_items)))) = 0;
4313   END_ENTITY;
4314
4315   ENTITY variable
4316   ABSTRACT SUPERTYPE OF (ONEOF(numeric_variable, boolean_variable, string_variable))
4317   SUBTYPE OF (generic_variable);
4318   END_ENTITY;
4319
4320   ENTITY variable_semantics
4321   ABSTRACT SUPERTYPE;
4322   END_ENTITY;
4323
4324   ENTITY vector
4325   SUBTYPE OF (geometric_representation_item);
4326      orientation : direction;
4327      magnitude : length_measure;
4328   WHERE
4329      WR1:
4330         magnitude >= 0.00000;
4331   END_ENTITY;
4332
4333   ENTITY velocity_measure_with_unit
4334   SUBTYPE OF (measure_with_unit);
4335   WHERE
4336      WR1:
4337         'ENGINEERING_PROPERTIES_SCHEMA.VELOCITY_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
4338   END_ENTITY;
4339
4340	ENTITY velocity_unit
4341  SUBTYPE OF (derived_unit);
4342  WHERE
4343  WR1: derive_dimensional_exponents(SELF) =
4344       dimensional_exponents ( 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0 );
4345  END_ENTITY;
4346
4347   ENTITY versioned_action_request;
4348      id : identifier;
4349      version : label;
4350      purpose : text;
4351      description : OPTIONAL text;
4352   END_ENTITY;
4353
4354   ENTITY volume
4355   SUPERTYPE OF (ONEOF(block_volume, spherical_volume, cylindrical_volume))
4356   SUBTYPE OF (geometric_representation_item);
4357   WHERE
4358      WR1:
4359         SELF\geometric_representation_item.dim = 3;
4360   END_ENTITY;
4361
4362   ENTITY volume_measure_with_unit
4363   SUBTYPE OF (measure_with_unit);
4364   WHERE
4365      WR1:
4366         'ENGINEERING_PROPERTIES_SCHEMA.VOLUME_UNIT' IN TYPEOF(SELF\measure_with_unit.unit_component);
4367   END_ENTITY;
4368
4369   ENTITY volume_unit
4370   SUBTYPE OF (derived_unit);
4371   WHERE
4372      WR1:
4373         derive_dimensional_exponents(SELF) = dimensional_exponents(3.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000);
4374   END_ENTITY;
4375
4376   ENTITY week_of_year_and_day_date
4377   SUBTYPE OF (date);
4378      week_component : week_in_year_number;
4379      day_component : OPTIONAL day_in_week_number;
4380   END_ENTITY;
4381
4382   ENTITY xor_expression
4383   SUBTYPE OF (binary_boolean_expression);
4384      SELF\binary_generic_expression.operands : LIST [2:2] OF boolean_expression;
4385   END_ENTITY;
4386
4387   ENTITY year_month
4388   SUBTYPE OF (date);
4389      month_component : month_in_year_number;
4390   END_ENTITY;
4391
4392
4393(* ***********************************
4394Types in the schema engineering_properties_schema
4395*********************************** *)
4396
4397   TYPE absorbed_dose_measure = REAL;
4398   END_TYPE;
4399
4400   TYPE acceleration_measure = REAL;
4401   END_TYPE;
4402
4403   TYPE action_item = SELECT
4404      (approval,
4405       certification,
4406       document,
4407       material_property,
4408       material_property_representation,
4409       product_definition,
4410       property_definition,
4411       property_definition_representation);
4412   END_TYPE;
4413
4414   TYPE action_request_item = SELECT
4415      (action,
4416       approval,
4417       certification,
4418       document,
4419       executed_action,
4420       material_property,
4421       product,
4422       product_definition,
4423       product_definition_formation,
4424       property_definition,
4425       organizational_project,
4426       security_classification,
4427       security_classification_level);
4428   END_TYPE;
4429
4430   TYPE ahead_or_behind = ENUMERATION OF
4431      (ahead,
4432       exact,
4433       behind);
4434   END_TYPE;
4435
4436   TYPE amount_of_substance_measure = REAL;
4437   END_TYPE;
4438
4439   TYPE angle_relator = ENUMERATION OF
4440      (equal,
4441       large,
4442       small);
4443   END_TYPE;
4444
4445   TYPE approval_item = SELECT
4446      (material_property,
4447       product,
4448       product_definition,
4449       product_definition_formation,
4450       property_definition,
4451       representation,
4452       versioned_action_request);
4453   END_TYPE;
4454
4455   TYPE area_measure = REAL;
4456   END_TYPE;
4457
4458   TYPE atom_based_tuple = LIST OF atom_based_value;
4459   END_TYPE;
4460
4461   TYPE atom_based_value = SELECT
4462      (maths_atom,
4463       atom_based_tuple);
4464   END_TYPE;
4465
4466   TYPE attribute_language_item = SELECT
4467      (action,
4468       action_method,
4469       action_property,
4470       application_context,
4471       certification,
4472       document,
4473       descriptive_representation_item,
4474       material_designation,
4475       material_property,
4476       material_property_representation,
4477       product,
4478       product_definition,
4479       product_definition_formation,
4480       property_definition,
4481       qualification_type,
4482       representation);
4483   END_TYPE;
4484
4485   TYPE attribute_type = SELECT
4486      (label,
4487       text);
4488   END_TYPE;
4489
4490   TYPE axis2_placement = SELECT
4491      (axis2_placement_2d,
4492       axis2_placement_3d);
4493   END_TYPE;
4494
4495   TYPE capacitance_measure = REAL;
4496   END_TYPE;
4497
4498   TYPE celsius_temperature_measure = REAL;
4499   END_TYPE;
4500
4501   TYPE certification_item = SELECT
4502      (action,
4503       action_method,
4504       material_property,
4505       organization,
4506       product,
4507       product_definition,
4508       product_definition_formation,
4509       person_and_organization,
4510       property_definition);
4511   END_TYPE;
4512
4513   TYPE characterized_action_definition = SELECT
4514      (action,
4515       action_method,
4516       action_method_relationship,
4517       action_relationship);
4518   END_TYPE;
4519
4520   TYPE characterized_definition = SELECT
4521      (characterized_object,
4522       characterized_product_definition,
4523       shape_definition);
4524   END_TYPE;
4525
4526   TYPE characterized_material_property = SELECT
4527      (material_property_representation,
4528	 product_material_composition_relationship);
4529   END_TYPE;
4530
4531   TYPE characterized_product_composition_value = SELECT
4532      (maths_value_with_unit,
4533       measure_with_unit);
4534   END_TYPE;
4535
4536   TYPE characterized_product_definition = SELECT
4537      (product_definition,
4538       product_definition_relationship);
4539   END_TYPE;
4540
4541   TYPE characterized_resource_definition = SELECT
4542      (action_resource,
4543       action_resource_relationship,
4544       action_resource_requirement,
4545       action_resource_requirement_relationship);
4546   END_TYPE;
4547
4548   TYPE compound_item_definition = SELECT
4549      (list_representation_item,
4550       set_representation_item);
4551   END_TYPE;
4552
4553   TYPE conductance_measure = REAL;
4554   END_TYPE;
4555
4556   TYPE configuration_design_item = SELECT
4557      (product_definition,
4558       product_definition_formation);
4559   END_TYPE;
4560
4561   TYPE context_dependent_measure = REAL;
4562   END_TYPE;
4563
4564   TYPE contract_item = SELECT
4565      (action,
4566       material_property,
4567       organizational_project,
4568       person_organization_select,
4569       product,
4570       property_definition);
4571   END_TYPE;
4572
4573   TYPE count_measure = NUMBER;
4574   END_TYPE;
4575
4576   TYPE date_and_time_item = SELECT
4577      (action,
4578       event_occurrence,
4579       representation,
4580       versioned_action_request);
4581   END_TYPE;
4582
4583   TYPE date_item = SELECT
4584      (action,
4585       approval,
4586       certification,
4587       contract,
4588       event_occurrence,
4589       product_definition_formation,
4590       representation,
4591       versioned_action_request);
4592   END_TYPE;
4593
4594   TYPE date_time_or_event_occurrence = SELECT
4595      (date_time_select,
4596       event_occurrence);
4597   END_TYPE;
4598
4599   TYPE date_time_select = SELECT
4600      (date,
4601       date_and_time,
4602       local_time);
4603   END_TYPE;
4604
4605   TYPE day_in_month_number = INTEGER;
4606   WHERE
4607      WR1:
4608         (1 <= SELF) AND (SELF <= 31);
4609   END_TYPE;
4610
4611   TYPE day_in_week_number = INTEGER;
4612   WHERE
4613      WR1:
4614         (1 <= SELF) AND (SELF <= 7);
4615   END_TYPE;
4616
4617   TYPE day_in_year_number = INTEGER;
4618   WHERE
4619      WR1:
4620         (1 <= SELF) AND (SELF <= 366);
4621   END_TYPE;
4622
4623   TYPE derived_property_select = SELECT
4624      (property_definition,
4625       action_property,
4626       resource_property);
4627   END_TYPE;
4628
4629   TYPE description_attribute_select = SELECT
4630      (action_request_solution,
4631       application_context,
4632       approval_role,
4633       configuration_design,
4634       date_role,
4635       date_time_role,
4636       context_dependent_shape_representation,
4637       effectivity,
4638       external_source,
4639       organization_role,
4640       person_and_organization_role,
4641       person_and_organization,
4642       person_role,
4643       property_definition_representation,
4644       representation,
4645       time_role);
4646   END_TYPE;
4647
4648   TYPE descriptive_measure = STRING;
4649   END_TYPE;
4650
4651   TYPE dimension_count = positive_integer;
4652   END_TYPE;
4653
4654   TYPE dimensional_characteristic = SELECT
4655      (dimensional_location,
4656       dimensional_size);
4657   END_TYPE;
4658
4659   TYPE document_item = SELECT
4660      (action,
4661       action_method,
4662       action_resource,
4663       action_resource_requirement,
4664       contract,
4665       geometric_tolerance,
4666       material_designation,
4667       material_property,
4668       product_definition,
4669       product_definition_formation,
4670       product_definition_process,
4671       property_definition,
4672       representation);
4673   END_TYPE;
4674
4675   TYPE dose_equivalent_measure = REAL;
4676   END_TYPE;
4677
4678   TYPE dotted_express_identifier = STRING;
4679   WHERE
4680      syntax:
4681         dotted_identifiers_syntax(SELF);
4682   END_TYPE;
4683
4684   TYPE effectivity_item = SELECT
4685      (action,
4686       document,
4687       product_definition_formation);
4688   END_TYPE;
4689
4690   TYPE electric_charge_measure = REAL;
4691   END_TYPE;
4692
4693   TYPE electric_current_measure = REAL;
4694   END_TYPE;
4695
4696   TYPE electric_potential_measure = REAL;
4697   END_TYPE;
4698
4699   TYPE elementary_function_enumerators = ENUMERATION OF
4700      (ef_and,
4701       ef_or,
4702       ef_not,
4703       ef_xor,
4704       ef_negate_i,
4705       ef_add_i,
4706       ef_subtract_i,
4707       ef_multiply_i,
4708       ef_divide_i,
4709       ef_mod_i,
4710       ef_exponentiate_i,
4711       ef_eq_i,
4712       ef_ne_i,
4713       ef_gt_i,
4714       ef_lt_i,
4715       ef_ge_i,
4716       ef_le_i,
4717       ef_abs_i,
4718       ef_max_i,
4719       ef_min_i,
4720       ef_if_i,
4721       ef_negate_r,
4722       ef_reciprocal_r,
4723       ef_add_r,
4724       ef_subtract_r,
4725       ef_multiply_r,
4726       ef_divide_r,
4727       ef_mod_r,
4728       ef_exponentiate_r,
4729       ef_exponentiate_ri,
4730       ef_eq_r,
4731       ef_ne_r,
4732       ef_gt_r,
4733       ef_lt_r,
4734       ef_ge_r,
4735       ef_le_r,
4736       ef_abs_r,
4737       ef_max_r,
4738       ef_min_r,
4739       ef_acos_r,
4740       ef_asin_r,
4741       ef_atan2_r,
4742       ef_cos_r,
4743       ef_exp_r,
4744       ef_ln_r,
4745       ef_log2_r,
4746       ef_log10_r,
4747       ef_sin_r,
4748       ef_sqrt_r,
4749       ef_tan_r,
4750       ef_if_r,
4751       ef_form_c,
4752       ef_rpart_c,
4753       ef_ipart_c,
4754       ef_negate_c,
4755       ef_reciprocal_c,
4756       ef_add_c,
4757       ef_subtract_c,
4758       ef_multiply_c,
4759       ef_divide_c,
4760       ef_exponentiate_c,
4761       ef_exponentiate_ci,
4762       ef_eq_c,
4763       ef_ne_c,
4764       ef_conjugate_c,
4765       ef_abs_c,
4766       ef_arg_c,
4767       ef_cos_c,
4768       ef_exp_c,
4769       ef_ln_c,
4770       ef_sin_c,
4771       ef_sqrt_c,
4772       ef_tan_c,
4773       ef_if_c,
4774       ef_subscript_s,
4775       ef_eq_s,
4776       ef_ne_s,
4777       ef_gt_s,
4778       ef_lt_s,
4779       ef_ge_s,
4780       ef_le_s,
4781       ef_subsequence_s,
4782       ef_concat_s,
4783       ef_size_s,
4784       ef_format,
4785       ef_value,
4786       ef_like,
4787       ef_if_s,
4788       ef_subscript_b,
4789       ef_eq_b,
4790       ef_ne_b,
4791       ef_gt_b,
4792       ef_lt_b,
4793       ef_ge_b,
4794       ef_le_b,
4795       ef_subsequence_b,
4796       ef_concat_b,
4797       ef_size_b,
4798       ef_if_b,
4799       ef_subscript_t,
4800       ef_eq_t,
4801       ef_ne_t,
4802       ef_concat_t,
4803       ef_size_t,
4804       ef_entuple,
4805       ef_detuple,
4806       ef_insert,
4807       ef_remove,
4808       ef_if_t,
4809       ef_sum_it,
4810       ef_product_it,
4811       ef_add_it,
4812       ef_subtract_it,
4813       ef_scalar_mult_it,
4814       ef_dot_prod_it,
4815       ef_sum_rt,
4816       ef_product_rt,
4817       ef_add_rt,
4818       ef_subtract_rt,
4819       ef_scalar_mult_rt,
4820       ef_dot_prod_rt,
4821       ef_norm_rt,
4822       ef_sum_ct,
4823       ef_product_ct,
4824       ef_add_ct,
4825       ef_subtract_ct,
4826       ef_scalar_mult_ct,
4827       ef_dot_prod_ct,
4828       ef_norm_ct,
4829       ef_if,
4830       ef_ensemble,
4831       ef_member_of);
4832   END_TYPE;
4833
4834   TYPE elementary_space_enumerators = ENUMERATION OF
4835      (es_numbers,
4836       es_complex_numbers,
4837       es_reals,
4838       es_integers,
4839       es_logicals,
4840       es_booleans,
4841       es_strings,
4842       es_binarys,
4843       es_maths_spaces,
4844       es_maths_functions,
4845       es_generics);
4846   END_TYPE;
4847
4848   TYPE energy_measure = REAL;
4849   END_TYPE;
4850
4851   TYPE event_occurred_item = SELECT
4852      (action);
4853   END_TYPE;
4854
4855   TYPE express_identifier = dotted_express_identifier;
4856   WHERE
4857      syntax:
4858         dot_count(SELF) = 0;
4859   END_TYPE;
4860
4861   TYPE extension_options = ENUMERATION OF
4862      (eo_none,
4863       eo_cont,
4864       eo_cont_right,
4865       eo_cont_left);
4866   END_TYPE;
4867
4868   TYPE external_identification_item = SELECT
4869      (document,
4870       product,
4871       product_definition,
4872       externally_defined_class,
4873       externally_defined_engineering_property);
4874   END_TYPE;
4875
4876   TYPE force_measure = REAL;
4877   END_TYPE;
4878
4879   TYPE founded_item_select = SELECT
4880      (founded_item,
4881       representation_item);
4882   END_TYPE;
4883
4884   TYPE frequency_measure = REAL;
4885   END_TYPE;
4886
4887   TYPE geometric_set_select = SELECT
4888      (point,
4889       curve,
4890       surface);
4891   END_TYPE;
4892
4893   TYPE groupable_item = SELECT
4894      (action,
4895       action_method,
4896       material_property,
4897       property_definition,
4898       product,
4899       product_definition);
4900   END_TYPE;
4901
4902   TYPE hour_in_day = INTEGER;
4903   WHERE
4904      WR1:
4905         (0 <= SELF) AND (SELF < 24);
4906   END_TYPE;
4907
4908   TYPE id_attribute_select = SELECT
4909      (action,
4910       address,
4911       product_category,
4912       property_definition,
4913       shape_aspect,
4914       shape_aspect_relationship,
4915       application_context,
4916       group,
4917       organizational_project,
4918       representation);
4919   END_TYPE;
4920
4921   TYPE identification_item = SELECT
4922      (certification,
4923       document,
4924       product,
4925       product_definition,
4926       organization,
4927       person_and_organization);
4928   END_TYPE;
4929
4930   TYPE identifier = STRING;
4931   END_TYPE;
4932
4933   TYPE illuminance_measure = REAL;
4934   END_TYPE;
4935
4936   TYPE inductance_measure = REAL;
4937   END_TYPE;
4938
4939   TYPE input_selector = positive_integer;
4940   END_TYPE;
4941
4942   TYPE label = STRING;
4943   END_TYPE;
4944
4945   TYPE language_item = SELECT
4946      (action,
4947       action_method,
4948       action_property,
4949       application_context,
4950       certification,
4951       document,
4952       descriptive_representation_item,
4953       material_designation,
4954       material_property,
4955       material_property_representation,
4956       product,
4957       product_definition,
4958       product_definition_formation,
4959       property_definition,
4960       qualification_type,
4961       representation);
4962   END_TYPE;
4963
4964   TYPE length_measure = REAL;
4965   END_TYPE;
4966
4967   TYPE limit_condition = ENUMERATION OF
4968      (maximum_material_condition,
4969       least_material_condition,
4970       regardless_of_feature_size);
4971   END_TYPE;
4972
4973   TYPE list_representation_item = LIST [1:?] OF representation_item;
4974   END_TYPE;
4975
4976   TYPE location_item = SELECT
4977      (action,
4978       event_occurrence,
4979       product,
4980       product_definition,
4981       product_definition_formation);
4982   END_TYPE;
4983
4984   TYPE location_representation_item = SELECT
4985      (representation);
4986   END_TYPE;
4987
4988   TYPE lower_upper = ENUMERATION OF
4989      (lower,
4990       upper);
4991   END_TYPE;
4992
4993   TYPE luminous_flux_measure = REAL;
4994   END_TYPE;
4995
4996   TYPE luminous_intensity_measure = REAL;
4997   END_TYPE;
4998
4999   TYPE magnetic_flux_density_measure = REAL;
5000   END_TYPE;
5001
5002   TYPE magnetic_flux_measure = REAL;
5003   END_TYPE;
5004
5005   TYPE mass_measure = REAL;
5006   END_TYPE;
5007
5008   TYPE maths_atom = SELECT
5009      (maths_simple_atom,
5010       maths_enum_atom);
5011   END_TYPE;
5012
5013   TYPE maths_binary = BINARY;
5014   END_TYPE;
5015
5016   TYPE maths_boolean = BOOLEAN;
5017   END_TYPE;
5018
5019   TYPE maths_enum_atom = SELECT
5020      (elementary_space_enumerators,
5021       ordering_type,
5022       lower_upper,
5023       symmetry_type,
5024       elementary_function_enumerators,
5025       open_closed,
5026       space_constraint_type,
5027       repackage_options,
5028       extension_options);
5029   END_TYPE;
5030
5031   TYPE maths_expression = SELECT
5032      (atom_based_value,
5033       maths_tuple,
5034       generic_expression);
5035   END_TYPE;
5036
5037   TYPE maths_function_select = SELECT
5038      (maths_function,
5039       elementary_function_enumerators);
5040   END_TYPE;
5041
5042   TYPE maths_integer = INTEGER;
5043   END_TYPE;
5044
5045   TYPE maths_logical = LOGICAL;
5046   END_TYPE;
5047
5048   TYPE maths_number = NUMBER;
5049   END_TYPE;
5050
5051   TYPE maths_real = REAL;
5052   END_TYPE;
5053
5054   TYPE maths_simple_atom = SELECT
5055      (maths_number,
5056       maths_real,
5057       maths_logical,
5058       maths_boolean,
5059       maths_string,
5060       maths_binary);
5061   END_TYPE;
5062
5063   TYPE maths_space_or_function = SELECT
5064      (maths_space,
5065       maths_function);
5066   END_TYPE;
5067
5068   TYPE maths_string = STRING;
5069   END_TYPE;
5070
5071   TYPE maths_tuple = LIST [0:?] OF maths_value;
5072   END_TYPE;
5073
5074   TYPE maths_value = SELECT
5075      (atom_based_value,
5076       maths_tuple,
5077       generic_expression);
5078   WHERE
5079      constancy:
5080         NOT ('GENERIC_EXPRESSION' IN stripped_typeof(SELF)) OR expression_is_constant(SELF);
5081   END_TYPE;
5082
5083   TYPE measure_value = SELECT
5084      (absorbed_dose_measure,
5085       dose_equivalent_measure,
5086       radioactivity_measure,
5087       acceleration_measure,
5088       amount_of_substance_measure,
5089       area_measure,
5090       celsius_temperature_measure,
5091       context_dependent_measure,
5092       count_measure,
5093       descriptive_measure,
5094       capacitance_measure,
5095       electric_charge_measure,
5096       conductance_measure,
5097       electric_current_measure,
5098       electric_potential_measure,
5099       energy_measure,
5100       magnetic_flux_density_measure,
5101       force_measure,
5102       frequency_measure,
5103       illuminance_measure,
5104       inductance_measure,
5105       length_measure,
5106       luminous_flux_measure,
5107       luminous_intensity_measure,
5108       magnetic_flux_measure,
5109       mass_measure,
5110       numeric_measure,
5111       non_negative_length_measure,
5112       parameter_value,
5113       plane_angle_measure,
5114       positive_length_measure,
5115       positive_plane_angle_measure,
5116       positive_ratio_measure,
5117       power_measure,
5118       pressure_measure,
5119       ratio_measure,
5120       resistance_measure,
5121       solid_angle_measure,
5122       thermodynamic_temperature_measure,
5123       time_measure,
5124       velocity_measure,
5125       volume_measure);
5126   END_TYPE;
5127
5128   TYPE message = STRING;
5129   END_TYPE;
5130
5131   TYPE minute_in_hour = INTEGER;
5132   WHERE
5133      WR1:
5134         (0 <= SELF) AND (SELF <= 59);
5135   END_TYPE;
5136
5137   TYPE month_in_year_number = INTEGER;
5138   WHERE
5139      WR1:
5140         (1 <= SELF) AND (SELF <= 12);
5141   END_TYPE;
5142
5143   TYPE multi_language_attribute_item = SELECT
5144      (action,
5145       action_method,
5146       action_property,
5147       application_context,
5148       certification,
5149       document,
5150       descriptive_representation_item,
5151       material_designation,
5152       material_property,
5153       material_property_representation,
5154       product,
5155       product_definition,
5156       product_definition_formation,
5157       property_definition,
5158       qualification_type,
5159       representation);
5160   END_TYPE;
5161
5162   TYPE name_attribute_select = SELECT
5163      (action_request_solution,
5164       address,
5165       configuration_design,
5166       context_dependent_shape_representation,
5167       derived_unit,
5168       effectivity,
5169       person_and_organization,
5170       product_definition,
5171       product_definition_substitute,
5172       property_definition_representation);
5173   END_TYPE;
5174
5175   TYPE non_negative_length_measure = length_measure;
5176   WHERE
5177      WR1:
5178         SELF >= 0.00000;
5179   END_TYPE;
5180
5181   TYPE nonnegative_integer = INTEGER;
5182   WHERE
5183      nonnegativity:
5184         SELF >= 0;
5185   END_TYPE;
5186
5187   TYPE numeric_measure = NUMBER;
5188   END_TYPE;
5189
5190   TYPE one_or_two = positive_integer;
5191   WHERE
5192      in_range:
5193         (SELF = 1) OR (SELF = 2);
5194   END_TYPE;
5195
5196   TYPE open_closed = ENUMERATION OF
5197      (open,
5198       closed);
5199   END_TYPE;
5200
5201   TYPE ordering_type = ENUMERATION OF
5202      (by_rows,
5203       by_columns);
5204   END_TYPE;
5205
5206   TYPE organization_item = SELECT
5207      (action,
5208       approval,
5209       certification,
5210       document,
5211       material_designation,
5212       versioned_action_request);
5213   END_TYPE;
5214
5215   TYPE organizational_project_item = SELECT
5216      (action,
5217       action_method,
5218       document,
5219       product,
5220       material_property);
5221   END_TYPE;
5222
5223   TYPE parameter_value = REAL;
5224   END_TYPE;
5225
5226   TYPE pcurve_or_surface = SELECT
5227      (surface);
5228   END_TYPE;
5229
5230   TYPE person_and_organization_item = SELECT
5231      (action,
5232       certification,
5233       product_definition_formation,
5234       versioned_action_request);
5235   END_TYPE;
5236
5237   TYPE person_item = SELECT
5238      (action,
5239       document,
5240       versioned_action_request);
5241   END_TYPE;
5242
5243   TYPE person_organization_select = SELECT
5244      (person,
5245       organization,
5246       person_and_organization);
5247   END_TYPE;
5248
5249   TYPE plane_angle_measure = REAL;
5250   END_TYPE;
5251
5252   TYPE positive_integer = nonnegative_integer;
5253   WHERE
5254      positivity:
5255         SELF > 0;
5256   END_TYPE;
5257
5258   TYPE positive_length_measure = non_negative_length_measure;
5259   WHERE
5260      WR1:
5261         SELF > 0.00000;
5262   END_TYPE;
5263
5264   TYPE positive_plane_angle_measure = plane_angle_measure;
5265   WHERE
5266      WR1:
5267         SELF > 0.00000;
5268   END_TYPE;
5269
5270   TYPE positive_ratio_measure = ratio_measure;
5271   WHERE
5272      WR1:
5273         SELF > 0.00000;
5274   END_TYPE;
5275
5276   TYPE power_measure = REAL;
5277   END_TYPE;
5278
5279   TYPE pressure_measure = REAL;
5280   END_TYPE;
5281
5282   TYPE process_or_process_relationship = SELECT
5283      (product_definition_process,
5284       property_process,
5285       relationship_with_condition);
5286   END_TYPE;
5287
5288   TYPE product_or_formation_or_definition = SELECT
5289      (product,
5290       product_definition_formation,
5291       product_definition);
5292   END_TYPE;
5293
5294   TYPE product_space = SELECT
5295      (uniform_product_space,
5296       listed_product_space);
5297   END_TYPE;
5298
5299   TYPE property_or_shape_select = SELECT
5300      (property_definition,
5301       shape_definition);
5302   END_TYPE;
5303   TYPE qualification_item = SELECT
5304      (person,
5305       person_and_organization,
5306       organization);
5307   END_TYPE;
5308
5309   TYPE radioactivity_measure = REAL;
5310   END_TYPE;
5311
5312   TYPE ratio_measure = REAL;
5313   END_TYPE;
5314
5315   TYPE real_interval = SELECT
5316      (real_interval_from_min,
5317       real_interval_to_max,
5318       finite_real_interval,
5319       elementary_space);
5320   WHERE
5321      WR1:
5322         NOT ('ELEMENTARY_SPACE' IN stripped_typeof(SELF)) OR (SELF\elementary_space.space_id = es_reals);
5323   END_TYPE;
5324
5325   TYPE relationship_with_condition = SELECT
5326      (action_method_relationship,
5327       action_relationship,
5328       context_dependent_action_method_relationship,
5329       context_dependent_action_relationship);
5330   END_TYPE;
5331
5332   TYPE repackage_options = ENUMERATION OF
5333      (ro_nochange,
5334       ro_wrap_as_tuple,
5335       ro_unwrap_tuple);
5336   END_TYPE;
5337
5338   TYPE represented_definition = SELECT
5339      (general_property,
5340       property_definition,
5341       property_definition_relationship,
5342       shape_aspect,
5343       shape_aspect_relationship);
5344   END_TYPE;
5345
5346   TYPE resistance_measure = REAL;
5347   END_TYPE;
5348
5349   TYPE role_select = SELECT
5350      (action_assignment,
5351       action_request_assignment,
5352       approval_assignment,
5353       approval_date_time,
5354       certification_assignment,
5355       contract_assignment,
5356       document_reference,
5357       effectivity_assignment,
5358       external_referent_assignment,
5359       group_assignment,
5360       name_assignment,
5361       security_classification_assignment);
5362   END_TYPE;
5363
5364   TYPE second_in_minute = REAL;
5365   WHERE
5366      WR1:
5367         (0 <= SELF) AND (SELF <= 60.0000);
5368   END_TYPE;
5369
5370   TYPE security_classified_item = SELECT
5371      (action,
5372       action_method,
5373       document,
5374       material_property,
5375       representation,
5376       representation_item);
5377   END_TYPE;
5378
5379   TYPE set_representation_item = SET [1:?] OF representation_item;
5380   END_TYPE;
5381
5382   TYPE shape_definition = SELECT
5383      (product_definition_shape,
5384       shape_aspect,
5385       shape_aspect_relationship);
5386   END_TYPE;
5387
5388   TYPE shape_tolerance_select = SELECT
5389      (geometric_tolerance,
5390       plus_minus_tolerance);
5391   END_TYPE;
5392
5393   TYPE si_prefix = ENUMERATION OF
5394      (exa,
5395       peta,
5396       tera,
5397       giga,
5398       mega,
5399       kilo,
5400       hecto,
5401       deca,
5402       deci,
5403       centi,
5404       milli,
5405       micro,
5406       nano,
5407       pico,
5408       femto,
5409       atto);
5410   END_TYPE;
5411
5412   TYPE si_unit_name = ENUMERATION OF
5413      (metre,
5414       gram,
5415       second,
5416       ampere,
5417       kelvin,
5418       mole,
5419       candela,
5420       radian,
5421       steradian,
5422       hertz,
5423       newton,
5424       pascal,
5425       joule,
5426       watt,
5427       coulomb,
5428       volt,
5429       farad,
5430       ohm,
5431       siemens,
5432       weber,
5433       tesla,
5434       henry,
5435       degree_Celsius,
5436       lumen,
5437       lux,
5438       becquerel,
5439       gray,
5440       sievert);
5441   END_TYPE;
5442
5443   TYPE solid_angle_measure = REAL;
5444   END_TYPE;
5445
5446   TYPE source_item = SELECT
5447      (identifier,
5448       message);
5449   END_TYPE;
5450
5451   TYPE space_constraint_type = ENUMERATION OF
5452      (sc_equal,
5453       sc_subspace,
5454       sc_member);
5455   END_TYPE;
5456
5457   TYPE state_item = SELECT
5458      (action,
5459       action_method,
5460       product,
5461       product_definition,
5462       product_definition_formation,
5463       property_definition,
5464       material_property,
5465       material_property_representation);
5466   END_TYPE;
5467
5468   TYPE state_observed_item = SELECT
5469      (action,
5470       action_method,
5471       product,
5472       product_definition,
5473       product_definition_formation,
5474       property_definition,
5475       material_property,
5476       material_property_representation);
5477   END_TYPE;
5478
5479   TYPE supported_item = SELECT
5480      (action_directive,
5481       action,
5482       action_method);
5483   END_TYPE;
5484
5485   TYPE symmetry_type = ENUMERATION OF
5486      (identity,
5487       skew,
5488       hermitian,
5489       skew_hermitian);
5490   END_TYPE;
5491
5492   TYPE text = STRING;
5493   END_TYPE;
5494
5495   TYPE thermodynamic_temperature_measure = REAL;
5496   END_TYPE;
5497
5498   TYPE time_interval_item = SELECT
5499      (action,
5500       approval,
5501       effectivity,
5502       document,
5503       qualification);
5504   END_TYPE;
5505
5506   TYPE time_measure = REAL;
5507   END_TYPE;
5508
5509   TYPE tolerance_method_definition = SELECT
5510      (tolerance_value,
5511       limits_and_fits);
5512   END_TYPE;
5513
5514   TYPE transformation = SELECT
5515      (item_defined_transformation,
5516       functionally_defined_transformation);
5517   END_TYPE;
5518
5519   TYPE trimming_select = SELECT
5520      (cartesian_point,
5521       parameter_value);
5522   END_TYPE;
5523
5524   TYPE tuple_space = SELECT
5525      (product_space,
5526       extended_tuple_space);
5527   END_TYPE;
5528
5529   TYPE unit = SELECT
5530      (derived_unit,
5531       named_unit);
5532   END_TYPE;
5533
5534   TYPE value_qualifier = SELECT
5535      (precision_qualifier,
5536       type_qualifier,
5537       uncertainty_qualifier);
5538   END_TYPE;
5539
5540   TYPE vector_or_direction = SELECT
5541      (vector,
5542       direction);
5543   END_TYPE;
5544
5545   TYPE velocity_measure = REAL;
5546   END_TYPE;
5547
5548   TYPE volume_measure = REAL;
5549   END_TYPE;
5550
5551   TYPE week_in_year_number = INTEGER;
5552   WHERE
5553      WR1:
5554         (1 <= SELF) AND (SELF <= 53);
5555   END_TYPE;
5556
5557   TYPE year_number = INTEGER;
5558   END_TYPE;
5559
5560   TYPE zero_or_one = nonnegative_integer;
5561   WHERE
5562      in_range:
5563         (SELF = 0) OR (SELF = 1);
5564   END_TYPE;
5565
5566
5567(* ***********************************
5568Functions in the schema engineering_properties_schema
5569*********************************** *)
5570
5571   FUNCTION acyclic
5572      (arg1 : generic_expression;
5573       arg2 : SET OF generic_expression ) : BOOLEAN;
5574   LOCAL
5575      result : BOOLEAN;
5576   END_LOCAL;
5577      IF 'ENGINEERING_PROPERTIES_SCHEMA.SIMPLE_GENERIC_EXPRESSION' IN TYPEOF(arg1) THEN
5578         RETURN (TRUE);
5579      END_IF;
5580      IF arg1 IN arg2 THEN
5581         RETURN (FALSE);
5582      END_IF;
5583      IF 'ENGINEERING_PROPERTIES_SCHEMA.UNARY_GENERIC_EXPRESSION' IN TYPEOF(arg1) THEN
5584         RETURN (acyclic(arg1\unary_generic_expression.operand, arg2 + [ arg1 ]));
5585      END_IF;
5586      IF 'ENGINEERING_PROPERTIES_SCHEMA.BINARY_GENERIC_EXPRESSION' IN TYPEOF(arg1) THEN
5587         RETURN (acyclic(arg1\binary_generic_expression.operands[1], (arg2 + [ arg1 ])) AND acyclic(arg1\binary_generic_expression.operands[2], (arg2 + [ arg1 ])));
5588      END_IF;
5589      IF 'ENGINEERING_PROPERTIES_SCHEMA.MULTIPLE_ARITY_GENERIC_EXPRESSION' IN TYPEOF(arg1) THEN
5590         result := TRUE;
5591         REPEAT i := 1 TO SIZEOF(arg1\multiple_arity_generic_expression.operands);
5592            result := result AND acyclic(arg1\multiple_arity_generic_expression.operands[i], (arg2 + [ arg1 ]));
5593         END_REPEAT;
5594         RETURN (result);
5595      END_IF;
5596   END_FUNCTION;
5597
5598   FUNCTION acyclic_mapped_representation
5599      (parent_set : SET OF representation;
5600       children_set : SET OF representation_item ) : BOOLEAN;
5601   LOCAL
5602      x : SET OF representation_item;
5603      y : SET OF representation_item;
5604   END_LOCAL;
5605      x := QUERY (z <* children_set| 'ENGINEERING_PROPERTIES_SCHEMA.MAPPED_ITEM' IN TYPEOF(z));
5606      IF SIZEOF(x) > 0 THEN
5607         REPEAT i := 1 TO HIINDEX(x);
5608            IF x[i]\mapped_item.mapping_source.mapped_representation IN parent_set THEN
5609               RETURN (FALSE);
5610            END_IF;
5611            IF NOT acyclic_mapped_representation((parent_set + x[i]\mapped_item.mapping_source.mapped_representation), x[i]\mapped_item.mapping_source.mapped_representation.items) THEN
5612               RETURN (FALSE);
5613            END_IF;
5614         END_REPEAT;
5615      END_IF;
5616      x := children_set - x;
5617      IF SIZEOF(x) > 0 THEN
5618         REPEAT i := 1 TO HIINDEX(x);
5619            y := QUERY (z <* bag_to_set(USEDIN(x[i], ''))| 'ENGINEERING_PROPERTIES_SCHEMA.REPRESENTATION_ITEM' IN TYPEOF(z));
5620            IF NOT acyclic_mapped_representation(parent_set, y) THEN
5621               RETURN (FALSE);
5622            END_IF;
5623         END_REPEAT;
5624      END_IF;
5625      RETURN (TRUE);
5626   END_FUNCTION;
5627
5628   FUNCTION acyclic_product_category_relationship
5629      (relation : product_category_relationship;
5630       children : SET OF product_category ) : BOOLEAN;
5631   LOCAL
5632      x : SET OF product_category_relationship;
5633      local_children : SET OF product_category;
5634   END_LOCAL;
5635      REPEAT i := 1 TO HIINDEX(children);
5636         IF relation.category :=: children[i] THEN
5637            RETURN (FALSE);
5638         END_IF;
5639      END_REPEAT;
5640      x := bag_to_set(USEDIN(relation.category, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'PRODUCT_CATEGORY_RELATIONSHIP.SUB_CATEGORY'));
5641      local_children := children + relation.category;
5642      IF SIZEOF(x) > 0 THEN
5643         REPEAT i := 1 TO HIINDEX(x);
5644            IF NOT acyclic_product_category_relationship(x[i], local_children) THEN
5645               RETURN (FALSE);
5646            END_IF;
5647         END_REPEAT;
5648      END_IF;
5649      RETURN (TRUE);
5650   END_FUNCTION;
5651
5652   FUNCTION all_members_of_es
5653      (sv : SET OF maths_value;
5654       es : elementary_space_enumerators ) : LOGICAL;
5655   CONSTANT
5656      base_types : SET OF STRING := [ 'NUMBER', 'COMPLEX_NUMBER_LITERAL', 'REAL', 'INTEGER', 'LOGICAL', 'BOOLEAN', 'STRING', 'BINARY', 'MATHS_SPACE', 'MATHS_FUNCTION', 'LIST', 'ELEMENTARY_SPACE_ENUMERATORS', 'ORDERING_TYPE', 'LOWER_UPPER', 'SYMMETRY_TYPE', 'ELEMENTARY_FUNCTION_ENUMERATORS', 'OPEN_CLOSED', 'SPACE_CONSTRAINT_TYPE', 'REPACKAGE_OPTIONS', 'EXTENSION_OPTIONS' ];
5657   END_CONSTANT;
5658   LOCAL
5659      v : maths_value;
5660      key_type : STRING := '';
5661      types : SET OF STRING;
5662      ge : generic_expression;
5663      cum : LOGICAL := TRUE;
5664      vspc : maths_space;
5665   END_LOCAL;
5666      IF NOT EXISTS(sv) OR NOT EXISTS(es) THEN
5667         RETURN (FALSE);
5668      END_IF;
5669      CASE es OF
5670         es_numbers :
5671               key_type := 'NUMBER';
5672         es_complex_numbers :
5673               key_type := 'COMPLEX_NUMBER_LITERAL';
5674         es_reals :
5675               key_type := 'REAL';
5676         es_integers :
5677               key_type := 'INTEGER';
5678         es_logicals :
5679               key_type := 'LOGICAL';
5680         es_booleans :
5681               key_type := 'BOOLEAN';
5682         es_strings :
5683               key_type := 'STRING';
5684         es_binarys :
5685               key_type := 'BINARY';
5686         es_maths_spaces :
5687               key_type := 'MATHS_SPACE';
5688         es_maths_functions :
5689               key_type := 'MATHS_FUNCTION';
5690         es_generics :
5691               RETURN (TRUE);
5692      END_CASE;
5693      REPEAT i := 1 TO SIZEOF(sv);
5694         IF NOT EXISTS(sv[i]) THEN
5695            RETURN (FALSE);
5696         END_IF;
5697         v := simplify_maths_value(sv[i]);
5698         types := stripped_typeof(v);
5699         IF key_type IN types THEN
5700            SKIP;
5701         END_IF;
5702         IF (es = es_numbers) AND ('COMPLEX_NUMBER_LITERAL' IN types) THEN
5703            SKIP;
5704         END_IF;
5705         IF SIZEOF(base_types * types) > 0 THEN
5706            RETURN (FALSE);
5707         END_IF;
5708         ge := v;
5709         IF has_values_space(ge) THEN
5710            vspc := values_space_of(ge);
5711            IF NOT subspace_of_es(vspc, es) THEN
5712               IF NOT compatible_spaces(vspc, make_elementary_space(es)) THEN
5713                  RETURN (FALSE);
5714               END_IF;
5715               cum := UNKNOWN;
5716            END_IF;
5717         ELSE
5718            cum := UNKNOWN;
5719         END_IF;
5720         IF cum = FALSE THEN
5721            RETURN (FALSE);
5722         END_IF;
5723      END_REPEAT;
5724      RETURN (cum);
5725   END_FUNCTION;
5726
5727   FUNCTION any_space_satisfies
5728      (sc : space_constraint_type;
5729       spc : maths_space ) : BOOLEAN;
5730   LOCAL
5731      spc_id : elementary_space_enumerators;
5732   END_LOCAL;
5733      IF (sc = sc_equal) OR NOT ('ELEMENTARY_SPACE' IN stripped_typeof(spc)) THEN
5734         RETURN (FALSE);
5735      END_IF;
5736      spc_id := spc\elementary_space.space_id;
5737      IF sc = sc_subspace THEN
5738         RETURN (bool(spc_id = es_generics));
5739      END_IF;
5740      IF sc = sc_member THEN
5741         RETURN (bool((spc_id = es_generics) OR (spc_id = es_maths_spaces)));
5742      END_IF;
5743      RETURN (?);
5744   END_FUNCTION;
5745
5746   FUNCTION assoc_product_space
5747      (ts1 : tuple_space;
5748       ts2 : tuple_space ) : tuple_space;
5749   LOCAL
5750      types1 : SET OF STRING := stripped_typeof(ts1);
5751      types2 : SET OF STRING := stripped_typeof(ts2);
5752      up1 : uniform_product_space := make_uniform_product_space(the_reals, 1);
5753      up2 : uniform_product_space := make_uniform_product_space(the_reals, 1);
5754      lp1 : listed_product_space := the_zero_tuple_space;
5755      lp2 : listed_product_space := the_zero_tuple_space;
5756      lps : listed_product_space := the_zero_tuple_space;
5757      et1 : extended_tuple_space := the_tuples;
5758      et2 : extended_tuple_space := the_tuples;
5759      ets : extended_tuple_space := the_tuples;
5760      use_up1 : BOOLEAN;
5761      use_up2 : BOOLEAN;
5762      use_lp1 : BOOLEAN;
5763      use_lp2 : BOOLEAN;
5764      factors : LIST OF maths_space := [];
5765      tspace : tuple_space;
5766   END_LOCAL;
5767      IF 'UNIFORM_PRODUCT_SPACE' IN types1 THEN
5768         up1 := ts1;
5769         use_up1 := FALSE;
5770         use_lp1 := FALSE;
5771      ELSE
5772         IF 'LISTED_PRODUCT_SPACE' IN types1 THEN
5773            lp1 := ts1;
5774            use_up1 := FALSE;
5775            use_lp1 := FALSE;
5776         ELSE
5777            IF NOT ('EXTENDED_TUPLE_SPACE' IN types1) THEN
5778               RETURN (?);
5779            END_IF;
5780            et1 := ts1;
5781            use_up1 := FALSE;
5782            use_lp1 := FALSE;
5783         END_IF;
5784      END_IF;
5785      IF 'UNIFORM_PRODUCT_SPACE' IN types2 THEN
5786         up2 := ts2;
5787         use_up2 := FALSE;
5788         use_lp2 := FALSE;
5789      ELSE
5790         IF 'LISTED_PRODUCT_SPACE' IN types2 THEN
5791            lp2 := ts2;
5792            use_up2 := FALSE;
5793            use_lp2 := FALSE;
5794         ELSE
5795            IF NOT ('EXTENDED_TUPLE_SPACE' IN types2) THEN
5796               RETURN (?);
5797            END_IF;
5798            et2 := ts2;
5799            use_up2 := FALSE;
5800            use_lp2 := FALSE;
5801         END_IF;
5802      END_IF;
5803      IF use_up1 THEN
5804         IF use_up2 THEN
5805            IF up1.base = up2.base THEN
5806               tspace := make_uniform_product_space(up1.base, up1.exponent + up2.exponent);
5807            ELSE
5808               factors := [ up1.base, up2.base ];
5809               tspace := make_listed_product_space(factors);
5810            END_IF;
5811         ELSE
5812            IF use_lp2 THEN
5813               factors := [ up1.base ];
5814               factors := factors + lp2.factors;
5815               tspace := make_listed_product_space(factors);
5816            ELSE
5817               tspace := assoc_product_space(up1, et2.base);
5818               tspace := make_extended_tuple_space(tspace, et2.extender);
5819            END_IF;
5820         END_IF;
5821      ELSE
5822         IF use_lp1 THEN
5823            IF use_up2 THEN
5824               factors := [ up2.base ];
5825               factors := lp1.factors + factors;
5826               tspace := make_listed_product_space(factors);
5827            ELSE
5828               IF use_lp2 THEN
5829                  tspace := make_listed_product_space(lp1.factors + lp2.factors);
5830               ELSE
5831                  tspace := assoc_product_space(lp1, et2.base);
5832                  tspace := make_extended_tuple_space(tspace, et2.extender);
5833               END_IF;
5834            END_IF;
5835         ELSE
5836            IF use_up2 THEN
5837               IF et1.extender = up2.base THEN
5838                  tspace := assoc_product_space(et1.base, up2);
5839                  tspace := make_extended_tuple_space(tspace, et1.extender);
5840               ELSE
5841                  RETURN (?);
5842               END_IF;
5843            ELSE
5844               IF use_lp2 THEN
5845                  factors := lp2.factors;
5846                  REPEAT i := 1 TO SIZEOF(factors);
5847                     IF et1.extender <> factors[i] THEN
5848                        RETURN (?);
5849                     END_IF;
5850                  END_REPEAT;
5851                  tspace := assoc_product_space(et1.base, lp2);
5852                  tspace := make_extended_tuple_space(tspace, et1.extender);
5853               ELSE
5854                  IF et1.extender = et2.extender THEN
5855                     tspace := assoc_product_space(et1, et2.base);
5856                  ELSE
5857                     RETURN (?);
5858                  END_IF;
5859               END_IF;
5860            END_IF;
5861         END_IF;
5862      END_IF;
5863      RETURN (tspace);
5864   END_FUNCTION;
5865
5866   FUNCTION atan2
5867      (y : REAL;
5868       x : REAL ) : REAL;
5869   LOCAL
5870      r : REAL;
5871   END_LOCAL;
5872      IF (y = 0.00000) AND (x = 0.00000) THEN
5873         RETURN (?);
5874      END_IF;
5875      r := ATAN(y, x);
5876      IF x < 0.00000 THEN
5877         IF y < 0.00000 THEN
5878            r := r - 3.14159;
5879         ELSE
5880            r := r + 3.14159;
5881         END_IF;
5882      END_IF;
5883      RETURN (r);
5884   END_FUNCTION;
5885
5886   FUNCTION bag_to_set
5887      (the_bag : BAG OF GENERIC : intype ) : SET OF GENERIC : intype;
5888   LOCAL
5889      the_set : SET OF GENERIC : intype := [];
5890   END_LOCAL;
5891      IF SIZEOF(the_bag) > 0 THEN
5892         REPEAT i := 1 TO HIINDEX(the_bag);
5893            the_set := the_set + the_bag[i];
5894         END_REPEAT;
5895      END_IF;
5896      RETURN (the_set);
5897   END_FUNCTION;
5898
5899   FUNCTION base_axis
5900      (dim : INTEGER;
5901       axis1 : direction;
5902       axis2 : direction;
5903       axis3 : direction ) : LIST [2:3] OF direction;
5904   LOCAL
5905      u : LIST [2:3] OF direction;
5906      factor : REAL;
5907      d1 : direction;
5908      d2 : direction;
5909   END_LOCAL;
5910      IF dim = 3 THEN
5911         d1 := NVL(normalise(axis3), dummy_gri || direction([ 0.00000, 0.00000, 1.00000 ]));
5912         d2 := first_proj_axis(d1, axis1);
5913         u := [ d2, second_proj_axis(d1, d2, axis2), d1 ];
5914      ELSE
5915         IF EXISTS(axis1) THEN
5916            d1 := normalise(axis1);
5917            u := [ d1, orthogonal_complement(d1) ];
5918            IF EXISTS(axis2) THEN
5919               factor := dot_product(axis2, u[2]);
5920               IF factor < 0.00000 THEN
5921                  u[2].direction_ratios[1] := -u[2].direction_ratios[1];
5922                  u[2].direction_ratios[2] := -u[2].direction_ratios[2];
5923               END_IF;
5924            END_IF;
5925         ELSE
5926            IF EXISTS(axis2) THEN
5927               d1 := normalise(axis2);
5928               u := [ orthogonal_complement(d1), d1 ];
5929               u[1].direction_ratios[1] := -u[1].direction_ratios[1];
5930               u[1].direction_ratios[2] := -u[1].direction_ratios[2];
5931            ELSE
5932               u := [ dummy_gri || direction([ 1.00000, 0.00000 ]), dummy_gri || direction([ 0.00000, 1.00000 ]) ];
5933            END_IF;
5934         END_IF;
5935      END_IF;
5936      RETURN (u);
5937   END_FUNCTION;
5938
5939   FUNCTION bool
5940      (lgcl : LOGICAL ) : BOOLEAN;
5941      IF NOT EXISTS(lgcl) THEN
5942         RETURN (FALSE);
5943      END_IF;
5944      IF lgcl <> TRUE THEN
5945         RETURN (FALSE);
5946      END_IF;
5947      RETURN (TRUE);
5948   END_FUNCTION;
5949
5950   FUNCTION build_2axes
5951      (ref_direction : direction ) : LIST [2:2] OF direction;
5952   LOCAL
5953      d : direction := NVL(normalise(ref_direction), dummy_gri || direction([ 1.00000, 0.00000 ]));
5954   END_LOCAL;
5955      RETURN ([ d, orthogonal_complement(d) ]);
5956   END_FUNCTION;
5957
5958   FUNCTION build_axes
5959      (axis : direction;
5960       ref_direction : direction ) : LIST [3:3] OF direction;
5961   LOCAL
5962      d1 : direction;
5963      d2 : direction;
5964   END_LOCAL;
5965      d1 := NVL(normalise(axis), dummy_gri || direction([ 0.00000, 0.00000, 1.00000 ]));
5966      d2 := first_proj_axis(d1, ref_direction);
5967      RETURN ([ d2, normalise(cross_product(d1, d2)).orientation, d1 ]);
5968   END_FUNCTION;
5969
5970   FUNCTION check_sparse_index_domain
5971      (idxdom : tuple_space;
5972       base : zero_or_one;
5973       shape : LIST [1:?] OF positive_integer;
5974       order : ordering_type ) : BOOLEAN;
5975   LOCAL
5976      mthspc : maths_space;
5977      interval : finite_integer_interval;
5978      i : INTEGER;
5979   END_LOCAL;
5980      mthspc := factor1(idxdom);
5981      interval := mthspc;
5982      IF order = by_rows THEN
5983         i := 1;
5984      ELSE
5985         i := 2;
5986      END_IF;
5987      RETURN (bool((interval.min <= base) AND (interval.max >= base + shape[i])));
5988   END_FUNCTION;
5989
5990   FUNCTION check_sparse_index_to_loc
5991      (index_range : tuple_space;
5992       loc_domain : tuple_space ) : BOOLEAN;
5993   LOCAL
5994      temp : maths_space;
5995      idx_rng_itvl : finite_integer_interval;
5996      loc_dmn_itvl : finite_integer_interval;
5997   END_LOCAL;
5998      temp := factor1(index_range);
5999      IF schema_prefix + 'TUPLE_SPACE' IN TYPEOF(temp) THEN
6000         temp := factor1(temp);
6001      END_IF;
6002      IF NOT (schema_prefix + 'FINITE_INTEGER_INTERVAL' IN TYPEOF(temp)) THEN
6003         RETURN (FALSE);
6004      END_IF;
6005      idx_rng_itvl := temp;
6006      temp := factor1(loc_domain);
6007      IF schema_prefix + 'TUPLE_SPACE' IN TYPEOF(temp) THEN
6008         temp := factor1(temp);
6009      END_IF;
6010      IF NOT (schema_prefix + 'FINITE_INTEGER_INTERVAL' IN TYPEOF(temp)) THEN
6011         RETURN (FALSE);
6012      END_IF;
6013      loc_dmn_itvl := temp;
6014      RETURN (bool((loc_dmn_itvl.min <= idx_rng_itvl.min) AND (idx_rng_itvl.max <= loc_dmn_itvl.max + 1)));
6015   END_FUNCTION;
6016
6017   FUNCTION check_sparse_loc_range
6018      (locrng : tuple_space;
6019       base : zero_or_one;
6020       shape : LIST [1:?] OF positive_integer;
6021       order : ordering_type ) : BOOLEAN;
6022   LOCAL
6023      mthspc : maths_space;
6024      interval : finite_integer_interval;
6025      i : INTEGER;
6026   END_LOCAL;
6027      IF space_dimension(locrng) <> 1 THEN
6028         RETURN (FALSE);
6029      END_IF;
6030      mthspc := factor1(locrng);
6031      IF NOT (schema_prefix + 'FINITE_INTEGER_INTERVAL' IN TYPEOF(mthspc)) THEN
6032         RETURN (FALSE);
6033      END_IF;
6034      interval := mthspc;
6035      IF order = by_rows THEN
6036         i := 2;
6037      ELSE
6038         i := 1;
6039      END_IF;
6040      RETURN (bool((interval.min >= base) AND (interval.max <= base + shape[i] - 1)));
6041   END_FUNCTION;
6042
6043   FUNCTION compare_basis_and_coef
6044      (basis : LIST [1:?] OF b_spline_basis;
6045       coef : maths_function ) : BOOLEAN;
6046   LOCAL
6047      shape : LIST OF positive_integer;
6048   END_LOCAL;
6049      IF NOT EXISTS(basis) OR NOT EXISTS(coef) THEN
6050         RETURN (FALSE);
6051      END_IF;
6052      shape := shape_of_array(coef);
6053      IF NOT EXISTS(shape) THEN
6054         RETURN (FALSE);
6055      END_IF;
6056      IF SIZEOF(shape) < SIZEOF(basis) THEN
6057         RETURN (FALSE);
6058      END_IF;
6059      REPEAT i := 1 TO SIZEOF(basis);
6060         IF (basis[i].num_basis = shape[i]) <> TRUE THEN
6061            RETURN (FALSE);
6062         END_IF;
6063      END_REPEAT;
6064      RETURN (TRUE);
6065   END_FUNCTION;
6066
6067   FUNCTION compatible_complex_number_regions
6068      (sp1 : maths_space;
6069       sp2 : maths_space ) : BOOLEAN;
6070   LOCAL
6071      typenames : SET OF STRING := stripped_typeof(sp1);
6072      crgn1 : cartesian_complex_number_region;
6073      crgn2 : cartesian_complex_number_region;
6074      prgn1 : polar_complex_number_region;
6075      prgn2 : polar_complex_number_region;
6076      prgn1c2 : polar_complex_number_region;
6077      prgn2c1 : polar_complex_number_region;
6078      sp1_is_crgn : BOOLEAN;
6079      sp2_is_crgn : BOOLEAN;
6080   END_LOCAL;
6081      IF 'CARTESIAN_COMPLEX_NUMBER_REGION' IN typenames THEN
6082         sp1_is_crgn := TRUE;
6083         crgn1 := sp1;
6084      ELSE
6085         IF 'POLAR_COMPLEX_NUMBER_REGION' IN typenames THEN
6086            sp1_is_crgn := FALSE;
6087            prgn1 := sp1;
6088         ELSE
6089            RETURN (TRUE);
6090         END_IF;
6091      END_IF;
6092      typenames := stripped_typeof(sp2);
6093      IF 'CARTESIAN_COMPLEX_NUMBER_REGION' IN typenames THEN
6094         sp2_is_crgn := TRUE;
6095         crgn2 := sp2;
6096      ELSE
6097         IF 'POLAR_COMPLEX_NUMBER_REGION' IN typenames THEN
6098            sp2_is_crgn := FALSE;
6099            prgn2 := sp2;
6100         ELSE
6101            RETURN (TRUE);
6102         END_IF;
6103      END_IF;
6104      IF sp1_is_crgn AND sp2_is_crgn THEN
6105         RETURN (compatible_intervals(crgn1.real_constraint, crgn2.real_constraint) AND compatible_intervals(crgn1.imag_constraint, crgn2.imag_constraint));
6106      END_IF;
6107      IF ((NOT sp1_is_crgn AND NOT sp2_is_crgn) AND (prgn1.centre.real_part = prgn2.centre.real_part)) AND (prgn1.centre.imag_part = prgn2.centre.imag_part) THEN
6108         IF NOT compatible_intervals(prgn1.distance_constraint, prgn2.distance_constraint) THEN
6109            RETURN (FALSE);
6110         END_IF;
6111         IF compatible_intervals(prgn1.direction_constraint, prgn2.direction_constraint) THEN
6112            RETURN (TRUE);
6113         END_IF;
6114         IF (prgn1.direction_constraint.max > 3.14159) AND (prgn2.direction_constraint.max < 3.14159) THEN
6115            RETURN (compatible_intervals(prgn2.direction_constraint, make_finite_real_interval(-3.14159, open, prgn1.direction_constraint.max - 2.00000 * 3.14159, prgn1.direction_constraint.max_closure)));
6116         END_IF;
6117         IF (prgn2.direction_constraint.max > 3.14159) AND (prgn1.direction_constraint.max < 3.14159) THEN
6118            RETURN (compatible_intervals(prgn1.direction_constraint, make_finite_real_interval(-3.14159, open, prgn2.direction_constraint.max - 2.00000 * 3.14159, prgn2.direction_constraint.max_closure)));
6119         END_IF;
6120         RETURN (FALSE);
6121      END_IF;
6122      IF sp1_is_crgn AND NOT sp2_is_crgn THEN
6123         crgn2 := enclose_pregion_in_cregion(prgn2);
6124         prgn1 := enclose_cregion_in_pregion(crgn1, prgn2.centre);
6125         RETURN (compatible_complex_number_regions(crgn1, crgn2) AND compatible_complex_number_regions(prgn1, prgn2));
6126      END_IF;
6127      IF NOT sp1_is_crgn AND sp2_is_crgn THEN
6128         crgn1 := enclose_pregion_in_cregion(prgn1);
6129         prgn2 := enclose_cregion_in_pregion(crgn2, prgn1.centre);
6130         RETURN (compatible_complex_number_regions(crgn1, crgn2) AND compatible_complex_number_regions(prgn1, prgn2));
6131      END_IF;
6132      prgn1c2 := enclose_pregion_in_pregion(prgn1, prgn2.centre);
6133      prgn2c1 := enclose_pregion_in_pregion(prgn2, prgn1.centre);
6134      RETURN (compatible_complex_number_regions(prgn1, prgn2c1) AND compatible_complex_number_regions(prgn1c2, prgn2));
6135   END_FUNCTION;
6136
6137   FUNCTION compatible_es_values
6138      (esval1 : elementary_space_enumerators;
6139       esval2 : elementary_space_enumerators ) : BOOLEAN;
6140   LOCAL
6141      esval1_is_numeric : LOGICAL;
6142      esval2_is_numeric : LOGICAL;
6143   END_LOCAL;
6144      IF ((esval1 = esval2) OR (esval1 = es_generics)) OR (esval2 = es_generics) THEN
6145         RETURN (TRUE);
6146      END_IF;
6147      esval1_is_numeric := (esval1 >= es_numbers) AND (esval1 <= es_integers);
6148      esval2_is_numeric := (esval2 >= es_numbers) AND (esval2 <= es_integers);
6149      IF esval1_is_numeric AND (esval2 = es_numbers) OR esval2_is_numeric AND (esval1 = es_numbers) THEN
6150         RETURN (TRUE);
6151      END_IF;
6152      IF esval1_is_numeric XOR esval2_is_numeric THEN
6153         RETURN (FALSE);
6154      END_IF;
6155      IF (esval1 = es_logicals) AND (esval2 = es_booleans) OR (esval1 = es_booleans) AND (esval2 = es_logicals) THEN
6156         RETURN (TRUE);
6157      END_IF;
6158      RETURN (FALSE);
6159   END_FUNCTION;
6160
6161   FUNCTION compatible_intervals
6162      (sp1 : maths_space;
6163       sp2 : maths_space ) : BOOLEAN;
6164   LOCAL
6165      amin : REAL;
6166      amax : REAL;
6167   END_LOCAL;
6168      IF min_exists(sp1) AND max_exists(sp2) THEN
6169         amin := real_min(sp1);
6170         amax := real_max(sp2);
6171         IF amin > amax THEN
6172            RETURN (FALSE);
6173         END_IF;
6174         IF amin = amax THEN
6175            RETURN (min_included(sp1) AND max_included(sp2));
6176         END_IF;
6177      END_IF;
6178      IF min_exists(sp2) AND max_exists(sp1) THEN
6179         amin := real_min(sp2);
6180         amax := real_max(sp1);
6181         IF amin > amax THEN
6182            RETURN (FALSE);
6183         END_IF;
6184         IF amin = amax THEN
6185            RETURN (min_included(sp2) AND max_included(sp1));
6186         END_IF;
6187      END_IF;
6188      RETURN (TRUE);
6189   END_FUNCTION;
6190
6191   FUNCTION compatible_spaces
6192      (sp1 : maths_space;
6193       sp2 : maths_space ) : BOOLEAN;
6194   LOCAL
6195      types1 : SET OF STRING := stripped_typeof(sp1);
6196      types2 : SET OF STRING := stripped_typeof(sp2);
6197      lgcl : LOGICAL := UNKNOWN;
6198      m : INTEGER;
6199      n : INTEGER;
6200      s1 : maths_space;
6201      s2 : maths_space;
6202   END_LOCAL;
6203      IF 'FINITE_SPACE' IN types1 THEN
6204         REPEAT i := 1 TO SIZEOF(sp1\finite_space.members);
6205            lgcl := member_of(sp1\finite_space.members[i], sp2);
6206            IF lgcl <> FALSE THEN
6207               RETURN (TRUE);
6208            END_IF;
6209         END_REPEAT;
6210         RETURN (FALSE);
6211      END_IF;
6212      IF 'FINITE_SPACE' IN types2 THEN
6213         REPEAT i := 1 TO SIZEOF(sp2\finite_space.members);
6214            lgcl := member_of(sp2\finite_space.members[i], sp1);
6215            IF lgcl <> FALSE THEN
6216               RETURN (TRUE);
6217            END_IF;
6218         END_REPEAT;
6219         RETURN (FALSE);
6220      END_IF;
6221      IF 'ELEMENTARY_SPACE' IN types1 THEN
6222         IF sp1\elementary_space.space_id = es_generics THEN
6223            RETURN (TRUE);
6224         END_IF;
6225         IF 'ELEMENTARY_SPACE' IN types2 THEN
6226            RETURN (compatible_es_values(sp1\elementary_space.space_id, sp2\elementary_space.space_id));
6227         END_IF;
6228         IF (('FINITE_INTEGER_INTERVAL' IN types2) OR ('INTEGER_INTERVAL_FROM_MIN' IN types2)) OR ('INTEGER_INTERVAL_TO_MAX' IN types2) THEN
6229            RETURN (compatible_es_values(sp1\elementary_space.space_id, es_integers));
6230         END_IF;
6231         IF (('FINITE_REAL_INTERVAL' IN types2) OR ('REAL_INTERVAL_FROM_MIN' IN types2)) OR ('REAL_INTERVAL_TO_MAX' IN types2) THEN
6232            RETURN (compatible_es_values(sp1\elementary_space.space_id, es_reals));
6233         END_IF;
6234         IF ('CARTESIAN_COMPLEX_NUMBER_REGION' IN types2) OR ('POLAR_COMPLEX_NUMBER_REGION' IN types2) THEN
6235            RETURN (compatible_es_values(sp1\elementary_space.space_id, es_complex_numbers));
6236         END_IF;
6237         IF 'TUPLE_SPACE' IN types2 THEN
6238            RETURN (FALSE);
6239         END_IF;
6240         IF 'FUNCTION_SPACE' IN types2 THEN
6241            RETURN (bool(sp1\elementary_space.space_id = es_maths_functions));
6242         END_IF;
6243         RETURN (TRUE);
6244      END_IF;
6245      IF 'ELEMENTARY_SPACE' IN types2 THEN
6246         IF sp2\elementary_space.space_id = es_generics THEN
6247            RETURN (TRUE);
6248         END_IF;
6249         IF (('FINITE_INTEGER_INTERVAL' IN types1) OR ('INTEGER_INTERVAL_FROM_MIN' IN types1)) OR ('INTEGER_INTERVAL_TO_MAX' IN types1) THEN
6250            RETURN (compatible_es_values(sp2\elementary_space.space_id, es_integers));
6251         END_IF;
6252         IF (('FINITE_REAL_INTERVAL' IN types1) OR ('REAL_INTERVAL_FROM_MIN' IN types1)) OR ('REAL_INTERVAL_TO_MAX' IN types1) THEN
6253            RETURN (compatible_es_values(sp2\elementary_space.space_id, es_reals));
6254         END_IF;
6255         IF ('CARTESIAN_COMPLEX_NUMBER_REGION' IN types1) OR ('POLAR_COMPLEX_NUMBER_REGION' IN types1) THEN
6256            RETURN (compatible_es_values(sp2\elementary_space.space_id, es_complex_numbers));
6257         END_IF;
6258         IF 'TUPLE_SPACE' IN types1 THEN
6259            RETURN (FALSE);
6260         END_IF;
6261         IF 'FUNCTION_SPACE' IN types1 THEN
6262            RETURN (bool(sp2\elementary_space.space_id = es_maths_functions));
6263         END_IF;
6264         RETURN (TRUE);
6265      END_IF;
6266      IF subspace_of_es(sp1, es_integers) THEN
6267         IF subspace_of_es(sp2, es_integers) THEN
6268            RETURN (compatible_intervals(sp1, sp2));
6269         END_IF;
6270         RETURN (FALSE);
6271      END_IF;
6272      IF subspace_of_es(sp2, es_integers) THEN
6273         RETURN (FALSE);
6274      END_IF;
6275      IF subspace_of_es(sp1, es_reals) THEN
6276         IF subspace_of_es(sp2, es_reals) THEN
6277            RETURN (compatible_intervals(sp1, sp2));
6278         END_IF;
6279         RETURN (FALSE);
6280      END_IF;
6281      IF subspace_of_es(sp2, es_reals) THEN
6282         RETURN (FALSE);
6283      END_IF;
6284      IF subspace_of_es(sp1, es_complex_numbers) THEN
6285         IF subspace_of_es(sp2, es_complex_numbers) THEN
6286            RETURN (compatible_complex_number_regions(sp1, sp2));
6287         END_IF;
6288         RETURN (FALSE);
6289      END_IF;
6290      IF subspace_of_es(sp2, es_complex_numbers) THEN
6291         RETURN (FALSE);
6292      END_IF;
6293      IF 'UNIFORM_PRODUCT_SPACE' IN types1 THEN
6294         IF 'UNIFORM_PRODUCT_SPACE' IN types2 THEN
6295            IF sp1\uniform_product_space.exponent <> sp2\uniform_product_space.exponent THEN
6296               RETURN (FALSE);
6297            END_IF;
6298            RETURN (compatible_spaces(sp1\uniform_product_space.base, sp2\uniform_product_space.base));
6299         END_IF;
6300         IF 'LISTED_PRODUCT_SPACE' IN types2 THEN
6301            n := SIZEOF(sp2\listed_product_space.factors);
6302            IF sp1\uniform_product_space.exponent <> n THEN
6303               RETURN (FALSE);
6304            END_IF;
6305            REPEAT i := 1 TO n;
6306               IF NOT compatible_spaces(sp1\uniform_product_space.base, sp2\listed_product_space.factors[i]) THEN
6307                  RETURN (FALSE);
6308               END_IF;
6309            END_REPEAT;
6310            RETURN (TRUE);
6311         END_IF;
6312         IF 'EXTENDED_TUPLE_SPACE' IN types2 THEN
6313            m := sp1\uniform_product_space.exponent;
6314            n := space_dimension(sp2\extended_tuple_space.base);
6315            IF m < n THEN
6316               RETURN (FALSE);
6317            END_IF;
6318            IF m = n THEN
6319               RETURN (compatible_spaces(sp1, sp2\extended_tuple_space.base));
6320            END_IF;
6321            RETURN (compatible_spaces(sp1, assoc_product_space(sp2\extended_tuple_space.base, make_uniform_product_space(sp2\extended_tuple_space.extender, m - n))));
6322         END_IF;
6323         IF 'FUNCTION_SPACE' IN types2 THEN
6324            RETURN (FALSE);
6325         END_IF;
6326         RETURN (TRUE);
6327      END_IF;
6328      IF 'LISTED_PRODUCT_SPACE' IN types1 THEN
6329         n := SIZEOF(sp1\listed_product_space.factors);
6330         IF 'UNIFORM_PRODUCT_SPACE' IN types2 THEN
6331            IF n <> sp2\uniform_product_space.exponent THEN
6332               RETURN (FALSE);
6333            END_IF;
6334            REPEAT i := 1 TO n;
6335               IF NOT compatible_spaces(sp2\uniform_product_space.base, sp1\listed_product_space.factors[i]) THEN
6336                  RETURN (FALSE);
6337               END_IF;
6338            END_REPEAT;
6339            RETURN (TRUE);
6340         END_IF;
6341         IF 'LISTED_PRODUCT_SPACE' IN types2 THEN
6342            IF n <> SIZEOF(sp2\listed_product_space.factors) THEN
6343               RETURN (FALSE);
6344            END_IF;
6345            REPEAT i := 1 TO n;
6346               IF NOT compatible_spaces(sp1\listed_product_space.factors[i], sp2\listed_product_space.factors[i]) THEN
6347                  RETURN (FALSE);
6348               END_IF;
6349            END_REPEAT;
6350            RETURN (TRUE);
6351         END_IF;
6352         IF 'EXTENDED_TUPLE_SPACE' IN types2 THEN
6353            m := space_dimension(sp2\extended_tuple_space.base);
6354            IF n < m THEN
6355               RETURN (FALSE);
6356            END_IF;
6357            IF n = m THEN
6358               RETURN (compatible_spaces(sp1, sp2\extended_tuple_space.base));
6359            END_IF;
6360            RETURN (compatible_spaces(sp1, assoc_product_space(sp2\extended_tuple_space.base, make_uniform_product_space(sp2\extended_tuple_space.extender, n - m))));
6361         END_IF;
6362         IF schema_prefix + 'FUNCTION_SPACE' IN types2 THEN
6363            RETURN (FALSE);
6364         END_IF;
6365         RETURN (TRUE);
6366      END_IF;
6367      IF 'EXTENDED_TUPLE_SPACE' IN types1 THEN
6368         IF ('UNIFORM_PRODUCT_SPACE' IN types2) OR ('LISTED_PRODUCT_SPACE' IN types2) THEN
6369            RETURN (compatible_spaces(sp2, sp1));
6370         END_IF;
6371         IF 'EXTENDED_TUPLE_SPACE' IN types2 THEN
6372            IF NOT compatible_spaces(sp1\extended_tuple_space.extender, sp2\extended_tuple_space.extender) THEN
6373               RETURN (FALSE);
6374            END_IF;
6375            n := space_dimension(sp1\extended_tuple_space.base);
6376            m := space_dimension(sp2\extended_tuple_space.base);
6377            IF n < m THEN
6378               RETURN (compatible_spaces(assoc_product_space(sp1\extended_tuple_space.base, make_uniform_product_space(sp1\extended_tuple_space.extender, m - n)), sp2\extended_tuple_space.base));
6379            END_IF;
6380            IF n = m THEN
6381               RETURN (compatible_spaces(sp1\extended_tuple_space.base, sp2\extended_tuple_space.base));
6382            END_IF;
6383            IF n > m THEN
6384               RETURN (compatible_spaces(sp1\extended_tuple_space.base, assoc_product_space(sp2\extended_tuple_space.base, make_uniform_product_space(sp2\extended_tuple_space.extender, n - m))));
6385            END_IF;
6386         END_IF;
6387         IF 'FUNCTION_SPACE' IN types2 THEN
6388            RETURN (FALSE);
6389         END_IF;
6390         RETURN (TRUE);
6391      END_IF;
6392      IF 'FUNCTION_SPACE' IN types1 THEN
6393         IF 'FUNCTION_SPACE' IN types2 THEN
6394            s1 := sp1\function_space.domain_argument;
6395            s2 := sp2\function_space.domain_argument;
6396            CASE sp1\function_space.domain_constraint OF
6397               sc_equal :
6398                     BEGIN
6399                        CASE sp2\function_space.domain_constraint OF
6400                           sc_equal :
6401                                 lgcl := subspace_of(s1, s2) AND subspace_of(s2, s1);
6402                           sc_subspace :
6403                                 lgcl := subspace_of(s1, s2);
6404                           sc_member :
6405                                 lgcl := member_of(s1, s2);
6406                        END_CASE;
6407                     END;
6408               sc_subspace :
6409                     BEGIN
6410                        CASE sp2\function_space.domain_constraint OF
6411                           sc_equal :
6412                                 lgcl := subspace_of(s2, s1);
6413                           sc_subspace :
6414                                 lgcl := compatible_spaces(s1, s2);
6415                           sc_member :
6416                                 lgcl := UNKNOWN;
6417                        END_CASE;
6418                     END;
6419               sc_member :
6420                     BEGIN
6421                        CASE sp2\function_space.domain_constraint OF
6422                           sc_equal :
6423                                 lgcl := member_of(s2, s1);
6424                           sc_subspace :
6425                                 lgcl := UNKNOWN;
6426                           sc_member :
6427                                 lgcl := compatible_spaces(s1, s2);
6428                        END_CASE;
6429                     END;
6430            END_CASE;
6431            IF lgcl = FALSE THEN
6432               RETURN (FALSE);
6433            END_IF;
6434            s1 := sp1\function_space.range_argument;
6435            s2 := sp2\function_space.range_argument;
6436            CASE sp1\function_space.range_constraint OF
6437               sc_equal :
6438                     BEGIN
6439                        CASE sp2\function_space.range_constraint OF
6440                           sc_equal :
6441                                 lgcl := subspace_of(s1, s2) AND subspace_of(s2, s1);
6442                           sc_subspace :
6443                                 lgcl := subspace_of(s1, s2);
6444                           sc_member :
6445                                 lgcl := member_of(s1, s2);
6446                        END_CASE;
6447                     END;
6448               sc_subspace :
6449                     BEGIN
6450                        CASE sp2\function_space.range_constraint OF
6451                           sc_equal :
6452                                 lgcl := subspace_of(s2, s1);
6453                           sc_subspace :
6454                                 lgcl := compatible_spaces(s1, s2);
6455                           sc_member :
6456                                 lgcl := UNKNOWN;
6457                        END_CASE;
6458                     END;
6459               sc_member :
6460                     BEGIN
6461                        CASE sp2\function_space.range_constraint OF
6462                           sc_equal :
6463                                 lgcl := member_of(s2, s1);
6464                           sc_subspace :
6465                                 lgcl := UNKNOWN;
6466                           sc_member :
6467                                 lgcl := compatible_spaces(s1, s2);
6468                        END_CASE;
6469                     END;
6470            END_CASE;
6471            IF lgcl = FALSE THEN
6472               RETURN (FALSE);
6473            END_IF;
6474            RETURN (TRUE);
6475         END_IF;
6476         RETURN (TRUE);
6477      END_IF;
6478      RETURN (TRUE);
6479   END_FUNCTION;
6480
6481   FUNCTION composable_sequence
6482      (operands : LIST [2:?] OF maths_function ) : BOOLEAN;
6483      REPEAT i := 1 TO SIZEOF(operands) - 1;
6484         IF NOT compatible_spaces(operands[i].range, operands[(i + 1)].domain) THEN
6485            RETURN (FALSE);
6486         END_IF;
6487      END_REPEAT;
6488      RETURN (TRUE);
6489   END_FUNCTION;
6490
6491   FUNCTION convert_to_literal
6492      (val : maths_atom ) : generic_literal;
6493   LOCAL
6494      types : SET OF STRING := TYPEOF(val);
6495   END_LOCAL;
6496      IF 'INTEGER' IN types THEN
6497         RETURN (make_int_literal(val));
6498      END_IF;
6499      IF 'REAL' IN types THEN
6500         RETURN (make_real_literal(val));
6501      END_IF;
6502      IF 'BOOLEAN' IN types THEN
6503         RETURN (make_boolean_literal(val));
6504      END_IF;
6505      IF 'STRING' IN types THEN
6506         RETURN (make_string_literal(val));
6507      END_IF;
6508      IF 'LOGICAL' IN types THEN
6509         RETURN (make_logical_literal(val));
6510      END_IF;
6511      IF 'BINARY' IN types THEN
6512         RETURN (make_binary_literal(val));
6513      END_IF;
6514      IF schema_prefix + 'MATHS_ENUM_ATOM' IN types THEN
6515         RETURN (make_maths_enum_literal(val));
6516      END_IF;
6517      RETURN (?);
6518   END_FUNCTION;
6519
6520   FUNCTION convert_to_maths_function
6521      (func : maths_function_select ) : maths_function;
6522   LOCAL
6523      efenum : elementary_function_enumerators;
6524      mthfun : maths_function;
6525   END_LOCAL;
6526      IF schema_prefix + 'MATHS_FUNCTION' IN TYPEOF(func) THEN
6527         mthfun := func;
6528      ELSE
6529         efenum := func;
6530         mthfun := make_elementary_function(efenum);
6531      END_IF;
6532      RETURN (mthfun);
6533   END_FUNCTION;
6534
6535   FUNCTION convert_to_maths_value
6536      (val : GENERIC : G ) : maths_value;
6537   LOCAL
6538      types : SET OF STRING := TYPEOF(val);
6539      ival : maths_integer;
6540      rval : maths_real;
6541      nval : maths_number;
6542      tfval : maths_boolean;
6543      lval : maths_logical;
6544      sval : maths_string;
6545      bval : maths_binary;
6546      tval : maths_tuple := the_empty_maths_tuple;
6547      mval : maths_value;
6548   END_LOCAL;
6549      IF schema_prefix + 'MATHS_VALUE' IN types THEN
6550         RETURN (val);
6551      END_IF;
6552      IF 'INTEGER' IN types THEN
6553         ival := val;
6554         RETURN (ival);
6555      END_IF;
6556      IF 'REAL' IN types THEN
6557         rval := val;
6558         RETURN (rval);
6559      END_IF;
6560      IF 'NUMBER' IN types THEN
6561         nval := val;
6562         RETURN (nval);
6563      END_IF;
6564      IF 'BOOLEAN' IN types THEN
6565         tfval := val;
6566         RETURN (tfval);
6567      END_IF;
6568      IF 'LOGICAL' IN types THEN
6569         lval := val;
6570         RETURN (lval);
6571      END_IF;
6572      IF 'STRING' IN types THEN
6573         sval := val;
6574         RETURN (sval);
6575      END_IF;
6576      IF 'BINARY' IN types THEN
6577         bval := val;
6578         RETURN (bval);
6579      END_IF;
6580      IF 'LIST' IN types THEN
6581         REPEAT i := 1 TO SIZEOF(val);
6582            mval := convert_to_maths_value(val[i]);
6583            IF NOT EXISTS(mval) THEN
6584               RETURN (?);
6585            END_IF;
6586            INSERT( tval, mval, i - 1 );
6587         END_REPEAT;
6588         RETURN (tval);
6589      END_IF;
6590      RETURN (?);
6591   END_FUNCTION;
6592
6593   FUNCTION convert_to_operand
6594      (val : maths_value ) : generic_expression;
6595   LOCAL
6596      types : SET OF STRING := stripped_typeof(val);
6597   END_LOCAL;
6598      IF 'GENERIC_EXPRESSION' IN types THEN
6599         RETURN (val);
6600      END_IF;
6601      IF 'MATHS_ATOM' IN types THEN
6602         RETURN (convert_to_literal(val));
6603      END_IF;
6604      IF 'ATOM_BASED_VALUE' IN types THEN
6605         RETURN (make_atom_based_literal(val));
6606      END_IF;
6607      IF 'MATHS_TUPLE' IN types THEN
6608         RETURN (make_maths_tuple_literal(val));
6609      END_IF;
6610      RETURN (?);
6611   END_FUNCTION;
6612
6613   FUNCTION convert_to_operands
6614      (values : AGGREGATE OF maths_value ) : LIST OF generic_expression;
6615   LOCAL
6616      operands : LIST OF generic_expression := [];
6617      loc : INTEGER := 0;
6618   END_LOCAL;
6619      IF NOT EXISTS(values) THEN
6620         RETURN (?);
6621      END_IF;
6622      REPEAT i := LOINDEX(values) TO HIINDEX(values);
6623         INSERT( operands, convert_to_operand(values[i]), loc );
6624         loc := loc + 1;
6625      END_REPEAT;
6626      RETURN (operands);
6627   END_FUNCTION;
6628
6629   FUNCTION convert_to_operands_prcmfn
6630      (srcdom : maths_space_or_function;
6631       prepfun : LIST OF maths_function;
6632       finfun : maths_function_select ) : LIST [2:?] OF generic_expression;
6633   LOCAL
6634      operands : LIST OF generic_expression := [];
6635   END_LOCAL;
6636      INSERT( operands, srcdom, 0 );
6637      REPEAT i := 1 TO SIZEOF(prepfun);
6638         INSERT( operands, prepfun[i], i );
6639      END_REPEAT;
6640      INSERT( operands, convert_to_maths_function(finfun), SIZEOF(prepfun) + 1 );
6641      RETURN (operands);
6642   END_FUNCTION;
6643
6644   FUNCTION cross_product
6645      (arg1 : direction;
6646       arg2 : direction ) : vector;
6647   LOCAL
6648      mag : REAL;
6649      res : direction;
6650      v1 : LIST [3:3] OF REAL;
6651      v2 : LIST [3:3] OF REAL;
6652      result : vector;
6653   END_LOCAL;
6654      IF (NOT EXISTS(arg1) OR (arg1.dim = 2)) OR (NOT EXISTS(arg2) OR (arg2.dim = 2)) THEN
6655         RETURN (?);
6656      ELSE
6657         BEGIN
6658            v1 := normalise(arg1).direction_ratios;
6659            v2 := normalise(arg2).direction_ratios;
6660            res := dummy_gri || direction([ (v1[2] * v2[3] - v1[3] * v2[2]), (v1[3] * v2[1] - v1[1] * v2[3]), (v1[1] * v2[2] - v1[2] * v2[1]) ]);
6661            mag := 0.00000;
6662            REPEAT i := 1 TO 3;
6663               mag := mag + res.direction_ratios[i] * res.direction_ratios[i];
6664            END_REPEAT;
6665            IF mag > 0.00000 THEN
6666               result := dummy_gri || vector(res, SQRT(mag));
6667            ELSE
6668               result := dummy_gri || vector(arg1, 0.00000);
6669            END_IF;
6670            RETURN (result);
6671         END;
6672      END_IF;
6673   END_FUNCTION;
6674
6675   FUNCTION definite_integral_check
6676      (domain : tuple_space;
6677       vrblint : input_selector;
6678       lowerinf : BOOLEAN;
6679       upperinf : BOOLEAN ) : BOOLEAN;
6680   LOCAL
6681      domn : tuple_space := domain;
6682      fspc : maths_space;
6683      dim : nonnegative_integer;
6684      k : positive_integer;
6685   END_LOCAL;
6686      IF (space_dimension(domain) = 1) AND (schema_prefix + 'TUPLE_SPACE' IN TYPEOF(factor1(domain))) THEN
6687         domn := factor1(domain);
6688      END_IF;
6689      dim := space_dimension(domn);
6690      k := vrblint;
6691      IF k > dim THEN
6692         RETURN (FALSE);
6693      END_IF;
6694      fspc := factor_space(domn, k);
6695      IF NOT (schema_prefix + 'REAL_INTERVAL' IN TYPEOF(fspc)) THEN
6696         RETURN (FALSE);
6697      END_IF;
6698      IF lowerinf AND min_exists(fspc) THEN
6699         RETURN (FALSE);
6700      END_IF;
6701      IF upperinf AND max_exists(fspc) THEN
6702         RETURN (FALSE);
6703      END_IF;
6704      RETURN (TRUE);
6705   END_FUNCTION;
6706
6707   FUNCTION definite_integral_expr_check
6708      (operands : LIST [2:?] OF generic_expression;
6709       lowerinf : BOOLEAN;
6710       upperinf : BOOLEAN ) : BOOLEAN;
6711   LOCAL
6712      nops : INTEGER := 2;
6713      vspc : maths_space;
6714      dim : nonnegative_integer;
6715      k : positive_integer;
6716      bspc : maths_space;
6717   END_LOCAL;
6718      IF NOT lowerinf THEN
6719         nops := nops + 1;
6720      END_IF;
6721      IF NOT upperinf THEN
6722         nops := nops + 1;
6723      END_IF;
6724      IF SIZEOF(operands) <> nops THEN
6725         RETURN (FALSE);
6726      END_IF;
6727      IF NOT ('GENERIC_VARIABLE' IN stripped_typeof(operands[2])) THEN
6728         RETURN (FALSE);
6729      END_IF;
6730      IF NOT has_values_space(operands[2]) THEN
6731         RETURN (FALSE);
6732      END_IF;
6733      vspc := values_space_of(operands[2]);
6734      IF NOT ('REAL_INTERVAL' IN stripped_typeof(vspc)) THEN
6735         RETURN (FALSE);
6736      END_IF;
6737      IF lowerinf THEN
6738         IF min_exists(vspc) THEN
6739            RETURN (FALSE);
6740         END_IF;
6741         k := 3;
6742      ELSE
6743         IF NOT has_values_space(operands[3]) THEN
6744            RETURN (FALSE);
6745         END_IF;
6746         bspc := values_space_of(operands[3]);
6747         IF NOT compatible_spaces(bspc, vspc) THEN
6748            RETURN (FALSE);
6749         END_IF;
6750         k := 4;
6751      END_IF;
6752      IF upperinf THEN
6753         IF max_exists(vspc) THEN
6754            RETURN (FALSE);
6755         END_IF;
6756      ELSE
6757         IF NOT has_values_space(operands[k]) THEN
6758            RETURN (FALSE);
6759         END_IF;
6760         bspc := values_space_of(operands[k]);
6761         IF NOT compatible_spaces(bspc, vspc) THEN
6762            RETURN (FALSE);
6763         END_IF;
6764      END_IF;
6765      RETURN (TRUE);
6766   END_FUNCTION;
6767
6768   FUNCTION derive_definite_integral_domain
6769      (igrl : definite_integral_function ) : tuple_space;
6770      FUNCTION process_product_space
6771         (spc : product_space;
6772          idx : INTEGER;
6773          prefix : INTEGER;
6774          vdomn : maths_space ) : product_space;
6775      LOCAL
6776         uspc : uniform_product_space;
6777         expnt : INTEGER;
6778         factors : LIST OF maths_space;
6779      END_LOCAL;
6780         IF schema_prefix + 'UNIFORM_PRODUCT_SPACE' IN TYPEOF(spc) THEN
6781            uspc := spc;
6782            expnt := uspc.exponent + prefix;
6783            IF idx <= uspc.exponent THEN
6784               expnt := expnt - 1;
6785            END_IF;
6786            IF expnt = 0 THEN
6787               RETURN (make_listed_product_space([]));
6788            ELSE
6789               RETURN (make_uniform_product_space(uspc.base, expnt));
6790            END_IF;
6791         ELSE
6792            factors := spc\listed_product_space.factors;
6793            IF idx <= SIZEOF(factors) THEN
6794               REMOVE( factors, idx );
6795            END_IF;
6796            IF prefix > 0 THEN
6797               INSERT( factors, vdomn, 0 );
6798               IF prefix > 1 THEN
6799                  INSERT( factors, vdomn, 0 );
6800               END_IF;
6801            END_IF;
6802            RETURN (make_listed_product_space(factors));
6803         END_IF;
6804      END_FUNCTION;
6805   LOCAL
6806      idomn : tuple_space := igrl.integrand.domain;
6807      types : SET OF STRING := TYPEOF(idomn);
6808      idx : INTEGER := igrl.variable_of_integration;
6809      tupled : BOOLEAN := bool((space_dimension(idomn) = 1) AND (schema_prefix + 'TUPLE_SPACE' IN types));
6810      prefix : INTEGER := 0;
6811      espc : extended_tuple_space;
6812      vdomn : maths_space;
6813   END_LOCAL;
6814      IF tupled THEN
6815         idomn := factor1(idomn);
6816         types := TYPEOF(idomn);
6817      END_IF;
6818      IF igrl.lower_limit_neg_infinity THEN
6819         prefix := prefix + 1;
6820      END_IF;
6821      IF igrl.upper_limit_pos_infinity THEN
6822         prefix := prefix + 1;
6823      END_IF;
6824      vdomn := factor_space(idomn, idx);
6825      IF schema_prefix + 'EXTENDED_TUPLE_SPACE' IN types THEN
6826         espc := idomn;
6827         idomn := make_extended_tuple_space(process_product_space(espc.base, idx, prefix, vdomn), espc.extender);
6828      ELSE
6829         idomn := process_product_space(idomn, idx, prefix, vdomn);
6830      END_IF;
6831      IF tupled THEN
6832         RETURN (one_tuples_of(idomn));
6833      ELSE
6834         RETURN (idomn);
6835      END_IF;
6836   END_FUNCTION;
6837
6838   FUNCTION derive_dimensional_exponents
6839      (x : unit ) : dimensional_exponents;
6840   LOCAL
6841      result : dimensional_exponents := dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000);
6842   END_LOCAL;
6843      IF 'ENGINEERING_PROPERTIES_SCHEMA.DERIVED_UNIT' IN TYPEOF(x) THEN
6844         REPEAT i := LOINDEX(x\derived_unit.elements) TO HIINDEX(x\derived_unit.elements);
6845            result.length_exponent := result.length_exponent + x\derived_unit.elements[i]\derived_unit_element.exponent * x\derived_unit.elements[i]\derived_unit_element.unit\named_unit.dimensions.length_exponent;
6846            result.mass_exponent := result.mass_exponent + x\derived_unit.elements[i]\derived_unit_element.exponent * x\derived_unit.elements[i]\derived_unit_element.unit\named_unit.dimensions.mass_exponent;
6847            result.time_exponent := result.time_exponent + x\derived_unit.elements[i]\derived_unit_element.exponent * x\derived_unit.elements[i]\derived_unit_element.unit\named_unit.dimensions.time_exponent;
6848            result.electric_current_exponent := result.electric_current_exponent + x\derived_unit.elements[i]\derived_unit_element.exponent * x\derived_unit.elements[i]\derived_unit_element.unit\named_unit.dimensions.electric_current_exponent;
6849            result.thermodynamic_temperature_exponent := result.thermodynamic_temperature_exponent + x\derived_unit.elements[i]\derived_unit_element.exponent * x\derived_unit.elements[i]\derived_unit_element.unit\named_unit.dimensions.thermodynamic_temperature_exponent;
6850            result.amount_of_substance_exponent := result.amount_of_substance_exponent + x\derived_unit.elements[i]\derived_unit_element.exponent * x\derived_unit.elements[i]\derived_unit_element.unit\named_unit.dimensions.amount_of_substance_exponent;
6851            result.luminous_intensity_exponent := result.luminous_intensity_exponent + x\derived_unit.elements[i]\derived_unit_element.exponent * x\derived_unit.elements[i]\derived_unit_element.unit\named_unit.dimensions.luminous_intensity_exponent;
6852         END_REPEAT;
6853      ELSE
6854         result := x\named_unit.dimensions;
6855      END_IF;
6856      RETURN (result);
6857   END_FUNCTION;
6858
6859   FUNCTION derive_elementary_function_domain
6860      (ef_val : elementary_function_enumerators ) : tuple_space;
6861      IF NOT EXISTS(ef_val) THEN
6862         RETURN (?);
6863      END_IF;
6864      CASE ef_val OF
6865         ef_and :
6866               RETURN (make_extended_tuple_space(the_zero_tuple_space, the_logicals));
6867         ef_or :
6868               RETURN (make_extended_tuple_space(the_zero_tuple_space, the_logicals));
6869         ef_not :
6870               RETURN (make_uniform_product_space(the_logicals, 1));
6871         ef_xor :
6872               RETURN (make_uniform_product_space(the_logicals, 2));
6873         ef_negate_i :
6874               RETURN (make_uniform_product_space(the_integers, 1));
6875         ef_add_i :
6876               RETURN (the_integer_tuples);
6877         ef_subtract_i :
6878               RETURN (make_uniform_product_space(the_integers, 2));
6879         ef_multiply_i :
6880               RETURN (the_integer_tuples);
6881         ef_divide_i :
6882               RETURN (make_uniform_product_space(the_integers, 2));
6883         ef_mod_i :
6884               RETURN (make_uniform_product_space(the_integers, 2));
6885         ef_exponentiate_i :
6886               RETURN (make_uniform_product_space(the_integers, 2));
6887         ef_eq_i :
6888               RETURN (make_uniform_product_space(the_integers, 2));
6889         ef_ne_i :
6890               RETURN (make_uniform_product_space(the_integers, 2));
6891         ef_gt_i :
6892               RETURN (make_uniform_product_space(the_integers, 2));
6893         ef_lt_i :
6894               RETURN (make_uniform_product_space(the_integers, 2));
6895         ef_ge_i :
6896               RETURN (make_uniform_product_space(the_integers, 2));
6897         ef_le_i :
6898               RETURN (make_uniform_product_space(the_integers, 2));
6899         ef_abs_i :
6900               RETURN (make_uniform_product_space(the_integers, 1));
6901         ef_if_i :
6902               RETURN (make_listed_product_space([ the_logicals, the_integers, the_integers ]));
6903         ef_negate_r :
6904               RETURN (make_uniform_product_space(the_reals, 1));
6905         ef_reciprocal_r :
6906               RETURN (make_uniform_product_space(the_reals, 1));
6907         ef_add_r :
6908               RETURN (the_real_tuples);
6909         ef_subtract_r :
6910               RETURN (make_uniform_product_space(the_reals, 2));
6911         ef_multiply_r :
6912               RETURN (the_real_tuples);
6913         ef_divide_r :
6914               RETURN (make_uniform_product_space(the_reals, 2));
6915         ef_mod_r :
6916               RETURN (make_uniform_product_space(the_reals, 2));
6917         ef_exponentiate_r :
6918               RETURN (make_listed_product_space([ the_nonnegative_reals, the_reals ]));
6919         ef_exponentiate_ri :
6920               RETURN (make_listed_product_space([ the_reals, the_integers ]));
6921         ef_eq_r :
6922               RETURN (make_uniform_product_space(the_reals, 2));
6923         ef_ne_r :
6924               RETURN (make_uniform_product_space(the_reals, 2));
6925         ef_gt_r :
6926               RETURN (make_uniform_product_space(the_reals, 2));
6927         ef_lt_r :
6928               RETURN (make_uniform_product_space(the_reals, 2));
6929         ef_ge_r :
6930               RETURN (make_uniform_product_space(the_reals, 2));
6931         ef_le_r :
6932               RETURN (make_uniform_product_space(the_reals, 2));
6933         ef_abs_r :
6934               RETURN (make_uniform_product_space(the_reals, 1));
6935         ef_acos_r :
6936               RETURN (make_uniform_product_space(the_neg1_one_interval, 1));
6937         ef_asin_r :
6938               RETURN (make_uniform_product_space(the_neg1_one_interval, 1));
6939         ef_atan2_r :
6940               RETURN (make_uniform_product_space(the_reals, 2));
6941         ef_cos_r :
6942               RETURN (make_uniform_product_space(the_reals, 1));
6943         ef_exp_r :
6944               RETURN (make_uniform_product_space(the_reals, 1));
6945         ef_ln_r :
6946               RETURN (make_uniform_product_space(the_nonnegative_reals, 1));
6947         ef_log2_r :
6948               RETURN (make_uniform_product_space(the_nonnegative_reals, 1));
6949         ef_log10_r :
6950               RETURN (make_uniform_product_space(the_nonnegative_reals, 1));
6951         ef_sin_r :
6952               RETURN (make_uniform_product_space(the_reals, 1));
6953         ef_sqrt_r :
6954               RETURN (make_uniform_product_space(the_nonnegative_reals, 1));
6955         ef_tan_r :
6956               RETURN (make_uniform_product_space(the_reals, 1));
6957         ef_if_r :
6958               RETURN (make_listed_product_space([ the_logicals, the_reals, the_reals ]));
6959         ef_negate_c :
6960               RETURN (make_uniform_product_space(the_complex_numbers, 1));
6961         ef_reciprocal_c :
6962               RETURN (make_uniform_product_space(the_complex_numbers, 1));
6963         ef_add_c :
6964               RETURN (the_complex_tuples);
6965         ef_subtract_c :
6966               RETURN (make_uniform_product_space(the_complex_numbers, 2));
6967         ef_multiply_c :
6968               RETURN (the_complex_tuples);
6969         ef_divide_c :
6970               RETURN (make_uniform_product_space(the_complex_numbers, 2));
6971         ef_exponentiate_c :
6972               RETURN (make_uniform_product_space(the_complex_numbers, 2));
6973         ef_exponentiate_ci :
6974               RETURN (make_listed_product_space([ the_complex_numbers, the_integers ]));
6975         ef_eq_c :
6976               RETURN (make_uniform_product_space(the_complex_numbers, 2));
6977         ef_ne_c :
6978               RETURN (make_uniform_product_space(the_complex_numbers, 2));
6979         ef_conjugate_c :
6980               RETURN (make_uniform_product_space(the_complex_numbers, 1));
6981         ef_abs_c :
6982               RETURN (make_uniform_product_space(the_complex_numbers, 1));
6983         ef_arg_c :
6984               RETURN (make_uniform_product_space(the_complex_numbers, 1));
6985         ef_cos_c :
6986               RETURN (make_uniform_product_space(the_complex_numbers, 1));
6987         ef_exp_c :
6988               RETURN (make_uniform_product_space(the_complex_numbers, 1));
6989         ef_ln_c :
6990               RETURN (make_uniform_product_space(the_complex_numbers, 1));
6991         ef_sin_c :
6992               RETURN (make_uniform_product_space(the_complex_numbers, 1));
6993         ef_sqrt_c :
6994               RETURN (make_uniform_product_space(the_complex_numbers, 1));
6995         ef_tan_c :
6996               RETURN (make_uniform_product_space(the_complex_numbers, 1));
6997         ef_if_c :
6998               RETURN (make_listed_product_space([ the_logicals, the_complex_numbers, the_complex_numbers ]));
6999         ef_subscript_s :
7000               RETURN (make_listed_product_space([ the_strings, the_integers ]));
7001         ef_eq_s :
7002               RETURN (make_uniform_product_space(the_strings, 2));
7003         ef_ne_s :
7004               RETURN (make_uniform_product_space(the_strings, 2));
7005         ef_gt_s :
7006               RETURN (make_uniform_product_space(the_strings, 2));
7007         ef_lt_s :
7008               RETURN (make_uniform_product_space(the_strings, 2));
7009         ef_ge_s :
7010               RETURN (make_uniform_product_space(the_strings, 2));
7011         ef_le_s :
7012               RETURN (make_uniform_product_space(the_strings, 2));
7013         ef_subsequence_s :
7014               RETURN (make_listed_product_space([ the_strings, the_integers, the_integers ]));
7015         ef_concat_s :
7016               RETURN (make_extended_tuple_space(the_zero_tuple_space, the_strings));
7017         ef_size_s :
7018               RETURN (make_uniform_product_space(the_strings, 1));
7019         ef_format :
7020               RETURN (make_listed_product_space([ the_numbers, the_strings ]));
7021         ef_value :
7022               RETURN (make_uniform_product_space(the_strings, 1));
7023         ef_like :
7024               RETURN (make_uniform_product_space(the_strings, 2));
7025         ef_if_s :
7026               RETURN (make_listed_product_space([ the_logicals, the_strings, the_strings ]));
7027         ef_subscript_b :
7028               RETURN (make_listed_product_space([ the_binarys, the_integers ]));
7029         ef_eq_b :
7030               RETURN (make_uniform_product_space(the_binarys, 2));
7031         ef_ne_b :
7032               RETURN (make_uniform_product_space(the_binarys, 2));
7033         ef_gt_b :
7034               RETURN (make_uniform_product_space(the_binarys, 2));
7035         ef_lt_b :
7036               RETURN (make_uniform_product_space(the_binarys, 2));
7037         ef_ge_b :
7038               RETURN (make_uniform_product_space(the_binarys, 2));
7039         ef_le_b :
7040               RETURN (make_uniform_product_space(the_binarys, 2));
7041         ef_subsequence_b :
7042               RETURN (make_listed_product_space([ the_binarys, the_integers, the_integers ]));
7043         ef_concat_b :
7044               RETURN (make_extended_tuple_space(the_zero_tuple_space, the_binarys));
7045         ef_size_b :
7046               RETURN (make_uniform_product_space(the_binarys, 1));
7047         ef_if_b :
7048               RETURN (make_listed_product_space([ the_logicals, the_binarys, the_binarys ]));
7049         ef_subscript_t :
7050               RETURN (make_listed_product_space([ the_tuples, the_integers ]));
7051         ef_eq_t :
7052               RETURN (make_uniform_product_space(the_tuples, 2));
7053         ef_ne_t :
7054               RETURN (make_uniform_product_space(the_tuples, 2));
7055         ef_concat_t :
7056               RETURN (make_extended_tuple_space(the_zero_tuple_space, the_tuples));
7057         ef_size_t :
7058               RETURN (make_uniform_product_space(the_tuples, 1));
7059         ef_entuple :
7060               RETURN (the_tuples);
7061         ef_detuple :
7062               RETURN (make_uniform_product_space(the_generics, 1));
7063         ef_insert :
7064               RETURN (make_listed_product_space([ the_tuples, the_generics, the_integers ]));
7065         ef_remove :
7066               RETURN (make_listed_product_space([ the_tuples, the_integers ]));
7067         ef_if_t :
7068               RETURN (make_listed_product_space([ the_logicals, the_tuples, the_tuples ]));
7069         ef_sum_it :
7070               RETURN (make_uniform_product_space(the_integer_tuples, 1));
7071         ef_product_it :
7072               RETURN (make_uniform_product_space(the_integer_tuples, 1));
7073         ef_add_it :
7074               RETURN (make_extended_tuple_space(the_integer_tuples, the_integer_tuples));
7075         ef_subtract_it :
7076               RETURN (make_uniform_product_space(the_integer_tuples, 2));
7077         ef_scalar_mult_it :
7078               RETURN (make_listed_product_space([ the_integers, the_integer_tuples ]));
7079         ef_dot_prod_it :
7080               RETURN (make_uniform_product_space(the_integer_tuples, 2));
7081         ef_sum_rt :
7082               RETURN (make_uniform_product_space(the_real_tuples, 1));
7083         ef_product_rt :
7084               RETURN (make_uniform_product_space(the_real_tuples, 1));
7085         ef_add_rt :
7086               RETURN (make_extended_tuple_space(the_real_tuples, the_real_tuples));
7087         ef_subtract_rt :
7088               RETURN (make_uniform_product_space(the_real_tuples, 2));
7089         ef_scalar_mult_rt :
7090               RETURN (make_listed_product_space([ the_reals, the_real_tuples ]));
7091         ef_dot_prod_rt :
7092               RETURN (make_uniform_product_space(the_real_tuples, 2));
7093         ef_norm_rt :
7094               RETURN (make_uniform_product_space(the_real_tuples, 1));
7095         ef_sum_ct :
7096               RETURN (make_uniform_product_space(the_complex_tuples, 1));
7097         ef_product_ct :
7098               RETURN (make_uniform_product_space(the_complex_tuples, 1));
7099         ef_add_ct :
7100               RETURN (make_extended_tuple_space(the_complex_tuples, the_complex_tuples));
7101         ef_subtract_ct :
7102               RETURN (make_uniform_product_space(the_complex_tuples, 2));
7103         ef_scalar_mult_ct :
7104               RETURN (make_listed_product_space([ the_complex_numbers, the_complex_tuples ]));
7105         ef_dot_prod_ct :
7106               RETURN (make_uniform_product_space(the_complex_tuples, 2));
7107         ef_norm_ct :
7108               RETURN (make_uniform_product_space(the_complex_tuples, 1));
7109         ef_if :
7110               RETURN (make_listed_product_space([ the_logicals, the_generics, the_generics ]));
7111         ef_ensemble :
7112               RETURN (the_tuples);
7113         ef_member_of :
7114               RETURN (make_listed_product_space([ the_generics, the_maths_spaces ]));
7115      OTHERWISE :
7116            RETURN (?);
7117      END_CASE;
7118   END_FUNCTION;
7119
7120   FUNCTION derive_elementary_function_range
7121      (ef_val : elementary_function_enumerators ) : tuple_space;
7122      IF NOT EXISTS(ef_val) THEN
7123         RETURN (?);
7124      END_IF;
7125      CASE ef_val OF
7126         ef_and :
7127               RETURN (make_uniform_product_space(the_logicals, 1));
7128         ef_or :
7129               RETURN (make_uniform_product_space(the_logicals, 1));
7130         ef_not :
7131               RETURN (make_uniform_product_space(the_logicals, 1));
7132         ef_xor :
7133               RETURN (make_uniform_product_space(the_logicals, 2));
7134         ef_negate_i :
7135               RETURN (make_uniform_product_space(the_integers, 1));
7136         ef_add_i :
7137               RETURN (make_uniform_product_space(the_integers, 1));
7138         ef_subtract_i :
7139               RETURN (make_uniform_product_space(the_integers, 1));
7140         ef_multiply_i :
7141               RETURN (make_uniform_product_space(the_integers, 1));
7142         ef_divide_i :
7143               RETURN (make_uniform_product_space(the_integers, 1));
7144         ef_mod_i :
7145               RETURN (make_uniform_product_space(the_integers, 1));
7146         ef_exponentiate_i :
7147               RETURN (make_uniform_product_space(the_integers, 1));
7148         ef_eq_i :
7149               RETURN (make_uniform_product_space(the_logicals, 1));
7150         ef_ne_i :
7151               RETURN (make_uniform_product_space(the_logicals, 1));
7152         ef_gt_i :
7153               RETURN (make_uniform_product_space(the_logicals, 1));
7154         ef_lt_i :
7155               RETURN (make_uniform_product_space(the_logicals, 1));
7156         ef_ge_i :
7157               RETURN (make_uniform_product_space(the_logicals, 1));
7158         ef_le_i :
7159               RETURN (make_uniform_product_space(the_logicals, 1));
7160         ef_abs_i :
7161               RETURN (make_uniform_product_space(the_integers, 1));
7162         ef_if_i :
7163               RETURN (make_uniform_product_space(the_integers, 1));
7164         ef_negate_r :
7165               RETURN (make_uniform_product_space(the_reals, 1));
7166         ef_reciprocal_r :
7167               RETURN (make_uniform_product_space(the_reals, 1));
7168         ef_add_r :
7169               RETURN (make_uniform_product_space(the_reals, 1));
7170         ef_subtract_r :
7171               RETURN (make_uniform_product_space(the_reals, 1));
7172         ef_multiply_r :
7173               RETURN (make_uniform_product_space(the_reals, 1));
7174         ef_divide_r :
7175               RETURN (make_uniform_product_space(the_reals, 1));
7176         ef_mod_r :
7177               RETURN (make_uniform_product_space(the_reals, 1));
7178         ef_exponentiate_r :
7179               RETURN (make_uniform_product_space(the_reals, 1));
7180         ef_exponentiate_ri :
7181               RETURN (make_uniform_product_space(the_reals, 1));
7182         ef_eq_r :
7183               RETURN (make_uniform_product_space(the_logicals, 1));
7184         ef_ne_r :
7185               RETURN (make_uniform_product_space(the_logicals, 1));
7186         ef_gt_r :
7187               RETURN (make_uniform_product_space(the_logicals, 1));
7188         ef_lt_r :
7189               RETURN (make_uniform_product_space(the_logicals, 1));
7190         ef_ge_r :
7191               RETURN (make_uniform_product_space(the_logicals, 1));
7192         ef_le_r :
7193               RETURN (make_uniform_product_space(the_logicals, 1));
7194         ef_abs_r :
7195               RETURN (make_uniform_product_space(the_nonnegative_reals, 1));
7196         ef_acos_r :
7197               RETURN (make_uniform_product_space(the_zero_pi_interval, 1));
7198         ef_asin_r :
7199               RETURN (make_uniform_product_space(the_neghalfpi_halfpi_interval, 1));
7200         ef_atan2_r :
7201               RETURN (make_uniform_product_space(the_negpi_pi_interval, 1));
7202         ef_cos_r :
7203               RETURN (make_uniform_product_space(the_neg1_one_interval, 1));
7204         ef_exp_r :
7205               RETURN (make_uniform_product_space(the_nonnegative_reals, 1));
7206         ef_ln_r :
7207               RETURN (make_uniform_product_space(the_reals, 1));
7208         ef_log2_r :
7209               RETURN (make_uniform_product_space(the_reals, 1));
7210         ef_log10_r :
7211               RETURN (make_uniform_product_space(the_reals, 1));
7212         ef_sin_r :
7213               RETURN (make_uniform_product_space(the_neg1_one_interval, 1));
7214         ef_sqrt_r :
7215               RETURN (make_uniform_product_space(the_nonnegative_reals, 1));
7216         ef_tan_r :
7217               RETURN (make_uniform_product_space(the_reals, 1));
7218         ef_if_r :
7219               RETURN (make_uniform_product_space(the_reals, 1));
7220         ef_negate_c :
7221               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7222         ef_reciprocal_c :
7223               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7224         ef_add_c :
7225               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7226         ef_subtract_c :
7227               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7228         ef_multiply_c :
7229               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7230         ef_divide_c :
7231               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7232         ef_exponentiate_c :
7233               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7234         ef_exponentiate_ci :
7235               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7236         ef_eq_c :
7237               RETURN (make_uniform_product_space(the_logicals, 1));
7238         ef_ne_c :
7239               RETURN (make_uniform_product_space(the_logicals, 1));
7240         ef_conjugate_c :
7241               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7242         ef_abs_c :
7243               RETURN (make_uniform_product_space(the_nonnegative_reals, 1));
7244         ef_arg_c :
7245               RETURN (make_uniform_product_space(the_negpi_pi_interval, 1));
7246         ef_cos_c :
7247               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7248         ef_exp_c :
7249               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7250         ef_ln_c :
7251               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7252         ef_sin_c :
7253               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7254         ef_sqrt_c :
7255               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7256         ef_tan_c :
7257               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7258         ef_if_c :
7259               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7260         ef_subscript_s :
7261               RETURN (make_uniform_product_space(the_strings, 1));
7262         ef_eq_s :
7263               RETURN (make_uniform_product_space(the_logicals, 1));
7264         ef_ne_s :
7265               RETURN (make_uniform_product_space(the_logicals, 1));
7266         ef_gt_s :
7267               RETURN (make_uniform_product_space(the_logicals, 1));
7268         ef_lt_s :
7269               RETURN (make_uniform_product_space(the_logicals, 1));
7270         ef_ge_s :
7271               RETURN (make_uniform_product_space(the_logicals, 1));
7272         ef_le_s :
7273               RETURN (make_uniform_product_space(the_logicals, 1));
7274         ef_subsequence_s :
7275               RETURN (make_uniform_product_space(the_strings, 1));
7276         ef_concat_s :
7277               RETURN (make_uniform_product_space(the_strings, 1));
7278         ef_size_s :
7279               RETURN (make_uniform_product_space(the_integers, 1));
7280         ef_format :
7281               RETURN (make_uniform_product_space(the_strings, 1));
7282         ef_value :
7283               RETURN (make_uniform_product_space(the_reals, 1));
7284         ef_like :
7285               RETURN (make_uniform_product_space(the_booleans, 1));
7286         ef_if_s :
7287               RETURN (make_uniform_product_space(the_strings, 1));
7288         ef_subscript_b :
7289               RETURN (make_uniform_product_space(the_binarys, 1));
7290         ef_eq_b :
7291               RETURN (make_uniform_product_space(the_logicals, 1));
7292         ef_ne_b :
7293               RETURN (make_uniform_product_space(the_logicals, 1));
7294         ef_gt_b :
7295               RETURN (make_uniform_product_space(the_logicals, 1));
7296         ef_lt_b :
7297               RETURN (make_uniform_product_space(the_logicals, 1));
7298         ef_ge_b :
7299               RETURN (make_uniform_product_space(the_logicals, 1));
7300         ef_le_b :
7301               RETURN (make_uniform_product_space(the_logicals, 1));
7302         ef_subsequence_b :
7303               RETURN (make_uniform_product_space(the_binarys, 1));
7304         ef_concat_b :
7305               RETURN (make_uniform_product_space(the_binarys, 1));
7306         ef_size_b :
7307               RETURN (make_uniform_product_space(the_integers, 1));
7308         ef_if_b :
7309               RETURN (make_uniform_product_space(the_binarys, 1));
7310         ef_subscript_t :
7311               RETURN (make_uniform_product_space(the_generics, 1));
7312         ef_eq_t :
7313               RETURN (make_uniform_product_space(the_logicals, 1));
7314         ef_ne_t :
7315               RETURN (make_uniform_product_space(the_logicals, 1));
7316         ef_concat_t :
7317               RETURN (make_uniform_product_space(the_tuples, 1));
7318         ef_size_t :
7319               RETURN (make_uniform_product_space(the_integers, 1));
7320         ef_entuple :
7321               RETURN (make_uniform_product_space(the_tuples, 1));
7322         ef_detuple :
7323               RETURN (the_tuples);
7324         ef_insert :
7325               RETURN (make_uniform_product_space(the_tuples, 1));
7326         ef_remove :
7327               RETURN (make_uniform_product_space(the_tuples, 1));
7328         ef_if_t :
7329               RETURN (make_uniform_product_space(the_tuples, 1));
7330         ef_sum_it :
7331               RETURN (make_uniform_product_space(the_integers, 1));
7332         ef_product_it :
7333               RETURN (make_uniform_product_space(the_integers, 1));
7334         ef_add_it :
7335               RETURN (make_uniform_product_space(the_integer_tuples, 1));
7336         ef_subtract_it :
7337               RETURN (make_uniform_product_space(the_integer_tuples, 1));
7338         ef_scalar_mult_it :
7339               RETURN (make_uniform_product_space(the_integer_tuples, 1));
7340         ef_dot_prod_it :
7341               RETURN (make_uniform_product_space(the_integers, 1));
7342         ef_sum_rt :
7343               RETURN (make_uniform_product_space(the_reals, 1));
7344         ef_product_rt :
7345               RETURN (make_uniform_product_space(the_reals, 1));
7346         ef_add_rt :
7347               RETURN (make_uniform_product_space(the_real_tuples, 1));
7348         ef_subtract_rt :
7349               RETURN (make_uniform_product_space(the_real_tuples, 1));
7350         ef_scalar_mult_rt :
7351               RETURN (make_uniform_product_space(the_real_tuples, 1));
7352         ef_dot_prod_rt :
7353               RETURN (make_uniform_product_space(the_reals, 1));
7354         ef_norm_rt :
7355               RETURN (make_uniform_product_space(the_reals, 1));
7356         ef_sum_ct :
7357               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7358         ef_product_ct :
7359               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7360         ef_add_ct :
7361               RETURN (make_uniform_product_space(the_complex_tuples, 1));
7362         ef_subtract_ct :
7363               RETURN (make_uniform_product_space(the_complex_tuples, 1));
7364         ef_scalar_mult_ct :
7365               RETURN (make_uniform_product_space(the_complex_tuples, 1));
7366         ef_dot_prod_ct :
7367               RETURN (make_uniform_product_space(the_complex_numbers, 1));
7368         ef_norm_ct :
7369               RETURN (make_uniform_product_space(the_nonnegative_reals, 1));
7370         ef_if :
7371               RETURN (make_uniform_product_space(the_generics, 1));
7372         ef_ensemble :
7373               RETURN (make_uniform_product_space(the_maths_spaces, 1));
7374         ef_member_of :
7375               RETURN (make_uniform_product_space(the_logicals, 1));
7376      OTHERWISE :
7377            RETURN (?);
7378      END_CASE;
7379   END_FUNCTION;
7380
7381   FUNCTION derive_finite_function_domain
7382      (pairs : SET [1:?] OF LIST [2:2] OF maths_value ) : tuple_space;
7383   LOCAL
7384      result : SET OF maths_value := [];
7385   END_LOCAL;
7386      result := result + list_selected_components(pairs, 1);
7387      RETURN (one_tuples_of(make_finite_space(result)));
7388   END_FUNCTION;
7389
7390   FUNCTION derive_finite_function_range
7391      (pairs : SET [1:?] OF LIST [2:2] OF maths_value ) : tuple_space;
7392   LOCAL
7393      result : SET OF maths_value := [];
7394   END_LOCAL;
7395      result := result + list_selected_components(pairs, 2);
7396      RETURN (one_tuples_of(make_finite_space(result)));
7397   END_FUNCTION;
7398
7399   FUNCTION derive_function_domain
7400      (func : maths_function ) : tuple_space;
7401   LOCAL
7402      typenames : SET OF STRING := stripped_typeof(func);
7403      tspace : tuple_space := make_listed_product_space([]);
7404      shape : LIST OF positive_integer;
7405      sidxs : LIST OF INTEGER := [ 0 ];
7406      itvl : finite_integer_interval;
7407      factors : LIST OF finite_integer_interval := [];
7408      is_uniform : BOOLEAN := TRUE;
7409   END_LOCAL;
7410      IF 'FINITE_FUNCTION' IN typenames THEN
7411         RETURN (derive_finite_function_domain(func\finite_function.pairs));
7412      END_IF;
7413      IF 'CONSTANT_FUNCTION' IN typenames THEN
7414         RETURN (domain_from(func\constant_function.source_of_domain));
7415      END_IF;
7416      IF 'SELECTOR_FUNCTION' IN typenames THEN
7417         RETURN (domain_from(func\selector_function.source_of_domain));
7418      END_IF;
7419      IF 'ELEMENTARY_FUNCTION' IN typenames THEN
7420         RETURN (derive_elementary_function_domain(func\elementary_function.func_id));
7421      END_IF;
7422      IF 'RESTRICTION_FUNCTION' IN typenames THEN
7423         RETURN (one_tuples_of(func\restriction_function.operand));
7424      END_IF;
7425      IF 'REPACKAGING_FUNCTION' IN typenames THEN
7426         IF func\repackaging_function.input_repack = ro_nochange THEN
7427            RETURN (func\repackaging_function.operand.domain);
7428         END_IF;
7429         IF func\repackaging_function.input_repack = ro_wrap_as_tuple THEN
7430            RETURN (factor1(func\repackaging_function.operand.domain));
7431         END_IF;
7432         IF func\repackaging_function.input_repack = ro_unwrap_tuple THEN
7433            RETURN (one_tuples_of(func\repackaging_function.operand.domain));
7434         END_IF;
7435         RETURN (?);
7436      END_IF;
7437      IF 'REINDEXED_ARRAY_FUNCTION' IN typenames THEN
7438         shape := shape_of_array(func\unary_generic_expression.operand);
7439         sidxs := func\reindexed_array_function.starting_indices;
7440         REPEAT i := 1 TO SIZEOF(shape);
7441            itvl := make_finite_integer_interval(sidxs[i], sidxs[i] + shape[i] - 1);
7442            INSERT( factors, itvl, i - 1 );
7443            IF shape[i] <> shape[1] THEN
7444               is_uniform := FALSE;
7445            END_IF;
7446         END_REPEAT;
7447         IF is_uniform THEN
7448            RETURN (make_uniform_product_space(factors[1], SIZEOF(shape)));
7449         END_IF;
7450         RETURN (make_listed_product_space(factors));
7451      END_IF;
7452      IF 'SERIES_COMPOSED_FUNCTION' IN typenames THEN
7453         RETURN (func\series_composed_function.operands[1].domain);
7454      END_IF;
7455      IF 'PARALLEL_COMPOSED_FUNCTION' IN typenames THEN
7456         RETURN (domain_from(func\parallel_composed_function.source_of_domain));
7457      END_IF;
7458      IF 'EXPLICIT_TABLE_FUNCTION' IN typenames THEN
7459         shape := func\explicit_table_function.shape;
7460         sidxs[1] := func\explicit_table_function.index_base;
7461         REPEAT i := 1 TO SIZEOF(shape);
7462            itvl := make_finite_integer_interval(sidxs[1], sidxs[1] + shape[i] - 1);
7463            INSERT( factors, itvl, i - 1 );
7464            IF shape[i] <> shape[1] THEN
7465               is_uniform := FALSE;
7466            END_IF;
7467         END_REPEAT;
7468         IF is_uniform THEN
7469            RETURN (make_uniform_product_space(factors[1], SIZEOF(shape)));
7470         END_IF;
7471         RETURN (make_listed_product_space(factors));
7472      END_IF;
7473      IF 'HOMOGENEOUS_LINEAR_FUNCTION' IN typenames THEN
7474         RETURN (one_tuples_of(make_uniform_product_space(factor1(func\homogeneous_linear_function.mat.range), func\homogeneous_linear_function.mat\explicit_table_function.shape[func\homogeneous_linear_function.sum_index])));
7475      END_IF;
7476      IF 'GENERAL_LINEAR_FUNCTION' IN typenames THEN
7477         RETURN (one_tuples_of(make_uniform_product_space(factor1(func\general_linear_function.mat.range), func\general_linear_function.mat\explicit_table_function.shape[func\general_linear_function.sum_index] - 1)));
7478      END_IF;
7479      IF 'B_SPLINE_BASIS' IN typenames THEN
7480         RETURN (one_tuples_of(make_finite_real_interval(func\b_spline_basis.repeated_knots[func\b_spline_basis.order], closed, func\b_spline_basis.repeated_knots[(func\b_spline_basis.num_basis + 1)], closed)));
7481      END_IF;
7482      IF 'B_SPLINE_FUNCTION' IN typenames THEN
7483         REPEAT i := 1 TO SIZEOF(func\b_spline_function.basis);
7484            tspace := assoc_product_space(tspace, func\b_spline_function.basis[i].domain);
7485         END_REPEAT;
7486         RETURN (one_tuples_of(tspace));
7487      END_IF;
7488      IF 'RATIONALIZE_FUNCTION' IN typenames THEN
7489         RETURN (func\rationalize_function.fun.domain);
7490      END_IF;
7491      IF 'PARTIAL_DERIVATIVE_FUNCTION' IN typenames THEN
7492         RETURN (func\partial_derivative_function.derivand.domain);
7493      END_IF;
7494      IF 'DEFINITE_INTEGRAL_FUNCTION' IN typenames THEN
7495         RETURN (derive_definite_integral_domain(func));
7496      END_IF;
7497      IF 'ABSTRACTED_EXPRESSION_FUNCTION' IN typenames THEN
7498         REPEAT i := 1 TO SIZEOF(func\abstracted_expression_function.variables);
7499            tspace := assoc_product_space(tspace, one_tuples_of(values_space_of(func\abstracted_expression_function.variables[i])));
7500         END_REPEAT;
7501         RETURN (tspace);
7502      END_IF;
7503      IF 'EXPRESSION_DENOTED_FUNCTION' IN typenames THEN
7504         RETURN (values_space_of(func\expression_denoted_function.expr)\function_space.domain_argument);
7505      END_IF;
7506      IF 'IMPORTED_POINT_FUNCTION' IN typenames THEN
7507         RETURN (one_tuples_of(make_listed_product_space([])));
7508      END_IF;
7509      IF 'IMPORTED_CURVE_FUNCTION' IN typenames THEN
7510         RETURN (func\imported_curve_function.parametric_domain);
7511      END_IF;
7512      IF 'IMPORTED_SURFACE_FUNCTION' IN typenames THEN
7513         RETURN (func\imported_surface_function.parametric_domain);
7514      END_IF;
7515      IF 'IMPORTED_VOLUME_FUNCTION' IN typenames THEN
7516         RETURN (func\imported_volume_function.parametric_domain);
7517      END_IF;
7518      IF 'APPLICATION_DEFINED_FUNCTION' IN typenames THEN
7519         RETURN (func\application_defined_function.explicit_domain);
7520      END_IF;
7521      RETURN (?);
7522   END_FUNCTION;
7523
7524   FUNCTION derive_function_range
7525      (func : maths_function ) : tuple_space;
7526   LOCAL
7527      typenames : SET OF STRING := stripped_typeof(func);
7528      tspace : tuple_space := make_listed_product_space([]);
7529      m : nonnegative_integer := 0;
7530      n : nonnegative_integer := 0;
7531   END_LOCAL;
7532      IF 'FINITE_FUNCTION' IN typenames THEN
7533         RETURN (derive_finite_function_range(func\finite_function.pairs));
7534      END_IF;
7535      IF 'CONSTANT_FUNCTION' IN typenames THEN
7536         RETURN (one_tuples_of(make_finite_space([ func\constant_function.sole_output ])));
7537      END_IF;
7538      IF 'SELECTOR_FUNCTION' IN typenames THEN
7539         tspace := func.domain;
7540         IF (space_dimension(tspace) = 1) AND (schema_prefix + 'TUPLE_SPACE' IN TYPEOF(tspace)) THEN
7541            tspace := factor1(tspace);
7542         END_IF;
7543         RETURN (one_tuples_of(factor_space(tspace, func\selector_function.selector)));
7544      END_IF;
7545      IF 'ELEMENTARY_FUNCTION' IN typenames THEN
7546         RETURN (derive_elementary_function_range(func\elementary_function.func_id));
7547      END_IF;
7548      IF 'RESTRICTION_FUNCTION' IN typenames THEN
7549         RETURN (one_tuples_of(func\restriction_function.operand));
7550      END_IF;
7551      IF 'REPACKAGING_FUNCTION' IN typenames THEN
7552         tspace := func\repackaging_function.operand.range;
7553         IF func\repackaging_function.output_repack = ro_wrap_as_tuple THEN
7554            tspace := one_tuples_of(tspace);
7555         END_IF;
7556         IF func\repackaging_function.output_repack = ro_unwrap_tuple THEN
7557            tspace := factor1(tspace);
7558         END_IF;
7559         IF func\repackaging_function.selected_output > 0 THEN
7560            tspace := one_tuples_of(factor_space(tspace, func\repackaging_function.selected_output));
7561         END_IF;
7562         RETURN (tspace);
7563      END_IF;
7564      IF 'REINDEXED_ARRAY_FUNCTION' IN typenames THEN
7565         RETURN (func\unary_generic_expression.operand\maths_function.range);
7566      END_IF;
7567      IF 'SERIES_COMPOSED_FUNCTION' IN typenames THEN
7568         RETURN (func\series_composed_function.operands[SIZEOF(func\series_composed_function.operands)].range);
7569      END_IF;
7570      IF 'PARALLEL_COMPOSED_FUNCTION' IN typenames THEN
7571         RETURN (func\parallel_composed_function.final_function.range);
7572      END_IF;
7573      IF 'EXPLICIT_TABLE_FUNCTION' IN typenames THEN
7574         IF 'LISTED_REAL_DATA' IN typenames THEN
7575            RETURN (one_tuples_of(the_reals));
7576         END_IF;
7577         IF 'LISTED_INTEGER_DATA' IN typenames THEN
7578            RETURN (one_tuples_of(the_integers));
7579         END_IF;
7580         IF 'LISTED_LOGICAL_DATA' IN typenames THEN
7581            RETURN (one_tuples_of(the_logicals));
7582         END_IF;
7583         IF 'LISTED_STRING_DATA' IN typenames THEN
7584            RETURN (one_tuples_of(the_strings));
7585         END_IF;
7586         IF 'LISTED_COMPLEX_NUMBER_DATA' IN typenames THEN
7587            RETURN (one_tuples_of(the_complex_numbers));
7588         END_IF;
7589         IF 'LISTED_DATA' IN typenames THEN
7590            RETURN (one_tuples_of(func\listed_data.value_range));
7591         END_IF;
7592         IF 'EXTERNALLY_LISTED_DATA' IN typenames THEN
7593            RETURN (one_tuples_of(func\externally_listed_data.value_range));
7594         END_IF;
7595         IF 'LINEARIZED_TABLE_FUNCTION' IN typenames THEN
7596            RETURN (func\linearized_table_function.source.range);
7597         END_IF;
7598         IF 'BASIC_SPARSE_MATRIX' IN typenames THEN
7599            RETURN (func\basic_sparse_matrix.val.range);
7600         END_IF;
7601         RETURN (?);
7602      END_IF;
7603      IF 'HOMOGENEOUS_LINEAR_FUNCTION' IN typenames THEN
7604         RETURN (one_tuples_of(make_uniform_product_space(factor1(func\homogeneous_linear_function.mat.range), func\homogeneous_linear_function.mat\explicit_table_function.shape[(3 - func\homogeneous_linear_function.sum_index)])));
7605      END_IF;
7606      IF 'GENERAL_LINEAR_FUNCTION' IN typenames THEN
7607         RETURN (one_tuples_of(make_uniform_product_space(factor1(func\general_linear_function.mat.range), func\general_linear_function.mat\explicit_table_function.shape[(3 - func\general_linear_function.sum_index)])));
7608      END_IF;
7609      IF 'B_SPLINE_BASIS' IN typenames THEN
7610         RETURN (one_tuples_of(make_uniform_product_space(the_reals, func\b_spline_basis.num_basis)));
7611      END_IF;
7612      IF 'B_SPLINE_FUNCTION' IN typenames THEN
7613         tspace := factor1(func\b_spline_function.coef.domain);
7614         m := SIZEOF(func\b_spline_function.basis);
7615         n := space_dimension(tspace);
7616         IF m = n THEN
7617            RETURN (one_tuples_of(the_reals));
7618         END_IF;
7619         IF m = n - 1 THEN
7620            RETURN (one_tuples_of(make_uniform_product_space(the_reals, factor_space(tspace, n)\finite_integer_interval.size)));
7621         END_IF;
7622         tspace := extract_factors(tspace, m + 1, n);
7623         RETURN (one_tuples_of(make_function_space(sc_equal, tspace, sc_subspace, number_superspace_of(func\b_spline_function.coef.range))));
7624      END_IF;
7625      IF 'RATIONALIZE_FUNCTION' IN typenames THEN
7626         tspace := factor1(func\rationalize_function.fun.range);
7627         n := space_dimension(tspace);
7628         RETURN (one_tuples_of(make_uniform_product_space(number_superspace_of(factor1(tspace)), n - 1)));
7629      END_IF;
7630      IF 'PARTIAL_DERIVATIVE_FUNCTION' IN typenames THEN
7631         RETURN (drop_numeric_constraints(func\partial_derivative_function.derivand.range));
7632      END_IF;
7633      IF 'DEFINITE_INTEGRAL_FUNCTION' IN typenames THEN
7634         RETURN (drop_numeric_constraints(func\definite_integral_function.integrand.range));
7635      END_IF;
7636      IF 'ABSTRACTED_EXPRESSION_FUNCTION' IN typenames THEN
7637         RETURN (one_tuples_of(values_space_of(func\abstracted_expression_function.expr)));
7638      END_IF;
7639      IF 'EXPRESSION_DENOTED_FUNCTION' IN typenames THEN
7640         RETURN (values_space_of(func\expression_denoted_function.expr)\function_space.range_argument);
7641      END_IF;
7642      IF 'IMPORTED_POINT_FUNCTION' IN typenames THEN
7643         RETURN (one_tuples_of(make_uniform_product_space(the_reals, dimension_of(func\imported_point_function.geometry))));
7644      END_IF;
7645      IF 'IMPORTED_CURVE_FUNCTION' IN typenames THEN
7646         RETURN (one_tuples_of(make_uniform_product_space(the_reals, dimension_of(func\imported_curve_function.geometry))));
7647      END_IF;
7648      IF 'IMPORTED_SURFACE_FUNCTION' IN typenames THEN
7649         RETURN (one_tuples_of(make_uniform_product_space(the_reals, dimension_of(func\imported_surface_function.geometry))));
7650      END_IF;
7651      IF 'IMPORTED_VOLUME_FUNCTION' IN typenames THEN
7652         RETURN (one_tuples_of(make_uniform_product_space(the_reals, dimension_of(func\imported_volume_function.geometry))));
7653      END_IF;
7654      IF 'APPLICATION_DEFINED_FUNCTION' IN typenames THEN
7655         RETURN (func\application_defined_function.explicit_range);
7656      END_IF;
7657      RETURN (?);
7658   END_FUNCTION;
7659
7660   FUNCTION dimension_of
7661      (item : geometric_representation_item ) : dimension_count;
7662   LOCAL
7663      x : SET OF representation;
7664      y : representation_context;
7665      dim : dimension_count;
7666   END_LOCAL;
7667      IF 'ENGINEERING_PROPERTIES_SCHEMA.CARTESIAN_POINT' IN TYPEOF(item) THEN
7668         dim := SIZEOF(item\cartesian_point.coordinates);
7669         RETURN (dim);
7670      END_IF;
7671      IF 'ENGINEERING_PROPERTIES_SCHEMA.DIRECTION' IN TYPEOF(item) THEN
7672         dim := SIZEOF(item\direction.direction_ratios);
7673         RETURN (dim);
7674      END_IF;
7675      IF 'ENGINEERING_PROPERTIES_SCHEMA.VECTOR' IN TYPEOF(item) THEN
7676         dim := SIZEOF(item\vector.orientation\direction.direction_ratios);
7677         RETURN (dim);
7678      END_IF;
7679      x := using_representations(item);
7680      y := x[1].context_of_items;
7681      dim := y\geometric_representation_context.coordinate_space_dimension;
7682      RETURN (dim);
7683   END_FUNCTION;
7684
7685   FUNCTION dimensions_for_si_unit
7686      (n : si_unit_name ) : dimensional_exponents;
7687      CASE n OF
7688         metre :
7689               RETURN (dimensional_exponents(1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000));
7690         gram :
7691               RETURN (dimensional_exponents(0.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000));
7692         second :
7693               RETURN (dimensional_exponents(0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000));
7694         ampere :
7695               RETURN (dimensional_exponents(0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000));
7696         kelvin :
7697               RETURN (dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000));
7698         mole :
7699               RETURN (dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000));
7700         candela :
7701               RETURN (dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000));
7702         radian :
7703               RETURN (dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000));
7704         steradian :
7705               RETURN (dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000));
7706         hertz :
7707               RETURN (dimensional_exponents(0.00000, 0.00000, -1.00000, 0.00000, 0.00000, 0.00000, 0.00000));
7708         newton :
7709               RETURN (dimensional_exponents(1.00000, 1.00000, -2.00000, 0.00000, 0.00000, 0.00000, 0.00000));
7710         pascal :
7711               RETURN (dimensional_exponents(-1.00000, 1.00000, -2.00000, 0.00000, 0.00000, 0.00000, 0.00000));
7712         joule :
7713               RETURN (dimensional_exponents(2.00000, 1.00000, -2.00000, 0.00000, 0.00000, 0.00000, 0.00000));
7714         watt :
7715               RETURN (dimensional_exponents(2.00000, 1.00000, -3.00000, 0.00000, 0.00000, 0.00000, 0.00000));
7716         coulomb :
7717               RETURN (dimensional_exponents(0.00000, 0.00000, 1.00000, 1.00000, 0.00000, 0.00000, 0.00000));
7718         volt :
7719               RETURN (dimensional_exponents(2.00000, 1.00000, -3.00000, -1.00000, 0.00000, 0.00000, 0.00000));
7720         farad :
7721               RETURN (dimensional_exponents(-2.00000, -1.00000, 4.00000, 1.00000, 0.00000, 0.00000, 0.00000));
7722         ohm :
7723               RETURN (dimensional_exponents(2.00000, 1.00000, -3.00000, -2.00000, 0.00000, 0.00000, 0.00000));
7724         siemens :
7725               RETURN (dimensional_exponents(-2.00000, -1.00000, 3.00000, 2.00000, 0.00000, 0.00000, 0.00000));
7726         weber :
7727               RETURN (dimensional_exponents(2.00000, 1.00000, -2.00000, -1.00000, 0.00000, 0.00000, 0.00000));
7728         tesla :
7729               RETURN (dimensional_exponents(0.00000, 1.00000, -2.00000, -1.00000, 0.00000, 0.00000, 0.00000));
7730         henry :
7731               RETURN (dimensional_exponents(2.00000, 1.00000, -2.00000, -2.00000, 0.00000, 0.00000, 0.00000));
7732         degree_Celsius :
7733               RETURN (dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000));
7734         lumen :
7735               RETURN (dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000));
7736         lux :
7737               RETURN (dimensional_exponents(-2.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000));
7738         becquerel :
7739               RETURN (dimensional_exponents(0.00000, 0.00000, -1.00000, 0.00000, 0.00000, 0.00000, 0.00000));
7740         gray :
7741               RETURN (dimensional_exponents(2.00000, 0.00000, -2.00000, 0.00000, 0.00000, 0.00000, 0.00000));
7742         sievert :
7743               RETURN (dimensional_exponents(2.00000, 0.00000, -2.00000, 0.00000, 0.00000, 0.00000, 0.00000));
7744      OTHERWISE :
7745            RETURN (?);
7746      END_CASE;
7747   END_FUNCTION;
7748
7749   FUNCTION domain_from
7750      (ref : maths_space_or_function ) : tuple_space;
7751   LOCAL
7752      typenames : SET OF STRING := stripped_typeof(ref);
7753      func : maths_function;
7754   END_LOCAL;
7755      IF NOT EXISTS(ref) THEN
7756         RETURN (?);
7757      END_IF;
7758      IF 'TUPLE_SPACE' IN typenames THEN
7759         RETURN (ref);
7760      END_IF;
7761      IF 'MATHS_SPACE' IN typenames THEN
7762         RETURN (one_tuples_of(ref));
7763      END_IF;
7764      func := ref;
7765      IF 'CONSTANT_FUNCTION' IN typenames THEN
7766         RETURN (domain_from(func\constant_function.source_of_domain));
7767      END_IF;
7768      IF 'SELECTOR_FUNCTION' IN typenames THEN
7769         RETURN (domain_from(func\selector_function.source_of_domain));
7770      END_IF;
7771      IF 'PARALLEL_COMPOSED_FUNCTION' IN typenames THEN
7772         RETURN (domain_from(func\parallel_composed_function.source_of_domain));
7773      END_IF;
7774      RETURN (func.domain);
7775   END_FUNCTION;
7776
7777   FUNCTION dot_count
7778      (str : STRING ) : INTEGER;
7779   LOCAL
7780      n : INTEGER := 0;
7781   END_LOCAL;
7782      REPEAT i := 1 TO LENGTH(str);
7783         IF str[i] = '.' THEN
7784            n := n + 1;
7785         END_IF;
7786      END_REPEAT;
7787      RETURN (n);
7788   END_FUNCTION;
7789
7790   FUNCTION dot_product
7791      (arg1 : direction;
7792       arg2 : direction ) : REAL;
7793   LOCAL
7794      scalar : REAL;
7795      vec1 : direction;
7796      vec2 : direction;
7797      ndim : INTEGER;
7798   END_LOCAL;
7799      IF NOT EXISTS(arg1) OR NOT EXISTS(arg2) THEN
7800         scalar := ?;
7801      ELSE
7802         IF arg1.dim <> arg2.dim THEN
7803            scalar := ?;
7804         ELSE
7805            BEGIN
7806               vec1 := normalise(arg1);
7807               vec2 := normalise(arg2);
7808               ndim := arg1.dim;
7809               scalar := 0.00000;
7810               REPEAT i := 1 TO ndim;
7811                  scalar := scalar + vec1.direction_ratios[i] * vec2.direction_ratios[i];
7812               END_REPEAT;
7813            END;
7814         END_IF;
7815      END_IF;
7816      RETURN (scalar);
7817   END_FUNCTION;
7818
7819   FUNCTION dotted_identifiers_syntax
7820      (str : STRING ) : BOOLEAN;
7821   LOCAL
7822      k : positive_integer;
7823      m : positive_integer;
7824   END_LOCAL;
7825      IF NOT EXISTS(str) THEN
7826         RETURN (FALSE);
7827      END_IF;
7828      k := parse_express_identifier(str, 1);
7829      IF k = 1 THEN
7830         RETURN (FALSE);
7831      END_IF;
7832      REPEAT WHILE k <= LENGTH(str);
7833         IF (str[k] <> '.') OR (k = LENGTH(str)) THEN
7834            RETURN (FALSE);
7835         END_IF;
7836         m := parse_express_identifier(str, k + 1);
7837         IF m = k + 1 THEN
7838            RETURN (FALSE);
7839         END_IF;
7840         k := m;
7841      END_REPEAT;
7842      RETURN (TRUE);
7843   END_FUNCTION;
7844
7845   FUNCTION drop_numeric_constraints
7846      (spc : maths_space ) : maths_space;
7847   LOCAL
7848      typenames : SET OF STRING := stripped_typeof(spc);
7849      tspc : listed_product_space;
7850      factors : LIST OF maths_space := [];
7851      xspc : extended_tuple_space;
7852   END_LOCAL;
7853      IF 'UNIFORM_PRODUCT_SPACE' IN typenames THEN
7854         RETURN (make_uniform_product_space(drop_numeric_constraints(spc\uniform_product_space.base), spc\uniform_product_space.exponent));
7855      END_IF;
7856      IF 'LISTED_PRODUCT_SPACE' IN typenames THEN
7857         tspc := spc;
7858         REPEAT i := 1 TO SIZEOF(tspc.factors);
7859            INSERT( factors, drop_numeric_constraints(tspc.factors[i]), i - 1 );
7860         END_REPEAT;
7861         RETURN (make_listed_product_space(factors));
7862      END_IF;
7863      IF 'EXTENDED_TUPLE_SPACE' IN typenames THEN
7864         xspc := spc;
7865         RETURN (make_extended_tuple_space(drop_numeric_constraints(xspc.base), drop_numeric_constraints(xspc.extender)));
7866      END_IF;
7867      IF subspace_of_es(spc, es_numbers) THEN
7868         RETURN (number_superspace_of(spc));
7869      END_IF;
7870      RETURN (spc);
7871   END_FUNCTION;
7872
7873   FUNCTION enclose_cregion_in_pregion
7874      (crgn : cartesian_complex_number_region;
7875       centre : complex_number_literal ) : polar_complex_number_region;
7876      FUNCTION angle
7877         (a : REAL ) : REAL;
7878         REPEAT WHILE a > 3.14159;
7879            a := a - 2.00000 * 3.14159;
7880         END_REPEAT;
7881         REPEAT WHILE a <= -3.14159;
7882            a := a + 2.00000 * 3.14159;
7883         END_REPEAT;
7884         RETURN (a);
7885      END_FUNCTION;
7886      FUNCTION strictly_in
7887         (z : REAL;
7888          zitv : real_interval ) : LOGICAL;
7889         RETURN ((NOT min_exists(zitv) OR (z > real_min(zitv))) AND (NOT max_exists(zitv) OR (z < real_max(zitv))));
7890      END_FUNCTION;
7891      PROCEDURE angle_minmax
7892         (ab : REAL;
7893          a : REAL;
7894          a_in : BOOLEAN;
7895          VAR amin : REAL;
7896          VAR amax : REAL;
7897          VAR amin_in : BOOLEAN;
7898          VAR amax_in : BOOLEAN );
7899         a := angle(a - ab);
7900         IF amin = a THEN
7901            amin_in := amin_in OR a_in;
7902         END_IF;
7903         IF amin > a THEN
7904            amin := a;
7905            amin_in := a_in;
7906         END_IF;
7907         IF amax = a THEN
7908            amax_in := amax_in OR a_in;
7909         END_IF;
7910         IF amax < a THEN
7911            amax := a;
7912            amax_in := a_in;
7913         END_IF;
7914      END_PROCEDURE;
7915      PROCEDURE range_max
7916         (r : REAL;
7917          incl : BOOLEAN;
7918          VAR rmax : REAL;
7919          VAR rmax_in : BOOLEAN );
7920         IF rmax = r THEN
7921            rmax_in := rmax_in OR incl;
7922         END_IF;
7923         IF rmax < r THEN
7924            rmax := r;
7925            rmax_in := incl;
7926         END_IF;
7927      END_PROCEDURE;
7928      PROCEDURE range_min
7929         (r : REAL;
7930          incl : BOOLEAN;
7931          VAR rmin : REAL;
7932          VAR rmin_in : BOOLEAN );
7933         IF rmin = r THEN
7934            rmin_in := rmin_in OR incl;
7935         END_IF;
7936         IF (rmin < 0.00000) OR (rmin > r) THEN
7937            rmin := r;
7938            rmin_in := incl;
7939         END_IF;
7940      END_PROCEDURE;
7941   LOCAL
7942      xitv : real_interval;
7943      yitv : real_interval;
7944      is_xmin : BOOLEAN;
7945      is_xmax : BOOLEAN;
7946      is_ymin : BOOLEAN;
7947      is_ymax : BOOLEAN;
7948      xmin : REAL := 0.00000;
7949      xmax : REAL := 0.00000;
7950      ymin : REAL := 0.00000;
7951      ymax : REAL := 0.00000;
7952      xc : REAL := 0.00000;
7953      yc : REAL := 0.00000;
7954      xmin_in : BOOLEAN := FALSE;
7955      xmax_in : BOOLEAN := FALSE;
7956      ymin_in : BOOLEAN := FALSE;
7957      ymax_in : BOOLEAN := FALSE;
7958      rmin : REAL := -1.00000;
7959      rmax : REAL := -1.00000;
7960      amin : REAL := 4.00000;
7961      amax : REAL := -4.00000;
7962      rmax_exists : BOOLEAN := TRUE;
7963      outside : BOOLEAN := TRUE;
7964      rmin_in : BOOLEAN := FALSE;
7965      rmax_in : BOOLEAN := FALSE;
7966      amin_in : BOOLEAN := FALSE;
7967      amax_in : BOOLEAN := FALSE;
7968      ab : REAL := 0.00000;
7969      a : REAL := 0.00000;
7970      r : REAL := 0.00000;
7971      incl : BOOLEAN;
7972      ritv : real_interval;
7973      aitv : finite_real_interval;
7974      minclo : open_closed := open;
7975      maxclo : open_closed := open;
7976   END_LOCAL;
7977      IF NOT EXISTS(crgn) OR NOT EXISTS(centre) THEN
7978         RETURN (?);
7979      END_IF;
7980      xitv := crgn.real_constraint;
7981      yitv := crgn.imag_constraint;
7982      xc := centre.real_part;
7983      yc := centre.imag_part;
7984      is_xmin := min_exists(xitv);
7985      is_xmax := max_exists(xitv);
7986      is_ymin := min_exists(yitv);
7987      is_ymax := max_exists(yitv);
7988      IF is_xmin THEN
7989         xmin := real_min(xitv);
7990         xmin_in := min_included(xitv);
7991      END_IF;
7992      IF is_xmax THEN
7993         xmax := real_max(xitv);
7994         xmax_in := max_included(xitv);
7995      END_IF;
7996      IF is_ymin THEN
7997         ymin := real_min(yitv);
7998         ymin_in := min_included(yitv);
7999      END_IF;
8000      IF is_ymax THEN
8001         ymax := real_max(yitv);
8002         ymax_in := max_included(yitv);
8003      END_IF;
8004      rmax_exists := ((is_xmin AND is_xmax) AND is_ymin) AND is_ymax;
8005      IF is_xmin AND (xc <= xmin) THEN
8006         ab := 0.00000;
8007      ELSE
8008         IF is_ymin AND (yc <= ymin) THEN
8009            ab := 0.500000 * 3.14159;
8010         ELSE
8011            IF is_ymax AND (yc >= ymax) THEN
8012               ab := -0.500000 * 3.14159;
8013            ELSE
8014               IF is_xmax AND (xc >= xmax) THEN
8015                  ab := 3.14159;
8016               ELSE
8017                  outside := FALSE;
8018               END_IF;
8019            END_IF;
8020         END_IF;
8021      END_IF;
8022      IF NOT outside AND NOT rmax_exists THEN
8023         RETURN (?);
8024      END_IF;
8025      IF (is_xmin AND (xc <= xmin)) AND strictly_in(yc, yitv) THEN
8026         rmin := xmin - xc;
8027         rmin_in := xmin_in;
8028      ELSE
8029         IF (is_ymin AND (yc <= ymin)) AND strictly_in(xc, xitv) THEN
8030            rmin := ymin - yc;
8031            rmin_in := ymin_in;
8032         ELSE
8033            IF (is_ymax AND (yc >= ymax)) AND strictly_in(xc, xitv) THEN
8034               rmin := yc - ymax;
8035               rmin_in := ymax_in;
8036            ELSE
8037               IF (is_xmax AND (xc >= xmax)) AND strictly_in(yc, yitv) THEN
8038                  rmin := xc - xmax;
8039                  rmin_in := xmax_in;
8040               END_IF;
8041            END_IF;
8042         END_IF;
8043      END_IF;
8044      IF is_xmin THEN
8045         IF is_ymin THEN
8046            r := SQRT((xmin - xc) ** 2 + (ymin - yc) ** 2);
8047            incl := xmin_in AND ymin_in;
8048            IF rmax_exists THEN
8049               range_max( r, incl, rmax, rmax_in );
8050            END_IF;
8051            IF outside THEN
8052               IF r > 0.00000 THEN
8053                  range_min( r, incl, rmin, rmin_in );
8054                  a := angle(atan2(ymin - yc, xmin - xc) - ab);
8055                  IF xc = xmin THEN
8056                     incl := xmin_in;
8057                  END_IF;
8058                  IF yc = ymin THEN
8059                     incl := ymin_in;
8060                  END_IF;
8061                  angle_minmax( ab, a, incl, amin, amax, amin_in, amax_in );
8062               ELSE
8063                  rmin := 0.00000;
8064                  rmin_in := xmin_in AND ymin_in;
8065                  amin := angle(0.00000 - ab);
8066                  amin_in := ymin_in;
8067                  amax := angle(0.500000 * 3.14159 - ab);
8068                  amax_in := xmin_in;
8069               END_IF;
8070            END_IF;
8071         ELSE
8072            IF xc <= xmin THEN
8073               angle_minmax( ab, -0.500000 * 3.14159, (xc = xmin) AND xmin_in, amin, amax, amin_in, amax_in );
8074            END_IF;
8075         END_IF;
8076         IF NOT is_ymax AND (xc <= xmin) THEN
8077            angle_minmax( ab, 0.500000 * 3.14159, (xc = xmin) AND xmin_in, amin, amax, amin_in, amax_in );
8078         END_IF;
8079      END_IF;
8080      IF is_ymin THEN
8081         IF is_xmax THEN
8082            r := SQRT((xmax - xc) ** 2 + (ymin - yc) ** 2);
8083            incl := xmax_in AND ymin_in;
8084            IF rmax_exists THEN
8085               range_max( r, incl, rmax, rmax_in );
8086            END_IF;
8087            IF outside THEN
8088               IF r > 0.00000 THEN
8089                  range_min( r, incl, rmin, rmin_in );
8090                  a := angle(atan2(ymin - yc, xmax - xc) - ab);
8091                  IF xc = xmax THEN
8092                     incl := xmax_in;
8093                  END_IF;
8094                  IF yc = ymin THEN
8095                     incl := ymin_in;
8096                  END_IF;
8097                  angle_minmax( ab, a, incl, amin, amax, amin_in, amax_in );
8098               ELSE
8099                  rmin := 0.00000;
8100                  rmin_in := xmax_in AND ymin_in;
8101                  amin := angle(0.500000 * 3.14159 - ab);
8102                  amin_in := ymin_in;
8103                  amax := angle(3.14159 - ab);
8104                  amax_in := xmax_in;
8105               END_IF;
8106            END_IF;
8107         ELSE
8108            IF yc <= ymin THEN
8109               angle_minmax( ab, 0.00000, (yc = ymin) AND ymin_in, amin, amax, amin_in, amax_in );
8110            END_IF;
8111         END_IF;
8112         IF NOT is_xmin AND (yc <= ymin) THEN
8113            angle_minmax( ab, 3.14159, (yc = ymin) AND ymin_in, amin, amax, amin_in, amax_in );
8114         END_IF;
8115      END_IF;
8116      IF is_xmax THEN
8117         IF is_ymax THEN
8118            r := SQRT((xmax - xc) ** 2 + (ymax - yc) ** 2);
8119            incl := xmax_in AND ymax_in;
8120            IF rmax_exists THEN
8121               range_max( r, incl, rmax, rmax_in );
8122            END_IF;
8123            IF outside THEN
8124               IF r > 0.00000 THEN
8125                  range_min( r, incl, rmin, rmin_in );
8126                  a := angle(atan2(ymax - yc, xmax - xc) - ab);
8127                  IF xc = xmax THEN
8128                     incl := xmax_in;
8129                  END_IF;
8130                  IF yc = ymax THEN
8131                     incl := ymax_in;
8132                  END_IF;
8133                  angle_minmax( ab, a, incl, amin, amax, amin_in, amax_in );
8134               ELSE
8135                  rmin := 0.00000;
8136                  rmin_in := xmax_in AND ymax_in;
8137                  amin := angle(-3.14159 - ab);
8138                  amin_in := ymax_in;
8139                  amax := angle(-0.500000 * 3.14159 - ab);
8140                  amax_in := xmax_in;
8141               END_IF;
8142            END_IF;
8143         ELSE
8144            IF xc >= xmax THEN
8145               angle_minmax( ab, 0.500000 * 3.14159, (xc = xmax) AND xmax_in, amin, amax, amin_in, amax_in );
8146            END_IF;
8147         END_IF;
8148         IF NOT is_ymin AND (xc >= xmax) THEN
8149            angle_minmax( ab, -0.500000 * 3.14159, (xc = xmax) AND xmax_in, amin, amax, amin_in, amax_in );
8150         END_IF;
8151      END_IF;
8152      IF is_ymax THEN
8153         IF is_xmin THEN
8154            r := SQRT((xmin - xc) ** 2 + (ymax - yc) ** 2);
8155            incl := xmin_in AND ymax_in;
8156            IF rmax_exists THEN
8157               range_max( r, incl, rmax, rmax_in );
8158            END_IF;
8159            IF outside THEN
8160               IF r > 0.00000 THEN
8161                  range_min( r, incl, rmin, rmin_in );
8162                  a := angle(atan2(ymax - yc, xmin - xc) - ab);
8163                  IF xc = xmin THEN
8164                     incl := xmin_in;
8165                  END_IF;
8166                  IF yc = ymax THEN
8167                     incl := ymax_in;
8168                  END_IF;
8169                  angle_minmax( ab, a, incl, amin, amax, amin_in, amax_in );
8170               ELSE
8171                  rmin := 0.00000;
8172                  rmin_in := xmin_in AND ymax_in;
8173                  amin := angle(0.500000 * 3.14159 - ab);
8174                  amin_in := ymax_in;
8175                  amax := angle(3.14159 - ab);
8176                  amax_in := xmin_in;
8177               END_IF;
8178            END_IF;
8179         ELSE
8180            IF yc >= ymax THEN
8181               angle_minmax( ab, 3.14159, (yc = ymax) AND ymax_in, amin, amax, amin_in, amax_in );
8182            END_IF;
8183         END_IF;
8184         IF NOT is_xmax AND (yc >= ymax) THEN
8185            angle_minmax( ab, 0.00000, (yc = ymax) AND ymax_in, amin, amax, amin_in, amax_in );
8186         END_IF;
8187      END_IF;
8188      IF outside THEN
8189         amin := angle(amin + ab);
8190         IF amin = 3.14159 THEN
8191            amin := -3.14159;
8192         END_IF;
8193         amax := angle(amax + ab);
8194         IF amax <= amin THEN
8195            amax := amax + 2.00000 * 3.14159;
8196         END_IF;
8197      ELSE
8198         amin := -3.14159;
8199         amin_in := FALSE;
8200         amax := 3.14159;
8201         amax_in := FALSE;
8202      END_IF;
8203      IF amin_in THEN
8204         minclo := closed;
8205      END_IF;
8206      IF amax_in THEN
8207         maxclo := closed;
8208      END_IF;
8209      aitv := make_finite_real_interval(amin, minclo, amax, maxclo);
8210      minclo := open;
8211      IF rmin_in THEN
8212         minclo := closed;
8213      END_IF;
8214      IF rmax_exists THEN
8215         maxclo := open;
8216         IF rmax_in THEN
8217            maxclo := closed;
8218         END_IF;
8219         ritv := make_finite_real_interval(rmin, minclo, rmax, maxclo);
8220      ELSE
8221         ritv := make_real_interval_from_min(rmin, minclo);
8222      END_IF;
8223      RETURN (make_polar_complex_number_region(centre, ritv, aitv));
8224   END_FUNCTION;
8225
8226   FUNCTION enclose_pregion_in_cregion
8227      (prgn : polar_complex_number_region ) : cartesian_complex_number_region;
8228      PROCEDURE nearest_good_direction
8229         (acart : REAL;
8230          aitv : finite_real_interval;
8231          VAR a : REAL;
8232          VAR a_in : BOOLEAN );
8233         a := acart;
8234         a_in := TRUE;
8235         IF a < aitv.min THEN
8236            IF a + 2.00000 * 3.14159 < aitv.max THEN
8237               RETURN;
8238            END_IF;
8239            IF a + 2.00000 * 3.14159 = aitv.max THEN
8240               a_in := max_included(aitv);
8241               RETURN;
8242            END_IF;
8243         ELSE
8244            IF a = aitv.min THEN
8245               a_in := min_included(aitv);
8246               RETURN;
8247            ELSE
8248               IF a < aitv.max THEN
8249                  RETURN;
8250               ELSE
8251                  IF a = aitv.max THEN
8252                     a_in := max_included(aitv);
8253                     RETURN;
8254                  END_IF;
8255               END_IF;
8256            END_IF;
8257         END_IF;
8258         IF COS(acart - aitv.max) >= COS(acart - aitv.min) THEN
8259            a := aitv.max;
8260            a_in := max_included(aitv);
8261         ELSE
8262            a := aitv.min;
8263            a_in := min_included(aitv);
8264         END_IF;
8265      END_PROCEDURE;
8266   LOCAL
8267      xc : REAL := 0.00000;
8268      yc : REAL := 0.00000;
8269      xmin : REAL := 0.00000;
8270      xmax : REAL := 0.00000;
8271      ymin : REAL := 0.00000;
8272      ymax : REAL := 0.00000;
8273      ritv : real_interval;
8274      xitv : real_interval;
8275      yitv : real_interval;
8276      aitv : finite_real_interval;
8277      xmin_exists : BOOLEAN;
8278      xmax_exists : BOOLEAN;
8279      ymin_exists : BOOLEAN;
8280      ymax_exists : BOOLEAN;
8281      xmin_in : BOOLEAN := FALSE;
8282      xmax_in : BOOLEAN := FALSE;
8283      ymin_in : BOOLEAN := FALSE;
8284      ymax_in : BOOLEAN := FALSE;
8285      a : REAL := 0.00000;
8286      r : REAL := 0.00000;
8287      a_in : BOOLEAN := FALSE;
8288      min_clo : open_closed := open;
8289      max_clo : open_closed := open;
8290   END_LOCAL;
8291      IF NOT EXISTS(prgn) THEN
8292         RETURN (?);
8293      END_IF;
8294      xc := prgn.centre.real_part;
8295      yc := prgn.centre.imag_part;
8296      ritv := prgn.distance_constraint;
8297      aitv := prgn.direction_constraint;
8298      nearest_good_direction( 3.14159, aitv, a, a_in );
8299      IF COS(a) >= 0.00000 THEN
8300         xmin_exists := TRUE;
8301         xmin := xc + real_min(ritv) * COS(a);
8302         xmin_in := a_in AND (min_included(ritv) OR (COS(a) = 0.00000));
8303      ELSE
8304         IF max_exists(ritv) THEN
8305            xmin_exists := TRUE;
8306            xmin := xc + real_max(ritv) * COS(a);
8307            xmin_in := a_in AND max_included(ritv);
8308         ELSE
8309            xmin_exists := FALSE;
8310         END_IF;
8311      END_IF;
8312      nearest_good_direction( 0.00000, aitv, a, a_in );
8313      IF COS(a) <= 0.00000 THEN
8314         xmax_exists := TRUE;
8315         xmax := xc + real_min(ritv) * COS(a);
8316         xmax_in := a_in AND (min_included(ritv) OR (COS(a) = 0.00000));
8317      ELSE
8318         IF max_exists(ritv) THEN
8319            xmax_exists := TRUE;
8320            xmax := xc + real_max(ritv) * COS(a);
8321            xmax_in := a_in AND max_included(ritv);
8322         ELSE
8323            xmax_exists := FALSE;
8324         END_IF;
8325      END_IF;
8326      nearest_good_direction( -0.500000 * 3.14159, aitv, a, a_in );
8327      IF SIN(a) >= 0.00000 THEN
8328         ymin_exists := TRUE;
8329         ymin := yc + real_min(ritv) * SIN(a);
8330         ymin_in := a_in AND (min_included(ritv) OR (SIN(a) = 0.00000));
8331      ELSE
8332         IF max_exists(ritv) THEN
8333            ymin_exists := TRUE;
8334            ymin := yc + real_max(ritv) * SIN(a);
8335            ymin_in := a_in AND max_included(ritv);
8336         ELSE
8337            ymin_exists := FALSE;
8338         END_IF;
8339      END_IF;
8340      nearest_good_direction( 0.500000 * 3.14159, aitv, a, a_in );
8341      IF SIN(a) <= 0.00000 THEN
8342         ymax_exists := TRUE;
8343         ymax := yc + real_min(ritv) * SIN(a);
8344         ymax_in := a_in AND (min_included(ritv) OR (SIN(a) = 0.00000));
8345      ELSE
8346         IF max_exists(ritv) THEN
8347            ymax_exists := TRUE;
8348            ymax := yc + real_max(ritv) * SIN(a);
8349            ymax_in := a_in AND max_included(ritv);
8350         ELSE
8351            ymax_exists := FALSE;
8352         END_IF;
8353      END_IF;
8354      IF NOT (((xmin_exists OR xmax_exists) OR ymin_exists) OR ymax_exists) THEN
8355         RETURN (?);
8356      END_IF;
8357      IF xmin_exists THEN
8358         IF xmin_in THEN
8359            min_clo := closed;
8360         ELSE
8361            min_clo := open;
8362         END_IF;
8363         IF xmax_exists THEN
8364            IF xmax_in THEN
8365               max_clo := closed;
8366            ELSE
8367               max_clo := open;
8368            END_IF;
8369            xitv := make_finite_real_interval(xmin, min_clo, xmax, max_clo);
8370         ELSE
8371            xitv := make_real_interval_from_min(xmin, min_clo);
8372         END_IF;
8373      ELSE
8374         IF xmax_exists THEN
8375            IF xmax_in THEN
8376               max_clo := closed;
8377            ELSE
8378               max_clo := open;
8379            END_IF;
8380            xitv := make_real_interval_to_max(xmax, max_clo);
8381         ELSE
8382            xitv := the_reals;
8383         END_IF;
8384      END_IF;
8385      IF ymin_exists THEN
8386         IF ymin_in THEN
8387            min_clo := closed;
8388         ELSE
8389            min_clo := open;
8390         END_IF;
8391         IF ymax_exists THEN
8392            IF ymax_in THEN
8393               max_clo := closed;
8394            ELSE
8395               max_clo := open;
8396            END_IF;
8397            yitv := make_finite_real_interval(ymin, min_clo, ymax, max_clo);
8398         ELSE
8399            yitv := make_real_interval_from_min(ymin, min_clo);
8400         END_IF;
8401      ELSE
8402         IF ymax_exists THEN
8403            IF ymax_in THEN
8404               max_clo := closed;
8405            ELSE
8406               max_clo := open;
8407            END_IF;
8408            yitv := make_real_interval_to_max(ymax, max_clo);
8409         ELSE
8410            yitv := the_reals;
8411         END_IF;
8412      END_IF;
8413      RETURN (make_cartesian_complex_number_region(xitv, yitv));
8414   END_FUNCTION;
8415
8416   FUNCTION enclose_pregion_in_pregion
8417      (prgn : polar_complex_number_region;
8418       centre : complex_number_literal ) : polar_complex_number_region;
8419      FUNCTION angle
8420         (a : REAL ) : REAL;
8421         REPEAT WHILE a > 3.14159;
8422            a := a - 2.00000 * 3.14159;
8423         END_REPEAT;
8424         REPEAT WHILE a <= -3.14159;
8425            a := a + 2.00000 * 3.14159;
8426         END_REPEAT;
8427         RETURN (a);
8428      END_FUNCTION;
8429      PROCEDURE angle_range
8430         (VAR amin : REAL;
8431          VAR amax : REAL );
8432         amin := angle(amin);
8433         IF amin = 3.14159 THEN
8434            amin := -3.14159;
8435         END_IF;
8436         amax := angle(amax);
8437         IF amax <= amin THEN
8438            amax := amax + 2.00000 * 3.14159;
8439         END_IF;
8440      END_PROCEDURE;
8441      FUNCTION strictly_in
8442         (a : REAL;
8443          aitv : finite_real_interval ) : LOGICAL;
8444         a := angle(a);
8445         RETURN ((aitv.min < a) AND (a < aitv.max) OR (aitv.min < a + 2.00000 * 3.14159) AND (a + 2.00000 * 3.14159 < aitv.max));
8446      END_FUNCTION;
8447      PROCEDURE find_aminmax
8448         (ab : REAL;
8449          a0 : REAL;
8450          a1 : REAL;
8451          a2 : REAL;
8452          a3 : REAL;
8453          in0 : BOOLEAN;
8454          in1 : BOOLEAN;
8455          in2 : BOOLEAN;
8456          in3 : BOOLEAN;
8457          VAR amin : REAL;
8458          VAR amax : REAL;
8459          VAR amin_in : BOOLEAN;
8460          VAR amax_in : BOOLEAN );
8461      LOCAL
8462         a : REAL;
8463      END_LOCAL;
8464         amin := angle(a0 - ab);
8465         amin_in := in0;
8466         amax := amin;
8467         amax_in := in0;
8468         a := angle(a1 - ab);
8469         IF a = amin THEN
8470            amin_in := amin_in OR in1;
8471         END_IF;
8472         IF a < amin THEN
8473            amin := a;
8474            amin_in := in1;
8475         END_IF;
8476         IF a = amax THEN
8477            amax_in := amax_in OR in1;
8478         END_IF;
8479         IF a > amax THEN
8480            amax := a;
8481            amax_in := in1;
8482         END_IF;
8483         a := angle(a2 - ab);
8484         IF a = amin THEN
8485            amin_in := amin_in OR in2;
8486         END_IF;
8487         IF a < amin THEN
8488            amin := a;
8489            amin_in := in2;
8490         END_IF;
8491         IF a = amax THEN
8492            amax_in := amax_in OR in2;
8493         END_IF;
8494         IF a > amax THEN
8495            amax := a;
8496            amax_in := in2;
8497         END_IF;
8498         a := angle(a3 - ab);
8499         IF a = amin THEN
8500            amin_in := amin_in OR in3;
8501         END_IF;
8502         IF a < amin THEN
8503            amin := a;
8504            amin_in := in3;
8505         END_IF;
8506         IF a = amax THEN
8507            amax_in := amax_in OR in3;
8508         END_IF;
8509         IF a > amax THEN
8510            amax := a;
8511            amax_in := in3;
8512         END_IF;
8513         amin := amin + ab;
8514         amax := amax + ab;
8515         angle_range( amin, amax );
8516      END_PROCEDURE;
8517   LOCAL
8518      ritp : real_interval;
8519      ritv : real_interval;
8520      aitp : finite_real_interval;
8521      aitv : finite_real_interval;
8522      xp : REAL := 0.00000;
8523      yp : REAL := 0.00000;
8524      xc : REAL := 0.00000;
8525      yc : REAL := 0.00000;
8526      rmax : REAL := 0.00000;
8527      rmin : REAL := 0.00000;
8528      amin : REAL := 0.00000;
8529      amax : REAL := 0.00000;
8530      rc : REAL := 0.00000;
8531      acp : REAL := 0.00000;
8532      apc : REAL := 0.00000;
8533      rmax_in : BOOLEAN := FALSE;
8534      rmin_in : BOOLEAN := FALSE;
8535      amin_in : BOOLEAN := FALSE;
8536      amax_in : BOOLEAN := FALSE;
8537      rmxp : REAL := 0.00000;
8538      rmnp : REAL := 0.00000;
8539      x : REAL := 0.00000;
8540      y : REAL := 0.00000;
8541      r : REAL := 0.00000;
8542      a : REAL := 0.00000;
8543      ab : REAL := 0.00000;
8544      r0 : REAL := 0.00000;
8545      a0 : REAL := 0.00000;
8546      r1 : REAL := 0.00000;
8547      a1 : REAL := 0.00000;
8548      r2 : REAL := 0.00000;
8549      a2 : REAL := 0.00000;
8550      r3 : REAL := 0.00000;
8551      a3 : REAL := 0.00000;
8552      in0 : BOOLEAN := FALSE;
8553      in1 : BOOLEAN := FALSE;
8554      in2 : BOOLEAN := FALSE;
8555      in3 : BOOLEAN := FALSE;
8556      inn : BOOLEAN := FALSE;
8557      minclo : open_closed := open;
8558      maxclo : open_closed := open;
8559   END_LOCAL;
8560      IF NOT EXISTS(prgn) OR NOT EXISTS(centre) THEN
8561         RETURN (?);
8562      END_IF;
8563      xp := prgn.centre.real_part;
8564      yp := prgn.centre.imag_part;
8565      ritp := prgn.distance_constraint;
8566      aitp := prgn.direction_constraint;
8567      xc := centre.real_part;
8568      yc := centre.imag_part;
8569      IF (xc = xp) AND (yc = yp) THEN
8570         RETURN (prgn);
8571      END_IF;
8572      rc := SQRT((xp - xc) ** 2 + (yp - yc) ** 2);
8573      acp := atan2(yp - yc, xp - xc);
8574      apc := atan2(yc - yp, xc - xp);
8575      rmnp := real_min(ritp);
8576      IF max_exists(ritp) THEN
8577         rmxp := real_max(ritp);
8578         IF aitp.max - aitp.min = 2.00000 * 3.14159 THEN
8579            inn := NOT max_included(aitp);
8580            a := angle(aitp.min);
8581            rmax := rc + rmxp;
8582            rmax_in := max_included(ritp);
8583            IF inn AND (acp = a) THEN
8584               rmax_in := FALSE;
8585            END_IF;
8586            IF rc > rmxp THEN
8587               a0 := ASIN(rmxp / rc);
8588               amin := angle(acp - a0);
8589               amin_in := max_included(ritp);
8590               IF amin = 3.14159 THEN
8591                  amin := -3.14159;
8592               END_IF;
8593               amax := angle(acp + a0);
8594               amax_in := amin_in;
8595               IF amax < amin THEN
8596                  amax := amax + 2.00000 * 3.14159;
8597               END_IF;
8598               rmin := rc - rmxp;
8599               rmin_in := amin_in;
8600               IF inn THEN
8601                  IF apc = a THEN
8602                     rmin_in := FALSE;
8603                  END_IF;
8604                  IF angle(amin + 0.500000 * 3.14159) = a THEN
8605                     amin_in := FALSE;
8606                  END_IF;
8607                  IF angle(amax - 0.500000 * 3.14159) = a THEN
8608                     amax_in := FALSE;
8609                  END_IF;
8610               END_IF;
8611            ELSE
8612               IF rc = rmxp THEN
8613                  amin := angle(acp - 0.500000 * 3.14159);
8614                  amin_in := FALSE;
8615                  IF amin = 3.14159 THEN
8616                     amin := -3.14159;
8617                  END_IF;
8618                  amax := angle(acp + 0.500000 * 3.14159);
8619                  amax_in := FALSE;
8620                  IF amax < amin THEN
8621                     amax := amax + 2.00000 * 3.14159;
8622                  END_IF;
8623                  rmin := 0.00000;
8624                  rmin_in := max_included(ritp);
8625                  IF inn AND (apc = a) THEN
8626                     rmin_in := FALSE;
8627                  END_IF;
8628               ELSE
8629                  IF rc > rmnp THEN
8630                     IF inn AND (apc = a) THEN
8631                        rmin := 0.00000;
8632                        rmin_in := FALSE;
8633                        amin := aitp.min;
8634                        amin_in := FALSE;
8635                        amax := aitp.max;
8636                        amax_in := FALSE;
8637                     ELSE
8638                        rmin := 0.00000;
8639                        rmin_in := TRUE;
8640                        amin := -3.14159;
8641                        amin_in := FALSE;
8642                        amax := 3.14159;
8643                        amax_in := TRUE;
8644                     END_IF;
8645                  ELSE
8646                     rmin := rmnp - rc;
8647                     rmin_in := min_included(ritp);
8648                     amin := -3.14159;
8649                     amin_in := FALSE;
8650                     amax := 3.14159;
8651                     amax_in := TRUE;
8652                     IF inn THEN
8653                        IF apc = a THEN
8654                           rmin_in := FALSE;
8655                           amin := aitp.min;
8656                           amin_in := FALSE;
8657                           amax := aitp.max;
8658                           amax_in := FALSE;
8659                        ELSE
8660                           IF acp = a THEN
8661                              amin := aitp.min;
8662                              amin_in := FALSE;
8663                              amax := aitp.max;
8664                              amax_in := FALSE;
8665                           END_IF;
8666                        END_IF;
8667                     END_IF;
8668                  END_IF;
8669               END_IF;
8670            END_IF;
8671         ELSE
8672            x := xp + rmxp * COS(aitp.min) - xc;
8673            y := yp + rmxp * SIN(aitp.min) - yc;
8674            r0 := SQRT(x ** 2 + y ** 2);
8675            in0 := max_included(ritp) AND min_included(aitp);
8676            IF r0 <> 0.00000 THEN
8677               a0 := atan2(y, x);
8678            END_IF;
8679            x := xp + rmxp * COS(aitp.max) - xc;
8680            y := yp + rmxp * SIN(aitp.max) - yc;
8681            r1 := SQRT(x ** 2 + y ** 2);
8682            in1 := max_included(ritp) AND max_included(aitp);
8683            IF r1 <> 0.00000 THEN
8684               a1 := atan2(y, x);
8685            END_IF;
8686            x := xp + rmnp * COS(aitp.max) - xc;
8687            y := yp + rmnp * SIN(aitp.max) - yc;
8688            r2 := SQRT(x ** 2 + y ** 2);
8689            in2 := min_included(ritp) AND max_included(aitp);
8690            IF r2 <> 0.00000 THEN
8691               a2 := atan2(y, x);
8692            ELSE
8693               a2 := a1;
8694               in2 := in1;
8695            END_IF;
8696            IF r1 = 0.00000 THEN
8697               a1 := a2;
8698               in1 := in2;
8699            END_IF;
8700            x := xp + rmnp * COS(aitp.min) - xc;
8701            y := yp + rmnp * SIN(aitp.min) - yc;
8702            r3 := SQRT(x ** 2 + y ** 2);
8703            in3 := min_included(ritp) AND min_included(aitp);
8704            IF r3 <> 0.00000 THEN
8705               a3 := atan2(y, x);
8706            ELSE
8707               a3 := a0;
8708               in3 := in0;
8709            END_IF;
8710            IF r0 = 0.00000 THEN
8711               a0 := a3;
8712               in0 := in3;
8713            END_IF;
8714            IF rmnp = 0.00000 THEN
8715               in2 := min_included(ritp);
8716               in3 := in2;
8717            END_IF;
8718            IF (apc = angle(aitp.min)) OR (acp = angle(aitp.min)) THEN
8719               in0 := min_included(aitp);
8720               in3 := in0;
8721            ELSE
8722               IF (apc = angle(aitp.max)) OR (acp = angle(aitp.max)) THEN
8723                  in1 := max_included(aitp);
8724                  in2 := in1;
8725               END_IF;
8726            END_IF;
8727            IF strictly_in(acp, aitp) THEN
8728               rmax := rc + rmxp;
8729               rmax_in := max_included(ritp);
8730            ELSE
8731               rmax := r0;
8732               rmax_in := in0;
8733               IF rmax = r1 THEN
8734                  rmax_in := rmax_in OR in1;
8735               END_IF;
8736               IF rmax < r1 THEN
8737                  rmax := r1;
8738                  rmax_in := in1;
8739               END_IF;
8740               IF rmax = r2 THEN
8741                  rmax_in := rmax_in OR in2;
8742               END_IF;
8743               IF rmax < r2 THEN
8744                  rmax := r2;
8745                  rmax_in := in2;
8746               END_IF;
8747               IF rmax = r3 THEN
8748                  rmax_in := rmax_in OR in3;
8749               END_IF;
8750               IF rmax < r3 THEN
8751                  rmax := r3;
8752                  rmax_in := in3;
8753               END_IF;
8754            END_IF;
8755            IF strictly_in(apc, aitp) THEN
8756               IF rc >= rmxp THEN
8757                  rmin := rc - rmxp;
8758                  rmin_in := max_included(ritp);
8759               ELSE
8760                  IF rc <= rmnp THEN
8761                     rmin := rmnp - rc;
8762                     rmin_in := min_included(ritp);
8763                  ELSE
8764                     rmin := 0.00000;
8765                     rmin_in := TRUE;
8766                  END_IF;
8767               END_IF;
8768            ELSE
8769               rmin := r0;
8770               rmin_in := in0;
8771               a := apc - aitp.min;
8772               r := rc * COS(a);
8773               IF (rmnp < r) AND (r < rmxp) THEN
8774                  rmin := rc * SIN(ABS(a));
8775                  rmin_in := min_included(aitp);
8776               END_IF;
8777               a := apc - aitp.max;
8778               r := rc * COS(a);
8779               IF (rmnp < r) AND (r < rmxp) THEN
8780                  r := rc * SIN(ABS(a));
8781                  inn := max_included(aitp);
8782                  IF r = rmin THEN
8783                     rmin_in := rmin_in OR inn;
8784                  END_IF;
8785                  IF r < rmin THEN
8786                     rmin := r;
8787                     rmin_in := inn;
8788                  END_IF;
8789               END_IF;
8790               IF r1 = rmin THEN
8791                  rmin_in := rmin_in OR in1;
8792               END_IF;
8793               IF r1 < rmin THEN
8794                  rmin := r1;
8795                  rmin_in := in1;
8796               END_IF;
8797               IF r2 = rmin THEN
8798                  rmin_in := rmin_in OR in2;
8799               END_IF;
8800               IF r2 < rmin THEN
8801                  rmin := r2;
8802                  rmin_in := in2;
8803               END_IF;
8804               IF r3 = rmin THEN
8805                  rmin_in := rmin_in OR in3;
8806               END_IF;
8807               IF r3 < rmin THEN
8808                  rmin := r3;
8809                  rmin_in := in3;
8810               END_IF;
8811            END_IF;
8812            IF rc >= rmxp THEN
8813               ab := acp;
8814               find_aminmax( ab, a0, a1, a2, a3, in0, in1, in2, in3, amin, amax, amin_in, amax_in );
8815               a := ACOS(rmxp / rc);
8816               IF strictly_in(apc - a, aitp) THEN
8817                  amin := ab - ASIN(rmxp / rc);
8818                  amin_in := max_included(ritp);
8819               END_IF;
8820               IF strictly_in(apc + a, aitp) THEN
8821                  amax := ab + ASIN(rmxp / rc);
8822                  amax_in := max_included(ritp);
8823               END_IF;
8824               angle_range( amin, amax );
8825            ELSE
8826               IF rc > rmnp THEN
8827                  ab := angle(0.500000 * (aitp.min + aitp.max));
8828                  find_aminmax( ab, a0, a1, a2, a3, in0, in1, in2, in3, amin, amax, amin_in, amax_in );
8829               ELSE
8830                  ab := angle(0.500000 * (aitp.min + aitp.max));
8831                  a0 := angle(a0 - ab);
8832                  a1 := angle(a1 - ab);
8833                  a2 := angle(a2 - ab);
8834                  a3 := angle(a3 - ab);
8835                  IF a3 > a2 THEN
8836                     a2 := a2 + 2.00000 * 3.14159;
8837                  END_IF;
8838                  IF a0 > a1 THEN
8839                     a0 := a0 + 2.00000 * 3.14159;
8840                  END_IF;
8841                  IF a3 < a0 THEN
8842                     amin := a3;
8843                     amin_in := in3;
8844                  ELSE
8845                     amin := a0;
8846                     amin_in := in0;
8847                  END_IF;
8848                  IF a2 > a1 THEN
8849                     amax := a2;
8850                     amax_in := in2;
8851                  ELSE
8852                     amax := a1;
8853                     amax_in := in1;
8854                  END_IF;
8855                  IF (amax - amin > 2.00000 * 3.14159) OR (amax - amin = 2.00000 * 3.14159) AND (amin_in OR amax_in) THEN
8856                     amin := -3.14159;
8857                     amin_in := FALSE;
8858                     amax := 3.14159;
8859                     amax_in := TRUE;
8860                  ELSE
8861                     amin := amin + ab;
8862                     amax := amax + ab;
8863                     angle_range( amin, amax );
8864                  END_IF;
8865               END_IF;
8866            END_IF;
8867         END_IF;
8868         IF rmin_in THEN
8869            minclo := closed;
8870         END_IF;
8871         IF rmax_in THEN
8872            maxclo := closed;
8873         END_IF;
8874         ritv := make_finite_real_interval(rmin, minclo, rmax, maxclo);
8875      ELSE
8876         IF (rc > rmnp) AND strictly_in(apc, aitp) THEN
8877            RETURN (?);
8878         END_IF;
8879         IF aitp.max - aitp.min = 2.00000 * 3.14159 THEN
8880            a := angle(aitp.min);
8881            IF rc > rmnp THEN
8882               IF max_included(aitp) THEN
8883                  RETURN (?);
8884               END_IF;
8885               rmin := 0.00000;
8886               rmin_in := FALSE;
8887               amin := aitp.min;
8888               amin_in := FALSE;
8889               amax := aitp.max;
8890               amax_in := FALSE;
8891            ELSE
8892               rmin := rmnp - rc;
8893               rmin_in := min_included(ritp);
8894               amin := -3.14159;
8895               amin_in := FALSE;
8896               amax := 3.14159;
8897               amax_in := TRUE;
8898               IF NOT max_included(aitp) THEN
8899                  IF apc = a THEN
8900                     rmin_in := FALSE;
8901                     amin := aitp.min;
8902                     amin_in := FALSE;
8903                     amax := aitp.max;
8904                     amax_in := FALSE;
8905                  ELSE
8906                     IF acp = a THEN
8907                        amin := aitp.min;
8908                        amin_in := FALSE;
8909                        amax := aitp.max;
8910                        amax_in := FALSE;
8911                     END_IF;
8912                  END_IF;
8913               END_IF;
8914            END_IF;
8915         ELSE
8916            a0 := angle(aitp.min);
8917            in0 := FALSE;
8918            a1 := angle(aitp.max);
8919            in1 := FALSE;
8920            x := xp + rmnp * COS(aitp.max) - xc;
8921            y := yp + rmnp * SIN(aitp.max) - yc;
8922            r2 := SQRT(x ** 2 + y ** 2);
8923            in2 := min_included(ritp) AND max_included(aitp);
8924            IF r2 <> 0.00000 THEN
8925               a2 := atan2(y, x);
8926            ELSE
8927               a2 := a1;
8928               in2 := in1;
8929            END_IF;
8930            x := xp + rmnp * COS(aitp.min) - xc;
8931            y := yp + rmnp * SIN(aitp.min) - yc;
8932            r3 := SQRT(x ** 2 + y ** 2);
8933            in3 := min_included(ritp) AND min_included(aitp);
8934            IF r3 <> 0.00000 THEN
8935               a3 := atan2(y, x);
8936            ELSE
8937               a3 := a0;
8938               in3 := in0;
8939            END_IF;
8940            IF rmnp = 0.00000 THEN
8941               in2 := min_included(ritp);
8942               in3 := in2;
8943            END_IF;
8944            IF (apc = angle(aitp.min)) OR (acp = angle(aitp.min)) THEN
8945               in0 := min_included(aitp);
8946               in3 := in0;
8947            ELSE
8948               IF (apc = angle(aitp.max)) OR (acp = angle(aitp.max)) THEN
8949                  in1 := max_included(aitp);
8950                  in2 := in1;
8951               END_IF;
8952            END_IF;
8953            IF strictly_in(apc, aitp) THEN
8954               rmin := rmnp - rc;
8955               rmin_in := min_included(ritp);
8956            ELSE
8957               rmin := r2;
8958               rmin_in := in2;
8959               a := apc - aitp.min;
8960               r := rc * COS(a);
8961               IF rmnp < r THEN
8962                  rmin := rc * SIN(ABS(a));
8963                  rmin_in := min_included(aitp);
8964               END_IF;
8965               a := apc - aitp.max;
8966               r := rc * COS(a);
8967               IF rmnp < r THEN
8968                  r := rc * SIN(ABS(a));
8969                  inn := max_included(aitp);
8970                  IF r = rmin THEN
8971                     rmin_in := rmin_in OR inn;
8972                  END_IF;
8973                  IF r < rmin THEN
8974                     rmin := r;
8975                     rmin_in := inn;
8976                  END_IF;
8977               END_IF;
8978               IF r3 = rmin THEN
8979                  rmin_in := rmin_in OR in3;
8980               END_IF;
8981               IF r3 < rmin THEN
8982                  rmin := r3;
8983                  rmin_in := in3;
8984               END_IF;
8985            END_IF;
8986            ab := angle(0.500000 * (aitp.min + aitp.max));
8987            IF rc > rmnp THEN
8988               find_aminmax( ab, a0, a1, a2, a3, in0, in1, in2, in3, amin, amax, amin_in, amax_in );
8989            ELSE
8990               a0 := angle(a0 - ab);
8991               a1 := angle(a1 - ab);
8992               a2 := angle(a2 - ab);
8993               a3 := angle(a3 - ab);
8994               IF a3 > a2 THEN
8995                  a2 := a2 + 2.00000 * 3.14159;
8996               END_IF;
8997               IF a0 > a1 THEN
8998                  a0 := a0 + 2.00000 * 3.14159;
8999               END_IF;
9000               IF a3 < a0 THEN
9001                  amin := a3;
9002                  amin_in := in3;
9003               ELSE
9004                  amin := a0;
9005                  amin_in := in0;
9006               END_IF;
9007               IF a2 > a1 THEN
9008                  amax := a2;
9009                  amax_in := in2;
9010               ELSE
9011                  amax := a1;
9012                  amax_in := in1;
9013               END_IF;
9014               IF (amax - amin > 2.00000 * 3.14159) OR (amax - amin = 2.00000 * 3.14159) AND (amin_in OR amax_in) THEN
9015                  amin := -3.14159;
9016                  amin_in := FALSE;
9017                  amax := 3.14159;
9018                  amax_in := TRUE;
9019                  IF (rmin = 0.00000) AND rmin_in THEN
9020                     RETURN (?);
9021                  END_IF;
9022               ELSE
9023                  amin := amin + ab;
9024                  amax := amax + ab;
9025                  angle_range( amin, amax );
9026               END_IF;
9027            END_IF;
9028         END_IF;
9029         IF rmin_in THEN
9030            minclo := closed;
9031         END_IF;
9032         ritv := make_real_interval_from_min(rmin, minclo);
9033      END_IF;
9034      minclo := open;
9035      maxclo := open;
9036      IF amin_in THEN
9037         minclo := closed;
9038      END_IF;
9039      IF amax_in THEN
9040         maxclo := closed;
9041      END_IF;
9042      aitv := make_finite_real_interval(amin, minclo, amax, maxclo);
9043      RETURN (make_polar_complex_number_region(centre, ritv, aitv));
9044   END_FUNCTION;
9045
9046   FUNCTION equal_cregion_pregion
9047      (crgn : cartesian_complex_number_region;
9048       prgn : polar_complex_number_region ) : LOGICAL;
9049   LOCAL
9050      arng : REAL;
9051      amin : REAL;
9052      xc : REAL;
9053      yc : REAL;
9054      aitv : real_interval;
9055      xitv : real_interval;
9056      yitv : real_interval;
9057      c_in : BOOLEAN;
9058   END_LOCAL;
9059      IF NOT EXISTS(crgn) OR NOT EXISTS(prgn) THEN
9060         RETURN (FALSE);
9061      END_IF;
9062      IF max_exists(prgn.distance_constraint) THEN
9063         RETURN (FALSE);
9064      END_IF;
9065      IF real_min(prgn.distance_constraint) <> 0.00000 THEN
9066         RETURN (FALSE);
9067      END_IF;
9068      c_in := min_included(prgn.distance_constraint);
9069      aitv := prgn.direction_constraint;
9070      amin := aitv.min;
9071      arng := aitv.max - amin;
9072      xc := prgn.centre.real_part;
9073      yc := prgn.centre.imag_part;
9074      xitv := crgn.real_constraint;
9075      yitv := crgn.imag_constraint;
9076      IF arng = 0.500000 * 3.14159 THEN
9077         IF amin = 0.00000 THEN
9078            RETURN ((((((NOT max_exists(xitv) AND NOT max_exists(yitv)) AND min_exists(xitv)) AND min_exists(yitv)) AND (real_min(xitv) = xc)) AND (real_min(yitv) = yc)) AND ((((((c_in AND min_included(aitv)) AND max_included(aitv)) AND min_included(xitv)) AND min_included(yitv) OR (((NOT c_in AND NOT min_included(aitv)) AND max_included(aitv)) AND min_included(xitv)) AND NOT min_included(yitv)) OR (((NOT c_in AND min_included(aitv)) AND NOT max_included(aitv)) AND NOT min_included(xitv)) AND min_included(yitv)) OR (((NOT c_in AND NOT min_included(aitv)) AND NOT max_included(aitv)) AND NOT min_included(xitv)) AND NOT min_included(yitv)));
9079         END_IF;
9080         IF amin = 0.500000 * 3.14159 THEN
9081            RETURN ((((((max_exists(xitv) AND NOT max_exists(yitv)) AND NOT min_exists(xitv)) AND min_exists(yitv)) AND (real_max(xitv) = xc)) AND (real_min(yitv) = yc)) AND ((((((c_in AND min_included(aitv)) AND max_included(aitv)) AND max_included(xitv)) AND min_included(yitv) OR (((NOT c_in AND NOT min_included(aitv)) AND max_included(aitv)) AND max_included(xitv)) AND NOT min_included(yitv)) OR (((NOT c_in AND min_included(aitv)) AND NOT max_included(aitv)) AND NOT max_included(xitv)) AND min_included(yitv)) OR (((NOT c_in AND NOT min_included(aitv)) AND NOT max_included(aitv)) AND NOT max_included(xitv)) AND NOT min_included(yitv)));
9082         END_IF;
9083         IF amin = -3.14159 THEN
9084            RETURN ((((((max_exists(xitv) AND max_exists(yitv)) AND NOT min_exists(xitv)) AND NOT min_exists(yitv)) AND (real_max(xitv) = xc)) AND (real_max(yitv) = yc)) AND ((((((c_in AND min_included(aitv)) AND max_included(aitv)) AND max_included(xitv)) AND max_included(yitv) OR (((NOT c_in AND NOT min_included(aitv)) AND max_included(aitv)) AND max_included(xitv)) AND NOT max_included(yitv)) OR (((NOT c_in AND min_included(aitv)) AND NOT max_included(aitv)) AND NOT max_included(xitv)) AND max_included(yitv)) OR (((NOT c_in AND NOT min_included(aitv)) AND NOT max_included(aitv)) AND NOT max_included(xitv)) AND NOT max_included(yitv)));
9085         END_IF;
9086         IF amin = -0.500000 * 3.14159 THEN
9087            RETURN ((((((NOT max_exists(xitv) AND max_exists(yitv)) AND min_exists(xitv)) AND NOT min_exists(yitv)) AND (real_min(xitv) = xc)) AND (real_max(yitv) = yc)) AND ((((((c_in AND min_included(aitv)) AND max_included(aitv)) AND min_included(xitv)) AND max_included(yitv) OR (((NOT c_in AND NOT min_included(aitv)) AND max_included(aitv)) AND min_included(xitv)) AND NOT max_included(yitv)) OR (((NOT c_in AND min_included(aitv)) AND NOT max_included(aitv)) AND NOT min_included(xitv)) AND max_included(yitv)) OR (((NOT c_in AND NOT min_included(aitv)) AND NOT max_included(aitv)) AND NOT min_included(xitv)) AND NOT max_included(yitv)));
9088         END_IF;
9089      END_IF;
9090      IF arng = 3.14159 THEN
9091         IF amin = 0.00000 THEN
9092            RETURN (((((NOT max_exists(xitv) AND NOT max_exists(yitv)) AND NOT min_exists(xitv)) AND min_exists(yitv)) AND (real_min(yitv) = yc)) AND (((c_in AND min_included(aitv)) AND max_included(aitv)) AND min_included(yitv) OR ((NOT c_in AND NOT min_included(aitv)) AND NOT max_included(aitv)) AND NOT min_included(yitv)));
9093         END_IF;
9094         IF amin = 0.500000 * 3.14159 THEN
9095            RETURN (((((max_exists(xitv) AND NOT max_exists(yitv)) AND NOT min_exists(xitv)) AND NOT min_exists(yitv)) AND (real_max(xitv) = xc)) AND (((c_in AND min_included(aitv)) AND max_included(aitv)) AND max_included(xitv) OR ((NOT c_in AND NOT min_included(aitv)) AND NOT max_included(aitv)) AND NOT max_included(xitv)));
9096         END_IF;
9097         IF amin = -3.14159 THEN
9098            RETURN (((((NOT max_exists(xitv) AND max_exists(yitv)) AND NOT min_exists(xitv)) AND NOT min_exists(yitv)) AND (real_max(yitv) = yc)) AND (((c_in AND min_included(aitv)) AND max_included(aitv)) AND max_included(yitv) OR ((NOT c_in AND NOT min_included(aitv)) AND NOT max_included(aitv)) AND NOT max_included(yitv)));
9099         END_IF;
9100         IF amin = -0.500000 * 3.14159 THEN
9101            RETURN (((((NOT max_exists(xitv) AND NOT max_exists(yitv)) AND min_exists(xitv)) AND NOT min_exists(yitv)) AND (real_min(xitv) = xc)) AND (((c_in AND min_included(aitv)) AND max_included(aitv)) AND min_included(xitv) OR ((NOT c_in AND NOT min_included(aitv)) AND NOT max_included(aitv)) AND NOT min_included(xitv)));
9102         END_IF;
9103      END_IF;
9104      RETURN (FALSE);
9105   END_FUNCTION;
9106
9107   FUNCTION equal_maths_functions
9108      (fun1 : maths_function;
9109       fun2 : maths_function ) : LOGICAL;
9110   LOCAL
9111      cum : LOGICAL;
9112   END_LOCAL;
9113      IF fun1 = fun2 THEN
9114         RETURN (TRUE);
9115      END_IF;
9116      cum := equal_maths_spaces(fun1.domain, fun2.domain);
9117      IF cum = FALSE THEN
9118         RETURN (FALSE);
9119      END_IF;
9120      cum := cum AND equal_maths_spaces(fun1.range, fun2.range);
9121      IF cum = FALSE THEN
9122         RETURN (FALSE);
9123      END_IF;
9124      RETURN (UNKNOWN);
9125   END_FUNCTION;
9126
9127   FUNCTION equal_maths_spaces
9128      (spc1 : maths_space;
9129       spc2 : maths_space ) : LOGICAL;
9130   LOCAL
9131      spc1types : SET OF STRING := stripped_typeof(spc1);
9132      spc2types : SET OF STRING := stripped_typeof(spc2);
9133      set1 : SET OF maths_value;
9134      set2 : SET OF maths_value;
9135      cum : LOGICAL := TRUE;
9136      base : maths_space;
9137      expnt : INTEGER;
9138      factors : LIST OF maths_space;
9139      factors2 : LIST OF maths_space;
9140      fs1 : function_space;
9141      fs2 : function_space;
9142      cum2 : LOGICAL;
9143   END_LOCAL;
9144      IF spc1 = spc2 THEN
9145         RETURN (TRUE);
9146      END_IF;
9147      IF 'FINITE_SPACE' IN spc1types THEN
9148         set1 := spc1\finite_space.members;
9149         IF 'FINITE_SPACE' IN spc2types THEN
9150            set2 := spc2\finite_space.members;
9151            REPEAT i := 1 TO SIZEOF(set1);
9152               cum := cum AND member_of(set1[i], spc2);
9153               IF cum = FALSE THEN
9154                  RETURN (FALSE);
9155               END_IF;
9156            END_REPEAT;
9157            IF cum = TRUE THEN
9158               REPEAT i := 1 TO SIZEOF(set2);
9159                  cum := cum AND member_of(set2[i], spc1);
9160                  IF cum = FALSE THEN
9161                     RETURN (FALSE);
9162                  END_IF;
9163               END_REPEAT;
9164            END_IF;
9165            RETURN (cum);
9166         END_IF;
9167         IF 'FINITE_INTEGER_INTERVAL' IN spc2types THEN
9168            set2 := [];
9169            REPEAT i := spc2\finite_integer_interval.min TO spc2\finite_integer_interval.max;
9170               set2 := set2 + [ i ];
9171            END_REPEAT;
9172            RETURN (equal_maths_spaces(spc1, make_finite_space(set2)));
9173         END_IF;
9174      END_IF;
9175      IF ('FINITE_INTEGER_INTERVAL' IN spc1types) AND ('FINITE_SPACE' IN spc2types) THEN
9176         set1 := [];
9177         REPEAT i := spc1\finite_integer_interval.min TO spc1\finite_integer_interval.max;
9178            set1 := set1 + [ i ];
9179         END_REPEAT;
9180         RETURN (equal_maths_spaces(make_finite_space(set1), spc2));
9181      END_IF;
9182      IF ('CARTESIAN_COMPLEX_NUMBER_REGION' IN spc1types) AND ('POLAR_COMPLEX_NUMBER_REGION' IN spc2types) THEN
9183         RETURN (equal_cregion_pregion(spc1, spc2));
9184      END_IF;
9185      IF ('POLAR_COMPLEX_NUMBER_REGION' IN spc1types) AND ('CARTESIAN_COMPLEX_NUMBER_REGION' IN spc2types) THEN
9186         RETURN (equal_cregion_pregion(spc2, spc1));
9187      END_IF;
9188      IF 'UNIFORM_PRODUCT_SPACE' IN spc1types THEN
9189         base := spc1\uniform_product_space.base;
9190         expnt := spc1\uniform_product_space.exponent;
9191         IF 'UNIFORM_PRODUCT_SPACE' IN spc2types THEN
9192            IF expnt <> spc2\uniform_product_space.exponent THEN
9193               RETURN (FALSE);
9194            END_IF;
9195            RETURN (equal_maths_spaces(base, spc2\uniform_product_space.base));
9196         END_IF;
9197         IF 'LISTED_PRODUCT_SPACE' IN spc2types THEN
9198            factors := spc2\listed_product_space.factors;
9199            IF expnt <> SIZEOF(factors) THEN
9200               RETURN (FALSE);
9201            END_IF;
9202            REPEAT i := 1 TO SIZEOF(factors);
9203               cum := cum AND equal_maths_spaces(base, factors[i]);
9204               IF cum = FALSE THEN
9205                  RETURN (FALSE);
9206               END_IF;
9207            END_REPEAT;
9208            RETURN (cum);
9209         END_IF;
9210      END_IF;
9211      IF 'LISTED_PRODUCT_SPACE' IN spc1types THEN
9212         factors := spc1\listed_product_space.factors;
9213         IF 'UNIFORM_PRODUCT_SPACE' IN spc2types THEN
9214            IF spc2\uniform_product_space.exponent <> SIZEOF(factors) THEN
9215               RETURN (FALSE);
9216            END_IF;
9217            base := spc2\uniform_product_space.base;
9218            REPEAT i := 1 TO SIZEOF(factors);
9219               cum := cum AND equal_maths_spaces(base, factors[i]);
9220               IF cum = FALSE THEN
9221                  RETURN (FALSE);
9222               END_IF;
9223            END_REPEAT;
9224            RETURN (cum);
9225         END_IF;
9226         IF 'LISTED_PRODUCT_SPACE' IN spc2types THEN
9227            factors2 := spc2\listed_product_space.factors;
9228            IF SIZEOF(factors) <> SIZEOF(factors2) THEN
9229               RETURN (FALSE);
9230            END_IF;
9231            REPEAT i := 1 TO SIZEOF(factors);
9232               cum := cum AND equal_maths_spaces(factors[i], factors2[i]);
9233               IF cum = FALSE THEN
9234                  RETURN (FALSE);
9235               END_IF;
9236            END_REPEAT;
9237            RETURN (cum);
9238         END_IF;
9239      END_IF;
9240      IF ('EXTENDED_TUPLE_SPACE' IN spc1types) AND ('EXTENDED_TUPLE_SPACE' IN spc2types) THEN
9241         RETURN (equal_maths_spaces(spc1\extended_tuple_space.extender, spc2\extended_tuple_space.extender) AND equal_maths_spaces(spc1\extended_tuple_space.base, spc2\extended_tuple_space.base));
9242      END_IF;
9243      IF ('FUNCTION_SPACE' IN spc1types) AND ('FUNCTION_SPACE' IN spc2types) THEN
9244         fs1 := spc1;
9245         fs2 := spc2;
9246         IF fs1.domain_constraint <> fs2.domain_constraint THEN
9247            IF (fs1.domain_constraint = sc_equal) OR (fs2.domain_constraint = sc_equal) THEN
9248               RETURN (FALSE);
9249            END_IF;
9250            IF fs1.domain_constraint <> sc_subspace THEN
9251               fs1 := spc2;
9252               fs2 := spc1;
9253            END_IF;
9254            IF (fs1.domain_constraint <> sc_subspace) OR (fs2.domain_constraint <> sc_member) THEN
9255               RETURN (UNKNOWN);
9256            END_IF;
9257            IF any_space_satisfies(fs1.domain_constraint, fs1.domain_argument) <> any_space_satisfies(fs2.domain_constraint, fs2.domain_argument) THEN
9258               RETURN (FALSE);
9259            END_IF;
9260            IF NOT ('FINITE_SPACE' IN stripped_typeof(fs2.domain_argument)) THEN
9261               RETURN (FALSE);
9262            END_IF;
9263            IF SIZEOF([ 'FINITE_SPACE', 'FINITE_INTEGER_INTERVAL' ] * stripped_typeof(fs1.domain_argument)) = 0 THEN
9264               RETURN (FALSE);
9265            END_IF;
9266            RETURN (UNKNOWN);
9267         END_IF;
9268         cum := equal_maths_spaces(fs1.domain_argument, fs2.domain_argument);
9269         IF cum = FALSE THEN
9270            RETURN (FALSE);
9271         END_IF;
9272         IF fs1.range_constraint <> fs2.range_constraint THEN
9273            IF (fs1.range_constraint = sc_equal) OR (fs2.range_constraint = sc_equal) THEN
9274               RETURN (FALSE);
9275            END_IF;
9276            IF fs1.range_constraint <> sc_subspace THEN
9277               fs1 := spc2;
9278               fs2 := spc1;
9279            END_IF;
9280            IF (fs1.range_constraint <> sc_subspace) OR (fs2.range_constraint <> sc_member) THEN
9281               RETURN (UNKNOWN);
9282            END_IF;
9283            IF any_space_satisfies(fs1.range_constraint, fs1.range_argument) <> any_space_satisfies(fs2.range_constraint, fs2.range_argument) THEN
9284               RETURN (FALSE);
9285            END_IF;
9286            IF NOT ('FINITE_SPACE' IN stripped_typeof(fs2.range_argument)) THEN
9287               RETURN (FALSE);
9288            END_IF;
9289            IF SIZEOF([ 'FINITE_SPACE', 'FINITE_INTEGER_INTERVAL' ] * stripped_typeof(fs1.range_argument)) = 0 THEN
9290               RETURN (FALSE);
9291            END_IF;
9292            RETURN (UNKNOWN);
9293         END_IF;
9294         cum := cum AND equal_maths_spaces(fs1.range_argument, fs2.range_argument);
9295         RETURN (cum);
9296      END_IF;
9297      RETURN (FALSE);
9298   END_FUNCTION;
9299
9300   FUNCTION equal_maths_values
9301      (val1 : maths_value;
9302       val2 : maths_value ) : LOGICAL;
9303      FUNCTION mem_of_vs
9304         (val1 : maths_value;
9305          val2 : maths_value ) : LOGICAL;
9306         IF NOT has_values_space(val2) THEN
9307            RETURN (UNKNOWN);
9308         END_IF;
9309         IF NOT member_of(val1, values_space_of(val2)) THEN
9310            RETURN (FALSE);
9311         END_IF;
9312         RETURN (UNKNOWN);
9313      END_FUNCTION;
9314   LOCAL
9315      types1 : SET OF STRING;
9316      types2 : SET OF STRING;
9317      list1 : LIST OF maths_value;
9318      list2 : LIST OF maths_value;
9319      cum : LOGICAL := TRUE;
9320   END_LOCAL;
9321      IF NOT EXISTS(val1) OR NOT EXISTS(val2) THEN
9322         RETURN (FALSE);
9323      END_IF;
9324      IF val1 = val2 THEN
9325         RETURN (TRUE);
9326      END_IF;
9327      types1 := stripped_typeof(val1);
9328      types2 := stripped_typeof(val2);
9329      IF ('MATHS_ATOM' IN types1) OR ('COMPLEX_NUMBER_LITERAL' IN types1) THEN
9330         IF 'MATHS_ATOM' IN types2 THEN
9331            RETURN (FALSE);
9332         END_IF;
9333         IF 'COMPLEX_NUMBER_LITERAL' IN types2 THEN
9334            RETURN (FALSE);
9335         END_IF;
9336         IF 'LIST' IN types2 THEN
9337            RETURN (FALSE);
9338         END_IF;
9339         IF 'MATHS_SPACE' IN types2 THEN
9340            RETURN (FALSE);
9341         END_IF;
9342         IF 'MATHS_FUNCTION' IN types2 THEN
9343            RETURN (FALSE);
9344         END_IF;
9345         IF 'GENERIC_EXPRESSION' IN types2 THEN
9346            RETURN (mem_of_vs(val1, val2));
9347         END_IF;
9348         RETURN (UNKNOWN);
9349      END_IF;
9350      IF ('MATHS_ATOM' IN types2) OR ('COMPLEX_NUMBER_LITERAL' IN types2) THEN
9351         RETURN (equal_maths_values(val2, val1));
9352      END_IF;
9353      IF 'LIST' IN types1 THEN
9354         IF 'LIST' IN types2 THEN
9355            list1 := val1;
9356            list2 := val2;
9357            IF SIZEOF(list1) <> SIZEOF(list2) THEN
9358               RETURN (FALSE);
9359            END_IF;
9360            REPEAT i := 1 TO SIZEOF(list1);
9361               cum := cum AND equal_maths_values(list1[i], list2[i]);
9362               IF cum = FALSE THEN
9363                  RETURN (FALSE);
9364               END_IF;
9365            END_REPEAT;
9366            RETURN (cum);
9367         END_IF;
9368         IF 'MATHS_SPACE' IN types2 THEN
9369            RETURN (FALSE);
9370         END_IF;
9371         IF 'MATHS_FUNCTION' IN types2 THEN
9372            RETURN (FALSE);
9373         END_IF;
9374         IF 'GENERIC_EXPRESSION' IN types2 THEN
9375            RETURN (mem_of_vs(val1, val2));
9376         END_IF;
9377         RETURN (UNKNOWN);
9378      END_IF;
9379      IF 'LIST' IN types2 THEN
9380         RETURN (equal_maths_values(val2, val1));
9381      END_IF;
9382      IF 'MATHS_SPACE' IN types1 THEN
9383         IF 'MATHS_SPACE' IN types2 THEN
9384            RETURN (equal_maths_spaces(val1, val2));
9385         END_IF;
9386         IF 'MATHS_FUNCTION' IN types2 THEN
9387            RETURN (FALSE);
9388         END_IF;
9389         IF 'GENERIC_EXPRESSION' IN types2 THEN
9390            RETURN (mem_of_vs(val1, val2));
9391         END_IF;
9392         RETURN (UNKNOWN);
9393      END_IF;
9394      IF 'MATHS_SPACE' IN types2 THEN
9395         RETURN (equal_maths_values(val2, val1));
9396      END_IF;
9397      IF 'MATHS_FUNCTION' IN types1 THEN
9398         IF 'MATHS_FUNCTION' IN types2 THEN
9399            RETURN (equal_maths_functions(val1, val2));
9400         END_IF;
9401         IF 'GENERIC_EXPRESSION' IN types2 THEN
9402            RETURN (mem_of_vs(val1, val2));
9403         END_IF;
9404         RETURN (UNKNOWN);
9405      END_IF;
9406      IF 'MATHS_FUNCTION' IN types2 THEN
9407         RETURN (equal_maths_values(val2, val1));
9408      END_IF;
9409      IF ('GENERIC_EXPRESSION' IN types1) AND ('GENERIC_EXPRESSION' IN types2) THEN
9410         IF NOT has_values_space(val1) OR NOT has_values_space(val2) THEN
9411            RETURN (UNKNOWN);
9412         END_IF;
9413         IF NOT compatible_spaces(values_space_of(val1), values_space_of(val2)) THEN
9414            RETURN (FALSE);
9415         END_IF;
9416      END_IF;
9417      RETURN (UNKNOWN);
9418   END_FUNCTION;
9419
9420   FUNCTION es_subspace_of_es
9421      (es1 : elementary_space_enumerators;
9422       es2 : elementary_space_enumerators ) : BOOLEAN;
9423      IF NOT EXISTS(es1) OR NOT EXISTS(es2) THEN
9424         RETURN (FALSE);
9425      END_IF;
9426      IF es1 = es2 THEN
9427         RETURN (TRUE);
9428      END_IF;
9429      IF es2 = es_generics THEN
9430         RETURN (TRUE);
9431      END_IF;
9432      IF (es1 = es_booleans) AND (es2 = es_logicals) THEN
9433         RETURN (TRUE);
9434      END_IF;
9435      IF (es2 = es_numbers) AND (((es1 = es_complex_numbers) OR (es1 = es_reals)) OR (es1 = es_integers)) THEN
9436         RETURN (TRUE);
9437      END_IF;
9438      RETURN (FALSE);
9439   END_FUNCTION;
9440
9441   FUNCTION expression_is_constant
9442      (expr : generic_expression ) : BOOLEAN;
9443      RETURN (bool(SIZEOF(free_variables_of(expr)) = 0));
9444   END_FUNCTION;
9445
9446   FUNCTION extract_factors
9447      (tspace : tuple_space;
9448       m : INTEGER;
9449       n : INTEGER ) : tuple_space;
9450   LOCAL
9451      tsp : tuple_space := the_zero_tuple_space;
9452   END_LOCAL;
9453      REPEAT i := m TO n;
9454         tsp := assoc_product_space(tsp, factor_space(tspace, i));
9455      END_REPEAT;
9456      RETURN (tsp);
9457   END_FUNCTION;
9458
9459   FUNCTION extremal_position_check
9460      (fun : linearized_table_function ) : BOOLEAN;
9461   LOCAL
9462      source_domain : maths_space;
9463      source_interval : finite_integer_interval;
9464      index : INTEGER := 1;
9465      base : INTEGER;
9466      shape : LIST OF positive_integer;
9467      ndim : positive_integer;
9468      slo : INTEGER;
9469      shi : INTEGER;
9470      sublo : LIST OF INTEGER := [];
9471      subhi : LIST OF INTEGER := [];
9472   END_LOCAL;
9473      IF NOT EXISTS(fun) THEN
9474         RETURN (FALSE);
9475      END_IF;
9476      source_domain := factor1(fun.source.domain);
9477      IF schema_prefix + 'TUPLE_SPACE' IN TYPEOF(source_domain) THEN
9478         source_domain := factor1(source_domain);
9479      END_IF;
9480      IF NOT (schema_prefix + 'FINITE_INTEGER_INTERVAL' IN TYPEOF(source_domain)) THEN
9481         RETURN (FALSE);
9482      END_IF;
9483      source_interval := source_domain;
9484      base := fun\explicit_table_function.index_base;
9485      shape := fun\explicit_table_function.shape;
9486      IF schema_prefix + 'STANDARD_TABLE_FUNCTION' IN TYPEOF(fun) THEN
9487         REPEAT j := 1 TO SIZEOF(shape);
9488            index := index * shape[j];
9489         END_REPEAT;
9490         index := fun.first + index - 1;
9491         RETURN (bool((source_interval.min <= index) AND (index <= source_interval.max)));
9492      END_IF;
9493      IF schema_prefix + 'REGULAR_TABLE_FUNCTION' IN TYPEOF(fun) THEN
9494         ndim := SIZEOF(fun\explicit_table_function.shape);
9495         REPEAT j := 1 TO ndim;
9496            slo := base;
9497            shi := base + shape[j] - 1;
9498            IF fun\regular_table_function.increments[j] >= 0 THEN
9499               INSERT( sublo, slo, j - 1 );
9500               INSERT( subhi, shi, j - 1 );
9501            ELSE
9502               INSERT( sublo, shi, j - 1 );
9503               INSERT( subhi, slo, j - 1 );
9504            END_IF;
9505         END_REPEAT;
9506         index := regular_indexing(sublo, base, shape, fun\regular_table_function.increments, fun.first);
9507         IF NOT ((source_interval.min <= index) AND (index <= source_interval.max)) THEN
9508            RETURN (FALSE);
9509         END_IF;
9510         index := regular_indexing(subhi, base, shape, fun\regular_table_function.increments, fun.first);
9511         IF NOT ((source_interval.min <= index) AND (index <= source_interval.max)) THEN
9512            RETURN (FALSE);
9513         END_IF;
9514         RETURN (TRUE);
9515      END_IF;
9516      RETURN (FALSE);
9517   END_FUNCTION;
9518
9519   FUNCTION factor1
9520      (tspace : tuple_space ) : maths_space;
9521   LOCAL
9522      typenames : SET OF STRING := TYPEOF(tspace);
9523   END_LOCAL;
9524      IF schema_prefix + 'UNIFORM_PRODUCT_SPACE' IN typenames THEN
9525         RETURN (tspace\uniform_product_space.base);
9526      END_IF;
9527      IF schema_prefix + 'LISTED_PRODUCT_SPACE' IN typenames THEN
9528         RETURN (tspace\listed_product_space.factors[1]);
9529      END_IF;
9530      IF schema_prefix + 'EXTENDED_TUPLE_SPACE' IN typenames THEN
9531         RETURN (factor1(tspace\extended_tuple_space.base));
9532      END_IF;
9533      RETURN (?);
9534   END_FUNCTION;
9535
9536   FUNCTION factor_space
9537      (tspace : tuple_space;
9538       idx : positive_integer ) : maths_space;
9539   LOCAL
9540      typenames : SET OF STRING := TYPEOF(tspace);
9541   END_LOCAL;
9542      IF schema_prefix + 'UNIFORM_PRODUCT_SPACE' IN typenames THEN
9543         IF idx <= tspace\uniform_product_space.exponent THEN
9544            RETURN (tspace\uniform_product_space.base);
9545         END_IF;
9546         RETURN (?);
9547      END_IF;
9548      IF schema_prefix + 'LISTED_PRODUCT_SPACE' IN typenames THEN
9549         IF idx <= SIZEOF(tspace\listed_product_space.factors) THEN
9550            RETURN (tspace\listed_product_space.factors[idx]);
9551         END_IF;
9552         RETURN (?);
9553      END_IF;
9554      IF schema_prefix + 'EXTENDED_TUPLE_SPACE' IN typenames THEN
9555         IF idx <= space_dimension(tspace\extended_tuple_space.base) THEN
9556            RETURN (factor_space(tspace\extended_tuple_space.base, idx));
9557         END_IF;
9558         RETURN (tspace\extended_tuple_space.extender);
9559      END_IF;
9560      RETURN (?);
9561   END_FUNCTION;
9562
9563   FUNCTION first_proj_axis
9564      (z_axis : direction;
9565       arg : direction ) : direction;
9566   LOCAL
9567      x_axis : direction;
9568      v : direction;
9569      z : direction;
9570      x_vec : vector;
9571   END_LOCAL;
9572      IF NOT EXISTS(z_axis) THEN
9573         RETURN (?);
9574      ELSE
9575         z := normalise(z_axis);
9576         IF NOT EXISTS(arg) THEN
9577            IF (z.direction_ratios <> [ 1.00000, 0.00000, 0.00000 ]) AND (z.direction_ratios <> [ -1.00000, 0.00000, 0.00000 ]) THEN
9578               v := dummy_gri || direction([ 1.00000, 0.00000, 0.00000 ]);
9579            ELSE
9580               v := dummy_gri || direction([ 0.00000, 1.00000, 0.00000 ]);
9581            END_IF;
9582         ELSE
9583            IF arg.dim <> 3 THEN
9584               RETURN (?);
9585            END_IF;
9586            IF cross_product(arg, z).magnitude = 0.00000 THEN
9587               RETURN (?);
9588            ELSE
9589               v := normalise(arg);
9590            END_IF;
9591         END_IF;
9592         x_vec := scalar_times_vector(dot_product(v, z), z);
9593         x_axis := vector_difference(v, x_vec).orientation;
9594         x_axis := normalise(x_axis);
9595      END_IF;
9596      RETURN (x_axis);
9597   END_FUNCTION;
9598
9599   FUNCTION free_variables_of
9600      (expr : generic_expression ) : SET OF generic_variable;
9601   LOCAL
9602      typenames : SET OF STRING := stripped_typeof(expr);
9603      result : SET OF generic_variable := [];
9604      exprs : LIST OF generic_expression := [];
9605   END_LOCAL;
9606      IF 'GENERIC_LITERAL' IN typenames THEN
9607         RETURN (result);
9608      END_IF;
9609      IF 'GENERIC_VARIABLE' IN typenames THEN
9610         result := result + expr;
9611         RETURN (result);
9612      END_IF;
9613      IF 'QUANTIFIER_EXPRESSION' IN typenames THEN
9614         exprs := QUERY (ge <* expr\multiple_arity_generic_expression.operands| NOT (ge IN expr\quantifier_expression.variables));
9615         REPEAT i := 1 TO SIZEOF(exprs);
9616            result := result + free_variables_of(exprs[i]);
9617         END_REPEAT;
9618         REPEAT i := 1 TO SIZEOF(expr\quantifier_expression.variables);
9619            result := result - expr\quantifier_expression.variables[i];
9620         END_REPEAT;
9621         RETURN (result);
9622      END_IF;
9623      IF 'UNARY_GENERIC_EXPRESSION' IN typenames THEN
9624         RETURN (free_variables_of(expr\unary_generic_expression.operand));
9625      END_IF;
9626      IF 'BINARY_GENERIC_EXPRESSION' IN typenames THEN
9627         result := free_variables_of(expr\binary_generic_expression.operands[1]);
9628         RETURN (result + free_variables_of(expr\binary_generic_expression.operands[2]));
9629      END_IF;
9630      IF 'MULTIPLE_ARITY_GENERIC_EXPRESSION' IN typenames THEN
9631         REPEAT i := 1 TO SIZEOF(expr\multiple_arity_generic_expression.operands);
9632            result := result + free_variables_of(expr\multiple_arity_generic_expression.operands[i]);
9633         END_REPEAT;
9634         RETURN (result);
9635      END_IF;
9636      RETURN (result);
9637   END_FUNCTION;
9638
9639   FUNCTION function_applicability
9640      (func : maths_function_select;
9641       arguments : LIST [1:?] OF maths_value ) : BOOLEAN;
9642   LOCAL
9643      domain : tuple_space := convert_to_maths_function(func).domain;
9644      domain_types : SET OF STRING := TYPEOF(domain);
9645      narg : positive_integer := SIZEOF(arguments);
9646      arg : generic_expression;
9647   END_LOCAL;
9648      IF schema_prefix + 'PRODUCT_SPACE' IN domain_types THEN
9649         IF space_dimension(domain) <> narg THEN
9650            RETURN (FALSE);
9651         END_IF;
9652      ELSE
9653         IF schema_prefix + 'EXTENDED_TUPLE_SPACE' IN domain_types THEN
9654            IF space_dimension(domain) > narg THEN
9655               RETURN (FALSE);
9656            END_IF;
9657         ELSE
9658            RETURN (FALSE);
9659         END_IF;
9660      END_IF;
9661      REPEAT i := 1 TO narg;
9662         arg := convert_to_operand(arguments[i]);
9663         IF NOT has_values_space(arg) THEN
9664            RETURN (FALSE);
9665         END_IF;
9666         IF NOT compatible_spaces(factor_space(domain, i), values_space_of(arg)) THEN
9667            RETURN (FALSE);
9668         END_IF;
9669      END_REPEAT;
9670      RETURN (TRUE);
9671   END_FUNCTION;
9672
9673   FUNCTION function_is_1d_array
9674      (func : maths_function ) : BOOLEAN;
9675   LOCAL
9676      temp : maths_space;
9677   END_LOCAL;
9678      IF NOT EXISTS(func) THEN
9679         RETURN (FALSE);
9680      END_IF;
9681      IF space_dimension(func.domain) <> 1 THEN
9682         RETURN (FALSE);
9683      END_IF;
9684      temp := factor1(func.domain);
9685      IF schema_prefix + 'PRODUCT_SPACE' IN TYPEOF(temp) THEN
9686         IF space_dimension(temp) <> 1 THEN
9687            RETURN (FALSE);
9688         END_IF;
9689         temp := factor1(temp);
9690      END_IF;
9691      IF schema_prefix + 'FINITE_INTEGER_INTERVAL' IN TYPEOF(temp) THEN
9692         RETURN (TRUE);
9693      END_IF;
9694      RETURN (FALSE);
9695   END_FUNCTION;
9696
9697   FUNCTION function_is_1d_table
9698      (func : maths_function ) : BOOLEAN;
9699   LOCAL
9700      temp : maths_space;
9701      itvl : finite_integer_interval;
9702   END_LOCAL;
9703      IF NOT EXISTS(func) THEN
9704         RETURN (FALSE);
9705      END_IF;
9706      IF space_dimension(func.domain) <> 1 THEN
9707         RETURN (FALSE);
9708      END_IF;
9709      temp := factor1(func.domain);
9710      IF schema_prefix + 'PRODUCT_SPACE' IN TYPEOF(temp) THEN
9711         IF space_dimension(temp) <> 1 THEN
9712            RETURN (FALSE);
9713         END_IF;
9714         temp := factor1(temp);
9715      END_IF;
9716      IF schema_prefix + 'FINITE_INTEGER_INTERVAL' IN TYPEOF(temp) THEN
9717         itvl := temp;
9718         RETURN (bool((itvl.min = 0) OR (itvl.min = 1)));
9719      END_IF;
9720      RETURN (FALSE);
9721   END_FUNCTION;
9722
9723   FUNCTION function_is_2d_table
9724      (func : maths_function ) : BOOLEAN;
9725   LOCAL
9726      temp : maths_space;
9727      pspace : product_space;
9728      itvl1 : finite_integer_interval;
9729      itvl2 : finite_integer_interval;
9730   END_LOCAL;
9731      IF NOT EXISTS(func) THEN
9732         RETURN (FALSE);
9733      END_IF;
9734      IF space_dimension(func.domain) <> 1 THEN
9735         RETURN (FALSE);
9736      END_IF;
9737      temp := factor1(func.domain);
9738      IF NOT ('PRODUCT_SPACE' IN stripped_typeof(temp)) THEN
9739         RETURN (FALSE);
9740      END_IF;
9741      pspace := temp;
9742      IF space_dimension(pspace) <> 2 THEN
9743         RETURN (FALSE);
9744      END_IF;
9745      temp := factor1(pspace);
9746      IF NOT ('FINITE_INTEGER_INTERVAL' IN stripped_typeof(temp)) THEN
9747         RETURN (FALSE);
9748      END_IF;
9749      itvl1 := temp;
9750      temp := factor_space(pspace, 2);
9751      IF NOT ('FINITE_INTEGER_INTERVAL' IN stripped_typeof(temp)) THEN
9752         RETURN (FALSE);
9753      END_IF;
9754      itvl2 := temp;
9755      RETURN (bool((itvl1.min = itvl2.min) AND ((itvl1.min = 0) OR (itvl1.min = 1))));
9756   END_FUNCTION;
9757
9758   FUNCTION function_is_array
9759      (func : maths_function ) : BOOLEAN;
9760   LOCAL
9761      tspace : tuple_space;
9762      temp : maths_space;
9763   END_LOCAL;
9764      IF NOT EXISTS(func) THEN
9765         RETURN (FALSE);
9766      END_IF;
9767      tspace := func.domain;
9768      IF (space_dimension(tspace) = 1) AND (schema_prefix + 'TUPLE_SPACE' IN TYPEOF(factor1(tspace))) THEN
9769         tspace := factor1(tspace);
9770      END_IF;
9771      IF NOT (schema_prefix + 'PRODUCT_SPACE' IN TYPEOF(tspace)) THEN
9772         RETURN (FALSE);
9773      END_IF;
9774      REPEAT i := 1 TO space_dimension(tspace);
9775         temp := factor_space(tspace, i);
9776         IF NOT (schema_prefix + 'FINITE_INTEGER_INTERVAL' IN TYPEOF(temp)) THEN
9777            RETURN (FALSE);
9778         END_IF;
9779      END_REPEAT;
9780      RETURN (TRUE);
9781   END_FUNCTION;
9782
9783   FUNCTION function_is_table
9784      (func : maths_function ) : BOOLEAN;
9785   LOCAL
9786      tspace : tuple_space;
9787      temp : maths_space;
9788      base : INTEGER;
9789   END_LOCAL;
9790      IF NOT EXISTS(func) THEN
9791         RETURN (FALSE);
9792      END_IF;
9793      tspace := func.domain;
9794      IF (space_dimension(tspace) = 1) AND (schema_prefix + 'TUPLE_SPACE' IN TYPEOF(factor1(tspace))) THEN
9795         tspace := factor1(tspace);
9796      END_IF;
9797      IF NOT (schema_prefix + 'PRODUCT_SPACE' IN TYPEOF(tspace)) THEN
9798         RETURN (FALSE);
9799      END_IF;
9800      temp := factor1(tspace);
9801      IF NOT (schema_prefix + 'FINITE_INTEGER_INTERVAL' IN TYPEOF(temp)) THEN
9802         RETURN (FALSE);
9803      END_IF;
9804      base := temp\finite_integer_interval.min;
9805      IF (base <> 0) AND (base <> 1) THEN
9806         RETURN (FALSE);
9807      END_IF;
9808      REPEAT i := 2 TO space_dimension(tspace);
9809         temp := factor_space(tspace, i);
9810         IF NOT (schema_prefix + 'FINITE_INTEGER_INTERVAL' IN TYPEOF(temp)) THEN
9811            RETURN (FALSE);
9812         END_IF;
9813         IF temp\finite_integer_interval.min <> base THEN
9814            RETURN (FALSE);
9815         END_IF;
9816      END_REPEAT;
9817      RETURN (TRUE);
9818   END_FUNCTION;
9819
9820   FUNCTION get_description_value
9821      (obj : description_attribute_select ) : text;
9822   LOCAL
9823      description_bag : BAG OF description_attribute := USEDIN(obj, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.' + 'DESCRIBED_ITEM');
9824   END_LOCAL;
9825      IF SIZEOF(description_bag) = 1 THEN
9826         RETURN (description_bag[1].attribute_value);
9827      ELSE
9828         RETURN (?);
9829      END_IF;
9830   END_FUNCTION;
9831
9832   FUNCTION get_id_value
9833      (obj : id_attribute_select ) : identifier;
9834   LOCAL
9835      id_bag : BAG OF id_attribute := USEDIN(obj, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ID_ATTRIBUTE.' + 'IDENTIFIED_ITEM');
9836   END_LOCAL;
9837      IF SIZEOF(id_bag) = 1 THEN
9838         RETURN (id_bag[1].attribute_value);
9839      ELSE
9840         RETURN (?);
9841      END_IF;
9842   END_FUNCTION;
9843
9844	FUNCTION get_multi_language
9845  		(x : attribute_value_assignment ) : label;
9846     		LOCAL
9847        	alas : BAG OF attribute_language_assignment := USEDIN(x.items[1], 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ATTRIBUTE_LANGUAGE_ASSIGNMENT.ITEMS');
9848    	 END_LOCAL;
9849        IF SIZEOF(alas) > 0 THEN
9850           RETURN (alas[1].language);
9851        END_IF;
9852        RETURN (?);
9853  	END_FUNCTION;
9854
9855   FUNCTION get_name_value
9856      (obj : name_attribute_select ) : label;
9857   LOCAL
9858      name_bag : BAG OF name_attribute := USEDIN(obj, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'NAME_ATTRIBUTE.' + 'NAMED_ITEM');
9859   END_LOCAL;
9860      IF SIZEOF(name_bag) = 1 THEN
9861         RETURN (name_bag[1].attribute_value);
9862      ELSE
9863         RETURN (?);
9864      END_IF;
9865   END_FUNCTION;
9866
9867   FUNCTION get_role
9868      (obj : role_select ) : object_role;
9869   LOCAL
9870      role_bag : BAG OF role_association := USEDIN(obj, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'ROLE_ASSOCIATION.' + 'ITEM_WITH_ROLE');
9871   END_LOCAL;
9872      IF SIZEOF(role_bag) = 1 THEN
9873         RETURN (role_bag[1].role);
9874      ELSE
9875         RETURN (?);
9876      END_IF;
9877   END_FUNCTION;
9878
9879   FUNCTION has_values_space
9880      (expr : generic_expression ) : BOOLEAN;
9881   LOCAL
9882      typenames : SET OF STRING := stripped_typeof(expr);
9883   END_LOCAL;
9884      IF 'EXPRESSION' IN typenames THEN
9885         RETURN (bool((('NUMERIC_EXPRESSION' IN typenames) OR ('STRING_EXPRESSION' IN typenames)) OR ('BOOLEAN_EXPRESSION' IN typenames)));
9886      END_IF;
9887      IF 'MATHS_FUNCTION' IN typenames THEN
9888         RETURN (TRUE);
9889      END_IF;
9890      IF 'FUNCTION_APPLICATION' IN typenames THEN
9891         RETURN (TRUE);
9892      END_IF;
9893      IF 'MATHS_SPACE' IN typenames THEN
9894         RETURN (TRUE);
9895      END_IF;
9896      IF 'MATHS_VARIABLE' IN typenames THEN
9897         RETURN (TRUE);
9898      END_IF;
9899      IF 'DEPENDENT_VARIABLE_DEFINITION' IN typenames THEN
9900         RETURN (has_values_space(expr\unary_generic_expression.operand));
9901      END_IF;
9902      IF 'COMPLEX_NUMBER_LITERAL' IN typenames THEN
9903         RETURN (TRUE);
9904      END_IF;
9905      IF 'LOGICAL_LITERAL' IN typenames THEN
9906         RETURN (TRUE);
9907      END_IF;
9908      IF 'BINARY_LITERAL' IN typenames THEN
9909         RETURN (TRUE);
9910      END_IF;
9911      IF 'MATHS_ENUM_LITERAL' IN typenames THEN
9912         RETURN (TRUE);
9913      END_IF;
9914      IF 'REAL_TUPLE_LITERAL' IN typenames THEN
9915         RETURN (TRUE);
9916      END_IF;
9917      IF 'INTEGER_TUPLE_LITERAL' IN typenames THEN
9918         RETURN (TRUE);
9919      END_IF;
9920      IF 'ATOM_BASED_LITERAL' IN typenames THEN
9921         RETURN (TRUE);
9922      END_IF;
9923      IF 'MATHS_TUPLE_LITERAL' IN typenames THEN
9924         RETURN (TRUE);
9925      END_IF;
9926      IF 'PARTIAL_DERIVATIVE_EXPRESSION' IN typenames THEN
9927         RETURN (TRUE);
9928      END_IF;
9929      IF 'DEFINITE_INTEGRAL_EXPRESSION' IN typenames THEN
9930         RETURN (TRUE);
9931      END_IF;
9932      RETURN (FALSE);
9933   END_FUNCTION;
9934
9935   FUNCTION is_SQL_mappable
9936      (arg : expression ) : BOOLEAN;
9937   LOCAL
9938      i : INTEGER;
9939   END_LOCAL;
9940      IF 'ENGINEERING_PROPERTIES_SCHEMA.SIMPLE_NUMERIC_EXPRESSION' IN TYPEOF(arg) THEN
9941         RETURN (TRUE);
9942      END_IF;
9943      IF 'ENGINEERING_PROPERTIES_SCHEMA.SQL_MAPPABLE_DEFINED_FUNCTION' IN TYPEOF(arg) THEN
9944         RETURN (TRUE);
9945      END_IF;
9946      IF 'ENGINEERING_PROPERTIES_SCHEMA.MINUS_FUNCTION' IN TYPEOF(arg) THEN
9947         RETURN (is_SQL_mappable(arg\unary_numeric_expression.operand));
9948      END_IF;
9949      IF ((((((((((((('ENGINEERING_PROPERTIES_SCHEMA.ABS_FUNCTION' IN TYPEOF(arg)) OR ('ENGINEERING_PROPERTIES_SCHEMA.SIN_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.COS_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.TAN_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.ASIN_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.ACOS_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.ATAN_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.EXP_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.LOG_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.LOG2_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.LOG10_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.SQUARE_ROOT_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.VALUE_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.LENGTH_FUNCTION' IN TYPEOF(arg)) THEN
9950         RETURN (FALSE);
9951      END_IF;
9952      IF ((('ENGINEERING_PROPERTIES_SCHEMA.PLUS_EXPRESSION' IN TYPEOF(arg)) OR ('ENGINEERING_PROPERTIES_SCHEMA.MULT_EXPRESSION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.MAXIMUM_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.MINIMUM_FUNCTION' IN TYPEOF(arg)) THEN
9953         REPEAT i := 1 TO SIZEOF(arg\multiple_arity_numeric_expression.operands);
9954            IF NOT is_SQL_mappable(arg\multiple_arity_numeric_expression.operands[i]) THEN
9955               RETURN (FALSE);
9956            END_IF;
9957         END_REPEAT;
9958         RETURN (TRUE);
9959      END_IF;
9960      IF ('ENGINEERING_PROPERTIES_SCHEMA.MINUS_EXPRESSION' IN TYPEOF(arg)) OR ('ENGINEERING_PROPERTIES_SCHEMA.SLASH_EXPRESSION' IN TYPEOF(arg)) THEN
9961         RETURN (is_SQL_mappable(arg\binary_numeric_expression.operands[1]) AND is_SQL_mappable(arg\binary_numeric_expression.operands[2]));
9962      END_IF;
9963      IF (('ENGINEERING_PROPERTIES_SCHEMA.DIV_EXPRESSION' IN TYPEOF(arg)) OR ('ENGINEERING_PROPERTIES_SCHEMA.MOD_EXPRESSION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.POWER_EXPRESSION' IN TYPEOF(arg)) THEN
9964         RETURN (FALSE);
9965      END_IF;
9966      IF 'ENGINEERING_PROPERTIES_SCHEMA.SIMPLE_BOOLEAN_EXPRESSION' IN TYPEOF(arg) THEN
9967         RETURN (TRUE);
9968      END_IF;
9969      IF 'ENGINEERING_PROPERTIES_SCHEMA.NOT_EXPRESSION' IN TYPEOF(arg) THEN
9970         RETURN (is_SQL_mappable(arg\unary_generic_expression.operand));
9971      END_IF;
9972      IF ('ENGINEERING_PROPERTIES_SCHEMA.ODD_FUNCTION' IN TYPEOF(arg)) OR ('ENGINEERING_PROPERTIES_SCHEMA.XOR_EXPRESSION' IN TYPEOF(arg)) THEN
9973         RETURN (FALSE);
9974      END_IF;
9975      IF ('ENGINEERING_PROPERTIES_SCHEMA.AND_EXPRESSION' IN TYPEOF(arg)) OR ('ENGINEERING_PROPERTIES_SCHEMA.OR_EXPRESSION' IN TYPEOF(arg)) THEN
9976         REPEAT i := 1 TO SIZEOF(arg\multiple_arity_boolean_expression.operands);
9977            IF NOT is_SQL_mappable(arg\multiple_arity_boolean_expression.operands[i]) THEN
9978               RETURN (FALSE);
9979            END_IF;
9980         END_REPEAT;
9981         RETURN (TRUE);
9982      END_IF;
9983      IF 'ENGINEERING_PROPERTIES_SCHEMA.EQUALS_EXPRESSION' IN TYPEOF(arg) THEN
9984         RETURN (is_SQL_mappable(arg\binary_generic_expression.operands[1]) AND is_SQL_mappable(arg\binary_generic_expression.operands[2]));
9985      END_IF;
9986      IF (((((('ENGINEERING_PROPERTIES_SCHEMA.COMPARISON_EQUAL' IN TYPEOF(arg)) OR ('ENGINEERING_PROPERTIES_SCHEMA.COMPARISON_GREATER' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.COMPARISON_GREATER_EQUAL' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.COMPARISON_LESS' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.COMPARISON_LESS_EQUAL' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.COMPARISON_NOT_EQUAL' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.LIKE_EXPRESSION' IN TYPEOF(arg)) THEN
9987         RETURN (is_SQL_mappable(arg\comparison_expression.operands[1]) AND is_SQL_mappable(arg\comparison_expression.operands[2]));
9988      END_IF;
9989      IF 'ENGINEERING_PROPERTIES_SCHEMA.INTERVAL_EXPRESSION' IN TYPEOF(arg) THEN
9990         RETURN ((is_SQL_mappable(arg\interval_expression.interval_low) AND is_SQL_mappable(arg\interval_expression.interval_high)) AND is_SQL_mappable(arg\interval_expression.interval_item));
9991      END_IF;
9992      IF (('ENGINEERING_PROPERTIES_SCHEMA.NUMERIC_DEFINED_FUNCTION' IN TYPEOF(arg)) OR ('ENGINEERING_PROPERTIES_SCHEMA.BOOLEAN_DEFINED_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.STRING_DEFINED_FUNCTION' IN TYPEOF(arg)) THEN
9993         RETURN (FALSE);
9994      END_IF;
9995      IF 'ENGINEERING_PROPERTIES_SCHEMA.SIMPLE_STRING_EXPRESSION' IN TYPEOF(arg) THEN
9996         RETURN (TRUE);
9997      END_IF;
9998      IF ((('ENGINEERING_PROPERTIES_SCHEMA.INDEX_EXPRESSION' IN TYPEOF(arg)) OR ('ENGINEERING_PROPERTIES_SCHEMA.SUBSTRING_EXPRESSION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.CONCAT_EXPRESSION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.FORMAT_FUNCTION' IN TYPEOF(arg)) THEN
9999         RETURN (FALSE);
10000      END_IF;
10001      RETURN (FALSE);
10002   END_FUNCTION;
10003
10004   FUNCTION is_acyclic
10005      (arg : generic_expression ) : BOOLEAN;
10006      RETURN (acyclic(arg, []));
10007   END_FUNCTION;
10008
10009   FUNCTION is_int_expr
10010      (arg : numeric_expression ) : BOOLEAN;
10011   LOCAL
10012      i : INTEGER;
10013   END_LOCAL;
10014      IF 'ENGINEERING_PROPERTIES_SCHEMA.INT_LITERAL' IN TYPEOF(arg) THEN
10015         RETURN (TRUE);
10016      END_IF;
10017      IF 'ENGINEERING_PROPERTIES_SCHEMA.REAL_LITERAL' IN TYPEOF(arg) THEN
10018         RETURN (FALSE);
10019      END_IF;
10020      IF 'ENGINEERING_PROPERTIES_SCHEMA.INT_NUMERIC_VARIABLE' IN TYPEOF(arg) THEN
10021         RETURN (TRUE);
10022      END_IF;
10023      IF 'ENGINEERING_PROPERTIES_SCHEMA.REAL_NUMERIC_VARIABLE' IN TYPEOF(arg) THEN
10024         RETURN (FALSE);
10025      END_IF;
10026      IF 'ENGINEERING_PROPERTIES_SCHEMA.ABS_FUNCTION' IN TYPEOF(arg) THEN
10027         RETURN (is_int_expr(arg\unary_numeric_expression.operand));
10028      END_IF;
10029      IF 'ENGINEERING_PROPERTIES_SCHEMA.MINUS_FUNCTION' IN TYPEOF(arg) THEN
10030         RETURN (is_int_expr(arg\unary_numeric_expression.operand));
10031      END_IF;
10032      IF (((((((((('ENGINEERING_PROPERTIES_SCHEMA.SIN_FUNCTION' IN TYPEOF(arg)) OR ('ENGINEERING_PROPERTIES_SCHEMA.COS_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.TAN_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.ASIN_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.ACOS_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.ATAN_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.EXP_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.LOG_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.LOG2_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.LOG10_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.SQUARE_ROOT_FUNCTION' IN TYPEOF(arg)) THEN
10033         RETURN (FALSE);
10034      END_IF;
10035      IF ((('ENGINEERING_PROPERTIES_SCHEMA.PLUS_EXPRESSION' IN TYPEOF(arg)) OR ('ENGINEERING_PROPERTIES_SCHEMA.MULT_EXPRESSION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.MAXIMUM_FUNCTION' IN TYPEOF(arg))) OR ('ENGINEERING_PROPERTIES_SCHEMA.MINIMUM_FUNCTION' IN TYPEOF(arg)) THEN
10036         REPEAT i := 1 TO SIZEOF(arg\multiple_arity_numeric_expression.operands);
10037            IF NOT is_int_expr(arg\multiple_arity_numeric_expression.operands[i]) THEN
10038               RETURN (FALSE);
10039            END_IF;
10040         END_REPEAT;
10041         RETURN (TRUE);
10042      END_IF;
10043      IF ('ENGINEERING_PROPERTIES_SCHEMA.MINUS_EXPRESSION' IN TYPEOF(arg)) OR ('ENGINEERING_PROPERTIES_SCHEMA.POWER_EXPRESSION' IN TYPEOF(arg)) THEN
10044         RETURN (is_int_expr(arg\binary_numeric_expression.operands[1]) AND is_int_expr(arg\binary_numeric_expression.operands[2]));
10045      END_IF;
10046      IF ('ENGINEERING_PROPERTIES_SCHEMA.DIV_EXPRESSION' IN TYPEOF(arg)) OR ('ENGINEERING_PROPERTIES_SCHEMA.MOD_EXPRESSION' IN TYPEOF(arg)) THEN
10047         RETURN (TRUE);
10048      END_IF;
10049      IF 'ENGINEERING_PROPERTIES_SCHEMA.SLASH_EXPRESSION' IN TYPEOF(arg) THEN
10050         RETURN (FALSE);
10051      END_IF;
10052      IF 'ENGINEERING_PROPERTIES_SCHEMA.LENGTH_FUNCTION' IN TYPEOF(arg) THEN
10053         RETURN (TRUE);
10054      END_IF;
10055      IF 'ENGINEERING_PROPERTIES_SCHEMA.VALUE_FUNCTION' IN TYPEOF(arg) THEN
10056         IF 'ENGINEERING_PROPERTIES_SCHEMA.INT_VALUE_FUNCTION' IN TYPEOF(arg) THEN
10057            RETURN (TRUE);
10058         ELSE
10059            RETURN (FALSE);
10060         END_IF;
10061      END_IF;
10062      IF 'ENGINEERING_PROPERTIES_SCHEMA.INTEGER_DEFINED_FUNCTION' IN TYPEOF(arg) THEN
10063         RETURN (TRUE);
10064      END_IF;
10065      IF 'ENGINEERING_PROPERTIES_SCHEMA.REAL_DEFINED_FUNCTION' IN TYPEOF(arg) THEN
10066         RETURN (FALSE);
10067      END_IF;
10068      IF 'ENGINEERING_PROPERTIES_SCHEMA.BOOLEAN_DEFINED_FUNCTION' IN TYPEOF(arg) THEN
10069         RETURN (FALSE);
10070      END_IF;
10071      IF 'ENGINEERING_PROPERTIES_SCHEMA.STRING_DEFINED_FUNCTION' IN TYPEOF(arg) THEN
10072         RETURN (FALSE);
10073      END_IF;
10074      RETURN (FALSE);
10075   END_FUNCTION;
10076
10077	FUNCTION item_correlation
10078  		(items : SET OF GENERIC;
10079         c_items : SET OF STRING ) : LOGICAL;
10080     		LOCAL
10081        		c_types : SET OF STRING := [];
10082        		c_hit : INTEGER := 0;
10083    		 END_LOCAL;
10084        REPEAT i := 1 TO HIINDEX(c_items);
10085           c_types := c_types + [ 'ENGINEERING_PROPERTIES_SCHEMA.' + c_items[i] ];
10086        END_REPEAT;
10087        REPEAT i := 1 TO HIINDEX(items);
10088           IF SIZEOF(c_types * TYPEOF(items[i])) = 1 THEN
10089              c_hit := c_hit + 1;
10090           END_IF;
10091        END_REPEAT;
10092        IF SIZEOF(items) = c_hit THEN
10093           RETURN (TRUE);
10094        ELSE
10095           RETURN (FALSE);
10096        END_IF;
10097  	END_FUNCTION;
10098
10099   FUNCTION item_in_context
10100      (item : representation_item;
10101       cntxt : representation_context ) : BOOLEAN;
10102   LOCAL
10103      y : BAG OF representation_item;
10104   END_LOCAL;
10105      IF SIZEOF(USEDIN(item, 'ENGINEERING_PROPERTIES_SCHEMA.REPRESENTATION.ITEMS') * cntxt.representations_in_context) > 0 THEN
10106         RETURN (TRUE);
10107      ELSE
10108         y := QUERY (z <* USEDIN(item, '')| 'ENGINEERING_PROPERTIES_SCHEMA.REPRESENTATION_ITEM' IN TYPEOF(z));
10109         IF SIZEOF(y) > 0 THEN
10110            REPEAT i := 1 TO HIINDEX(y);
10111               IF item_in_context(y[i], cntxt) THEN
10112                  RETURN (TRUE);
10113               END_IF;
10114            END_REPEAT;
10115         END_IF;
10116      END_IF;
10117      RETURN (FALSE);
10118   END_FUNCTION;
10119
10120   FUNCTION leap_year
10121      (year : year_number ) : BOOLEAN;
10122      IF (year MOD 4 = 0) AND (year MOD 100 <> 0) OR (year MOD 400 = 0) THEN
10123         RETURN (TRUE);
10124      ELSE
10125         RETURN (FALSE);
10126      END_IF;
10127   END_FUNCTION;
10128
10129   FUNCTION list_selected_components
10130      (aggr : AGGREGATE OF LIST OF maths_value;
10131       k : positive_integer ) : LIST OF maths_value;
10132   LOCAL
10133      result : LIST OF maths_value := [];
10134      j : INTEGER := 0;
10135   END_LOCAL;
10136      REPEAT i := LOINDEX(aggr) TO HIINDEX(aggr);
10137         IF k <= SIZEOF(aggr[i]) THEN
10138            INSERT( result, aggr[i][k], j );
10139            j := j + 1;
10140         END_IF;
10141      END_REPEAT;
10142      RETURN (result);
10143   END_FUNCTION;
10144
10145   FUNCTION make_atom_based_literal
10146      (lit_value : atom_based_value ) : atom_based_literal;
10147      RETURN (atom_based_literal(lit_value) || generic_literal() || simple_generic_expression() || generic_expression());
10148   END_FUNCTION;
10149
10150   FUNCTION make_binary_literal
10151      (lit_value : BINARY ) : binary_literal;
10152      RETURN (binary_literal(lit_value) || generic_literal() || simple_generic_expression() || generic_expression());
10153   END_FUNCTION;
10154
10155   FUNCTION make_boolean_literal
10156      (lit_value : BOOLEAN ) : boolean_literal;
10157      RETURN (boolean_literal(lit_value) || simple_boolean_expression() || boolean_expression() || expression() || generic_expression() || simple_generic_expression() || generic_literal());
10158   END_FUNCTION;
10159
10160   FUNCTION make_cartesian_complex_number_region
10161      (real_constraint : real_interval;
10162       imag_constraint : real_interval ) : cartesian_complex_number_region;
10163      RETURN (cartesian_complex_number_region(real_constraint, imag_constraint) || maths_space() || generic_expression() || generic_literal() || simple_generic_expression());
10164   END_FUNCTION;
10165
10166  FUNCTION make_complex_number_literal(rpart, ipart : REAL) : complex_number_literal;
10167     RETURN (complex_number_literal (rpart, ipart)
10168    || generic_literal()
10169      || simple_generic_expression()
10170        || generic_expression() );
10171  END_FUNCTION;  -- make_complex_number_literal
10172
10173   FUNCTION make_elementary_function
10174      (func_id : elementary_function_enumerators ) : elementary_function;
10175      RETURN (elementary_function(func_id) || maths_function() || generic_expression() || generic_literal() || simple_generic_expression());
10176   END_FUNCTION;
10177
10178   FUNCTION make_elementary_space
10179      (space_id : elementary_space_enumerators ) : elementary_space;
10180      RETURN (elementary_space(space_id) || maths_space() || generic_expression() || generic_literal() || simple_generic_expression());
10181   END_FUNCTION;
10182
10183   FUNCTION make_extended_tuple_space
10184      (base : product_space;
10185       extender : maths_space ) : extended_tuple_space;
10186      RETURN (extended_tuple_space(base, extender) || maths_space() || generic_expression() || generic_literal() || simple_generic_expression());
10187   END_FUNCTION;
10188
10189   FUNCTION make_finite_integer_interval
10190      (min : INTEGER;
10191       max : INTEGER ) : finite_integer_interval;
10192      RETURN (finite_integer_interval(min, max) || maths_space() || generic_expression() || generic_literal() || simple_generic_expression());
10193   END_FUNCTION;
10194
10195   FUNCTION make_finite_real_interval
10196      (min : REAL;
10197       minclo : open_closed;
10198       max : REAL;
10199       maxclo : open_closed ) : finite_real_interval;
10200      RETURN (finite_real_interval(min, minclo, max, maxclo) || maths_space() || generic_expression() || generic_literal() || simple_generic_expression());
10201   END_FUNCTION;
10202
10203   FUNCTION make_finite_space
10204      (members : SET OF maths_value ) : finite_space;
10205      RETURN (finite_space(members) || maths_space() || generic_expression() || generic_literal() || simple_generic_expression());
10206   END_FUNCTION;
10207
10208   FUNCTION make_function_application
10209      (afunction : maths_function_select;
10210       arguments : LIST [1:?] OF maths_value ) : function_application;
10211      RETURN (function_application(afunction, arguments) || multiple_arity_generic_expression((convert_to_maths_function(afunction) + convert_to_operands(arguments))) || generic_expression());
10212   END_FUNCTION;
10213
10214   FUNCTION make_function_space
10215      (domain_constraint : space_constraint_type;
10216       domain_argument : maths_space;
10217       range_constraint : space_constraint_type;
10218       range_argument : maths_space ) : function_space;
10219      RETURN (function_space(domain_constraint, domain_argument, range_constraint, range_argument) || maths_space() || generic_expression() || generic_literal() || simple_generic_expression());
10220   END_FUNCTION;
10221
10222   FUNCTION make_int_literal
10223      (lit_value : INTEGER ) : int_literal;
10224      RETURN (int_literal() || literal_number(lit_value) || simple_numeric_expression() || numeric_expression() || expression() || generic_expression() || simple_generic_expression() || generic_literal());
10225   END_FUNCTION;
10226
10227   FUNCTION make_listed_product_space
10228      (factors : LIST OF maths_space ) : listed_product_space;
10229      RETURN (listed_product_space(factors) || maths_space() || generic_expression() || generic_literal() || simple_generic_expression());
10230   END_FUNCTION;
10231
10232   FUNCTION make_logical_literal
10233      (lit_value : LOGICAL ) : logical_literal;
10234      RETURN (logical_literal(lit_value) || generic_literal() || simple_generic_expression() || generic_expression());
10235   END_FUNCTION;
10236
10237   FUNCTION make_maths_enum_literal
10238      (lit_value : maths_enum_atom ) : maths_enum_literal;
10239      RETURN (maths_enum_literal(lit_value) || generic_literal() || simple_generic_expression() || generic_expression());
10240   END_FUNCTION;
10241
10242   FUNCTION make_maths_tuple_literal
10243      (lit_value : LIST OF maths_value ) : maths_tuple_literal;
10244      RETURN (maths_tuple_literal(lit_value) || generic_literal() || simple_generic_expression() || generic_expression());
10245   END_FUNCTION;
10246
10247   FUNCTION make_parallel_composed_function
10248      (srcdom : maths_space_or_function;
10249       prepfuncs : LIST [2:?] OF maths_function;
10250       finfunc : maths_function_select ) : parallel_composed_function;
10251      RETURN (parallel_composed_function(srcdom, prepfuncs, finfunc) || maths_function() || generic_expression() || multiple_arity_generic_expression(convert_to_operands_prcmfn(srcdom, prepfuncs, finfunc)));
10252   END_FUNCTION;
10253
10254   FUNCTION make_polar_complex_number_region
10255      (centre : complex_number_literal;
10256       dis_constraint : real_interval;
10257       dir_constraint : finite_real_interval ) : polar_complex_number_region;
10258      RETURN (polar_complex_number_region(centre, dis_constraint, dir_constraint) || maths_space() || generic_expression() || generic_literal() || simple_generic_expression());
10259   END_FUNCTION;
10260
10261   FUNCTION make_real_interval_from_min
10262      (min : REAL;
10263       minclo : open_closed ) : real_interval_from_min;
10264      RETURN (real_interval_from_min(min, minclo) || maths_space() || generic_expression() || generic_literal() || simple_generic_expression());
10265   END_FUNCTION;
10266
10267   FUNCTION make_real_interval_to_max
10268      (max : REAL;
10269       maxclo : open_closed ) : real_interval_to_max;
10270      RETURN (real_interval_to_max(max, maxclo) || maths_space() || generic_expression() || generic_literal() || simple_generic_expression());
10271   END_FUNCTION;
10272
10273   FUNCTION make_real_literal
10274      (lit_value : REAL ) : real_literal;
10275      RETURN (real_literal() || literal_number(lit_value) || simple_numeric_expression() || numeric_expression() || expression() || generic_expression() || simple_generic_expression() || generic_literal());
10276   END_FUNCTION;
10277
10278   FUNCTION make_string_literal
10279      (lit_value : STRING ) : string_literal;
10280      RETURN (string_literal(lit_value) || simple_string_expression() || string_expression() || expression() || generic_expression() || simple_generic_expression() || generic_literal());
10281   END_FUNCTION;
10282
10283   FUNCTION make_uniform_product_space
10284      (base : maths_space;
10285       exponent : positive_integer ) : uniform_product_space;
10286      RETURN (uniform_product_space(base, exponent) || maths_space() || generic_expression() || generic_literal() || simple_generic_expression());
10287   END_FUNCTION;
10288
10289   FUNCTION max_exists
10290      (spc : maths_space ) : BOOLEAN;
10291   LOCAL
10292      types : SET OF STRING := TYPEOF(spc);
10293   END_LOCAL;
10294      RETURN (bool((((schema_prefix + 'FINITE_INTEGER_INTERVAL' IN types) OR (schema_prefix + 'INTEGER_INTERVAL_TO_MAX' IN types)) OR (schema_prefix + 'FINITE_REAL_INTERVAL' IN types)) OR (schema_prefix + 'REAL_INTERVAL_TO_MAX' IN types)));
10295   END_FUNCTION;
10296
10297   FUNCTION max_included
10298      (spc : maths_space ) : BOOLEAN;
10299   LOCAL
10300      types : SET OF STRING := TYPEOF(spc);
10301   END_LOCAL;
10302      IF (schema_prefix + 'FINITE_INTEGER_INTERVAL' IN types) OR (schema_prefix + 'INTEGER_INTERVAL_TO_MAX' IN types) THEN
10303         RETURN (TRUE);
10304      END_IF;
10305      IF schema_prefix + 'FINITE_REAL_INTERVAL' IN types THEN
10306         RETURN (bool(spc\finite_real_interval.max_closure = closed));
10307      END_IF;
10308      IF schema_prefix + 'REAL_INTERVAL_TO_MAX' IN types THEN
10309         RETURN (bool(spc\real_interval_to_max.max_closure = closed));
10310      END_IF;
10311      RETURN (FALSE);
10312   END_FUNCTION;
10313
10314   FUNCTION member_of
10315      (val : GENERIC : G;
10316       spc : maths_space ) : LOGICAL;
10317      FUNCTION fedex
10318         (val : AGGREGATE OF GENERIC : x;
10319          i : INTEGER ) : GENERIC : x;
10320         RETURN (val[i]);
10321      END_FUNCTION;
10322   LOCAL
10323      v : maths_value := simplify_maths_value(convert_to_maths_value(val));
10324      vtypes : SET OF STRING := stripped_typeof(v);
10325      s : maths_space := simplify_maths_space(spc);
10326      stypes : SET OF STRING := stripped_typeof(s);
10327      tmp_int : INTEGER;
10328      tmp_real : REAL;
10329      tmp_cmplx : complex_number_literal;
10330      lgcl : LOGICAL;
10331      cum : LOGICAL;
10332      vspc : maths_space;
10333      sspc : maths_space;
10334      smem : SET OF maths_value;
10335      factors : LIST OF maths_space;
10336   END_LOCAL;
10337      IF NOT EXISTS(s) THEN
10338         RETURN (FALSE);
10339      END_IF;
10340      IF NOT EXISTS(v) THEN
10341         RETURN (s = the_generics);
10342      END_IF;
10343      IF ((('GENERIC_EXPRESSION' IN vtypes) AND NOT ('MATHS_SPACE' IN vtypes)) AND NOT ('MATHS_FUNCTION' IN vtypes)) AND NOT ('COMPLEX_NUMBER_LITERAL' IN vtypes) THEN
10344         IF has_values_space(v) THEN
10345            vspc := values_space_of(v);
10346            IF subspace_of(vspc, s) THEN
10347               RETURN (TRUE);
10348            END_IF;
10349            IF NOT compatible_spaces(vspc, s) THEN
10350               RETURN (FALSE);
10351            END_IF;
10352            RETURN (UNKNOWN);
10353         END_IF;
10354         RETURN (UNKNOWN);
10355      END_IF;
10356      IF 'ELEMENTARY_SPACE' IN stypes THEN
10357         CASE s\elementary_space.space_id OF
10358            es_numbers :
10359                  RETURN (('NUMBER' IN vtypes) OR ('COMPLEX_NUMBER_LITERAL' IN vtypes));
10360            es_complex_numbers :
10361                  RETURN ('COMPLEX_NUMBER_LITERAL' IN vtypes);
10362            es_reals :
10363                  RETURN (('REAL' IN vtypes) AND NOT ('INTEGER' IN vtypes));
10364            es_integers :
10365                  RETURN ('INTEGER' IN vtypes);
10366            es_logicals :
10367                  RETURN ('LOGICAL' IN vtypes);
10368            es_booleans :
10369                  RETURN ('BOOLEAN' IN vtypes);
10370            es_strings :
10371                  RETURN ('STRING' IN vtypes);
10372            es_binarys :
10373                  RETURN ('BINARY' IN vtypes);
10374            es_maths_spaces :
10375                  RETURN ('MATHS_SPACE' IN vtypes);
10376            es_maths_functions :
10377                  RETURN ('MATHS_FUNCTION' IN vtypes);
10378            es_generics :
10379                  RETURN (TRUE);
10380         END_CASE;
10381      END_IF;
10382      IF 'FINITE_INTEGER_INTERVAL' IN stypes THEN
10383         IF 'INTEGER' IN vtypes THEN
10384            tmp_int := v;
10385            RETURN ((s\finite_integer_interval.min <= tmp_int) AND (tmp_int <= s\finite_integer_interval.max));
10386         END_IF;
10387         RETURN (FALSE);
10388      END_IF;
10389      IF 'INTEGER_INTERVAL_FROM_MIN' IN stypes THEN
10390         IF 'INTEGER' IN vtypes THEN
10391            tmp_int := v;
10392            RETURN (s\integer_interval_from_min.min <= tmp_int);
10393         END_IF;
10394         RETURN (FALSE);
10395      END_IF;
10396      IF 'INTEGER_INTERVAL_TO_MAX' IN stypes THEN
10397         IF 'INTEGER' IN vtypes THEN
10398            tmp_int := v;
10399            RETURN (tmp_int <= s\integer_interval_to_max.max);
10400         END_IF;
10401         RETURN (FALSE);
10402      END_IF;
10403      IF 'FINITE_REAL_INTERVAL' IN stypes THEN
10404         IF ('REAL' IN vtypes) AND NOT ('INTEGER' IN vtypes) THEN
10405            tmp_real := v;
10406            IF s\finite_real_interval.min_closure = closed THEN
10407               IF s\finite_real_interval.max_closure = closed THEN
10408                  RETURN ((s\finite_real_interval.min <= tmp_real) AND (tmp_real <= s\finite_real_interval.max));
10409               ELSE
10410                  RETURN ((s\finite_real_interval.min <= tmp_real) AND (tmp_real < s\finite_real_interval.max));
10411               END_IF;
10412            ELSE
10413               IF s\finite_real_interval.max_closure = closed THEN
10414                  RETURN ((s\finite_real_interval.min < tmp_real) AND (tmp_real <= s\finite_real_interval.max));
10415               ELSE
10416                  RETURN ((s\finite_real_interval.min < tmp_real) AND (tmp_real < s\finite_real_interval.max));
10417               END_IF;
10418            END_IF;
10419         END_IF;
10420         RETURN (FALSE);
10421      END_IF;
10422      IF 'REAL_INTERVAL_FROM_MIN' IN stypes THEN
10423         IF ('REAL' IN vtypes) AND NOT ('INTEGER' IN vtypes) THEN
10424            tmp_real := v;
10425            IF s\real_interval_from_min.min_closure = closed THEN
10426               RETURN (s\real_interval_from_min.min <= tmp_real);
10427            ELSE
10428               RETURN (s\real_interval_from_min.min < tmp_real);
10429            END_IF;
10430         END_IF;
10431         RETURN (FALSE);
10432      END_IF;
10433      IF 'REAL_INTERVAL_TO_MAX' IN stypes THEN
10434         IF ('REAL' IN vtypes) AND NOT ('INTEGER' IN vtypes) THEN
10435            tmp_real := v;
10436            IF s\real_interval_to_max.max_closure = closed THEN
10437               RETURN (tmp_real <= s\real_interval_to_max.max);
10438            ELSE
10439               RETURN (tmp_real < s\real_interval_to_max.max);
10440            END_IF;
10441         END_IF;
10442         RETURN (FALSE);
10443      END_IF;
10444      IF 'CARTESIAN_COMPLEX_NUMBER_REGION' IN stypes THEN
10445         IF 'COMPLEX_NUMBER_LITERAL' IN vtypes THEN
10446            RETURN (member_of(v\complex_number_literal.real_part, s\cartesian_complex_number_region.real_constraint) AND member_of(v\complex_number_literal.imag_part, s\cartesian_complex_number_region.imag_constraint));
10447         END_IF;
10448         RETURN (FALSE);
10449      END_IF;
10450      IF 'POLAR_COMPLEX_NUMBER_REGION' IN stypes THEN
10451         IF 'COMPLEX_NUMBER_LITERAL' IN vtypes THEN
10452            tmp_cmplx := v;
10453            tmp_cmplx.real_part := tmp_cmplx.real_part - s\polar_complex_number_region.centre.real_part;
10454            tmp_cmplx.imag_part := tmp_cmplx.imag_part - s\polar_complex_number_region.centre.imag_part;
10455            tmp_real := SQRT(tmp_cmplx.real_part ** 2 + tmp_cmplx.imag_part ** 2);
10456            IF NOT member_of(tmp_real, s\polar_complex_number_region.distance_constraint) THEN
10457               RETURN (FALSE);
10458            END_IF;
10459            IF tmp_real = 0.00000 THEN
10460               RETURN (TRUE);
10461            END_IF;
10462            tmp_real := atan2(tmp_cmplx.imag_part, tmp_cmplx.real_part);
10463            RETURN (member_of(tmp_real, s\polar_complex_number_region.direction_constraint) OR member_of(tmp_real + 2.00000 * 3.14159, s\polar_complex_number_region.direction_constraint));
10464         END_IF;
10465         RETURN (FALSE);
10466      END_IF;
10467      IF 'FINITE_SPACE' IN stypes THEN
10468         smem := s\finite_space.members;
10469         cum := FALSE;
10470         REPEAT i := 1 TO SIZEOF(smem);
10471            cum := cum OR equal_maths_values(v, smem[i]);
10472            IF cum = TRUE THEN
10473               RETURN (TRUE);
10474            END_IF;
10475         END_REPEAT;
10476         RETURN (cum);
10477      END_IF;
10478      IF 'UNIFORM_PRODUCT_SPACE' IN stypes THEN
10479         IF 'LIST' IN vtypes THEN
10480            IF SIZEOF(v) = s\uniform_product_space.exponent THEN
10481               sspc := s\uniform_product_space.base;
10482               cum := TRUE;
10483               REPEAT i := 1 TO SIZEOF(v);
10484                  cum := cum AND member_of(v[i], sspc);
10485                  IF cum = FALSE THEN
10486                     RETURN (FALSE);
10487                  END_IF;
10488               END_REPEAT;
10489               RETURN (cum);
10490            END_IF;
10491         END_IF;
10492         RETURN (FALSE);
10493      END_IF;
10494      IF 'LISTED_PRODUCT_SPACE' IN stypes THEN
10495         IF 'LIST' IN vtypes THEN
10496            factors := s\listed_product_space.factors;
10497            IF SIZEOF(v) = SIZEOF(factors) THEN
10498               cum := TRUE;
10499               REPEAT i := 1 TO SIZEOF(v);
10500                  cum := cum AND member_of(v[i], factors[i]);
10501                  IF cum = FALSE THEN
10502                     RETURN (FALSE);
10503                  END_IF;
10504               END_REPEAT;
10505               RETURN (cum);
10506            END_IF;
10507         END_IF;
10508         RETURN (FALSE);
10509      END_IF;
10510      IF 'EXTENDED_TUPLE_SPACE' IN stypes THEN
10511         IF 'LIST' IN vtypes THEN
10512            sspc := s\extended_tuple_space.base;
10513            tmp_int := space_dimension(sspc);
10514            IF SIZEOF(v) >= tmp_int THEN
10515               cum := TRUE;
10516               REPEAT i := 1 TO tmp_int;
10517                  cum := cum AND member_of(v[i], factor_space(sspc, i));
10518                  IF cum = FALSE THEN
10519                     RETURN (FALSE);
10520                  END_IF;
10521               END_REPEAT;
10522               sspc := s\extended_tuple_space.extender;
10523               REPEAT i := tmp_int + 1 TO SIZEOF(v);
10524                  cum := cum AND member_of(v[i], sspc);
10525                  IF cum = FALSE THEN
10526                     RETURN (FALSE);
10527                  END_IF;
10528               END_REPEAT;
10529               RETURN (cum);
10530            END_IF;
10531         END_IF;
10532         RETURN (FALSE);
10533      END_IF;
10534      IF 'FUNCTION_SPACE' IN stypes THEN
10535         IF 'MATHS_FUNCTION' IN vtypes THEN
10536            vspc := v\maths_function.domain;
10537            sspc := s\function_space.domain_argument;
10538            CASE s\function_space.domain_constraint OF
10539               sc_equal :
10540                     cum := equal_maths_spaces(vspc, sspc);
10541               sc_subspace :
10542                     cum := subspace_of(vspc, sspc);
10543               sc_member :
10544                     cum := member_of(vspc, sspc);
10545            END_CASE;
10546            IF cum = FALSE THEN
10547               RETURN (FALSE);
10548            END_IF;
10549            vspc := v\maths_function.range;
10550            sspc := s\function_space.range_argument;
10551            CASE s\function_space.range_constraint OF
10552               sc_equal :
10553                     cum := cum AND equal_maths_spaces(vspc, sspc);
10554               sc_subspace :
10555                     cum := cum AND subspace_of(vspc, sspc);
10556               sc_member :
10557                     cum := cum AND member_of(vspc, sspc);
10558            END_CASE;
10559            RETURN (cum);
10560         END_IF;
10561         RETURN (FALSE);
10562      END_IF;
10563      RETURN (UNKNOWN);
10564   END_FUNCTION;
10565
10566   FUNCTION min_exists
10567      (spc : maths_space ) : BOOLEAN;
10568   LOCAL
10569      types : SET OF STRING := TYPEOF(spc);
10570   END_LOCAL;
10571      RETURN (bool((((schema_prefix + 'FINITE_INTEGER_INTERVAL' IN types) OR (schema_prefix + 'INTEGER_INTERVAL_FROM_MIN' IN types)) OR (schema_prefix + 'FINITE_REAL_INTERVAL' IN types)) OR (schema_prefix + 'REAL_INTERVAL_FROM_MIN' IN types)));
10572   END_FUNCTION;
10573
10574   FUNCTION min_included
10575      (spc : maths_space ) : BOOLEAN;
10576   LOCAL
10577      types : SET OF STRING := TYPEOF(spc);
10578   END_LOCAL;
10579      IF (schema_prefix + 'FINITE_INTEGER_INTERVAL' IN types) OR (schema_prefix + 'INTEGER_INTERVAL_FROM_MIN' IN types) THEN
10580         RETURN (TRUE);
10581      END_IF;
10582      IF schema_prefix + 'FINITE_REAL_INTERVAL' IN types THEN
10583         RETURN (bool(spc\finite_real_interval.min_closure = closed));
10584      END_IF;
10585      IF schema_prefix + 'REAL_INTERVAL_FROM_MIN' IN types THEN
10586         RETURN (bool(spc\real_interval_from_min.min_closure = closed));
10587      END_IF;
10588      RETURN (FALSE);
10589   END_FUNCTION;
10590
10591   FUNCTION no_cyclic_domain_reference
10592      (ref : maths_space_or_function;
10593       used : SET OF maths_function ) : BOOLEAN;
10594   LOCAL
10595      typenames : SET OF STRING := TYPEOF(ref);
10596      func : maths_function;
10597   END_LOCAL;
10598      IF NOT EXISTS(ref) OR NOT EXISTS(used) THEN
10599         RETURN (FALSE);
10600      END_IF;
10601      IF schema_prefix + 'MATHS_SPACE' IN typenames THEN
10602         RETURN (TRUE);
10603      END_IF;
10604      func := ref;
10605      IF func IN used THEN
10606         RETURN (FALSE);
10607      END_IF;
10608      IF schema_prefix + 'CONSTANT_FUNCTION' IN typenames THEN
10609         RETURN (no_cyclic_domain_reference(func\constant_function.source_of_domain, used + [ func ]));
10610      END_IF;
10611      IF schema_prefix + 'SELECTOR_FUNCTION' IN typenames THEN
10612         RETURN (no_cyclic_domain_reference(func\selector_function.source_of_domain, used + [ func ]));
10613      END_IF;
10614      IF schema_prefix + 'PARALLEL_COMPOSED_FUNCTION' IN typenames THEN
10615         RETURN (no_cyclic_domain_reference(func\parallel_composed_function.source_of_domain, used + [ func ]));
10616      END_IF;
10617      RETURN (TRUE);
10618   END_FUNCTION;
10619
10620   FUNCTION no_cyclic_space_reference
10621      (spc : maths_space;
10622       refs : SET OF maths_space ) : BOOLEAN;
10623   LOCAL
10624      types : SET OF STRING;
10625      refs_plus : SET OF maths_space;
10626   END_LOCAL;
10627      IF spc IN refs THEN
10628         RETURN (FALSE);
10629      END_IF;
10630      types := TYPEOF(spc);
10631      refs_plus := refs + spc;
10632      IF schema_prefix + 'FINITE_SPACE' IN types THEN
10633         RETURN (bool(SIZEOF(QUERY (sp <* QUERY (mem <* spc\finite_space.members| (schema_prefix + 'MATHS_SPACE' IN TYPEOF(mem)))| NOT no_cyclic_space_reference(sp, refs_plus))) = 0));
10634      END_IF;
10635      IF schema_prefix + 'UNIFORM_PRODUCT_SPACE' IN types THEN
10636         RETURN (no_cyclic_space_reference(spc\uniform_product_space.base, refs_plus));
10637      END_IF;
10638      IF schema_prefix + 'LISTED_PRODUCT_SPACE' IN types THEN
10639         RETURN (bool(SIZEOF(QUERY (fac <* spc\listed_product_space.factors| NOT no_cyclic_space_reference(fac, refs_plus))) = 0));
10640      END_IF;
10641      IF schema_prefix + 'EXTENDED_TUPLE_SPACE' IN types THEN
10642         RETURN (no_cyclic_space_reference(spc\extended_tuple_space.base, refs_plus) AND no_cyclic_space_reference(spc\extended_tuple_space.extender, refs_plus));
10643      END_IF;
10644      RETURN (TRUE);
10645   END_FUNCTION;
10646
10647   FUNCTION nondecreasing
10648      (lr : LIST OF REAL ) : BOOLEAN;
10649      IF NOT EXISTS(lr) THEN
10650         RETURN (FALSE);
10651      END_IF;
10652      REPEAT j := 2 TO SIZEOF(lr);
10653         IF lr[j] < lr[(j - 1)] THEN
10654            RETURN (FALSE);
10655         END_IF;
10656      END_REPEAT;
10657      RETURN (TRUE);
10658   END_FUNCTION;
10659
10660   FUNCTION normalise
10661      (arg : vector_or_direction ) : vector_or_direction;
10662   LOCAL
10663      ndim : INTEGER;
10664      v : direction;
10665      result : vector_or_direction;
10666      vec : vector;
10667      mag : REAL;
10668   END_LOCAL;
10669      IF NOT EXISTS(arg) THEN
10670         result := ?;
10671      ELSE
10672         ndim := arg.dim;
10673         IF 'ENGINEERING_PROPERTIES_SCHEMA.VECTOR' IN TYPEOF(arg) THEN
10674            BEGIN
10675               v := dummy_gri || direction(arg.orientation.direction_ratios);
10676               IF arg.magnitude = 0.00000 THEN
10677                  RETURN (?);
10678               ELSE
10679                  vec := dummy_gri || vector(v, 1.00000);
10680               END_IF;
10681            END;
10682         ELSE
10683            v := dummy_gri || direction(arg.direction_ratios);
10684         END_IF;
10685         mag := 0.00000;
10686         REPEAT i := 1 TO ndim;
10687            mag := mag + v.direction_ratios[i] * v.direction_ratios[i];
10688         END_REPEAT;
10689         IF mag > 0.00000 THEN
10690            mag := SQRT(mag);
10691            REPEAT i := 1 TO ndim;
10692               v.direction_ratios[i] := v.direction_ratios[i] / mag;
10693            END_REPEAT;
10694            IF 'ENGINEERING_PROPERTIES_SCHEMA.VECTOR' IN TYPEOF(arg) THEN
10695               vec.orientation := v;
10696               result := vec;
10697            ELSE
10698               result := v;
10699            END_IF;
10700         ELSE
10701            RETURN (?);
10702         END_IF;
10703      END_IF;
10704      RETURN (result);
10705   END_FUNCTION;
10706
10707   FUNCTION number_superspace_of
10708      (spc : maths_space ) : elementary_space;
10709      IF subspace_of_es(spc, es_integers) THEN
10710         RETURN (the_integers);
10711      END_IF;
10712      IF subspace_of_es(spc, es_reals) THEN
10713         RETURN (the_reals);
10714      END_IF;
10715      IF subspace_of_es(spc, es_complex_numbers) THEN
10716         RETURN (the_complex_numbers);
10717      END_IF;
10718      IF subspace_of_es(spc, es_numbers) THEN
10719         RETURN (the_numbers);
10720      END_IF;
10721      RETURN (?);
10722   END_FUNCTION;
10723
10724   FUNCTION number_tuple_subspace_check
10725      (spc : maths_space ) : LOGICAL;
10726   LOCAL
10727      types : SET OF STRING := stripped_typeof(spc);
10728      factors : LIST OF maths_space;
10729      cum : LOGICAL := TRUE;
10730   END_LOCAL;
10731      IF 'UNIFORM_PRODUCT_SPACE' IN types THEN
10732         RETURN (subspace_of_es(spc\uniform_product_space.base, es_numbers));
10733      END_IF;
10734      IF 'LISTED_PRODUCT_SPACE' IN types THEN
10735         factors := spc\listed_product_space.factors;
10736         REPEAT i := 1 TO SIZEOF(factors);
10737            cum := cum AND subspace_of_es(factors[i], es_numbers);
10738         END_REPEAT;
10739         RETURN (cum);
10740      END_IF;
10741      IF 'EXTENDED_TUPLE_SPACE' IN types THEN
10742         cum := subspace_of_es(spc\extended_tuple_space.extender, es_numbers);
10743         cum := cum AND number_tuple_subspace_check(spc\extended_tuple_space.base);
10744         RETURN (cum);
10745      END_IF;
10746      RETURN (FALSE);
10747   END_FUNCTION;
10748
10749   FUNCTION one_tuples_of
10750      (spc : maths_space ) : tuple_space;
10751      RETURN (make_uniform_product_space(spc, 1));
10752   END_FUNCTION;
10753
10754   FUNCTION orthogonal_complement
10755      (vec : direction ) : direction;
10756   LOCAL
10757      result : direction;
10758   END_LOCAL;
10759      IF (vec.dim <> 2) OR NOT EXISTS(vec) THEN
10760         RETURN (?);
10761      ELSE
10762         result := dummy_gri || direction([ -vec.direction_ratios[2], vec.direction_ratios[1] ]);
10763         RETURN (result);
10764      END_IF;
10765   END_FUNCTION;
10766
10767   FUNCTION parallel_composed_function_composability_check
10768      (funcs : LIST OF maths_function;
10769       final : maths_function_select ) : BOOLEAN;
10770   LOCAL
10771      tplsp : tuple_space := the_zero_tuple_space;
10772      finfun : maths_function := convert_to_maths_function(final);
10773   END_LOCAL;
10774      REPEAT i := 1 TO SIZEOF(funcs);
10775         tplsp := assoc_product_space(tplsp, funcs[i].range);
10776      END_REPEAT;
10777      RETURN (compatible_spaces(tplsp, finfun.domain));
10778   END_FUNCTION;
10779
10780   FUNCTION parallel_composed_function_domain_check
10781      (comdom : tuple_space;
10782       funcs : LIST OF maths_function ) : BOOLEAN;
10783      REPEAT i := 1 TO SIZEOF(funcs);
10784         IF NOT compatible_spaces(comdom, funcs[i].domain) THEN
10785            RETURN (FALSE);
10786         END_IF;
10787      END_REPEAT;
10788      RETURN (TRUE);
10789   END_FUNCTION;
10790
10791   FUNCTION parse_express_identifier
10792      (s : STRING;
10793       i : positive_integer ) : positive_integer;
10794   LOCAL
10795      k : positive_integer;
10796   END_LOCAL;
10797      k := i;
10798      IF i <= LENGTH(s) THEN
10799         IF s[i] LIKE '@' THEN
10800            REPEAT UNTIL (k > LENGTH(s)) OR ((s[k] <> '_') AND NOT (s[k] LIKE '@')) AND NOT (s[k] LIKE '#');
10801               k := k + 1;
10802            END_REPEAT;
10803         END_IF;
10804      END_IF;
10805      RETURN (k);
10806   END_FUNCTION;
10807
10808   FUNCTION partial_derivative_check
10809      (domain : tuple_space;
10810       d_vars : LIST [1:?] OF input_selector ) : BOOLEAN;
10811   LOCAL
10812      domn : tuple_space := domain;
10813      fspc : maths_space;
10814      dim : INTEGER;
10815      k : INTEGER;
10816   END_LOCAL;
10817      IF (space_dimension(domain) = 1) AND (schema_prefix + 'TUPLE_SPACE' IN TYPEOF(factor1(domain))) THEN
10818         domn := factor1(domain);
10819      END_IF;
10820      dim := space_dimension(domn);
10821      REPEAT i := 1 TO SIZEOF(d_vars);
10822         k := d_vars[i];
10823         IF k > dim THEN
10824            RETURN (FALSE);
10825         END_IF;
10826         fspc := factor_space(domn, k);
10827         IF NOT subspace_of_es(fspc, es_reals) AND NOT subspace_of_es(fspc, es_complex_numbers) THEN
10828            RETURN (FALSE);
10829         END_IF;
10830      END_REPEAT;
10831      RETURN (TRUE);
10832   END_FUNCTION;
10833
10834   FUNCTION real_max
10835      (spc : maths_space ) : REAL;
10836   LOCAL
10837      types : SET OF STRING := TYPEOF(spc);
10838   END_LOCAL;
10839      IF schema_prefix + 'FINITE_INTEGER_INTERVAL' IN types THEN
10840         RETURN (spc\finite_integer_interval.max);
10841      END_IF;
10842      IF schema_prefix + 'INTEGER_INTERVAL_TO_MAX' IN types THEN
10843         RETURN (spc\integer_interval_to_max.max);
10844      END_IF;
10845      IF schema_prefix + 'FINITE_REAL_INTERVAL' IN types THEN
10846         RETURN (spc\finite_real_interval.max);
10847      END_IF;
10848      IF schema_prefix + 'REAL_INTERVAL_TO_MAX' IN types THEN
10849         RETURN (spc\real_interval_to_max.max);
10850      END_IF;
10851      RETURN (?);
10852   END_FUNCTION;
10853
10854   FUNCTION real_min
10855      (spc : maths_space ) : REAL;
10856   LOCAL
10857      types : SET OF STRING := TYPEOF(spc);
10858   END_LOCAL;
10859      IF schema_prefix + 'FINITE_INTEGER_INTERVAL' IN types THEN
10860         RETURN (spc\finite_integer_interval.min);
10861      END_IF;
10862      IF schema_prefix + 'INTEGER_INTERVAL_FROM_MIN' IN types THEN
10863         RETURN (spc\integer_interval_from_min.min);
10864      END_IF;
10865      IF schema_prefix + 'FINITE_REAL_INTERVAL' IN types THEN
10866         RETURN (spc\finite_real_interval.min);
10867      END_IF;
10868      IF schema_prefix + 'REAL_INTERVAL_FROM_MIN' IN types THEN
10869         RETURN (spc\real_interval_from_min.min);
10870      END_IF;
10871      RETURN (?);
10872   END_FUNCTION;
10873
10874   FUNCTION regular_indexing
10875      (sub : LIST OF INTEGER;
10876       base : zero_or_one;
10877       shape : LIST [1:?] OF positive_integer;
10878       inc : LIST [1:?] OF INTEGER;
10879       first : INTEGER ) : INTEGER;
10880   LOCAL
10881      k : INTEGER;
10882      index : INTEGER;
10883   END_LOCAL;
10884      IF (((NOT EXISTS(sub) OR NOT EXISTS(base)) OR NOT EXISTS(shape)) OR NOT EXISTS(inc)) OR NOT EXISTS(first) THEN
10885         RETURN (?);
10886      END_IF;
10887      IF (SIZEOF(sub) <> SIZEOF(inc)) OR (SIZEOF(sub) <> SIZEOF(shape)) THEN
10888         RETURN (?);
10889      END_IF;
10890      index := first;
10891      REPEAT j := 1 TO SIZEOF(sub);
10892         IF NOT EXISTS(sub[j]) OR NOT EXISTS(inc[j]) THEN
10893            RETURN (?);
10894         END_IF;
10895         k := sub[j] - base;
10896         IF NOT ((0 <= k) AND (k < shape[j])) THEN
10897            RETURN (?);
10898         END_IF;
10899         index := index + k * inc[j];
10900      END_REPEAT;
10901      RETURN (index);
10902   END_FUNCTION;
10903
10904   FUNCTION remove_first
10905      (alist : LIST OF GENERIC : GEN ) : LIST OF GENERIC : GEN;
10906   LOCAL
10907      blist : LIST OF GENERIC : GEN := alist;
10908   END_LOCAL;
10909      IF SIZEOF(blist) > 0 THEN
10910         REMOVE( blist, 1 );
10911      END_IF;
10912      RETURN (blist);
10913   END_FUNCTION;
10914
10915   FUNCTION repackage
10916      (tspace : tuple_space;
10917       repckg : repackage_options ) : tuple_space;
10918      CASE repckg OF
10919         ro_nochange :
10920               RETURN (tspace);
10921         ro_wrap_as_tuple :
10922               RETURN (one_tuples_of(tspace));
10923         ro_unwrap_tuple :
10924               RETURN (factor1(tspace));
10925      OTHERWISE :
10926            RETURN (?);
10927      END_CASE;
10928   END_FUNCTION;
10929
10930   FUNCTION scalar_times_vector
10931      (scalar : REAL;
10932       vec : vector_or_direction ) : vector;
10933   LOCAL
10934      v : direction;
10935      mag : REAL;
10936      result : vector;
10937   END_LOCAL;
10938      IF NOT EXISTS(scalar) OR NOT EXISTS(vec) THEN
10939         RETURN (?);
10940      ELSE
10941         IF 'ENGINEERING_PROPERTIES_SCHEMA.VECTOR' IN TYPEOF(vec) THEN
10942            v := dummy_gri || direction(vec.orientation.direction_ratios);
10943            mag := scalar * vec.magnitude;
10944         ELSE
10945            v := dummy_gri || direction(vec.direction_ratios);
10946            mag := scalar;
10947         END_IF;
10948         IF mag < 0.00000 THEN
10949            REPEAT i := 1 TO SIZEOF(v.direction_ratios);
10950               v.direction_ratios[i] := -v.direction_ratios[i];
10951            END_REPEAT;
10952            mag := -mag;
10953         END_IF;
10954         result := dummy_gri || vector(normalise(v), mag);
10955      END_IF;
10956      RETURN (result);
10957   END_FUNCTION;
10958
10959   FUNCTION second_proj_axis
10960      (z_axis : direction;
10961       x_axis : direction;
10962       arg : direction ) : direction;
10963   LOCAL
10964      y_axis : vector;
10965      v : direction;
10966      temp : vector;
10967   END_LOCAL;
10968      IF NOT EXISTS(arg) THEN
10969         v := dummy_gri || direction([ 0.00000, 1.00000, 0.00000 ]);
10970      ELSE
10971         v := arg;
10972      END_IF;
10973      temp := scalar_times_vector(dot_product(v, z_axis), z_axis);
10974      y_axis := vector_difference(v, temp);
10975      temp := scalar_times_vector(dot_product(v, x_axis), x_axis);
10976      y_axis := vector_difference(y_axis, temp);
10977      y_axis := normalise(y_axis);
10978      RETURN (y_axis.orientation);
10979   END_FUNCTION;
10980
10981   FUNCTION shape_of_array
10982      (func : maths_function ) : LIST OF positive_integer;
10983   LOCAL
10984      tspace : tuple_space;
10985      temp : maths_space;
10986      result : LIST OF positive_integer := [];
10987   END_LOCAL;
10988      IF schema_prefix + 'EXPLICIT_TABLE_FUNCTION' IN TYPEOF(func) THEN
10989         RETURN (func\explicit_table_function.shape);
10990      END_IF;
10991      tspace := func.domain;
10992      IF (space_dimension(tspace) = 1) AND (schema_prefix + 'TUPLE_SPACE' IN TYPEOF(factor1(tspace))) THEN
10993         tspace := factor1(tspace);
10994      END_IF;
10995      REPEAT i := 1 TO space_dimension(tspace);
10996         temp := factor_space(tspace, i);
10997         IF NOT (schema_prefix + 'FINITE_INTEGER_INTERVAL' IN TYPEOF(temp)) THEN
10998            RETURN (?);
10999         END_IF;
11000         INSERT( result, temp\finite_integer_interval.size, i - 1 );
11001      END_REPEAT;
11002      RETURN (result);
11003   END_FUNCTION;
11004
11005   FUNCTION simplify_function_application(expr : function_application) : maths_value;
11006  FUNCTION ctmv(x : GENERIC:G) : maths_value;
11007    RETURN (convert_to_maths_value(x));
11008  END_FUNCTION;  -- local abbreviation for convert_to_maths_value function
11009  PROCEDURE parts(       c : complex_number_literal;
11010                  VAR x, y : REAL);
11011    x := c.real_part;  y := c.imag_part;
11012  END_PROCEDURE;  -- parts
11013  FUNCTION makec(x, y : REAL) : complex_number_literal;
11014    RETURN (make_complex_number_literal(x,y));
11015  END_FUNCTION;  -- local abbreviation for make_complex_number_literal function
11016
11017 FUNCTION good_t(v  : maths_value;
11018                  tn : STRING) : BOOLEAN;
11019    LOCAL
11020      tpl : LIST OF maths_value;
11021    END_LOCAL;
11022    IF 'LIST' IN TYPEOF (v) THEN
11023      tpl := v;
11024      REPEAT i := 1 TO SIZEOF (tpl);
11025        IF NOT (tn IN TYPEOF (tpl[i])) THEN  RETURN (FALSE);  END_IF;
11026      END_REPEAT;
11027      RETURN (TRUE);
11028    END_IF;
11029    RETURN (FALSE);
11030  END_FUNCTION;  -- good_t
11031  CONSTANT
11032    cnlit : STRING := schema_prefix + 'COMPLEX_NUMBER_LITERAL';
11033  END_CONSTANT;
11034  LOCAL
11035    types : SET OF STRING := stripped_typeof(expr.func);
11036    ef_val : elementary_function_enumerators;
11037    is_elementary : BOOLEAN := FALSE;
11038    v, v1, v2, v3 : maths_value;
11039    vlist : LIST OF maths_value := [];
11040    gexpr : generic_expression;
11041    pairs : SET [1:?] OF LIST [2:2] OF maths_value;
11042    boo : BOOLEAN;
11043    lgc, cum : LOGICAL;
11044    j, k, n : INTEGER;
11045    p, q, r, s, t, u : REAL;
11046    str, st2 : STRING;
11047    bin, bi2 : BINARY;
11048    tpl, tp2 : LIST OF maths_value;
11049    mem :SET OF maths_value := [];
11050  END_LOCAL;
11051  REPEAT i := 1 TO SIZEOF (expr.arguments);
11052    v := simplify_maths_value(expr.arguments[i]);
11053    INSERT (vlist, v, i-1);
11054  END_REPEAT;
11055  IF SIZEOF (vlist) >= 1 THEN  v1 := vlist[1];  END_IF;
11056  IF SIZEOF (vlist) >= 2 THEN  v2 := vlist[2];  END_IF;
11057  IF SIZEOF (vlist) >= 3 THEN  v3 := vlist[3];  END_IF;
11058  IF 'ELEMENTARY_FUNCTION_ENUMERATORS' IN types THEN
11059    ef_val := expr.func;
11060    is_elementary := TRUE;
11061  END_IF;
11062  IF 'ELEMENTARY_FUNCTION' IN types THEN
11063    ef_val := expr.func\elementary_function.func_id;
11064    is_elementary := TRUE;
11065  END_IF;
11066  IF is_elementary THEN
11067    CASE ef_val OF
11068    ef_and : BEGIN
11069      cum := TRUE;
11070      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11071        IF 'LOGICAL' IN TYPEOF (vlist[i]) THEN
11072          lgc := vlist[i];  cum := cum AND lgc;
11073          IF lgc = FALSE THEN  RETURN (ctmv(FALSE));  END_IF;
11074          REMOVE (vlist, i);
11075        END_IF;
11076      END_REPEAT;
11077      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(cum));  END_IF;
11078      IF cum <> TRUE THEN  INSERT (vlist, ctmv(cum), 0);  END_IF;
11079      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11080      END;
11081    ef_or : BEGIN
11082      cum := FALSE;
11083      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11084        IF 'LOGICAL' IN TYPEOF (vlist[i]) THEN
11085          lgc := vlist[i];  cum := cum OR lgc;
11086          IF lgc = TRUE THEN  RETURN (ctmv(TRUE));  END_IF;
11087          REMOVE (vlist, i);
11088        END_IF;
11089      END_REPEAT;
11090      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(cum));  END_IF;
11091      IF cum <> FALSE THEN  INSERT (vlist, ctmv(cum), 0);  END_IF;
11092      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11093      END;
11094    ef_not :
11095      IF 'LOGICAL' IN TYPEOF (v1) THEN  lgc := v1;  RETURN (ctmv(NOT lgc));  END_IF;
11096    ef_xor : BEGIN
11097      IF 'LOGICAL' IN TYPEOF (v1) THEN
11098        lgc := v1;
11099        IF 'LOGICAL' IN TYPEOF (v2) THEN  cum := v2;  RETURN (ctmv(lgc XOR cum));
11100        ELSE IF lgc = FALSE THEN  RETURN (ctmv(v2));
11101        ELSE IF lgc = UNKNOWN THEN  RETURN (ctmv(UNKNOWN));
11102        ELSE  RETURN (make_function_application(ef_not,[v2]));
11103        END_IF;  END_IF;  END_IF;
11104      ELSE IF 'LOGICAL' IN TYPEOF (v2) THEN
11105        lgc := v2;
11106        IF lgc = FALSE THEN  RETURN (ctmv(v1));
11107        ELSE IF lgc = UNKNOWN THEN  RETURN (ctmv(UNKNOWN));
11108        ELSE  RETURN (make_function_application(ef_not,[v1]));
11109        END_IF;  END_IF;
11110      END_IF;  END_IF;
11111      END;
11112    ef_negate_i :
11113      IF 'INTEGER' IN TYPEOF (v1) THEN  j := v1;  RETURN (ctmv(-j));  END_IF;
11114    ef_add_i : BEGIN
11115      j := 0;
11116      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11117        IF 'INTEGER' IN TYPEOF (vlist[i]) THEN
11118          k := vlist[i];  j := j + k;
11119          REMOVE (vlist, i);
11120        END_IF;
11121      END_REPEAT;
11122      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(j));  END_IF;
11123      IF j <> 0 THEN  INSERT (vlist, ctmv(j), 0);  END_IF;
11124      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11125      END;
11126    ef_subtract_i :
11127      IF ('INTEGER' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11128        j := v1;  k := v2;  RETURN (ctmv(j - k));
11129      END_IF;
11130    ef_multiply_i : BEGIN
11131      j := 1;
11132      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11133        IF 'INTEGER' IN TYPEOF (vlist[i]) THEN
11134          k := vlist[i];  j := j * k;
11135          REMOVE (vlist, i);
11136        END_IF;
11137      END_REPEAT;
11138      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(j));  END_IF;
11139      IF j <> 1 THEN  INSERT (vlist, ctmv(j), 0);  END_IF;
11140      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11141      END;
11142    ef_divide_i :
11143      IF ('INTEGER' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11144        j := v1;  k := v2;  RETURN (ctmv(j DIV k));
11145      END_IF;
11146    ef_mod_i :
11147      IF ('INTEGER' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11148        j := v1;  k := v2;  RETURN (ctmv(j MOD k));
11149      END_IF;
11150    ef_exponentiate_i :
11151      IF ('INTEGER' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11152        j := v1;  k := v2;  n := 1;
11153        REPEAT i := 1 TO ABS(k);  n := n * j;  END_REPEAT;
11154        IF k < 0 THEN  n := 1 DIV n;  END_IF;
11155        RETURN (ctmv(n));
11156      END_IF;
11157    ef_eq_i :
11158      IF ('INTEGER' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11159        j := v1;  k := v2;  RETURN (ctmv(j = k));
11160      END_IF;
11161    ef_ne_i :
11162      IF ('INTEGER' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11163        j := v1;  k := v2;  RETURN (ctmv(j <> k));
11164      END_IF;
11165    ef_gt_i :
11166      IF ('INTEGER' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11167        j := v1;  k := v2;  RETURN (ctmv(j > k));
11168      END_IF;
11169    ef_lt_i :
11170      IF ('INTEGER' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11171        j := v1;  k := v2;  RETURN (ctmv(j < k));
11172      END_IF;
11173    ef_ge_i :
11174      IF ('INTEGER' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11175        j := v1;  k := v2;  RETURN (ctmv(j >= k));
11176      END_IF;
11177    ef_le_i :
11178      IF ('INTEGER' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11179        j := v1;  k := v2;  RETURN (ctmv(j <= k));
11180      END_IF;
11181    ef_abs_i :
11182      IF 'INTEGER' IN TYPEOF (v1) THEN  j := v1;  RETURN (ctmv(ABS(j)));  END_IF;
11183    ef_max_i : BEGIN
11184      boo := FALSE;
11185      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11186        IF 'INTEGER' IN TYPEOF (vlist[i]) THEN
11187          IF boo THEN  k := vlist[i];  IF k > j THEN  j := k;  END_IF;
11188          ELSE  j := vlist[i];  boo := TRUE;  END_IF;
11189          REMOVE (vlist, i);
11190        END_IF;
11191      END_REPEAT;
11192      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(j));  END_IF;
11193      IF boo THEN  INSERT (vlist, ctmv(j), 0);  END_IF;
11194      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11195      END;
11196    ef_min_i : BEGIN
11197      boo := FALSE;
11198      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11199        IF 'INTEGER' IN TYPEOF (vlist[i]) THEN
11200          IF boo THEN  k := vlist[i];  IF k < j THEN  j := k;  END_IF;
11201          ELSE  j := vlist[i];  boo := TRUE;  END_IF;
11202          REMOVE (vlist, i);
11203        END_IF;
11204      END_REPEAT;
11205      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(j));  END_IF;
11206      IF boo THEN  INSERT (vlist, ctmv(j), 0);  END_IF;
11207      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11208      END;
11209    -- ef_if_i : combined with ef_if
11210    ef_negate_r :
11211      IF 'REAL' IN TYPEOF (v1) THEN  r := v1;  RETURN (ctmv(-r));  END_IF;
11212    ef_reciprocal_r :
11213      IF 'REAL' IN TYPEOF (v1) THEN  r := v1;  RETURN (ctmv(1.0/r));  END_IF;
11214    ef_add_r : BEGIN
11215      r := 0.0;
11216      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11217        IF 'REAL' IN TYPEOF (vlist[i]) THEN
11218          s := vlist[i];  r := r + s;
11219          REMOVE (vlist, i);
11220        END_IF;
11221      END_REPEAT;
11222      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(r));  END_IF;
11223      IF r <> 0.0 THEN  INSERT (vlist, ctmv(r), 0);  END_IF;
11224      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11225      END;
11226    ef_subtract_r :
11227      IF ('REAL' IN TYPEOF (v1)) AND ('REAL' IN TYPEOF (v2)) THEN
11228        r := v1;  s := v2;  RETURN (ctmv(r - s));
11229      END_IF;
11230    ef_multiply_r : BEGIN
11231      r := 1.0;
11232      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11233        IF 'REAL' IN TYPEOF (vlist[i]) THEN
11234          s := vlist[i];  r := r * s;
11235          REMOVE (vlist, i);
11236        END_IF;
11237      END_REPEAT;
11238      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(r));  END_IF;
11239      IF r <> 1.0 THEN  INSERT (vlist, ctmv(r), 0);  END_IF;
11240      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11241      END;
11242    ef_divide_r :
11243      IF ('REAL' IN TYPEOF (v1)) AND ('REAL' IN TYPEOF (v2)) THEN
11244        r := v1;  s := v2;  RETURN (ctmv(r / s));
11245      END_IF;
11246    ef_mod_r :
11247      IF ('REAL' IN TYPEOF (v1)) AND ('REAL' IN TYPEOF (v2)) THEN
11248        r := v1;  s := v2;  t := r/s;  j := t DIV 1;
11249        IF (t < 0.0) AND (j <> t) THEN  j := j - 1;  END_IF;
11250        RETURN (ctmv(r - j * s));
11251      END_IF;
11252    ef_exponentiate_r :
11253      IF ('REAL' IN TYPEOF (v1)) AND ('REAL' IN TYPEOF (v2)) THEN
11254        r := v1;  s := v2;  RETURN (ctmv(r ** s));
11255      END_IF;
11256    ef_exponentiate_ri :
11257      IF ('REAL' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11258        r := v1;  k := v2;  t := 1.0;
11259        REPEAT i := 1 TO ABS(k);  t := t * r;  END_REPEAT;
11260        IF k < 0 THEN  t := 1.0/t;  END_IF;
11261        RETURN (ctmv(t));
11262      END_IF;
11263    ef_eq_r :
11264      IF ('REAL' IN TYPEOF (v1)) AND ('REAL' IN TYPEOF (v2)) THEN
11265        r := v1;  s := v2;  RETURN (ctmv(r = s));
11266      END_IF;
11267    ef_ne_r :
11268      IF ('REAL' IN TYPEOF (v1)) AND ('REAL' IN TYPEOF (v2)) THEN
11269        r := v1;  s := v2;  RETURN (ctmv(r <> s));
11270      END_IF;
11271    ef_gt_r :
11272      IF ('REAL' IN TYPEOF (v1)) AND ('REAL' IN TYPEOF (v2)) THEN
11273        r := v1;  s := v2;  RETURN (ctmv(r > s));
11274      END_IF;
11275    ef_lt_r :
11276      IF ('REAL' IN TYPEOF (v1)) AND ('REAL' IN TYPEOF (v2)) THEN
11277        r := v1;  s := v2;  RETURN (ctmv(r < s));
11278      END_IF;
11279    ef_ge_r :
11280      IF ('REAL' IN TYPEOF (v1)) AND ('REAL' IN TYPEOF (v2)) THEN
11281        r := v1;  s := v2;  RETURN (ctmv(r >= s));
11282      END_IF;
11283    ef_le_r :
11284      IF ('REAL' IN TYPEOF (v1)) AND ('REAL' IN TYPEOF (v2)) THEN
11285        r := v1;  s := v2;  RETURN (ctmv(r <= s));
11286      END_IF;
11287    ef_abs_r :
11288      IF 'REAL' IN TYPEOF (v1) THEN  r := v1;  RETURN (ctmv(ABS(r)));  END_IF;
11289    ef_max_r : BEGIN
11290      boo := FALSE;
11291      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11292        IF 'REAL' IN TYPEOF (vlist[i]) THEN
11293          IF boo THEN  s := vlist[i];  IF s > r THEN  r := s;  END_IF;
11294          ELSE  r := vlist[i];  boo := TRUE;  END_IF;
11295          REMOVE (vlist, i);
11296        END_IF;
11297      END_REPEAT;
11298      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(r));  END_IF;
11299      IF boo THEN  INSERT (vlist, ctmv(r), 0);  END_IF;
11300      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11301      END;
11302    ef_min_r : BEGIN
11303      boo := FALSE;
11304      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11305        IF 'REAL' IN TYPEOF (vlist[i]) THEN
11306          IF boo THEN  s := vlist[i];  IF s < r THEN  r := s;  END_IF;
11307          ELSE  r := vlist[i];  boo := TRUE;  END_IF;
11308          REMOVE (vlist, i);
11309        END_IF;
11310      END_REPEAT;
11311      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(r));  END_IF;
11312      IF boo THEN  INSERT (vlist, ctmv(r), 0);  END_IF;
11313      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11314      END;
11315    ef_acos_r :
11316      IF 'REAL' IN TYPEOF (v1) THEN  r := v1;  RETURN (ctmv(ACOS(r)));  END_IF;
11317    ef_asin_r :
11318      IF 'REAL' IN TYPEOF (v1) THEN  r := v1;  RETURN (ctmv(ASIN(r)));  END_IF;
11319    ef_atan2_r :
11320      IF ('REAL' IN TYPEOF (v1)) AND ('REAL' IN TYPEOF (v2)) THEN
11321        r := v1;  s := v2;  RETURN (ctmv(atan2(r,s)));
11322      END_IF;
11323    ef_cos_r :
11324      IF 'REAL' IN TYPEOF (v1) THEN  r := v1;  RETURN (ctmv(COS(r)));  END_IF;
11325    ef_exp_r :
11326      IF 'REAL' IN TYPEOF (v1) THEN  r := v1;  RETURN (ctmv(EXP(r)));  END_IF;
11327    ef_ln_r :
11328      IF 'REAL' IN TYPEOF (v1) THEN  r := v1;  RETURN (ctmv(LOG(r)));  END_IF;
11329    ef_log2_r :
11330      IF 'REAL' IN TYPEOF (v1) THEN  r := v1;  RETURN (ctmv(LOG2(r)));  END_IF;
11331    ef_log10_r :
11332      IF 'REAL' IN TYPEOF (v1) THEN  r := v1;  RETURN (ctmv(LOG10(r)));  END_IF;
11333    ef_sin_r :
11334      IF 'REAL' IN TYPEOF (v1) THEN  r := v1;  RETURN (ctmv(SIN(r)));  END_IF;
11335    ef_sqrt_r :
11336      IF 'REAL' IN TYPEOF (v1) THEN  r := v1;  RETURN (ctmv(SQRT(r)));  END_IF;
11337    ef_tan_r :
11338      IF 'REAL' IN TYPEOF (v1) THEN  r := v1;  RETURN (ctmv(TAN(r)));  END_IF;
11339    -- ef_if_r : combined with ef_if
11340    ef_form_c :
11341      IF ('REAL' IN TYPEOF (v1)) AND ('REAL' IN TYPEOF (v2)) THEN
11342        r := v1;  s := v2;  RETURN (makec(r,s));
11343      END_IF;
11344    ef_rpart_c :
11345      IF cnlit IN TYPEOF (v1) THEN
11346        RETURN (ctmv(v1\complex_number_literal.real_part));
11347      END_IF;
11348    ef_ipart_c :
11349      IF cnlit IN TYPEOF (v1) THEN
11350        RETURN (ctmv(v1\complex_number_literal.imag_part));
11351      END_IF;
11352    ef_negate_c :
11353      IF cnlit IN TYPEOF (v1) THEN  parts(v1,p,q);  RETURN (makec(-p,-q));  END_IF;
11354    ef_reciprocal_c :
11355      IF cnlit IN TYPEOF (v1) THEN
11356        parts(v1,p,q);  t := p*p + q*q;  RETURN (makec(p/t,-q/t));
11357      END_IF;
11358    ef_add_c : BEGIN
11359      p := 0.0;  q := 0.0;
11360      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11361        IF cnlit IN TYPEOF (vlist[i]) THEN
11362          parts(vlist[i],r,s);  p := p + r;  q := q + s;
11363          REMOVE (vlist, i);
11364        END_IF;
11365      END_REPEAT;
11366      IF SIZEOF (vlist) = 0 THEN  RETURN (makec(p,q));  END_IF;
11367      IF p*p+q*q <> 0.0 THEN  INSERT (vlist, makec(p,q), 0);  END_IF;
11368      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11369      END;
11370    ef_subtract_c :
11371      IF (cnlit IN TYPEOF (v1)) AND (cnlit IN TYPEOF (v2)) THEN
11372        parts(v1,p,q);  parts(v2,r,s);  RETURN (makec(p-r,q-s));
11373      END_IF;
11374    ef_multiply_c : BEGIN
11375      p := 1.0;  q := 0.0;
11376      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11377        IF cnlit IN TYPEOF (vlist[i]) THEN
11378          parts(vlist[i],r,s);  p := p*r-q*s;  q := p*s+q*r;
11379          REMOVE (vlist, i);
11380        END_IF;
11381      END_REPEAT;
11382      IF SIZEOF (vlist) = 0 THEN  RETURN (makec(p,q));  END_IF;
11383      IF (p <> 1.0) OR (q <> 0.0) THEN  INSERT (vlist, makec(p,q), 0);  END_IF;
11384      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11385      END;
11386    ef_divide_c :
11387      IF (cnlit IN TYPEOF (v1)) AND (cnlit IN TYPEOF (v2)) THEN
11388        parts(v1,p,q);  parts(v2,r,s);  t := r*r+s*s;
11389        RETURN (makec((p*r+q*s)/t,(q*r-p*s)/t));
11390      END_IF;
11391    ef_exponentiate_c :
11392      IF (cnlit IN TYPEOF (v1)) AND (cnlit IN TYPEOF (v2)) THEN
11393        parts(v1,p,q);  parts(v2,r,s);  t := 0.5*LOG(p*p+q*q);  u := atan2(q,p);
11394        p := r*t-s*u;  q := r*u+s*t;  r := EXP(p);
11395        RETURN (makec(r*COS(q),r*SIN(q)));
11396      END_IF;
11397    ef_exponentiate_ci :
11398      IF (cnlit IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11399        parts(v1,p,q);  k := v2;  r := 1.0;  s := 0.0;
11400        REPEAT i := 1 TO ABS(k);  r := p*r-q*s;  s := p*s+q*r;  END_REPEAT;
11401        IF k < 0 THEN  t := r*r+s*s;  r := r/t;  s := -s/t;  END_IF;
11402        RETURN (makec(r,s));
11403      END_IF;
11404    ef_eq_c :
11405      IF (cnlit IN TYPEOF (v1)) AND (cnlit IN TYPEOF (v2)) THEN
11406        parts(v1,p,q);  parts(v2,r,s);  RETURN (ctmv((p = r) AND (q = s)));
11407      END_IF;
11408    ef_ne_c :
11409      IF (cnlit IN TYPEOF (v1)) AND (cnlit IN TYPEOF (v2)) THEN
11410        parts(v1,p,q);  parts(v2,r,s);  RETURN (ctmv((p <> r) OR (q <> s)));
11411      END_IF;
11412    ef_conjugate_c :
11413      IF cnlit IN TYPEOF (v1) THEN  parts(v1,p,q);  RETURN (makec(p,-q));  END_IF;
11414    ef_abs_c :
11415      IF cnlit IN TYPEOF (v1) THEN
11416        parts(v1,p,q);  RETURN (ctmv(SQRT(p*p+q*q)));
11417      END_IF;
11418    ef_arg_c :
11419      IF cnlit IN TYPEOF (v1) THEN
11420        parts(v1,p,q);  RETURN (ctmv(atan2(q,p)));
11421      END_IF;
11422    ef_cos_c :
11423      IF cnlit IN TYPEOF (v1) THEN
11424        parts(v1,p,q);  t := 0.5*EXP(-q);  u := 0.5*EXP(q);
11425        RETURN (makec((t+u)*COS(p),(t-u)*SIN(p)));
11426      END_IF;
11427    ef_exp_c :
11428      IF cnlit IN TYPEOF (v1) THEN
11429        parts(v1,p,q);  RETURN (makec(EXP(p)*COS(q),EXP(p)*SIN(q)));
11430      END_IF;
11431    ef_ln_c :
11432      IF cnlit IN TYPEOF (v1) THEN
11433        parts(v1,p,q);  RETURN (makec(0.5*LOG(p*p+q*q),atan2(q,p)));
11434      END_IF;
11435    ef_sin_c :
11436      IF cnlit IN TYPEOF (v1) THEN
11437        parts(v1,p,q);  t := 0.5*EXP(-q);  u := 0.5*EXP(q);
11438        RETURN (makec((t+u)*SIN(p),(u-t)*COS(p)));
11439      END_IF;
11440    ef_sqrt_c :
11441      IF cnlit IN TYPEOF (v1) THEN
11442        parts(v1,p,q);  t := SQRT(SQRT(p*p+q*q));  u := 0.5*atan2(q,p);
11443        RETURN (makec(t*COS(u),t*SIN(u)));
11444      END_IF;
11445    ef_tan_c :
11446      IF cnlit IN TYPEOF (v1) THEN
11447        parts(v1,p,q);  t := EXP(2.0*q) + EXP(-2.0*q) + 2.0*COS(2.0*p);
11448        RETURN (makec(2.0*SIN(2.0*p)/t,(EXP(-2.0*q)-EXP(2.0*q))/t));
11449      END_IF;
11450    -- ef_if_c : combined with ef_if
11451    ef_subscript_s :
11452      IF ('STRING' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11453        str := v1;  k := v2;  RETURN (ctmv(str[k]));
11454      END_IF;
11455    ef_eq_s :
11456      IF ('STRING' IN TYPEOF (v1)) AND ('STRING' IN TYPEOF (v2)) THEN
11457        str := v1;  st2 := v2;  RETURN (ctmv(str = st2));
11458      END_IF;
11459    ef_ne_s :
11460      IF ('STRING' IN TYPEOF (v1)) AND ('STRING' IN TYPEOF (v2)) THEN
11461        str := v1;  st2 := v2;  RETURN (ctmv(str <> st2));
11462      END_IF;
11463    ef_gt_s :
11464      IF ('STRING' IN TYPEOF (v1)) AND ('STRING' IN TYPEOF (v2)) THEN
11465        str := v1;  st2 := v2;  RETURN (ctmv(str > st2));
11466      END_IF;
11467    ef_lt_s :
11468      IF ('STRING' IN TYPEOF (v1)) AND ('STRING' IN TYPEOF (v2)) THEN
11469        str := v1;  st2 := v2;  RETURN (ctmv(str < st2));
11470      END_IF;
11471    ef_ge_s :
11472      IF ('STRING' IN TYPEOF (v1)) AND ('STRING' IN TYPEOF (v2)) THEN
11473        str := v1;  st2 := v2;  RETURN (ctmv(str >= st2));
11474      END_IF;
11475    ef_le_s :
11476      IF ('STRING' IN TYPEOF (v1)) AND ('STRING' IN TYPEOF (v2)) THEN
11477        str := v1;  st2 := v2;  RETURN (ctmv(str <= st2));
11478      END_IF;
11479    ef_subsequence_s :
11480      IF ('STRING' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) AND
11481        ('INTEGER' IN TYPEOF (v3)) THEN
11482        str := v1;  j := v2;  k := v3;  RETURN (ctmv(str[j:k]));
11483      END_IF;
11484    ef_concat_s : BEGIN
11485      str := '';
11486      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11487        IF 'STRING' IN TYPEOF (vlist[i]) THEN
11488          st2 := vlist[i];  str := str + st2;
11489          REMOVE (vlist, i);
11490        ELSE IF str <> '' THEN
11491          INSERT (vlist, ctmv(str), i);
11492          str := '';
11493        END_IF;  END_IF;
11494      END_REPEAT;
11495      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(str));  END_IF;
11496      IF str <> '' THEN  INSERT (vlist, ctmv(str), 0);  END_IF;
11497      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11498      END;
11499    ef_size_s :
11500      IF 'STRING' IN TYPEOF (v1) THEN  str:=v1;  RETURN (ctmv(LENGTH(str)));  END_IF;
11501    ef_format :
11502      IF ('NUMBER' IN TYPEOF (v1)) AND ('STRING' IN TYPEOF (v2)) THEN
11503        RETURN (ctmv(FORMAT(v1,v2)));
11504      END_IF;
11505    ef_value :
11506      IF 'STRING' IN TYPEOF (v1) THEN  str:=v1;  RETURN (ctmv(VALUE(str)));  END_IF;
11507    ef_like :
11508      IF ('STRING' IN TYPEOF (v1)) AND ('STRING' IN TYPEOF (v2)) THEN
11509        RETURN (ctmv(v1 LIKE v2));
11510      END_IF;
11511    -- ef_if_s : combined with ef_if
11512    ef_subscript_b :
11513      IF ('BINARY' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11514        bin := v1;  k := v2;  RETURN (ctmv(bin[k]));
11515      END_IF;
11516    ef_eq_b :
11517      IF ('BINARY' IN TYPEOF (v1)) AND ('BINARY' IN TYPEOF (v2)) THEN
11518        bin := v1;  bi2 := v2;  RETURN (ctmv(bin = bi2));
11519      END_IF;
11520    ef_ne_b :
11521      IF ('BINARY' IN TYPEOF (v1)) AND ('BINARY' IN TYPEOF (v2)) THEN
11522        bin := v1;  bi2 := v2;  RETURN (ctmv(bin <> bi2));
11523      END_IF;
11524    ef_gt_b :
11525      IF ('BINARY' IN TYPEOF (v1)) AND ('BINARY' IN TYPEOF (v2)) THEN
11526        bin := v1;  bi2 := v2;  RETURN (ctmv(bin > bi2));
11527      END_IF;
11528    ef_lt_b :
11529      IF ('BINARY' IN TYPEOF (v1)) AND ('BINARY' IN TYPEOF (v2)) THEN
11530        bin := v1;  bi2 := v2;  RETURN (ctmv(bin < bi2));
11531      END_IF;
11532    ef_ge_b :
11533      IF ('BINARY' IN TYPEOF (v1)) AND ('BINARY' IN TYPEOF (v2)) THEN
11534        bin := v1;  bi2 := v2;  RETURN (ctmv(bin >= bi2));
11535      END_IF;
11536    ef_le_b :
11537      IF ('BINARY' IN TYPEOF (v1)) AND ('BINARY' IN TYPEOF (v2)) THEN
11538        bin := v1;  bi2 := v2;  RETURN (ctmv(bin <= bi2));
11539      END_IF;
11540    ef_subsequence_b :
11541      IF ('BINARY' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) AND
11542        ('INTEGER' IN TYPEOF (v3)) THEN
11543        bin := v1;  j := v2;  k := v3;  RETURN (ctmv(bin[j:k]));
11544      END_IF;
11545    ef_concat_b : BEGIN
11546      boo := FALSE;
11547      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11548        IF 'BINARY' IN TYPEOF (vlist[i]) THEN
11549          IF boo THEN  bi2 := vlist[i];  bin := bin + bi2;
11550          ELSE         bin := vlist[i];  boo := TRUE;  END_IF;
11551          REMOVE (vlist, i);
11552        ELSE IF boo THEN
11553          INSERT (vlist, ctmv(bin), i);
11554          boo := FALSE;
11555        END_IF;  END_IF;
11556      END_REPEAT;
11557      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(bin));  END_IF;
11558      IF boo THEN  INSERT (vlist, ctmv(bin), 0);  END_IF;
11559      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11560      END;
11561    ef_size_b :
11562      IF 'BINARY' IN TYPEOF (v1) THEN  bin:=v1;  RETURN (ctmv(BLENGTH(bin)));  END_IF;
11563    -- ef_if_b : combined with ef_if
11564    ef_subscript_t :
11565      IF ('LIST' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11566        tpl := v1;  k := v2;  RETURN (ctmv(tpl[k]));
11567      END_IF;
11568    ef_eq_t :
11569      IF ('LIST' IN TYPEOF (v1)) AND ('LIST' IN TYPEOF (v2)) THEN
11570        lgc := equal_maths_values(v1,v2);
11571        IF lgc <> UNKNOWN THEN  RETURN (ctmv(lgc));  END_IF;
11572      END_IF;
11573    ef_ne_t :
11574      IF ('LIST' IN TYPEOF (v1)) AND ('LIST' IN TYPEOF (v2)) THEN
11575        lgc := equal_maths_values(v1,v2);
11576        IF lgc <> UNKNOWN THEN  RETURN (ctmv(NOT lgc));  END_IF;
11577      END_IF;
11578    ef_concat_t : BEGIN
11579      tpl := [];
11580      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11581        IF 'STRING' IN TYPEOF (vlist[i]) THEN
11582          tp2 := vlist[i];  tpl := tpl + tp2;
11583          REMOVE (vlist, i);
11584        ELSE IF SIZEOF (tpl) <> 0 THEN
11585          INSERT (vlist, ctmv(tpl), i);
11586          tpl := [];
11587        END_IF;  END_IF;
11588      END_REPEAT;
11589      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(tpl));  END_IF;
11590      IF SIZEOF (tpl) <> 0 THEN  INSERT (vlist, ctmv(tpl), 0);  END_IF;
11591      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11592      END;
11593    ef_size_t :
11594      IF 'LIST' IN TYPEOF (v1) THEN  tpl:=v1;  RETURN (ctmv(SIZEOF(tpl)));  END_IF;
11595    ef_entuple :
11596      RETURN (ctmv(vlist));
11597    ef_detuple :  -- This can have multiple outputs, but the expression only
11598                  -- denotes the first.
11599      IF 'LIST' IN TYPEOF (v1) THEN  tpl:=v1;  RETURN (ctmv(tpl[1]));  END_IF;
11600    ef_insert :
11601      IF ('LIST' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v3)) THEN
11602        tpl := v1;  k := v3;  INSERT (tpl, v2, k);  RETURN (ctmv(tpl));
11603      END_IF;
11604    ef_remove :
11605      IF ('LIST' IN TYPEOF (v1)) AND ('INTEGER' IN TYPEOF (v2)) THEN
11606        tpl := v1;  k := v2;  REMOVE (tpl, k);  RETURN (ctmv(tpl));
11607      END_IF;
11608    -- ef_if_t : combined with ef_if
11609    ef_sum_it :
11610      IF good_t(v1,'INTEGER') THEN
11611        tpl := v1;  j := 0;
11612        REPEAT i := 1 TO SIZEOF (tpl);  j := j + tpl[i];  END_REPEAT;
11613        RETURN (ctmv(j));
11614      END_IF;
11615    ef_product_it :
11616      IF good_t(v1,'INTEGER') THEN
11617        tpl := v1;  j := 1;
11618        REPEAT i := 1 TO SIZEOF (tpl);  j := j * tpl[i];  END_REPEAT;
11619        RETURN (ctmv(j));
11620      END_IF;
11621    ef_add_it : BEGIN
11622      boo := FALSE;
11623      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11624        IF good_t(vlist[i],'INTEGER') THEN
11625          IF NOT boo THEN  tpl := vlist[i];  boo := TRUE;
11626          ELSE
11627            tp2 := vlist[i];
11628            IF SIZEOF (tpl) <> SIZEOF (tp2) THEN  RETURN (?);  END_IF;
11629            REPEAT l := 1 TO SIZEOF (tpl);  tpl[j] := tpl[j] + tp2[j];  END_REPEAT;
11630          END_IF;
11631          REMOVE (vlist, i);
11632        END_IF;
11633      END_REPEAT;
11634      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(tpl));  END_IF;
11635      IF boo THEN  INSERT (vlist, ctmv(tpl), 0);  END_IF;
11636      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11637      END;
11638    ef_subtract_it :
11639      IF good_t(v1,'INTEGER') AND good_t(v2,'INTEGER') THEN
11640        tpl := v1;  tp2 := v2;
11641        IF SIZEOF (tpl) <> SIZEOF (tp2) THEN  RETURN (?);  END_IF;
11642        REPEAT i := 1 TO SIZEOF (tpl);  tpl[i] := tpl[i] - tp2[i];  END_REPEAT;
11643        RETURN (ctmv(tpl));
11644      END_IF;
11645    ef_scalar_mult_it :
11646      IF ('INTEGER' IN TYPEOF (v1)) AND good_t(v2,'INTEGER') THEN
11647        j := v1;  tpl := v2;
11648        REPEAT i := 1 TO SIZEOF (tpl);  tpl[i] := j * tpl[i];  END_REPEAT;
11649        RETURN (ctmv(tpl));
11650      END_IF;
11651    ef_dot_prod_it :
11652      IF good_t(v1,'INTEGER') AND good_t(v2,'INTEGER') THEN
11653        tpl := v1;  tp2 := v2;  j := 0;
11654        IF SIZEOF (tpl) <> SIZEOF (tp2) THEN  RETURN (?);  END_IF;
11655        REPEAT i := 1 TO SIZEOF (tpl);  j := j + tpl[i] * tp2[i];  END_REPEAT;
11656        RETURN (ctmv(j));
11657      END_IF;
11658    ef_sum_rt :
11659      IF good_t(v1,'REAL') THEN
11660        tpl := v1;  r := 0.0;
11661        REPEAT i := 1 TO SIZEOF (tpl);  r := r + tpl[i];  END_REPEAT;
11662        RETURN (ctmv(r));
11663      END_IF;
11664    ef_product_rt :
11665      IF good_t(v1,'REAL') THEN
11666        tpl := v1;  r := 1.0;
11667        REPEAT i := 1 TO SIZEOF (tpl);  r := r * tpl[i];  END_REPEAT;
11668        RETURN (ctmv(r));
11669      END_IF;
11670    ef_add_rt : BEGIN
11671      boo := FALSE;
11672      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11673        IF good_t(vlist[i],'REAL') THEN
11674          IF NOT boo THEN  tpl := vlist[i];  boo := TRUE;
11675          ELSE
11676            tp2 := vlist[i];
11677            IF SIZEOF (tpl) <> SIZEOF (tp2) THEN  RETURN (?);  END_IF;
11678            REPEAT l := 1 TO SIZEOF (tpl);  tpl[j] := tpl[j] + tp2[j];  END_REPEAT;
11679          END_IF;
11680          REMOVE (vlist, i);
11681        END_IF;
11682      END_REPEAT;
11683      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(tpl));  END_IF;
11684      IF boo THEN  INSERT (vlist, ctmv(tpl), 0);  END_IF;
11685      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11686      END;
11687    ef_subtract_rt :
11688      IF good_t(v1,'REAL') AND good_t(v2,'REAL') THEN
11689        tpl := v1;  tp2 := v2;
11690        IF SIZEOF (tpl) <> SIZEOF (tp2) THEN  RETURN (?);  END_IF;
11691        REPEAT i := 1 TO SIZEOF (tpl);  tpl[i] := tpl[i] - tp2[i];  END_REPEAT;
11692        RETURN (ctmv(tpl));
11693      END_IF;
11694    ef_scalar_mult_rt :
11695      IF ('REAL' IN TYPEOF (v1)) AND good_t(v2,'REAL') THEN
11696        r := v1;  tpl := v2;
11697        REPEAT i := 1 TO SIZEOF (tpl);  tpl[i] := r * tpl[i];  END_REPEAT;
11698        RETURN (ctmv(tpl));
11699      END_IF;
11700    ef_dot_prod_rt :
11701      IF good_t(v1,'REAL') AND good_t(v2,'REAL') THEN
11702        tpl := v1;  tp2 := v2;  r := 0;
11703        IF SIZEOF (tpl) <> SIZEOF (tp2) THEN  RETURN (?);  END_IF;
11704        REPEAT i := 1 TO SIZEOF (tpl);  r := r + tpl[i] * tp2[i];  END_REPEAT;
11705        RETURN (ctmv(r));
11706      END_IF;
11707    ef_norm_rt :
11708      IF good_t(v1,'REAL') THEN
11709        tpl := v1;  r := 0.0;
11710        REPEAT i := 1 TO SIZEOF (tpl);  r := r + tpl[i]*tpl[i];  END_REPEAT;
11711        RETURN (ctmv(SQRT(r)));
11712      END_IF;
11713    ef_sum_ct :
11714      IF good_t(v1,cnlit) THEN
11715        tpl := v1;  p := 0.0;  q := 0.0;
11716        REPEAT i:=1 TO SIZEOF (tpl);  parts(tpl[i],r,s);  p:=p+r;  q:=q+s;  END_REPEAT;
11717        RETURN (makec(p,q));
11718      END_IF;
11719    ef_product_ct :
11720      IF good_t(v1,cnlit) THEN
11721        tpl := v1;  p := 1.0;  q := 0.0;
11722        REPEAT i := 1 TO SIZEOF (tpl);
11723         parts(tpl[i],r,s);  p := p*r-q*s;  q := p*s+q*r;
11724        END_REPEAT;
11725        RETURN (makec(p,q));
11726      END_IF;
11727    ef_add_ct : BEGIN
11728      boo := FALSE;
11729      REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11730        IF good_t(vlist[i],cnlit) THEN
11731          IF NOT boo THEN  tpl := vlist[i];  boo := TRUE;
11732          ELSE
11733            tp2 := vlist[i];
11734            IF SIZEOF (tpl) <> SIZEOF (tp2) THEN  RETURN (?);  END_IF;
11735            REPEAT l := 1 TO SIZEOF (tpl);
11736              parts(tpl[j],p,q); parts(tp2[j],r,s);  tpl[j] := makec(p+r,q+s);
11737            END_REPEAT;
11738          END_IF;
11739          REMOVE (vlist, i);
11740        END_IF;
11741      END_REPEAT;
11742      IF SIZEOF (vlist) = 0 THEN  RETURN (ctmv(tpl));  END_IF;
11743      IF boo THEN  INSERT (vlist, ctmv(tpl), 0);  END_IF;
11744      IF SIZEOF (vlist) = 1 THEN  RETURN (vlist[1]);  END_IF;
11745      END;
11746    ef_subtract_ct :
11747      IF good_t(v1,cnlit) AND good_t(v2,cnlit) THEN
11748        tpl := v1;  tp2 := v2;
11749        IF SIZEOF (tpl) <> SIZEOF (tp2) THEN  RETURN (?);  END_IF;
11750        REPEAT i := 1 TO SIZEOF (tpl);
11751          parts(tpl[i],p,q);  parts(tp2[i],r,s);  tpl[i] := makec(p-r,q-s);
11752        END_REPEAT;
11753        RETURN (ctmv(tpl));
11754      END_IF;
11755    ef_scalar_mult_ct :
11756      IF (cnlit IN TYPEOF (v1)) AND good_t(v2,cnlit) THEN
11757        parts(v1,p,q);  tpl := v2;
11758        REPEAT i := 1 TO SIZEOF (tpl);
11759          parts(tpl[i],r,s);  tpl[i] := makec(p*r-q*s,p*s+q*r);
11760        END_REPEAT;
11761        RETURN (ctmv(tpl));
11762      END_IF;
11763    ef_dot_prod_ct :
11764      IF good_t(v1,cnlit) AND good_t(v2,cnlit) THEN
11765        tpl := v1;  tp2 := v2;  t := 0.0;  u := 0.0;
11766        IF SIZEOF (tpl) <> SIZEOF (tp2) THEN  RETURN (?);  END_IF;
11767        REPEAT i := 1 TO SIZEOF (tpl);
11768          parts(tpl[i],p,q);  parts(tp2[i],r,s);  t := t + p*r+q*s;  u := u + q*r-p*s;
11769        END_REPEAT;
11770        RETURN (makec(t,u));
11771      END_IF;
11772    ef_norm_ct :
11773      IF good_t(v1,cnlit) THEN
11774        tpl := v1;  r := 0.0;
11775        REPEAT i := 1 TO SIZEOF (tpl);  parts(tpl[i],p,q);  r:=r+p*p+q*q;  END_REPEAT;
11776        RETURN (ctmv(SQRT(r)));
11777      END_IF;
11778    ef_if, ef_if_i, ef_if_r, ef_if_c, ef_if_s, ef_if_b, ef_if_t :
11779      IF 'LOGICAL' IN TYPEOF (v1) THEN
11780        lgc := v1;  IF lgc THEN  RETURN (v2);  ELSE  RETURN (v3);  END_IF;
11781      END_IF;
11782    ef_ensemble :   -- (mem + vlist) effectively converts list to set
11783      RETURN (make_finite_space(mem + vlist));
11784    ef_member_of :
11785      IF (schema_prefix + 'MATHS_SPACE') IN TYPEOF (v2) THEN
11786        lgc := member_of(v1,v2);
11787        IF lgc <> UNKNOWN THEN  RETURN (ctmv(lgc));  END_IF;
11788      END_IF;
11789    END_CASE;
11790    RETURN (make_function_application(expr.func,vlist));
11791  END_IF;
11792  IF 'ABSTRACTED_EXPRESSION_FUNCTION' IN types THEN
11793    gexpr := substitute(expr.func\abstracted_expression_function.expr,
11794      expr.func\quantifier_expression.variables,vlist);
11795    RETURN (simplify_generic_expression(gexpr));
11796  END_IF;
11797  IF 'FINITE_FUNCTION' IN types THEN
11798    pairs := expr.func\finite_function.pairs;
11799    REPEAT i := 1 TO SIZEOF (pairs);
11800      IF equal_maths_values(vlist[1],pairs[i][1]) THEN
11801        RETURN (simplify_maths_value(pairs[i][2]));
11802      END_IF;
11803    END_REPEAT;
11804    RETURN (make_function_application(expr.func,vlist));
11805  END_IF;
11806  RETURN (expr);
11807END_FUNCTION;  -- simplify_function_application
11808
11809   FUNCTION simplify_generic_expression(expr : generic_expression) : maths_value;
11810  FUNCTION restore_unary(expr : unary_generic_expression;
11811                         opnd : generic_expression) : generic_expression;
11812    expr.operand := opnd;
11813    RETURN (expr);
11814  END_FUNCTION;  -- restore_unary
11815  FUNCTION restore_binary(expr       : binary_generic_expression;
11816                          opd1, opd2 : generic_expression) : generic_expression;
11817    expr.operands[1] := opd1;
11818    expr.operands[2] := opd2;
11819    RETURN (expr);
11820  END_FUNCTION;  -- restore_binary
11821  FUNCTION restore_mulary(expr : multiple_arity_generic_expression;
11822                          ops  : LIST OF generic_expression) : generic_expression;
11823    expr.operands := ops;
11824    RETURN (expr);
11825  END_FUNCTION;  -- restore_mulary
11826
11827 FUNCTION make_number_literal(nmb : NUMBER) : generic_literal;
11828    IF 'INTEGER' IN TYPEOF (nmb) THEN  RETURN (make_int_literal(nmb));  END_IF;
11829    RETURN (make_real_literal(nmb));
11830  END_FUNCTION;  -- make_number_literal;
11831  LOCAL
11832    types : SET OF STRING := stripped_typeof (expr);
11833    v1, v2 : maths_value;
11834    vlist : LIST OF maths_value := [];
11835    op1, op2 : generic_expression;
11836    oplist : LIST OF generic_expression := [];
11837    opnds : LIST [2:?] OF generic_expression;
11838    n, m : INTEGER;
11839    finfun : maths_function_select;
11840    boo : BOOLEAN;
11841    str : STRING;
11842    nmb : NUMBER;
11843  END_LOCAL;
11844  -- Unwrap the elementary kinds of literals
11845  IF 'INT_LITERAL' IN types THEN
11846    RETURN (convert_to_maths_value (expr\int_literal.the_value));
11847  END_IF;
11848  IF 'REAL_LITERAL' IN types THEN
11849    RETURN (convert_to_maths_value (expr\real_literal.the_value));
11850  END_IF;
11851  IF 'BOOLEAN_LITERAL' IN types THEN
11852    RETURN (convert_to_maths_value (expr\boolean_literal.the_value));
11853  END_IF;
11854  IF 'STRING_LITERAL' IN types THEN
11855    RETURN (convert_to_maths_value (expr\string_literal.the_value));
11856  END_IF;
11857  IF 'COMPLEX_NUMBER_LITERAL' IN types THEN
11858    RETURN (expr);  -- No simpler expression available
11859  END_IF;
11860  IF 'LOGICAL_LITERAL' IN types THEN
11861    RETURN (convert_to_maths_value (expr\logical_literal.lit_value));
11862  END_IF;
11863  IF 'BINARY_LITERAL' IN types THEN
11864    RETURN (convert_to_maths_value (expr\binary_literal.lit_value));
11865  END_IF;
11866  IF 'MATHS_ENUM_LITERAL' IN types THEN
11867    RETURN (expr\maths_enum_literal.lit_value);
11868  END_IF;
11869  IF 'REAL_TUPLE_LITERAL' IN types THEN
11870    RETURN (convert_to_maths_value (expr\real_tuple_literal.lit_value));
11871  END_IF;
11872  IF 'INTEGER_TUPLE_LITERAL' IN types THEN
11873    RETURN (convert_to_maths_value (expr\integer_tuple_literal.lit_value));
11874  END_IF;
11875  IF 'ATOM_BASED_LITERAL' IN types THEN
11876    RETURN (expr\atom_based_literal.lit_value);
11877  END_IF;
11878  IF 'MATHS_TUPLE_LITERAL' IN types THEN
11879    RETURN (convert_to_maths_value (expr\maths_tuple_literal.lit_value));
11880  END_IF;
11881  -- Simplify one special class of literals
11882  IF 'MATHS_SPACE' IN types THEN
11883    RETURN (simplify_maths_space(expr));
11884  END_IF;
11885  -- Simplify one special kind of expression
11886  IF 'FUNCTION_APPLICATION' IN types THEN
11887    RETURN (simplify_function_application(expr));
11888  END_IF;
11889  -- Separate and simplify the operands
11890  IF 'UNARY_GENERIC_EXPRESSION' IN types THEN
11891    v1 := simplify_generic_expression(expr\unary_generic_expression.operand);
11892    op1 := convert_to_operand(v1);
11893  END_IF;
11894  IF 'BINARY_GENERIC_EXPRESSION' IN types THEN
11895    v1 := simplify_generic_expression(expr\binary_generic_expression.operands[1]);
11896    op1 := convert_to_operand(v1);
11897    v2 := simplify_generic_expression(expr\binary_generic_expression.operands[2]);
11898    op2 := convert_to_operand(v2);
11899  END_IF;
11900  IF 'MULTIPLE_ARITY_GENERIC_EXPRESSION' IN types THEN
11901    opnds := expr\multiple_arity_generic_expression.operands;
11902    REPEAT i := 1 TO SIZEOF (opnds);
11903      v1 := simplify_generic_expression(opnds[i]);
11904      INSERT (vlist, v1, i-1);
11905      INSERT (oplist, convert_to_operand(v1), i-1);
11906    END_REPEAT;
11907  END_IF;
11908  -- Simplify the one kind of maths_function which derives its operands.
11909  IF 'PARALLEL_COMPOSED_FUNCTION' IN types THEN
11910    v1 := vlist[1];
11911    n := SIZEOF (vlist);
11912    finfun := vlist[n];
11913    REMOVE (vlist, n);
11914    REMOVE (vlist, 1);
11915    RETURN (make_parallel_composed_function(v1,vlist,finfun));
11916  END_IF;
11917  -- Simplify individual kinds of expressions.  It is not necessary to cover all cases.
11918  IF ('ABS_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
11919    RETURN (convert_to_maths_value (ABS(v1)));
11920  END_IF;
11921  IF ('ACOS_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
11922    RETURN (convert_to_maths_value (ACOS(v1)));
11923  END_IF;
11924  IF 'AND_EXPRESSION' IN types THEN
11925    REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11926      IF 'BOOLEAN' IN TYPEOF (vlist[i]) THEN
11927        boo := vlist[i];
11928        IF NOT boo THEN  RETURN (convert_to_maths_value(FALSE));  END_IF;
11929        REMOVE (oplist, i);
11930      END_IF;
11931    END_REPEAT;
11932    IF SIZEOF (oplist) = 0 THEN  RETURN (convert_to_maths_value(TRUE));  END_IF;
11933    IF SIZEOF (oplist) = 1 THEN  RETURN (oplist[1]);  END_IF;
11934  END_IF;
11935  IF ('ASIN_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
11936    RETURN (convert_to_maths_value (ASIN(v1)));
11937  END_IF;
11938  IF ('ATAN_EXPRESSION' IN types) AND
11939    ('NUMBER' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2)) THEN
11940    RETURN (convert_to_maths_value (ATAN(v1,v2)));
11941  END_IF;
11942  IF ('COMPARISON_EXPRESSION' IN types) AND (
11943    (('NUMBER' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2))) OR
11944    (('STRING' IN TYPEOF (v1)) AND ('STRING' IN TYPEOF (v2))) OR
11945    (('BOOLEAN' IN TYPEOF (v1)) AND ('BOOLEAN' IN TYPEOF (v2))) ) THEN
11946    IF      'COMPARISON_EQUAL'         IN types THEN  boo := bool(v1 = v2);
11947    ELSE IF 'COMPARISON_GREATER'       IN types THEN  boo := bool(v1 > v2);
11948    ELSE IF 'COMPARISON_GREATER_EQUAL' IN types THEN  boo := bool(v1 >= v2);
11949    ELSE IF 'COMPARISON_LESS'          IN types THEN  boo := bool(v1 < v2);
11950    ELSE IF 'COMPARISON_LESS_EQUAL'    IN types THEN  boo := bool(v1 <= v2);
11951    ELSE IF 'COMPARISON_NOT_EQUAL'     IN types THEN  boo := bool(v1 <> v2);
11952    ELSE IF 'LIKE_EXPRESSION'          IN types THEN  boo := bool(v1 LIKE v2);
11953    ELSE  RETURN (?);  -- Unreachable
11954    END_IF;  END_IF;  END_IF;  END_IF;  END_IF;  END_IF;  END_IF;
11955    RETURN (convert_to_maths_value (boo));
11956  END_IF;
11957  IF 'CONCAT_EXPRESSION' IN types THEN
11958    str := '';
11959    REPEAT i := SIZEOF (vlist) TO 1 BY -1;
11960      IF 'STRING' IN TYPEOF (vlist[i]) THEN
11961        str := vlist[i] + str;
11962        REMOVE (oplist, i);
11963      ELSE IF LENGTH(str) > 0 THEN
11964        INSERT (oplist, make_string_literal(str), i);
11965        str := '';
11966      END_IF;  END_IF;
11967    END_REPEAT;
11968    IF SIZEOF (oplist) = 0 THEN  RETURN (convert_to_maths_value(str));  END_IF;
11969    IF LENGTH(str) > 0 THEN  INSERT (oplist, make_string_literal(str), 0);  END_IF;
11970    IF SIZEOF (oplist) = 1 THEN  RETURN (oplist[1]);  END_IF;
11971  END_IF;
11972  IF ('COS_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
11973    RETURN (convert_to_maths_value (COS(v1)));
11974  END_IF;
11975  IF ('DIV_EXPRESSION' IN types) AND
11976    ('NUMBER' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2)) THEN
11977    RETURN (convert_to_maths_value (v1 DIV v2));
11978  END_IF;
11979  IF 'EQUALS_EXPRESSION' IN types THEN
11980    opnds := expr\binary_generic_expression.operands;
11981    RETURN (convert_to_maths_value (opnds[1] :=: opnds[2]));
11982  END_IF;
11983  IF ('EXP_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
11984    RETURN (convert_to_maths_value (EXP(v1)));
11985  END_IF;
11986  IF ('FORMAT_EXPRESSION' IN types) AND
11987    ('NUMBER' IN TYPEOF (v1)) AND ('STRING' IN TYPEOF (v2)) THEN
11988    RETURN (convert_to_maths_value (FORMAT(v1,v2)));
11989  END_IF;
11990  IF ('INDEX_EXPRESSION' IN types) AND
11991    ('STRING' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2)) THEN
11992    str := v1;  n := v2;
11993    RETURN (convert_to_maths_value (str[n]));
11994  END_IF;
11995  IF ('INT_VALUE_EXPRESSION' IN types) AND ('STRING' IN TYPEOF (v1)) THEN
11996    RETURN (convert_to_maths_value (VALUE(v1)));
11997  END_IF;
11998  IF 'INTERVAL_EXPRESSION' IN types THEN
11999    str := '';
12000    IF 'NUMBER'  IN TYPEOF (vlist[1]) THEN str := 'NUMBER';   END_IF;
12001    IF 'STRING'  IN TYPEOF (vlist[1]) THEN str := 'STRING';   END_IF;
12002    IF 'BOOLEAN' IN TYPEOF (vlist[1]) THEN str := 'BOOLEAN';  END_IF;
12003    IF (LENGTH (str) > 0) AND (str IN TYPEOF (vlist[2])) AND
12004      (str IN TYPEOF (vlist[3])) THEN
12005      RETURN (convert_to_maths_value ({vlist[1] <= vlist[2] <= vlist[3]}));
12006    END_IF;
12007  END_IF;
12008  IF ('LENGTH_EXPRESSION' IN types) AND ('STRING' IN TYPEOF (v1)) THEN
12009    RETURN (convert_to_maths_value (LENGTH(v1)));
12010  END_IF;
12011  IF ('LOG_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
12012    RETURN (convert_to_maths_value (LOG(v1)));
12013  END_IF;
12014  IF ('LOG10_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
12015    RETURN (convert_to_maths_value (LOG10(v1)));
12016  END_IF;
12017  IF ('LOG2_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
12018    RETURN (convert_to_maths_value (LOG2(v1)));
12019  END_IF;
12020  IF 'MAXIMUM_EXPRESSION' IN types THEN
12021    boo := FALSE;
12022    REPEAT i := SIZEOF (vlist) TO 1 BY -1;
12023      IF 'NUMBER' IN TYPEOF (vlist[i]) THEN
12024        IF boo THEN
12025          IF nmb < vlist[i] THEN  nmb := vlist[i];  END_IF;
12026        ELSE
12027          nmb := vlist[i];  boo := TRUE;
12028        END_IF;
12029        REMOVE (oplist, i);
12030      END_IF;
12031    END_REPEAT;
12032    IF SIZEOF (oplist) = 0 THEN  RETURN (convert_to_maths_value(nmb));  END_IF;
12033    IF boo THEN  INSERT (oplist, make_number_literal(nmb), 0);  END_IF;
12034  END_IF;
12035  IF 'MINIMUM_EXPRESSION' IN types THEN
12036    boo := FALSE;
12037    REPEAT i := SIZEOF (vlist) TO 1 BY -1;
12038      IF 'NUMBER' IN TYPEOF (vlist[i]) THEN
12039        IF boo THEN
12040          IF nmb > vlist[i] THEN  nmb := vlist[i];  END_IF;
12041        ELSE
12042          nmb := vlist[i];  boo := TRUE;
12043        END_IF;
12044        REMOVE (oplist, i);
12045      END_IF;
12046    END_REPEAT;
12047    IF SIZEOF (oplist) = 0 THEN  RETURN (convert_to_maths_value(nmb));  END_IF;
12048    IF boo THEN  INSERT (oplist, make_number_literal(nmb), 0);  END_IF;
12049  END_IF;
12050  IF ('MINUS_EXPRESSION' IN types) AND
12051    ('NUMBER' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2)) THEN
12052    RETURN (convert_to_maths_value (v1 - v2));
12053  END_IF;
12054  IF ('MOD_EXPRESSION' IN types) AND
12055    ('NUMBER' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2)) THEN
12056    RETURN (convert_to_maths_value (v1 MOD v2));
12057  END_IF;
12058  IF 'MULT_EXPRESSION' IN types THEN
12059    nmb := 1;
12060    REPEAT i := SIZEOF (vlist) TO 1 BY -1;
12061      IF 'NUMBER' IN TYPEOF (vlist[i]) THEN
12062        nmb := nmb * vlist[i];
12063        REMOVE (oplist, i);
12064      END_IF;
12065    END_REPEAT;
12066    IF SIZEOF (oplist) = 0 THEN  RETURN (convert_to_maths_value(nmb));  END_IF;
12067    IF nmb <> 1 THEN  INSERT (oplist, make_number_literal(nmb), 0);  END_IF;
12068    IF SIZEOF (oplist) = 1 THEN  RETURN (oplist[1]);  END_IF;
12069  END_IF;
12070  IF ('NOT_EXPRESSION' IN types) AND ('BOOLEAN' IN TYPEOF (v1)) THEN
12071    boo := v1;
12072    RETURN (convert_to_maths_value (NOT(boo)));
12073  END_IF;
12074  IF ('ODD_EXPRESSION' IN types) AND ('INTEGER' IN TYPEOF (v1)) THEN
12075    RETURN (convert_to_maths_value (ODD(v1)));
12076  END_IF;
12077  IF 'OR_EXPRESSION' IN types THEN
12078    REPEAT i := SIZEOF (vlist) TO 1 BY -1;
12079      IF 'BOOLEAN' IN TYPEOF (vlist[i]) THEN
12080        boo := vlist[i];
12081        IF boo THEN  RETURN (convert_to_maths_value(TRUE));  END_IF;
12082        REMOVE (oplist, i);
12083      END_IF;
12084    END_REPEAT;
12085    IF SIZEOF (oplist) = 0 THEN  RETURN (convert_to_maths_value(FALSE));  END_IF;
12086    IF SIZEOF (oplist) = 1 THEN  RETURN (oplist[1]);  END_IF;
12087  END_IF;
12088  IF 'PLUS_EXPRESSION' IN types THEN
12089    nmb := 0;
12090    REPEAT i := SIZEOF (vlist) TO 1 BY -1;
12091      IF 'NUMBER' IN TYPEOF (vlist[i]) THEN
12092        nmb := nmb + vlist[i];
12093        REMOVE (oplist, i);
12094      END_IF;
12095    END_REPEAT;
12096    IF SIZEOF (oplist) = 0 THEN  RETURN (convert_to_maths_value(nmb));  END_IF;
12097    IF nmb <> 0 THEN  INSERT (oplist, make_number_literal(nmb), 0);  END_IF;
12098    IF SIZEOF (oplist) = 1 THEN  RETURN (oplist[1]);  END_IF;
12099  END_IF;
12100  IF ('POWER_EXPRESSION' IN types) AND
12101    ('NUMBER' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2)) THEN
12102    RETURN (convert_to_maths_value (v1 ** v2));
12103  END_IF;
12104  IF ('SIN_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
12105    RETURN (convert_to_maths_value (SIN(v1)));
12106  END_IF;
12107  IF ('SLASH_EXPRESSION' IN types) AND
12108    ('NUMBER' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2)) THEN
12109    RETURN (convert_to_maths_value (v1 / v2));
12110  END_IF;
12111  IF ('SQUARE_ROOT_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
12112    RETURN (convert_to_maths_value (SQRT(v1)));
12113  END_IF;
12114  IF ('SUBSTRING_EXPRESSION' IN types) AND
12115    ('STRING' IN TYPEOF (vlist[1])) AND ('NUMBER' IN TYPEOF (vlist[2])) AND
12116    ('NUMBER' IN TYPEOF (vlist[3])) THEN
12117    str := vlist[1];  n := vlist[2];  m := vlist[3];
12118    RETURN (convert_to_maths_value (str[n:m]));
12119  END_IF;
12120  IF ('TAN_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
12121    RETURN (convert_to_maths_value (TAN(v1)));
12122  END_IF;
12123  IF ('UNARY_MINUS_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
12124    nmb := v1;
12125    RETURN (convert_to_maths_value (-nmb));
12126  END_IF;
12127  IF ('VALUE_EXPRESSION' IN types) AND ('STRING' IN TYPEOF (v1)) THEN
12128    RETURN (convert_to_maths_value (VALUE(v1)));
12129  END_IF;
12130  IF ('XOR_EXPRESSION' IN types) AND
12131    ('BOOLEAN' IN TYPEOF (v1)) AND ('BOOLEAN' IN TYPEOF (v2)) THEN
12132    RETURN (convert_to_maths_value (v1 XOR v2));
12133  END_IF;
12134  -- No special simplification defined, return same with simplified operands.
12135  IF 'UNARY_GENERIC_EXPRESSION' IN types THEN
12136    RETURN (restore_unary(expr,op1));
12137  END_IF;
12138  IF 'BINARY_GENERIC_EXPRESSION' IN types THEN
12139    RETURN (restore_binary(expr,op1,op2));
12140  END_IF;
12141  IF 'MULTIPLE_ARITY_GENERIC_EXPRESSION' IN types THEN
12142    RETURN (restore_mulary(expr,oplist));
12143  END_IF;
12144  -- Should be unreachable, but for safety, return unsimplified expression.
12145  RETURN (expr);
12146END_FUNCTION;  -- simplify_generic_expression
12147
12148   FUNCTION simplify_maths_space
12149      (spc : maths_space ) : maths_space;
12150   LOCAL
12151      stypes : SET OF STRING := stripped_typeof(spc);
12152      sset : SET OF maths_value;
12153      zset : SET OF maths_value := [];
12154      zval : maths_value;
12155      zspc : maths_space;
12156      zallint : BOOLEAN := TRUE;
12157      zint : INTEGER;
12158      zmin : INTEGER;
12159      zmax : INTEGER;
12160      factors : LIST OF maths_space;
12161      zfactors : LIST OF maths_space := [];
12162      rspc : maths_space;
12163   END_LOCAL;
12164      IF 'FINITE_SPACE' IN stypes THEN
12165         sset := spc\finite_space.members;
12166         REPEAT i := 1 TO SIZEOF(sset);
12167            zval := simplify_maths_value(sset[i]);
12168            zset := zset + [ zval ];
12169            IF zallint AND ('INTEGER' IN TYPEOF(zval)) THEN
12170               zint := zval;
12171               IF i = 1 THEN
12172                  zmin := zint;
12173                  zmax := zint;
12174               ELSE
12175                  IF zint < zmin THEN
12176                     zmin := zint;
12177                  END_IF;
12178                  IF zint > zmax THEN
12179                     zmax := zint;
12180                  END_IF;
12181               END_IF;
12182            ELSE
12183               zallint := FALSE;
12184            END_IF;
12185         END_REPEAT;
12186         IF zallint AND (SIZEOF(zset) = zmax - zmin + 1) THEN
12187            RETURN (make_finite_integer_interval(zmin, zmax));
12188         END_IF;
12189         RETURN (make_finite_space(zset));
12190      END_IF;
12191      IF 'UNIFORM_PRODUCT_SPACE' IN stypes THEN
12192         zspc := simplify_maths_space(spc\uniform_product_space.base);
12193         RETURN (make_uniform_product_space(zspc, spc\uniform_product_space.exponent));
12194      END_IF;
12195      IF 'LISTED_PRODUCT_SPACE' IN stypes THEN
12196         factors := spc\listed_product_space.factors;
12197         REPEAT i := 1 TO SIZEOF(factors);
12198            INSERT( zfactors, simplify_maths_space(factors[i]), i - 1 );
12199         END_REPEAT;
12200         RETURN (make_listed_product_space(zfactors));
12201      END_IF;
12202      IF 'EXTENDED_TUPLE_SPACE' IN stypes THEN
12203         zspc := simplify_maths_space(spc\extended_tuple_space.base);
12204         rspc := simplify_maths_space(spc\extended_tuple_space.extender);
12205         RETURN (make_extended_tuple_space(zspc, rspc));
12206      END_IF;
12207      IF 'FUNCTION_SPACE' IN stypes THEN
12208         zspc := simplify_maths_space(spc\function_space.domain_argument);
12209         rspc := simplify_maths_space(spc\function_space.range_argument);
12210         RETURN (make_function_space(spc\function_space.domain_constraint, zspc, spc\function_space.range_constraint, rspc));
12211      END_IF;
12212      RETURN (spc);
12213   END_FUNCTION;
12214
12215   FUNCTION simplify_maths_value
12216      (val : maths_value ) : maths_value;
12217   LOCAL
12218      vtypes : SET OF STRING := stripped_typeof(val);
12219      vlist : LIST OF maths_value;
12220      nlist : LIST OF maths_value := [];
12221   END_LOCAL;
12222      IF 'GENERIC_EXPRESSION' IN vtypes THEN
12223         RETURN (simplify_generic_expression(val));
12224      END_IF;
12225      IF 'LIST' IN vtypes THEN
12226         vlist := val;
12227         REPEAT i := 1 TO SIZEOF(vlist);
12228            INSERT( nlist, simplify_maths_value(vlist[i]), i - 1 );
12229         END_REPEAT;
12230         RETURN (convert_to_maths_value(nlist));
12231      END_IF;
12232      RETURN (val);
12233   END_FUNCTION;
12234
12235   FUNCTION singleton_member_of
12236      (spc : maths_space ) : maths_value;
12237   LOCAL
12238      types : SET OF STRING := stripped_typeof(spc);
12239   END_LOCAL;
12240      IF 'FINITE_SPACE' IN types THEN
12241         IF SIZEOF(spc\finite_space.members) = 1 THEN
12242            RETURN (spc\finite_space.members[1]);
12243         END_IF;
12244         RETURN (?);
12245      END_IF;
12246      IF 'FINITE_INTEGER_INTERVAL' IN types THEN
12247         IF spc\finite_integer_interval.size = 1 THEN
12248            RETURN (spc\finite_integer_interval.min);
12249         END_IF;
12250         RETURN (?);
12251      END_IF;
12252      RETURN (?);
12253   END_FUNCTION;
12254
12255   FUNCTION space_dimension
12256      (tspace : tuple_space ) : nonnegative_integer;
12257   LOCAL
12258      types : SET OF STRING := TYPEOF(tspace);
12259   END_LOCAL;
12260      IF schema_prefix + 'UNIFORM_PRODUCT_SPACE' IN types THEN
12261         RETURN (tspace\uniform_product_space.exponent);
12262      END_IF;
12263      IF schema_prefix + 'LISTED_PRODUCT_SPACE' IN types THEN
12264         RETURN (SIZEOF(tspace\listed_product_space.factors));
12265      END_IF;
12266      IF schema_prefix + 'EXTENDED_TUPLE_SPACE' IN types THEN
12267         RETURN (space_dimension(tspace\extended_tuple_space.base));
12268      END_IF;
12269      RETURN (?);
12270   END_FUNCTION;
12271
12272   FUNCTION space_is_continuum
12273      (space : maths_space ) : BOOLEAN;
12274   LOCAL
12275      typenames : SET OF STRING := TYPEOF(space);
12276      factors : LIST OF maths_space;
12277   END_LOCAL;
12278      IF NOT EXISTS(space) THEN
12279         RETURN (FALSE);
12280      END_IF;
12281      IF subspace_of_es(space, es_reals) OR subspace_of_es(space, es_complex_numbers) THEN
12282         RETURN (TRUE);
12283      END_IF;
12284      IF schema_prefix + 'UNIFORM_PRODUCT_SPACE' IN typenames THEN
12285         RETURN (space_is_continuum(space\uniform_product_space.base));
12286      END_IF;
12287      IF schema_prefix + 'LISTED_PRODUCT_SPACE' IN typenames THEN
12288         factors := space\listed_product_space.factors;
12289         IF SIZEOF(factors) = 0 THEN
12290            RETURN (FALSE);
12291         END_IF;
12292         REPEAT i := 1 TO SIZEOF(factors);
12293            IF NOT space_is_continuum(factors[i]) THEN
12294               RETURN (FALSE);
12295            END_IF;
12296         END_REPEAT;
12297         RETURN (TRUE);
12298      END_IF;
12299      RETURN (FALSE);
12300   END_FUNCTION;
12301
12302   FUNCTION space_is_singleton
12303      (spc : maths_space ) : BOOLEAN;
12304   LOCAL
12305      types : SET OF STRING := stripped_typeof(spc);
12306   END_LOCAL;
12307      IF 'FINITE_SPACE' IN types THEN
12308         RETURN (bool(SIZEOF(spc\finite_space.members) = 1));
12309      END_IF;
12310      IF 'FINITE_INTEGER_INTERVAL' IN types THEN
12311         RETURN (bool(spc\finite_integer_interval.size = 1));
12312      END_IF;
12313      RETURN (FALSE);
12314   END_FUNCTION;
12315
12316   FUNCTION stripped_typeof(arg : GENERIC:G) : SET OF STRING;
12317  LOCAL
12318    types : SET OF STRING := TYPEOF (arg);
12319    stypes : SET OF STRING := [];
12320    n : INTEGER := LENGTH (schema_prefix);
12321  END_LOCAL;
12322  REPEAT i := 1 TO SIZEOF (types);
12323    IF types[i][1:n] = schema_prefix THEN
12324       stypes := stypes + [types[i][n+1:LENGTH(types[i])]];
12325    ELSE
12326       stypes := stypes + [types[i]];
12327    END_IF;
12328  END_REPEAT;
12329  RETURN (stypes);
12330END_FUNCTION;  -- stripped_typeof
12331
12332   FUNCTION subspace_of
12333      (space1 : maths_space;
12334       space2 : maths_space ) : LOGICAL;
12335   LOCAL
12336      spc1 : maths_space := simplify_maths_space(space1);
12337      spc2 : maths_space := simplify_maths_space(space2);
12338      types1 : SET OF STRING := stripped_typeof(spc1);
12339      types2 : SET OF STRING := stripped_typeof(spc2);
12340      lgcl : LOGICAL;
12341      cum : LOGICAL;
12342      es_val : elementary_space_enumerators;
12343      bnd1 : REAL;
12344      bnd2 : REAL;
12345      n : INTEGER;
12346      sp1 : maths_space;
12347      sp2 : maths_space;
12348      prgn1 : polar_complex_number_region;
12349      prgn2 : polar_complex_number_region;
12350      aitv : finite_real_interval;
12351   END_LOCAL;
12352      IF NOT EXISTS(spc1) OR NOT EXISTS(spc2) THEN
12353         RETURN (FALSE);
12354      END_IF;
12355      IF spc2 = the_generics THEN
12356         RETURN (TRUE);
12357      END_IF;
12358      IF 'ELEMENTARY_SPACE' IN types1 THEN
12359         IF NOT ('ELEMENTARY_SPACE' IN types2) THEN
12360            RETURN (FALSE);
12361         END_IF;
12362         es_val := spc2\elementary_space.space_id;
12363         IF spc1\elementary_space.space_id = es_val THEN
12364            RETURN (TRUE);
12365         END_IF;
12366         CASE spc1\elementary_space.space_id OF
12367            es_numbers :
12368                  RETURN (FALSE);
12369            es_complex_numbers :
12370                  RETURN (es_val = es_numbers);
12371            es_reals :
12372                  RETURN (es_val = es_numbers);
12373            es_integers :
12374                  RETURN (es_val = es_numbers);
12375            es_logicals :
12376                  RETURN (FALSE);
12377            es_booleans :
12378                  RETURN (es_val = es_logicals);
12379            es_strings :
12380                  RETURN (FALSE);
12381            es_binarys :
12382                  RETURN (FALSE);
12383            es_maths_spaces :
12384                  RETURN (FALSE);
12385            es_maths_functions :
12386                  RETURN (FALSE);
12387            es_generics :
12388                  RETURN (FALSE);
12389         END_CASE;
12390         RETURN (UNKNOWN);
12391      END_IF;
12392      IF 'FINITE_INTEGER_INTERVAL' IN types1 THEN
12393         cum := TRUE;
12394         REPEAT i := spc1\finite_integer_interval.min TO spc1\finite_integer_interval.max;
12395            cum := cum AND member_of(i, spc2);
12396            IF cum = FALSE THEN
12397               RETURN (FALSE);
12398            END_IF;
12399         END_REPEAT;
12400         RETURN (cum);
12401      END_IF;
12402      IF 'INTEGER_INTERVAL_FROM_MIN' IN types1 THEN
12403         IF 'ELEMENTARY_SPACE' IN types2 THEN
12404            es_val := spc2\elementary_space.space_id;
12405            RETURN ((es_val = es_numbers) OR (es_val = es_integers));
12406         END_IF;
12407         IF 'INTEGER_INTERVAL_FROM_MIN' IN types2 THEN
12408            RETURN (spc1\integer_interval_from_min.min >= spc2\integer_interval_from_min.min);
12409         END_IF;
12410         RETURN (FALSE);
12411      END_IF;
12412      IF 'INTEGER_INTERVAL_TO_MAX' IN types1 THEN
12413         IF 'ELEMENTARY_SPACE' IN types2 THEN
12414            es_val := spc2\elementary_space.space_id;
12415            RETURN ((es_val = es_numbers) OR (es_val = es_integers));
12416         END_IF;
12417         IF 'INTEGER_INTERVAL_TO_MAX' IN types2 THEN
12418            RETURN (spc1\integer_interval_to_max.max <= spc2\integer_interval_to_max.max);
12419         END_IF;
12420         RETURN (FALSE);
12421      END_IF;
12422      IF 'FINITE_REAL_INTERVAL' IN types1 THEN
12423         IF 'ELEMENTARY_SPACE' IN types2 THEN
12424            es_val := spc2\elementary_space.space_id;
12425            RETURN ((es_val = es_numbers) OR (es_val = es_reals));
12426         END_IF;
12427         IF (('FINITE_REAL_INTERVAL' IN types2) OR ('REAL_INTERVAL_FROM_MIN' IN types2)) OR ('REAL_INTERVAL_TO_MAX' IN types2) THEN
12428            IF min_exists(spc2) THEN
12429               bnd1 := spc1\finite_real_interval.min;
12430               bnd2 := real_min(spc2);
12431               IF (bnd1 < bnd2) OR ((bnd1 = bnd2) AND min_included(spc1)) AND NOT min_included(spc2) THEN
12432                  RETURN (FALSE);
12433               END_IF;
12434            END_IF;
12435            IF max_exists(spc2) THEN
12436               bnd1 := spc1\finite_real_interval.max;
12437               bnd2 := real_max(spc2);
12438               IF (bnd1 > bnd2) OR ((bnd1 = bnd2) AND max_included(spc1)) AND NOT max_included(spc2) THEN
12439                  RETURN (FALSE);
12440               END_IF;
12441            END_IF;
12442            RETURN (TRUE);
12443         END_IF;
12444         RETURN (FALSE);
12445      END_IF;
12446      IF 'REAL_INTERVAL_FROM_MIN' IN types1 THEN
12447         IF 'ELEMENTARY_SPACE' IN types2 THEN
12448            es_val := spc2\elementary_space.space_id;
12449            RETURN ((es_val = es_numbers) OR (es_val = es_reals));
12450         END_IF;
12451         IF 'REAL_INTERVAL_FROM_MIN' IN types2 THEN
12452            bnd1 := spc1\real_interval_from_min.min;
12453            bnd2 := spc2\real_interval_from_min.min;
12454            RETURN ((bnd2 < bnd1) OR (bnd2 = bnd1) AND (min_included(spc2) OR NOT min_included(spc1)));
12455         END_IF;
12456         RETURN (FALSE);
12457      END_IF;
12458      IF 'REAL_INTERVAL_TO_MAX' IN types1 THEN
12459         IF 'ELEMENTARY_SPACE' IN types2 THEN
12460            es_val := spc2\elementary_space.space_id;
12461            RETURN ((es_val = es_numbers) OR (es_val = es_reals));
12462         END_IF;
12463         IF 'REAL_INTERVAL_TO_MAX' IN types2 THEN
12464            bnd1 := spc1\real_interval_to_max.max;
12465            bnd2 := spc2\real_interval_to_max.max;
12466            RETURN ((bnd2 > bnd1) OR (bnd2 = bnd1) AND (max_included(spc2) OR NOT max_included(spc1)));
12467         END_IF;
12468         RETURN (FALSE);
12469      END_IF;
12470      IF 'CARTESIAN_COMPLEX_NUMBER_REGION' IN types1 THEN
12471         IF 'ELEMENTARY_SPACE' IN types2 THEN
12472            es_val := spc2\elementary_space.space_id;
12473            RETURN ((es_val = es_numbers) OR (es_val = es_complex_numbers));
12474         END_IF;
12475         IF 'CARTESIAN_COMPLEX_NUMBER_REGION' IN types2 THEN
12476            RETURN (subspace_of(spc1\cartesian_complex_number_region.real_constraint, spc2\cartesian_complex_number_region.real_constraint) AND subspace_of(spc1\cartesian_complex_number_region.imag_constraint, spc2\cartesian_complex_number_region.imag_constraint));
12477         END_IF;
12478         IF 'POLAR_COMPLEX_NUMBER_REGION' IN types2 THEN
12479            RETURN (subspace_of(enclose_cregion_in_pregion(spc1, spc2\polar_complex_number_region.centre), spc2));
12480         END_IF;
12481         RETURN (FALSE);
12482      END_IF;
12483      IF 'POLAR_COMPLEX_NUMBER_REGION' IN types1 THEN
12484         IF 'ELEMENTARY_SPACE' IN types2 THEN
12485            es_val := spc2\elementary_space.space_id;
12486            RETURN ((es_val = es_numbers) OR (es_val = es_complex_numbers));
12487         END_IF;
12488         IF 'CARTESIAN_COMPLEX_NUMBER_REGION' IN types2 THEN
12489            RETURN (subspace_of(enclose_pregion_in_cregion(spc1), spc2));
12490         END_IF;
12491         IF 'POLAR_COMPLEX_NUMBER_REGION' IN types2 THEN
12492            prgn1 := spc1;
12493            prgn2 := spc2;
12494            IF prgn1.centre = prgn2.centre THEN
12495               IF prgn2.direction_constraint.max > 3.14159 THEN
12496                  aitv := make_finite_real_interval(-3.14159, open, prgn2.direction_constraint.max - 2.00000 * 3.14159, prgn2.direction_constraint.max_closure);
12497                  RETURN (subspace_of(prgn1.distance_constraint, prgn2.distance_constraint) AND (subspace_of(prgn1.direction_constraint, prgn2.direction_constraint) OR subspace_of(prgn1.direction_constraint, aitv)));
12498               ELSE
12499                  RETURN (subspace_of(prgn1.distance_constraint, prgn2.distance_constraint) AND subspace_of(prgn1.direction_constraint, prgn2.direction_constraint));
12500               END_IF;
12501            END_IF;
12502            RETURN (subspace_of(enclose_pregion_in_pregion(prgn1, prgn2.centre), prgn2));
12503         END_IF;
12504         RETURN (FALSE);
12505      END_IF;
12506      IF 'FINITE_SPACE' IN types1 THEN
12507         cum := TRUE;
12508         REPEAT i := 1 TO SIZEOF(spc1\finite_space.members);
12509            cum := cum AND member_of(spc1\finite_space.members[i], spc2);
12510            IF cum = FALSE THEN
12511               RETURN (FALSE);
12512            END_IF;
12513         END_REPEAT;
12514         RETURN (cum);
12515      END_IF;
12516      IF 'PRODUCT_SPACE' IN types1 THEN
12517         IF 'PRODUCT_SPACE' IN types2 THEN
12518            IF space_dimension(spc1) = space_dimension(spc2) THEN
12519               cum := TRUE;
12520               REPEAT i := 1 TO space_dimension(spc1);
12521                  cum := cum AND subspace_of(factor_space(spc1, i), factor_space(spc2, i));
12522                  IF cum = FALSE THEN
12523                     RETURN (FALSE);
12524                  END_IF;
12525               END_REPEAT;
12526               RETURN (cum);
12527            END_IF;
12528         END_IF;
12529         IF 'EXTENDED_TUPLE_SPACE' IN types2 THEN
12530            IF space_dimension(spc1) >= space_dimension(spc2) THEN
12531               cum := TRUE;
12532               REPEAT i := 1 TO space_dimension(spc1);
12533                  cum := cum AND subspace_of(factor_space(spc1, i), factor_space(spc2, i));
12534                  IF cum = FALSE THEN
12535                     RETURN (FALSE);
12536                  END_IF;
12537               END_REPEAT;
12538               RETURN (cum);
12539            END_IF;
12540         END_IF;
12541         RETURN (FALSE);
12542      END_IF;
12543      IF 'EXTENDED_TUPLE_SPACE' IN types1 THEN
12544         IF 'EXTENDED_TUPLE_SPACE' IN types2 THEN
12545            n := space_dimension(spc1);
12546            IF n < space_dimension(spc2) THEN
12547               n := space_dimension(spc2);
12548            END_IF;
12549            cum := TRUE;
12550            REPEAT i := 1 TO n + 1;
12551               cum := cum AND subspace_of(factor_space(spc1, i), factor_space(spc2, i));
12552               IF cum = FALSE THEN
12553                  RETURN (FALSE);
12554               END_IF;
12555            END_REPEAT;
12556            RETURN (cum);
12557         END_IF;
12558         RETURN (FALSE);
12559      END_IF;
12560      IF 'FUNCTION_SPACE' IN types1 THEN
12561         IF 'ELEMENTARY_SPACE' IN types2 THEN
12562            RETURN (spc2\elementary_space.space_id = es_maths_functions);
12563         END_IF;
12564         IF 'FUNCTION_SPACE' IN types2 THEN
12565            cum := TRUE;
12566            sp1 := spc1\function_space.domain_argument;
12567            sp2 := spc2\function_space.domain_argument;
12568            CASE spc1\function_space.domain_constraint OF
12569               sc_equal :
12570                     BEGIN
12571                        CASE spc2\function_space.domain_constraint OF
12572                           sc_equal :
12573                                 cum := cum AND equal_maths_spaces(sp1, sp2);
12574                           sc_subspace :
12575                                 cum := cum AND subspace_of(sp1, sp2);
12576                           sc_member :
12577                                 cum := cum AND member_of(sp1, sp2);
12578                        END_CASE;
12579                     END;
12580               sc_subspace :
12581                     BEGIN
12582                        CASE spc2\function_space.domain_constraint OF
12583                           sc_equal :
12584                                 RETURN (FALSE);
12585                           sc_subspace :
12586                                 cum := cum AND subspace_of(sp1, sp2);
12587                           sc_member :
12588                                 BEGIN
12589                                    IF NOT member_of(sp1, sp2) THEN
12590                                       RETURN (FALSE);
12591                                    END_IF;
12592                                    cum := UNKNOWN;
12593                                 END;
12594                        END_CASE;
12595                     END;
12596               sc_member :
12597                     BEGIN
12598                        CASE spc2\function_space.domain_constraint OF
12599                           sc_equal :
12600                                 cum := (cum AND space_is_singleton(sp1)) AND equal_maths_spaces(singleton_member_of(sp1), sp2);
12601                           sc_subspace :
12602                                 BEGIN
12603                                    IF NOT member_of(sp2, sp1) THEN
12604                                       RETURN (FALSE);
12605                                    END_IF;
12606                                    cum := UNKNOWN;
12607                                 END;
12608                           sc_member :
12609                                 cum := cum AND subspace_of(sp1, sp2);
12610                        END_CASE;
12611                     END;
12612            END_CASE;
12613            IF cum = FALSE THEN
12614               RETURN (FALSE);
12615            END_IF;
12616            sp1 := spc1\function_space.range_argument;
12617            sp2 := spc2\function_space.range_argument;
12618            CASE spc1\function_space.range_constraint OF
12619               sc_equal :
12620                     BEGIN
12621                        CASE spc2\function_space.range_constraint OF
12622                           sc_equal :
12623                                 cum := cum AND equal_maths_spaces(sp1, sp2);
12624                           sc_subspace :
12625                                 cum := cum AND subspace_of(sp1, sp2);
12626                           sc_member :
12627                                 cum := cum AND member_of(sp1, sp2);
12628                        END_CASE;
12629                     END;
12630               sc_subspace :
12631                     BEGIN
12632                        CASE spc2\function_space.domain_constraint OF
12633                           sc_equal :
12634                                 RETURN (FALSE);
12635                           sc_subspace :
12636                                 cum := cum AND subspace_of(sp1, sp2);
12637                           sc_member :
12638                                 BEGIN
12639                                    IF NOT member_of(sp1, sp2) THEN
12640                                       RETURN (FALSE);
12641                                    END_IF;
12642                                    cum := UNKNOWN;
12643                                 END;
12644                        END_CASE;
12645                     END;
12646               sc_member :
12647                     BEGIN
12648                        CASE spc2\function_space.domain_constraint OF
12649                           sc_equal :
12650                                 cum := (cum AND space_is_singleton(sp1)) AND equal_maths_spaces(singleton_member_of(sp1), sp2);
12651                           sc_subspace :
12652                                 BEGIN
12653                                    IF NOT member_of(sp2, sp1) THEN
12654                                       RETURN (FALSE);
12655                                    END_IF;
12656                                    cum := UNKNOWN;
12657                                 END;
12658                           sc_member :
12659                                 cum := cum AND subspace_of(sp1, sp2);
12660                        END_CASE;
12661                     END;
12662            END_CASE;
12663            RETURN (cum);
12664         END_IF;
12665         RETURN (FALSE);
12666      END_IF;
12667      RETURN (UNKNOWN);
12668   END_FUNCTION;
12669
12670   FUNCTION subspace_of_es
12671      (spc : maths_space;
12672       es : elementary_space_enumerators ) : LOGICAL;
12673   LOCAL
12674      types : SET OF STRING := stripped_typeof(spc);
12675   END_LOCAL;
12676      IF NOT EXISTS(spc) OR NOT EXISTS(es) THEN
12677         RETURN (FALSE);
12678      END_IF;
12679      IF 'ELEMENTARY_SPACE' IN types THEN
12680         RETURN (es_subspace_of_es(spc\elementary_space.space_id, es));
12681      END_IF;
12682      IF 'FINITE_SPACE' IN types THEN
12683         RETURN (all_members_of_es(spc\finite_space.members, es));
12684      END_IF;
12685      CASE es OF
12686         es_numbers :
12687               RETURN (((((((('FINITE_INTEGER_INTERVAL' IN types) OR ('INTEGER_INTERVAL_FROM_MIN' IN types)) OR ('INTEGER_INTERVAL_TO_MAX' IN types)) OR ('FINITE_REAL_INTERVAL' IN types)) OR ('REAL_INTERVAL_FROM_MIN' IN types)) OR ('REAL_INTERVAL_TO_MAX' IN types)) OR ('CARTESIAN_COMPLEX_NUMBER_REGION' IN types)) OR ('POLAR_COMPLEX_NUMBER_REGION' IN types));
12688         es_complex_numbers :
12689               RETURN (('CARTESIAN_COMPLEX_NUMBER_REGION' IN types) OR ('POLAR_COMPLEX_NUMBER_REGION' IN types));
12690         es_reals :
12691               RETURN ((('FINITE_REAL_INTERVAL' IN types) OR ('REAL_INTERVAL_FROM_MIN' IN types)) OR ('REAL_INTERVAL_TO_MAX' IN types));
12692         es_integers :
12693               RETURN ((('FINITE_INTEGER_INTERVAL' IN types) OR ('INTEGER_INTERVAL_FROM_MIN' IN types)) OR ('INTEGER_INTERVAL_TO_MAX' IN types));
12694         es_logicals :
12695               RETURN (FALSE);
12696         es_booleans :
12697               RETURN (FALSE);
12698         es_strings :
12699               RETURN (FALSE);
12700         es_binarys :
12701               RETURN (FALSE);
12702         es_maths_spaces :
12703               RETURN (FALSE);
12704         es_maths_functions :
12705               RETURN ('FUNCTION_SPACE' IN types);
12706         es_generics :
12707               RETURN (TRUE);
12708      END_CASE;
12709      RETURN (UNKNOWN);
12710   END_FUNCTION;
12711
12712   FUNCTION substitute(expr : generic_expression;
12713                    vars : LIST [1:?] OF generic_variable;
12714                    vals : LIST [1:?] OF maths_value) : generic_expression;
12715  LOCAL
12716    types : SET OF STRING := stripped_typeof(expr);
12717    opnds : LIST OF generic_expression;
12718    op1, op2 : generic_expression;
12719    qvars : LIST OF generic_variable;
12720    srcdom : maths_space_or_function;
12721    prpfun : LIST [1:?] OF maths_function;
12722    finfun : maths_function_select;
12723  END_LOCAL;
12724  IF SIZEOF (vars) <> SIZEOF (vals) THEN  RETURN (?);  END_IF;
12725  IF 'GENERIC_LITERAL' IN types THEN  RETURN (expr);  END_IF;
12726  IF 'GENERIC_VARIABLE' IN types THEN
12727    REPEAT i := 1 TO SIZEOF (vars);
12728      IF expr :=: vars[i] THEN  RETURN (vals[i]);  END_IF;
12729    END_REPEAT;
12730    RETURN (expr);
12731  END_IF;
12732  IF 'QUANTIFIER_EXPRESSION' IN types THEN
12733    qvars := expr\quantifier_expression.variables;
12734    -- Variables subject to a quantifier do not participate in this kind of
12735    -- substitution process.
12736    REPEAT i := SIZEOF (vars) TO 1 BY -1;
12737      IF vars[i] IN qvars THEN
12738        REMOVE (vars, i);
12739        REMOVE (vals, i);
12740      END_IF;
12741    END_REPEAT;
12742    opnds := expr\multiple_arity_generic_expression.operands;
12743    REPEAT i := 1 TO SIZEOF (opnds);
12744      IF NOT (opnds[i] IN qvars) THEN
12745        expr\multiple_arity_generic_expression.operands[i] :=
12746          substitute(opnds[i],vars,vals);
12747        -- This technique will not work on subtypes of quantifier_expression
12748        -- which derive their operands from other attributes!
12749      END_IF;
12750    END_REPEAT;
12751    RETURN (expr);  -- operands modified!
12752  END_IF;
12753  IF 'UNARY_GENERIC_EXPRESSION' IN types THEN
12754    op1 := expr\unary_generic_expression.operand;
12755    expr\unary_generic_expression.operand := substitute(op1, vars, vals);
12756    -- This technique will not work on subtypes of unary_generic_expression
12757    -- which derive their operands from other attributes!
12758  END_IF;
12759  IF 'BINARY_GENERIC_EXPRESSION' IN types THEN
12760    op1 := expr\binary_generic_expression.operands[1];
12761    expr\binary_generic_expression.operands[1] := substitute(op1, vars, vals);
12762    op2 := expr\binary_generic_expression.operands[2];
12763    expr\binary_generic_expression.operands[2] := substitute(op2, vars, vals);
12764    -- This technique will not work on subtypes of binary_generic_expression
12765    -- which derive their operands from other attributes!
12766  END_IF;
12767  IF 'PARALLEL_COMPOSED_FUNCTION' IN types THEN
12768    -- Subtype of multiple_arity_generic_expression which derives its operands.
12769    srcdom := expr\parallel_composed_function.source_of_domain;
12770    prpfun := expr\parallel_composed_function.prep_functions;
12771    finfun := expr\parallel_composed_function.final_function;
12772    srcdom := substitute(srcdom,vars,vals);
12773    REPEAT i := 1 TO SIZEOF (prpfun);
12774      prpfun[i] := substitute(prpfun[i],vars,vals);
12775    END_REPEAT;
12776    IF 'MATHS_FUNCTION' IN stripped_typeof(finfun) THEN
12777      finfun := substitute(finfun,vars,vals);
12778    END_IF;
12779    RETURN (make_parallel_composed_function(srcdom,prpfun,finfun));
12780  END_IF;
12781  IF 'MULTIPLE_ARITY_GENERIC_EXPRESSION' IN types THEN
12782    opnds := expr\multiple_arity_generic_expression.operands;
12783    REPEAT i := 1 TO SIZEOF (opnds);
12784      expr\multiple_arity_generic_expression.operands[i] :=
12785        substitute(opnds[i],vars,vals);
12786        -- This technique will not work on subtypes of multiple_arity_generic_
12787        -- expression which derive their operands from other attributes!
12788    END_REPEAT;
12789  END_IF;
12790  RETURN (expr);
12791END_FUNCTION;  -- substitute
12792
12793   FUNCTION using_items
12794      (item : founded_item_select;
12795       checked_items : SET OF founded_item_select ) : SET OF founded_item_select;
12796   LOCAL
12797      new_check_items : SET OF founded_item_select;
12798      result_items : SET OF founded_item_select;
12799      next_items : SET OF founded_item_select;
12800   END_LOCAL;
12801      result_items := [];
12802      new_check_items := checked_items + item;
12803      next_items := QUERY (z <* bag_to_set(USEDIN(item, ''))| ('ENGINEERING_PROPERTIES_SCHEMA.REPRESENTATION_ITEM' IN TYPEOF(z)) OR ('ENGINEERING_PROPERTIES_SCHEMA.FOUNDED_ITEM' IN TYPEOF(z)));
12804      IF SIZEOF(next_items) > 0 THEN
12805         REPEAT i := 1 TO HIINDEX(next_items);
12806            IF NOT (next_items[i] IN new_check_items) THEN
12807               result_items := result_items + next_items[i] + using_items(next_items[i], new_check_items);
12808            END_IF;
12809         END_REPEAT;
12810      END_IF;
12811      RETURN (result_items);
12812   END_FUNCTION;
12813
12814   FUNCTION using_representations
12815      (item : founded_item_select ) : SET OF representation;
12816   LOCAL
12817      results : SET OF representation;
12818      result_bag : BAG OF representation;
12819      intermediate_items : SET OF founded_item_select;
12820   END_LOCAL;
12821      results := [];
12822      result_bag := USEDIN(item, 'ENGINEERING_PROPERTIES_SCHEMA.REPRESENTATION.ITEMS');
12823      IF SIZEOF(result_bag) > 0 THEN
12824         REPEAT i := 1 TO HIINDEX(result_bag);
12825            results := results + result_bag[i];
12826         END_REPEAT;
12827      END_IF;
12828      intermediate_items := using_items(item, []);
12829      IF SIZEOF(intermediate_items) > 0 THEN
12830         REPEAT i := 1 TO HIINDEX(intermediate_items);
12831            result_bag := USEDIN(intermediate_items[i], 'ENGINEERING_PROPERTIES_SCHEMA.REPRESENTATION.ITEMS');
12832            IF SIZEOF(result_bag) > 0 THEN
12833               REPEAT j := 1 TO HIINDEX(result_bag);
12834                  results := results + result_bag[j];
12835               END_REPEAT;
12836            END_IF;
12837         END_REPEAT;
12838      END_IF;
12839      RETURN (results);
12840   END_FUNCTION;
12841
12842   FUNCTION valid_calendar_date
12843      (date : calendar_date ) : LOGICAL;
12844      CASE date.month_component OF
12845         1 :
12846               RETURN ((1 <= date.day_component) AND (date.day_component <= 31));
12847         2 :
12848               BEGIN
12849                  IF leap_year(date.year_component) THEN
12850                     RETURN ((1 <= date.day_component) AND (date.day_component <= 29));
12851                  ELSE
12852                     RETURN ((1 <= date.day_component) AND (date.day_component <= 28));
12853                  END_IF;
12854               END;
12855         3 :
12856               RETURN ((1 <= date.day_component) AND (date.day_component <= 31));
12857         4 :
12858               RETURN ((1 <= date.day_component) AND (date.day_component <= 30));
12859         5 :
12860               RETURN ((1 <= date.day_component) AND (date.day_component <= 31));
12861         6 :
12862               RETURN ((1 <= date.day_component) AND (date.day_component <= 30));
12863         7 :
12864               RETURN ((1 <= date.day_component) AND (date.day_component <= 31));
12865         8 :
12866               RETURN ((1 <= date.day_component) AND (date.day_component <= 31));
12867         9 :
12868               RETURN ((1 <= date.day_component) AND (date.day_component <= 30));
12869         10 :
12870               RETURN ((1 <= date.day_component) AND (date.day_component <= 31));
12871         11 :
12872               RETURN ((1 <= date.day_component) AND (date.day_component <= 30));
12873         12 :
12874               RETURN ((1 <= date.day_component) AND (date.day_component <= 31));
12875      END_CASE;
12876      RETURN (FALSE);
12877   END_FUNCTION;
12878
12879   FUNCTION valid_measure_value
12880      (m : measure_value ) : BOOLEAN;
12881      IF 'REAL' IN TYPEOF(m) THEN
12882         RETURN (m > 0.00000);
12883      ELSE
12884         IF 'INTEGER' IN TYPEOF(m) THEN
12885            RETURN (m > 0);
12886         ELSE
12887            RETURN (TRUE);
12888         END_IF;
12889      END_IF;
12890   END_FUNCTION;
12891
12892   FUNCTION valid_time
12893      (time : local_time ) : BOOLEAN;
12894      IF EXISTS(time.second_component) THEN
12895         RETURN (EXISTS(time.minute_component));
12896      ELSE
12897         RETURN (TRUE);
12898      END_IF;
12899   END_FUNCTION;
12900
12901   FUNCTION valid_units
12902      (m : measure_with_unit ) : BOOLEAN;
12903      IF 'ENGINEERING_PROPERTIES_SCHEMA.LENGTH_MEASURE' IN TYPEOF(m.value_component) THEN
12904         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
12905            RETURN (FALSE);
12906         END_IF;
12907      END_IF;
12908      IF 'ENGINEERING_PROPERTIES_SCHEMA.MASS_MEASURE' IN TYPEOF(m.value_component) THEN
12909         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
12910            RETURN (FALSE);
12911         END_IF;
12912      END_IF;
12913      IF 'ENGINEERING_PROPERTIES_SCHEMA.TIME_MEASURE' IN TYPEOF(m.value_component) THEN
12914         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
12915            RETURN (FALSE);
12916         END_IF;
12917      END_IF;
12918      IF 'ENGINEERING_PROPERTIES_SCHEMA.ELECTRIC_CURRENT_MEASURE' IN TYPEOF(m.value_component) THEN
12919         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000) THEN
12920            RETURN (FALSE);
12921         END_IF;
12922      END_IF;
12923      IF 'ENGINEERING_PROPERTIES_SCHEMA.THERMODYNAMIC_TEMPERATURE_MEASURE' IN TYPEOF(m.value_component) THEN
12924         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000) THEN
12925            RETURN (FALSE);
12926         END_IF;
12927      END_IF;
12928      IF 'ENGINEERING_PROPERTIES_SCHEMA.CELSIUS_TEMPERATURE_MEASURE' IN TYPEOF(m.value_component) THEN
12929         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000) THEN
12930            RETURN (FALSE);
12931         END_IF;
12932      END_IF;
12933      IF 'ENGINEERING_PROPERTIES_SCHEMA.AMOUNT_OF_SUBSTANCE_MEASURE' IN TYPEOF(m.value_component) THEN
12934         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000) THEN
12935            RETURN (FALSE);
12936         END_IF;
12937      END_IF;
12938      IF 'ENGINEERING_PROPERTIES_SCHEMA.LUMINOUS_INTENSITY_MEASURE' IN TYPEOF(m.value_component) THEN
12939         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000) THEN
12940            RETURN (FALSE);
12941         END_IF;
12942      END_IF;
12943      IF 'ENGINEERING_PROPERTIES_SCHEMA.PLANE_ANGLE_MEASURE' IN TYPEOF(m.value_component) THEN
12944         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
12945            RETURN (FALSE);
12946         END_IF;
12947      END_IF;
12948      IF 'ENGINEERING_PROPERTIES_SCHEMA.SOLID_ANGLE_MEASURE' IN TYPEOF(m.value_component) THEN
12949         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
12950            RETURN (FALSE);
12951         END_IF;
12952      END_IF;
12953      IF 'ENGINEERING_PROPERTIES_SCHEMA.AREA_MEASURE' IN TYPEOF(m.value_component) THEN
12954         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(2.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
12955            RETURN (FALSE);
12956         END_IF;
12957      END_IF;
12958      IF 'ENGINEERING_PROPERTIES_SCHEMA.VOLUME_MEASURE' IN TYPEOF(m.value_component) THEN
12959         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(3.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
12960            RETURN (FALSE);
12961         END_IF;
12962      END_IF;
12963      IF 'ENGINEERING_PROPERTIES_SCHEMA.RATIO_MEASURE' IN TYPEOF(m.value_component) THEN
12964         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
12965            RETURN (FALSE);
12966         END_IF;
12967      END_IF;
12968      IF 'ENGINEERING_PROPERTIES_SCHEMA.POSITIVE_LENGTH_MEASURE' IN TYPEOF(m.value_component) THEN
12969         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
12970            RETURN (FALSE);
12971         END_IF;
12972      END_IF;
12973      IF 'ENGINEERING_PROPERTIES_SCHEMA.POSITIVE_PLANE_ANGLE_MEASURE' IN TYPEOF(m.value_component) THEN
12974         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
12975            RETURN (FALSE);
12976         END_IF;
12977      END_IF;
12978      IF 'ENGINEERING_PROPERTIES_SCHEMA.ACCELERATION_MEASURE' IN TYPEOF(m.value_component) THEN
12979         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(1.00000, 0.00000, -2.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
12980            RETURN (FALSE);
12981         END_IF;
12982      END_IF;
12983      IF 'ENGINEERING_PROPERTIES_SCHEMA.CAPACITANCE_MEASURE' IN TYPEOF(m.value_component) THEN
12984         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(-2.00000, -1.00000, 4.00000, 1.00000, 0.00000, 0.00000, 0.00000) THEN
12985            RETURN (FALSE);
12986         END_IF;
12987      END_IF;
12988      IF 'ENGINEERING_PROPERTIES_SCHEMA.ELECTRIC_CHARGE_MEASURE' IN TYPEOF(m.value_component) THEN
12989         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 0.00000, 1.00000, 1.00000, 0.00000, 0.00000, 0.00000) THEN
12990            RETURN (FALSE);
12991         END_IF;
12992      END_IF;
12993      IF 'ENGINEERING_PROPERTIES_SCHEMA.CONDUCTANCE_MEASURE' IN TYPEOF(m.value_component) THEN
12994         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(-2.00000, -1.00000, 3.00000, 2.00000, 0.00000, 0.00000, 0.00000) THEN
12995            RETURN (FALSE);
12996         END_IF;
12997      END_IF;
12998      IF 'ENGINEERING_PROPERTIES_SCHEMA.ELECTRIC_POTENTIAL_MEASURE' IN TYPEOF(m.value_component) THEN
12999         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(2.00000, 1.00000, -3.00000, -1.00000, 0.00000, 0.00000, 0.00000) THEN
13000            RETURN (FALSE);
13001         END_IF;
13002      END_IF;
13003      IF 'ENGINEERING_PROPERTIES_SCHEMA.ENERGY_MEASURE' IN TYPEOF(m.value_component) THEN
13004         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(2.00000, 1.00000, -2.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
13005            RETURN (FALSE);
13006         END_IF;
13007      END_IF;
13008      IF 'ENGINEERING_PROPERTIES_SCHEMA.FORCE_MEASURE' IN TYPEOF(m.value_component) THEN
13009         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(1.00000, 1.00000, -2.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
13010            RETURN (FALSE);
13011         END_IF;
13012      END_IF;
13013      IF 'ENGINEERING_PROPERTIES_SCHEMA.FREQUENCY_MEASURE' IN TYPEOF(m.value_component) THEN
13014         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 0.00000, -1.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
13015            RETURN (FALSE);
13016         END_IF;
13017      END_IF;
13018      IF 'ENGINEERING_PROPERTIES_SCHEMA.ILLUMINANCE_MEASURE' IN TYPEOF(m.value_component) THEN
13019         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(-2.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000) THEN
13020            RETURN (FALSE);
13021         END_IF;
13022      END_IF;
13023      IF 'ENGINEERING_PROPERTIES_SCHEMA.INDUCTANCE_MEASURE' IN TYPEOF(m.value_component) THEN
13024         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(2.00000, 1.00000, -2.00000, -2.00000, 0.00000, 0.00000, 0.00000) THEN
13025            RETURN (FALSE);
13026         END_IF;
13027      END_IF;
13028      IF 'ENGINEERING_PROPERTIES_SCHEMA.LUMINOUS_FLUX_MEASURE' IN TYPEOF(m.value_component) THEN
13029         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000) THEN
13030            RETURN (FALSE);
13031         END_IF;
13032      END_IF;
13033      IF 'ENGINEERING_PROPERTIES_SCHEMA.MAGNETIC_FLUX_MEASURE' IN TYPEOF(m.value_component) THEN
13034         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(2.00000, 1.00000, -2.00000, -1.00000, 0.00000, 0.00000, 0.00000) THEN
13035            RETURN (FALSE);
13036         END_IF;
13037      END_IF;
13038      IF 'ENGINEERING_PROPERTIES_SCHEMA.MAGNETIC_FLUX_DENSITY_MEASURE' IN TYPEOF(m.value_component) THEN
13039         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 1.00000, -2.00000, -1.00000, 0.00000, 0.00000, 0.00000) THEN
13040            RETURN (FALSE);
13041         END_IF;
13042      END_IF;
13043      IF 'ENGINEERING_PROPERTIES_SCHEMA.POWER_MEASURE' IN TYPEOF(m.value_component) THEN
13044         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(2.00000, 1.00000, -3.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
13045            RETURN (FALSE);
13046         END_IF;
13047      END_IF;
13048      IF 'ENGINEERING_PROPERTIES_SCHEMA.PRESSURE_MEASURE' IN TYPEOF(m.value_component) THEN
13049         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(-1.00000, 1.00000, -2.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
13050            RETURN (FALSE);
13051         END_IF;
13052      END_IF;
13053      IF 'ENGINEERING_PROPERTIES_SCHEMA.RESISTANCE_MEASURE' IN TYPEOF(m.value_component) THEN
13054         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(2.00000, 1.00000, -3.00000, -2.00000, 0.00000, 0.00000, 0.00000) THEN
13055            RETURN (FALSE);
13056         END_IF;
13057      END_IF;
13058      IF 'ENGINEERING_PROPERTIES_SCHEMA.VELOCITY_MEASURE' IN TYPEOF(m.value_component) THEN
13059         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(1.00000, 0.00000, -1.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
13060            RETURN (FALSE);
13061         END_IF;
13062      END_IF;
13063      IF 'ENGINEERING_PROPERTIES_SCHEMA.RADIOACTIVITY_MEASURE' IN TYPEOF(m.value_component) THEN
13064         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(0.00000, 0.00000, -1.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
13065            RETURN (FALSE);
13066         END_IF;
13067      END_IF;
13068      IF 'ENGINEERING_PROPERTIES_SCHEMA.ABSORBED_DOSE_MEASURE' IN TYPEOF(m.value_component) THEN
13069         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(2.00000, 0.00000, -2.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
13070            RETURN (FALSE);
13071         END_IF;
13072      END_IF;
13073      IF 'ENGINEERING_PROPERTIES_SCHEMA.DOSE_EQUIVALENT_MEASURE' IN TYPEOF(m.value_component) THEN
13074         IF derive_dimensional_exponents(m.unit_component) <> dimensional_exponents(2.00000, 0.00000, -2.00000, 0.00000, 0.00000, 0.00000, 0.00000) THEN
13075            RETURN (FALSE);
13076         END_IF;
13077      END_IF;
13078      RETURN (TRUE);
13079   END_FUNCTION;
13080
13081   FUNCTION values_space_of
13082      (expr : generic_expression ) : maths_space;
13083   LOCAL
13084      e_prefix : STRING := 'ENGINEERING_PROPERTIES_SCHEMA.';
13085      typenames : SET OF STRING := TYPEOF(expr);
13086   END_LOCAL;
13087      IF schema_prefix + 'MATHS_VARIABLE' IN typenames THEN
13088         RETURN (expr\maths_variable.values_space);
13089      END_IF;
13090      IF e_prefix + 'EXPRESSION' IN typenames THEN
13091         IF e_prefix + 'NUMERIC_EXPRESSION' IN typenames THEN
13092            IF expr\numeric_expression.is_int THEN
13093               IF e_prefix + 'INT_LITERAL' IN typenames THEN
13094                  RETURN (make_finite_space([ expr\int_literal.the_value ]));
13095               ELSE
13096                  RETURN (the_integers);
13097               END_IF;
13098            ELSE
13099               IF e_prefix + 'REAL_LITERAL' IN typenames THEN
13100                  RETURN (make_finite_space([ expr\real_literal.the_value ]));
13101               ELSE
13102                  RETURN (the_reals);
13103               END_IF;
13104            END_IF;
13105         END_IF;
13106         IF e_prefix + 'BOOLEAN_EXPRESSION' IN typenames THEN
13107            IF e_prefix + 'BOOLEAN_LITERAL' IN typenames THEN
13108               RETURN (make_finite_space([ expr\boolean_literal.the_value ]));
13109            ELSE
13110               RETURN (the_booleans);
13111            END_IF;
13112         END_IF;
13113         IF e_prefix + 'STRING_EXPRESSION' IN typenames THEN
13114            IF e_prefix + 'STRING_LITERAL' IN typenames THEN
13115               RETURN (make_finite_space([ expr\string_literal.the_value ]));
13116            ELSE
13117               RETURN (the_strings);
13118            END_IF;
13119         END_IF;
13120         RETURN (?);
13121      END_IF;
13122      IF schema_prefix + 'MATHS_FUNCTION' IN typenames THEN
13123         IF expression_is_constant(expr) THEN
13124            RETURN (make_finite_space([ expr ]));
13125         ELSE
13126            RETURN (make_function_space(sc_equal, expr\maths_function.domain, sc_equal, expr\maths_function.range));
13127         END_IF;
13128      END_IF;
13129      IF schema_prefix + 'FUNCTION_APPLICATION' IN typenames THEN
13130         RETURN (expr\function_application.func.range);
13131      END_IF;
13132      IF schema_prefix + 'MATHS_SPACE' IN typenames THEN
13133         IF expression_is_constant(expr) THEN
13134            RETURN (make_finite_space([ expr ]));
13135         ELSE
13136            RETURN (make_elementary_space(es_maths_spaces));
13137         END_IF;
13138      END_IF;
13139      IF schema_prefix + 'DEPENDENT_VARIABLE_DEFINITION' IN typenames THEN
13140         RETURN (values_space_of(expr\unary_generic_expression.operand));
13141      END_IF;
13142      IF schema_prefix + 'COMPLEX_NUMBER_LITERAL' IN typenames THEN
13143         RETURN (make_finite_space([ expr ]));
13144      END_IF;
13145      IF schema_prefix + 'LOGICAL_LITERAL' IN typenames THEN
13146         RETURN (make_finite_space([ expr\logical_literal.lit_value ]));
13147      END_IF;
13148      IF schema_prefix + 'BINARY_LITERAL' IN typenames THEN
13149         RETURN (make_finite_space([ expr\binary_literal.lit_value ]));
13150      END_IF;
13151      IF schema_prefix + 'MATHS_ENUM_LITERAL' IN typenames THEN
13152         RETURN (make_finite_space([ expr\maths_enum_literal.lit_value ]));
13153      END_IF;
13154      IF schema_prefix + 'REAL_TUPLE_LITERAL' IN typenames THEN
13155         RETURN (make_finite_space([ expr\real_tuple_literal.lit_value ]));
13156      END_IF;
13157      IF schema_prefix + 'INTEGER_TUPLE_LITERAL' IN typenames THEN
13158         RETURN (make_finite_space([ expr\integer_tuple_literal.lit_value ]));
13159      END_IF;
13160      IF schema_prefix + 'ATOM_BASED_LITERAL' IN typenames THEN
13161         RETURN (make_finite_space([ expr\atom_based_literal.lit_value ]));
13162      END_IF;
13163      IF schema_prefix + 'MATHS_TUPLE_LITERAL' IN typenames THEN
13164         RETURN (make_finite_space([ expr\maths_tuple_literal.lit_value ]));
13165      END_IF;
13166      IF schema_prefix + 'PARTIAL_DERIVATIVE_EXPRESSION' IN typenames THEN
13167         RETURN (drop_numeric_constraints(values_space_of(expr\partial_derivative_expression.derivand)));
13168      END_IF;
13169      IF schema_prefix + 'DEFINITE_INTEGRAL_EXPRESSION' IN typenames THEN
13170         RETURN (drop_numeric_constraints(values_space_of(expr\definite_integral_expression.integrand)));
13171      END_IF;
13172      RETURN (?);
13173   END_FUNCTION;
13174
13175   FUNCTION vector_difference
13176      (arg1 : vector_or_direction;
13177       arg2 : vector_or_direction ) : vector;
13178   LOCAL
13179      result : vector;
13180      res : direction;
13181      vec1 : direction;
13182      vec2 : direction;
13183      mag : REAL;
13184      mag1 : REAL;
13185      mag2 : REAL;
13186      ndim : INTEGER;
13187   END_LOCAL;
13188      IF (NOT EXISTS(arg1) OR NOT EXISTS(arg2)) OR (arg1.dim <> arg2.dim) THEN
13189         RETURN (?);
13190      ELSE
13191         BEGIN
13192            IF 'ENGINEERING_PROPERTIES_SCHEMA.VECTOR' IN TYPEOF(arg1) THEN
13193               mag1 := arg1.magnitude;
13194               vec1 := arg1.orientation;
13195            ELSE
13196               mag1 := 1.00000;
13197               vec1 := arg1;
13198            END_IF;
13199            IF 'ENGINEERING_PROPERTIES_SCHEMA.VECTOR' IN TYPEOF(arg2) THEN
13200               mag2 := arg2.magnitude;
13201               vec2 := arg2.orientation;
13202            ELSE
13203               mag2 := 1.00000;
13204               vec2 := arg2;
13205            END_IF;
13206            vec1 := normalise(vec1);
13207            vec2 := normalise(vec2);
13208            ndim := SIZEOF(vec1.direction_ratios);
13209            mag := 0.00000;
13210            res := dummy_gri || direction(vec1.direction_ratios);
13211            REPEAT i := 1 TO ndim;
13212               res.direction_ratios[i] := mag1 * vec1.direction_ratios[i] + mag2 * vec2.direction_ratios[i];
13213               mag := mag + res.direction_ratios[i] * res.direction_ratios[i];
13214            END_REPEAT;
13215            IF mag > 0.00000 THEN
13216               result := dummy_gri || vector(res, SQRT(mag));
13217            ELSE
13218               result := dummy_gri || vector(vec1, 0.00000);
13219            END_IF;
13220         END;
13221      END_IF;
13222      RETURN (result);
13223   END_FUNCTION;
13224
13225(* ***********************************
13226Rules in the schema engineering_properties_schema
13227*********************************** *)
13228
13229   RULE compatible_dimension FOR (cartesian_point, direction, representation_context, geometric_representation_context );
13230   WHERE
13231      WR1:
13232         SIZEOF(QUERY (x <* cartesian_point| (SIZEOF(QUERY (y <* geometric_representation_context| item_in_context(x, y) AND (HIINDEX(x.coordinates) <> y.coordinate_space_dimension))) > 0))) = 0;
13233      WR2:
13234         SIZEOF(QUERY (x <* direction| (SIZEOF(QUERY (y <* geometric_representation_context| item_in_context(x, y) AND (HIINDEX(x.direction_ratios) <> y.coordinate_space_dimension))) > 0))) = 0;
13235   END_RULE;
13236
13237   RULE dependent_instantiable_attribute_value_role FOR (attribute_value_role );
13238   WHERE
13239      WR1:
13240         SIZEOF(QUERY (a <* attribute_value_role| NOT (SIZEOF(USEDIN(a, '')) > 0))) = 0;
13241   END_RULE;
13242
13243   RULE dependent_instantiable_classification_role FOR (classification_role );
13244   WHERE
13245      WR1:
13246         SIZEOF(QUERY (c <* classification_role| NOT (SIZEOF(USEDIN(c, '')) > 0))) = 0;
13247   END_RULE;
13248
13249   RULE dependent_instantiable_identification_role FOR (identification_role );
13250   WHERE
13251      WR1:
13252         SIZEOF(QUERY (i <* identification_role| NOT (SIZEOF(USEDIN(i, '')) > 0))) = 0;
13253   END_RULE;
13254
13255   RULE plib_class_reference_requires_version FOR (externally_defined_class );
13256   WHERE
13257      WR1:
13258         SIZEOF(QUERY (edc <* externally_defined_class| ('ENGINEERING_PROPERTIES_SCHEMA.' + 'EXTERNAL_SOURCE' IN TYPEOF(edc.source)) AND (SIZEOF(QUERY (aei <* USEDIN(edc, 'ENGINEERING_PROPERTIES_SCHEMA.APPLIED_EXTERNAL_IDENTIFICATION_ASSIGNMENT.ITEMS')| (aei.role.name = 'version'))) <> 1))) = 0;
13259      WR2:
13260         SIZEOF(QUERY (edc <* externally_defined_class| ('ENGINEERING_PROPERTIES_SCHEMA.' + 'EXTERNAL_SOURCE' IN TYPEOF(edc.source)) AND (SIZEOF(QUERY (aei <* USEDIN(edc, 'ENGINEERING_PROPERTIES_SCHEMA.APPLIED_EXTERNAL_IDENTIFICATION_ASSIGNMENT.ITEMS')| (aei.role.name = 'version'))) > 0))) = 0;
13261   END_RULE;
13262
13263   RULE plib_property_reference_requires_name_scope FOR (externally_defined_engineering_property );
13264   WHERE
13265      WR1:
13266         SIZEOF(QUERY (edep <* externally_defined_engineering_property| ('ENGINEERING_PROPERTIES_SCHEMA.' + 'EXTERNAL_SOURCE' IN TYPEOF(edep.source)) AND (SIZEOF(QUERY (edir <* USEDIN(edep, 'ENGINEERING_PROPERTIES_SCHEMA.' + 'EXTERNALLY_DEFINED_ITEM_RELATIONSHIP.' + 'RELATING_ITEM')| ((edir.name = 'name scope') AND ('ENGINEERING_PROPERTIES_SCHEMA.' + 'EXTERNALLY_DEFINED_CLASS' IN TYPEOF(edir.related_item))) AND ('ENGINEERING_PROPERTIES_SCHEMA.' + 'EXTERNAL_SOURCE' IN TYPEOF(edir.related_item.source)))) <> 1))) = 0;
13267   END_RULE;
13268
13269   RULE plib_property_reference_requires_version FOR (externally_defined_engineering_property );
13270   WHERE
13271      WR1:
13272         SIZEOF(QUERY (edep <* externally_defined_engineering_property| ('ENGINEERING_PROPERTIES_SCHEMA.' + 'EXTERNAL_SOURCE' IN TYPEOF(edep.source)) AND (SIZEOF(QUERY (edir <* USEDIN(edep, 'ENGINEERING_PROPERTIES_SCHEMA.APPLIED_EXTERNAL_IDENTIFICATION_ASSIGNMENT.ITEMS')| (edir.role.name = 'version'))) <> 1))) = 0;
13273   END_RULE;
13274END_SCHEMA;
13275