(*
   $Id$
   ISO TC184/SC4/WG12 N4143 - ISO/TS 10303-1732 Physical unit usage view - EXPRESS ARM
   Supersedes ISO TC184/SC4/WG12 N3579
*)

SCHEMA Physical_unit_usage_view_arm;

USE FROM Analytical_model_arm;	-- ISO/TS 10303-1603
USE FROM Feature_and_connection_zone_arm;	-- ISO/TS 10303-1671
USE FROM Item_definition_structure_arm;	-- ISO/TS 10303-1345
USE FROM Part_feature_location_arm;	-- ISO/TS 10303-1714
USE FROM Requirement_assignment_arm;	-- ISO/TS 10303-1233
USE FROM Shape_composition_arm;	-- ISO/TS 10303-1742

REFERENCE FROM Characterizable_object_arm(bag_to_set);  -- ISO/TS 10303-1765

  TYPE material_state_change_enumeration = ENUMERATION OF
    (material_addition,
     material_removal);
  END_TYPE;

  TYPE physical_unit = EXTENSIBLE GENERIC_ENTITY SELECT(Part_usage_view);
  END_TYPE;   

  TYPE puuv_groupable_item = SELECT BASED_ON groupable_item WITH 
    (Part_feature);
  END_TYPE; 

  TYPE puuv_requirement_assignment_item = EXTENSIBLE GENERIC_ENTITY SELECT BASED_ON requirement_assignment_item WITH 
    (Part_feature,
     Part_view_definition);
  END_TYPE; 

  TYPE puuv_documented_element_select = EXTENSIBLE GENERIC_ENTITY SELECT BASED_ON documented_element_select WITH 
    (Part_feature);
  END_TYPE;

  TYPE puuv_usage_concept = EXTENSIBLE GENERIC_ENTITY SELECT BASED_ON usage_concept WITH 
    (Part_feature);
  END_TYPE;
	
  ENTITY Derived_part_view_definition_relationship
    SUBTYPE OF(View_definition_relationship);
      SELF\View_definition_relationship.relating_view : Part_view_definition;
      SELF\View_definition_relationship.related_view  : Part_view_definition;
    WHERE
      WR1: SIZEOF(get_derived_shape_element(SELF\View_definition_relationship.related_view)) > 0;
      WR2: SIZEOF(QUERY(gdrse <* get_derived_shape_element(SELF\View_definition_relationship.related_view) |
             (SIZEOF(QUERY(se <* gdrse.derived_from |
              SELF\View_definition_relationship.relating_view <> se.containing_shape.described_element
              )) = 0)
             )) = SIZEOF(get_derived_shape_element(SELF\View_definition_relationship.related_view));
      WR3 : NOT EXISTS(SELF\View_definition_relationship.relation_type);             
  END_ENTITY;

  ENTITY Connection_zone_in_usage_view
  	SUBTYPE OF (Connection_zone);
  	DERIVE
  	  associated_definition : Part_usage_view := containing_shape.described_element;
    WHERE
      WR1 : NOT EXISTS(SELF\Shape_element.element_name);
  END_ENTITY; 

  ENTITY Connection_zone_map_identification;
      reference_connection_zone_shape : Usage_view_connection_zone_terminal_shape_relationship;
      mapped_connection_zone_shape    : Usage_view_connection_zone_terminal_shape_relationship;
    UNIQUE
      UR1 : reference_connection_zone_shape, mapped_connection_zone_shape;
    WHERE
      WR1 : reference_connection_zone_shape <> mapped_connection_zone_shape;
      WR2 : reference_connection_zone_shape.associated_connection_zone_shape_definition <> mapped_connection_zone_shape.associated_connection_zone_shape_definition;
  END_ENTITY;

  ENTITY Part_feature
    SUBTYPE OF (Shape_feature);
      SELF\Shape_element.containing_shape RENAMED associated_definition : Part_usage_view;
      material_state_change   : OPTIONAL material_state_change_enumeration;
      precedent_feature       : OPTIONAL Part_feature;
    INVERSE
      subsequent_feature      : SET [0:1] OF Part_feature for precedent_feature;
    WHERE
      WR1:  NOT EXISTS(precedent_feature) OR
            (NOT (SIZEOF(subsequent_feature) = 1) OR
            (acyclic_part_feature_precedence_relationship(SELF,
             [subsequent_feature[1]],
             'PHYSICAL_UNIT_USAGE_VIEW_ARM.PART_FEATURE')));
      WR2 : NOT EXISTS(SELF\Shape_element.description);
  END_ENTITY;

  ENTITY Part_feature_make_from_relationship
  	SUBTYPE OF (Shape_element_relationship);
      associated_make_from : View_definition_relationship;
      SELF\Shape_element_relationship.relating RENAMED reusable_feature	: Part_feature;
      SELF\Shape_element_relationship.related RENAMED resultant_feature	: Part_feature;
    UNIQUE
      UR1 : reusable_feature, resultant_feature;
    WHERE
      WR1 : reusable_feature :<>: resultant_feature;
      WR2 : reusable_feature.associated_definition :<>: resultant_feature.associated_definition;
  END_ENTITY;

  ENTITY Part_feature_template_definition
    SUBTYPE OF (Shape_feature_definition);
      id : STRING;
    DERIVE
      surface_conditions : SET OF Surface_condition := 
	       bag_to_set(USEDIN(SELF\Shape_feature_definition.of_shape,'SURFACE_CONDITIONS_ARM.SURFACE_CONDITION_ASSOCIATION.DESCRIBED_ELEMENT'));	  
    UNIQUE
      UR1 : id; 
  END_ENTITY;

  ENTITY Part_feature_template_shape_model
    SUBTYPE OF (Geometric_model);
    WHERE
      WR1 : NOT (SIZEOF(USEDIN(SELF, '')) > 1) OR 
       (SIZEOF(QUERY(foo <* USEDIN(SELF,'') | 
       NOT(SIZEOF(['PHYSICAL_UNIT_USAGE_VIEW_ARM.USAGE_CONCEPT_USAGE_RELATIONSHIP',
        'PHYSICAL_UNIT_USAGE_VIEW_ARM.SHAPE_DESCRIPTION_ASSOCIATION'] * TYPEOF(foo))= 1)
        )) 
        = 0);
      WR2 : NOT EXISTS(SELF\Representation.description);
      WR3: ((SIZEOF(USEDIN(SELF,
       'SHAPE_PROPERTY_ASSIGNMENT_ARM.SHAPE_DESCRIPTION_ASSOCIATION.REPRESENTATION'))=0) OR
       (SIZEOF(QUERY(sda <* USEDIN(SELF,
       'SHAPE_PROPERTY_ASSIGNMENT_ARM.SHAPE_DESCRIPTION_ASSOCIATION.REPRESENTATION') | 
       NOT (('SHAPE_PROPERTY_ASSIGNMENT_ARM.' +'ITEM_SHAPE' IN
       TYPEOF(sda.represented_characteristic)) AND 
       ('PHYSICAL_UNIT_USAGE_VIEW_ARM.' +'PART_FEATURE_TEMPLATE_DEFINITION' IN
       TYPEOF(sda.represented_characteristic.described_element)))
       )) = 0));
  END_ENTITY;

  ENTITY Part_usage_view
    SUBTYPE OF (Part_view_definition, Item_shape);
    DERIVE
      SELF\Item_shape.described_element : shapeable_item := SELF;
  END_ENTITY;

  ENTITY Usage_view_connection_zone_terminal_shape_relationship;
      associating_terminal_shape                  : Part_feature_template_shape_model;
      associated_usage                            : Connection_zone_in_usage_view;
      associated_connection_zone_shape_definition : Geometric_model;
      associated_usage_placement                  : Axis_placement;
    WHERE
      WR1 : associating_terminal_shape :<>: associated_connection_zone_shape_definition;
  END_ENTITY;

  RULE unique_assembly_component_relationship FOR (Assembly_component_relationship);
   LOCAL
     gee : SET OF Product_view_definition := [];
     gei : SET OF Product_view_definition := [];
   END_LOCAL;
   REPEAT i := 1 to SIZEOF(Assembly_component_relationship) by 1;
     gee  := gee + Assembly_component_relationship[i]\Product_occurrence_definition_relationship.related_view;
     gei  := gei + Assembly_component_relationship[i]\Product_occurrence_definition_relationship.relating_view;
   END_REPEAT;  
  WHERE
   WR1 : SIZEOF(gee) = SIZEOF(gei);
  END_RULE;

  FUNCTION acyclic_part_feature_precedence_relationship
      (relation : Part_feature; relatives : SET[1:?] OF
      Part_feature; specific_relation : STRING) : BOOLEAN; 
    LOCAL
      x : SET OF Part_feature;
    END_LOCAL;

    IF relation.precedent_feature IN relatives THEN
      RETURN (FALSE);
    END_IF;
      x := QUERY(pd <* bag_to_set(USEDIN(relation.precedent_feature,
        'PHYSICAL_UNIT_USAGE_VIEW_ARM.' + 'PART_FEATURE.' +
        'SUBSEQUENT_FEATURE')) | specific_relation IN TYPEOF(pd));
    REPEAT i := 1 TO HIINDEX(x);
      IF NOT acyclic_part_feature_precedence_relationship(x[i], relatives +
        relation.precedent_feature, specific_relation) THEN
        RETURN (FALSE);
      END_IF;
    END_REPEAT;
    RETURN (TRUE);
  END_FUNCTION; 

  FUNCTION get_derived_shape_element( input : Part_view_definition) : SET OF Derived_shape_element;
    LOCAL
      is : SET OF Item_shape := bag_to_set(USEDIN(input, 'SHAPE_PROPERTY_ASSIGNMENT_ARM.ITEM_SHAPE.DESCRIBED_ELEMENT'));
      se : SET OF Shape_element := [];
    END_LOCAL; 
    REPEAT i := 1 to SIZEOF(is) by 1;
      se  := se + bag_to_set(USEDIN(is[i], 'SHAPE_PROPERTY_ASSIGNMENT_ARM.SHAPE_ELEMENT.CONTAINING_SHAPE'));
    END_REPEAT;  
    RETURN(QUERY(dse <* se | 'DERIVED_SHAPE_ELEMENT_ARM.DERIVED_SHAPE_ELEMENT' IN TYPEOF(se)));
  END_FUNCTION;

END_SCHEMA;

