(*
   $Id$
   ISO TC184/SC4/WG12 N4086 - ISO/TS 10303-1713 Part feature grouping - EXPRESS ARM
   Supersedes ISO TC184/SC4/WG12 N3513
*)

SCHEMA Part_feature_grouping_arm;
 
USE FROM Physical_unit_usage_view_arm;	-- ISO/TS 10303-1732

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

  ENTITY Part_array_feature
    ABSTRACT SUPERTYPE OF (ONEOF (Part_linear_array_feature,
 Part_rectangular_array_feature))
    SUBTYPE OF (Part_group_feature);
  END_ENTITY;

  ENTITY Part_feature_placement_link;
      precedent_element  : Part_feature;
      subsequent_element : Part_feature;
    INVERSE
      referenced_by : part_linear_array_feature FOR element;
    WHERE  
      WR1 : acyclic_part_feature_placement_link(SELF, [subsequent_element], 
        'PART_FEATURE_GROUPING_ARM.PART_FEATURE_PLACEMENT_LINK');
  END_ENTITY;
   
  ENTITY Part_group_feature
    SUPERTYPE OF (Part_array_feature)
    SUBTYPE OF (Part_feature,
 Composite_shape_element);
  END_ENTITY;

  ENTITY Part_linear_array_feature
    SUBTYPE OF (Part_array_feature);
      element                               : SET[1:?] OF Part_feature_placement_link;
      initial_node_positive_x_displacement  : Length_data_element;
      terminus_node_positive_x_displacement : Length_data_element;
      location_uncertainty                  : Length_data_element;
    WHERE  
      WR1 : (1 + SIZEOF(element)) = pfg_get_sz_pf(element);      
  END_ENTITY;

  ENTITY Part_linear_array_feature_link;
      precedent_element  : Part_linear_array_feature;
      subsequent_element : Part_linear_array_feature;
    INVERSE
      referenced_by : part_rectangular_array_feature FOR element;
    WHERE
      WR1 : acyclic_part_linear_array_feature_link(SELF, [subsequent_element], 
        'PART_FEATURE_GROUPING_ARM.PART_LINEAR_ARRAY_FEATURE_LINK');
  END_ENTITY;

  ENTITY Part_rectangular_array_feature
    SUBTYPE OF (Part_array_feature);
      element                              : SET[1:?] OF Part_linear_array_feature_link;
      initial_row_positive_y_displacement  : Length_data_element;
      terminus_row_positive_y_displacement : Length_data_element;
      location_uncertainty                 : Length_data_element;
    WHERE  
      WR1 : (1 + SIZEOF(element)) = pfg_get_sz_plar(element);      
  END_ENTITY;

  FUNCTION acyclic_part_feature_placement_link
    (relation : Part_feature_placement_link; relatives : SET[1:?] OF 
    Part_feature; specific_relation : STRING) : BOOLEAN; 
    LOCAL
      x : SET OF Part_feature_placement_link := [];
    END_LOCAL;
    IF relation.subsequent_element IN relatives THEN
      RETURN (FALSE);
    END_IF;
    x := QUERY(pd <* bag_to_set(USEDIN(relation.subsequent_element,
      'PART_FEATURE_GROUPING_ARM.' +
      'PART_FEATURE_PLACEMENT_LINK.' +
      'SUBSEQUENT_ELEMENT')) | specific_relation IN TYPEOF(pd));
    REPEAT i := 1 TO HIINDEX(x);
      IF NOT acyclic_part_feature_placement_link(x[i], relatives +
        relation.subsequent_element, specific_relation) THEN
        RETURN (FALSE);
      END_IF;
    END_REPEAT;
    RETURN (TRUE);
  END_FUNCTION;    

  FUNCTION acyclic_part_linear_array_feature_link
    (relation : Part_linear_array_feature_link; relatives : SET[1:?] OF 
    Part_linear_array_feature; specific_relation : STRING) : BOOLEAN; 
    LOCAL
      x : SET OF Part_linear_array_feature_link := [];
    END_LOCAL;
    IF relation.subsequent_element IN relatives THEN
      RETURN (FALSE);
    END_IF;
    x := QUERY(pd <* bag_to_set(USEDIN(relation.subsequent_element,
      'PART_FEATURE_GROUPING_ARM.' +
      'PART_LINEAR_ARRAY_FEATURE_LINK.' +
      'SUBSEQUENT_ELEMENT')) | specific_relation IN TYPEOF(pd));
    REPEAT i := 1 TO HIINDEX(x);
      IF NOT acyclic_part_linear_array_feature_link(x[i], relatives +
        relation.subsequent_element, specific_relation) THEN
        RETURN (FALSE);
      END_IF;
    END_REPEAT;
    RETURN (TRUE);
  END_FUNCTION; 

  FUNCTION pfg_get_sz_pf (input : SET[1:?] OF Part_feature_placement_link) : INTEGER;
    LOCAL
      ac : SET OF Part_feature := [];
    END_LOCAL;
    REPEAT i := 1 TO HIINDEX(input);
      ac := ac + input[i]\Part_feature_placement_link.precedent_element +
        input[i]\Part_feature_placement_link.subsequent_element;
    END_REPEAT;
    RETURN (SIZEOF(ac));
  END_FUNCTION; 

  FUNCTION pfg_get_sz_plar (input : SET[1:?] OF Part_linear_array_feature_link) : INTEGER;
    LOCAL
      ac : SET OF Part_linear_array_feature := [];
    END_LOCAL;
    REPEAT i := 1 TO HIINDEX(input);
      ac := ac + input[i]\Part_linear_array_feature_link.precedent_element +
        input[i]\Part_linear_array_feature_link.subsequent_element;
    END_REPEAT;
    RETURN (SIZEOF(ac));
  END_FUNCTION;

END_SCHEMA;
