(*
   $Id$
   ISO TC184/SC4/WG12 N4158 - ISO/TS 10303-1737 Printed physical layout template - EXPRESS ARM
   Supersedes ISO TC184/SC4/WG12 N3582
*)

SCHEMA Printed_physical_layout_template_arm;

USE FROM Functional_usage_view_arm;	-- ISO/TS 10303-1705
USE FROM Part_template_2d_shape_arm; -- ISO/TS 10303-1716
REFERENCE FROM Characterizable_object_arm(bag_to_set);  -- ISO/TS 10303-1765

  TYPE pplt_usage_concept = EXTENSIBLE GENERIC_ENTITY SELECT BASED_ON usage_concept WITH 
    (Printed_part_template_terminal);
  END_TYPE;

  SUBTYPE_CONSTRAINT pplt_template_definition_subtypes FOR Template_definition; 
    ONEOF (Printed_part_template,
      Non_conductive_cross_section_template);
  END_SUBTYPE_CONSTRAINT;

  TYPE printed_part_template_terminal_class = ENUMERATION OF
    (curve_edge_segment,
     surface_point,
     area_edge_segment,
     surface_area);
  END_TYPE;

  ENTITY Basic_multi_stratum_printed_part_template 
    SUBTYPE OF (Printed_part_template);
      material_stack : Library_stack_model;
      reference_template : Stratum_feature_template;
  END_ENTITY;

  ENTITY Functional_usage_view_to_printed_part_template_terminal_assignment;
      physical_usage_view_terminal   : Printed_part_template_terminal;
      functional_usage_view_terminal : Scalar_terminal_definition;
    UNIQUE
      UR1 : functional_usage_view_terminal, physical_usage_view_terminal;
  END_ENTITY;

  ENTITY Multi_stratum_printed_part_template
    SUBTYPE OF (Structured_printed_part_template, Multi_stratum_structured_template);
  END_ENTITY;

  ENTITY Non_conductive_cross_section_template
    SUBTYPE OF (Template_definition);
      template_technology : OPTIONAL SET[1:?] OF Stratum_technology;
      nominal_width       : Length_data_element;
    WHERE
      WR1 : NOT EXISTS(SELF\Product_view_definition.name);
  END_ENTITY;

  ENTITY Printed_connector_template
    SUBTYPE OF (Printed_part_template);
    INVERSE
      characterized_connector_terminal_relationship : SET[1:?] OF printed_connector_template_terminal_relationship FOR connector;
  END_ENTITY;

  ENTITY Printed_connector_template_terminal_relationship;
      join_terminal      : Printed_part_template_join_terminal;
      interface_terminal : Printed_part_template_interface_terminal;
      connector          : Printed_connector_template;
    UNIQUE
      UR1: join_terminal;
    WHERE
      WR1: join_terminal\Printed_part_template_terminal.associated_definition :=: connector;
      WR2: interface_terminal.associated_definition :=: connector;
  END_ENTITY;

  ENTITY Printed_part_cross_section_template
    SUBTYPE OF (Printed_part_template);
      horizontal_material_link                 : OPTIONAL SET[1:?] OF Printed_part_template_material_link;
      vertical_material_link                   : OPTIONAL SET[1:?] OF Printed_part_template_material_link;
      transmission_line_model                  : Analytical_model_definition;
      maximum_transmission_line_characteristic : OPTIONAL SET[1:?] OF Analytical_model_application;
      minimum_transmission_line_characteristic : OPTIONAL SET[1:?] OF Analytical_model_application;
      width                                    : Length_tolerance_characteristic;
      unit_length                              : Length_data_element;
    INVERSE
      SELF\Printed_part_template.access_mechanisms : SET[1:?] OF Printed_part_cross_section_template_terminal FOR associated_definition;
    WHERE
      WR1 : SIZEOF(QUERY(hml <* horizontal_material_link | NOT (hml.precedent_material\Shape_element.element_name IN ['right']))) = 0;
      WR2 : SIZEOF(QUERY(hml <* horizontal_material_link | NOT (hml.subsequent_material\Shape_element.element_name IN ['left']))) = 0;
      WR3 : SIZEOF(QUERY(hml <* vertical_material_link | NOT (hml.precedent_material\Shape_element.element_name IN ['bottom']))) = 0;
      WR4 : SIZEOF(QUERY(hml <* vertical_material_link | NOT (hml.precedent_material\Shape_element.element_name IN ['top']))) = 0;
      WR5 : SIZEOF(QUERY(hml <* horizontal_material_link |
              (SIZEOF(QUERY(vml <* vertical_material_link |
                          (vml :=: hml)
                    )) > 0)
                  )) = 0;
      WR6 : NOT EXISTS(SELF\Product_view_definition.name);
      WR7 : EXISTS(horizontal_material_link) OR EXISTS(vertical_material_link);
      WR8 : NOT ('PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.PRINTED_CONNECTOR_TEMPLATE' IN TYPEOF(SELF));
  END_ENTITY;

  ENTITY Printed_part_cross_section_template_terminal
    SUBTYPE OF (Printed_part_template_terminal);
      SELF\Printed_part_template_terminal.associated_definition    : Printed_part_cross_section_template;
      material_to_left_of_terminal   : OPTIONAL Printed_part_template_material_link;
      material_to_right_of_terminal  : OPTIONAL Printed_part_template_material_link;
      material_to_top_of_terminal    : OPTIONAL Printed_part_template_material_link;
      material_to_bottom_of_terminal : OPTIONAL Printed_part_template_material_link;
    UNIQUE
      UR1 : associated_definition,
        material_to_left_of_terminal,
        material_to_right_of_terminal,
        material_to_top_of_terminal,
        material_to_bottom_of_terminal;
    WHERE
      WR1 : (SELF\Printed_part_template_terminal.connection_zone_category = curve_edge_segment) OR (SELF\Printed_part_template_terminal.connection_zone_category = area_edge_segment);
      WR2 : NOT (EXISTS(material_to_left_of_terminal) AND EXISTS(material_to_right_of_terminal)) OR (material_to_left_of_terminal :<>: material_to_right_of_terminal);
      WR3 : NOT (EXISTS(material_to_left_of_terminal) AND EXISTS(material_to_top_of_terminal)) OR (material_to_left_of_terminal :<>: material_to_top_of_terminal);
      WR4 : NOT (EXISTS(material_to_left_of_terminal) AND EXISTS(material_to_bottom_of_terminal)) OR (material_to_left_of_terminal :<>: material_to_bottom_of_terminal);
      WR5 : NOT (EXISTS(material_to_right_of_terminal) AND EXISTS(material_to_top_of_terminal)) OR (material_to_right_of_terminal :<>: material_to_top_of_terminal);
      WR6 : NOT (EXISTS(material_to_right_of_terminal) AND EXISTS(material_to_bottom_of_terminal)) OR (material_to_right_of_terminal :<>: material_to_bottom_of_terminal);
      WR7 : NOT (EXISTS(material_to_top_of_terminal) AND EXISTS(material_to_bottom_of_terminal)) OR (material_to_top_of_terminal :<>: material_to_bottom_of_terminal);
      WR8 : NOT EXISTS(material_to_left_of_terminal) OR  
                      (material_to_left_of_terminal\Printed_part_template_material_link.precedent_material\Shape_element.element_name = 'right');
      WR9 : NOT EXISTS(material_to_right_of_terminal) OR
                      (material_to_right_of_terminal\Printed_part_template_material_link.subsequent_material\Shape_element.element_name = 'left');
     WR10 : NOT EXISTS(material_to_bottom_of_terminal) OR
                      (material_to_bottom_of_terminal\Printed_part_template_material_link.subsequent_material\Shape_element.element_name = 'top');
     WR11 : NOT EXISTS(material_to_top_of_terminal) OR
                      (material_to_top_of_terminal\Printed_part_template_material_link.precedent_material\Shape_element.element_name = 'bottom');
  END_ENTITY;

  ENTITY Printed_part_template
   ABSTRACT SUPERTYPE OF (ONEOF (Basic_multi_stratum_printed_part_template,
    Structured_printed_part_template,Printed_part_cross_section_template) ANDOR Printed_connector_template)
      SUBTYPE OF (Template_definition);
         implemented_function : OPTIONAL Functional_unit_usage_view;
      INVERSE
        access_mechanisms : SET [1:?] OF Printed_part_template_terminal FOR associated_definition;
      WHERE
        WR1: (SIZEOF(QUERY(prpc <* USEDIN(defined_version.of_product,
            'PRODUCT_IDENTIFICATION_ARM.PRODUCT_CATEGORY_ASSIGNMENT.PRODUCTS')
              | (prpc.category\Product_category.name = 'printed part'))) >= 0) OR 
            ('LAYOUT_MACRO_DEFINITION_ARM.LAYOUT_MACRO_FLOOR_PLAN_TEMPLATE' IN TYPEOF(SELF));
        WR2 : NOT EXISTS(SELF\Product_view_definition.name);
  END_ENTITY;

  ENTITY Printed_part_template_connected_terminals_definition;
      name                : STRING;   
      connected_terminals : SET[2:?] OF Printed_part_template_terminal;
    DERIVE
      scope : Printed_part_template := connected_terminals[1].associated_definition;
    UNIQUE
      UR1 : name, scope;
    WHERE
      WR1 : SIZEOF(QUERY(t <* connected_terminals | t.associated_definition :<>: scope)) = 0;
  END_ENTITY;

  ENTITY Printed_part_template_interface_terminal
    SUBTYPE OF (Printed_part_template_terminal);
      SELF\Printed_part_template_terminal.associated_definition : Printed_connector_template;
    INVERSE
      external_connector_function : SET[1:?] OF printed_connector_template_terminal_relationship FOR interface_terminal;
  END_ENTITY;

  ENTITY Printed_part_template_join_terminal
    SUBTYPE OF (Printed_part_template_terminal);
    INVERSE
      internal_connector_function : SET[0:1] OF printed_connector_template_terminal_relationship FOR join_terminal;
  END_ENTITY;

  ENTITY Printed_part_template_material;
      width             : Length_tolerance_characteristic;
      required_material : Stratum_technology;
    INVERSE
      boundary : SET[0:4] OF template_material_cross_section_boundary FOR associated_definition;
    WHERE
      WR1 : SIZEOF(QUERY(temp <* (USEDIN(SELF,
        'PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.TEMPLATE_MATERIAL_CROSS_SECTION_BOUNDARY.' + 'ASSOCIATED_DEFINITION')) | temp\Shape_element.element_name = 'top')) <= 1;
      WR2 : SIZEOF(QUERY(temp <* (USEDIN(SELF,
        'PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.TEMPLATE_MATERIAL_CROSS_SECTION_BOUNDARY.' + 'ASSOCIATED_DEFINITION')) | temp\Shape_element.element_name = 'bottom')) <= 1;
      WR3 : SIZEOF(QUERY(temp <* (USEDIN(SELF,
        'PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.TEMPLATE_MATERIAL_CROSS_SECTION_BOUNDARY.' + 'ASSOCIATED_DEFINITION')) | temp\Shape_element.element_name = 'left')) <= 1;
      WR4 : SIZEOF(QUERY(temp <* (USEDIN(SELF,
        'PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.TEMPLATE_MATERIAL_CROSS_SECTION_BOUNDARY.' + 'ASSOCIATED_DEFINITION')) | temp\Shape_element.element_name = 'right')) <= 1;
  END_ENTITY;

  ENTITY Printed_part_template_material_link;
      precedent_material  : Template_material_cross_section_boundary;
      subsequent_material : Template_material_cross_section_boundary;
    UNIQUE
      UR1 : precedent_material, subsequent_material;
    WHERE
      WR1 : precedent_material :<>: subsequent_material;
      WR2 : precedent_material\Shape_element.element_name IN ['bottom', 'right'];
      WR3 : subsequent_material\Shape_element.element_name IN ['top', 'left'];
      WR4 : NOT((precedent_material\Shape_element.element_name IN ['bottom']) XOR (subsequent_material\Shape_element.element_name IN ['top']));
      WR5 : NOT((precedent_material\Shape_element.element_name IN ['right']) XOR (subsequent_material\Shape_element.element_name IN ['left']));
      WR6 : acyclic_printed_part_template_material_link(SELF,
        [subsequent_material], 
        'PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.PRINTED_PART_TEMPLATE_MATERIAL_LINK');
  END_ENTITY;

  ENTITY Printed_part_template_terminal
    ABSTRACT SUPERTYPE OF (((ONEOF (Printed_part_template_join_terminal, Printed_part_template_interface_terminal))
      ANDOR (Printed_part_cross_section_template_terminal)) ANDOR Structured_printed_part_template_terminal)
    SUBTYPE OF (Shape_feature);
      SELF\Shape_element.containing_shape RENAMED associated_definition    : Printed_part_template;
      connection_zone_category : printed_part_template_terminal_class;
      SELF\Shape_feature.connection_area : OPTIONAL SET[1:?] OF Connection_zone_in_layout_template;      
    INVERSE
      connection_requirement            : SET[0:1] OF printed_part_template_connected_terminals_definition FOR connected_terminals;
      functional_usage_view_terminal    : SET[0:1] OF functional_usage_view_to_printed_part_template_terminal_assignment FOR physical_usage_view_terminal;
    UNIQUE
      UR1 : SELF\Shape_element.element_name, associated_definition;
    WHERE
      WR1 : NOT EXISTS(SELF\Shape_element.description);
  END_ENTITY;

  ENTITY Printed_tiebar_template
    SUBTYPE OF (Structured_printed_part_template);
      DERIVE
        terminal_location : SET OF Axis_placement_2d :=  pplt_get_tl_ap2d(SELF);
        passage_component_location : SET OF Axis_placement_2d :=  pplt_get_pcl_ap2d(SELF);
        tiebar_shape_model : SET OF Geometric_model := pplt_get_gm(SELF); 
      WHERE
        WR1: SIZEOF(['PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.PRINTED_CONNECTOR_TEMPLATE',
                     'PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.NON_CONDUCTIVE_CROSS_SECTION_TEMPLATE',
                     'PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.PRINTED_PART_CROSS_SECTION_TEMPLATE'] * TYPEOF(SELF)) = 0;
        WR2: SIZEOF(QUERY(am <* SELF\Printed_part_template.access_mechanisms |
             NOT('PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.PRINTED_PART_TEMPLATE_JOIN_TERMINAL' IN TYPEOF(am))
              )) = 0;
        WR3: (SIZEOF(passage_component_location) = 0) OR
          (SIZEOF(QUERY(pcl <* passage_component_location |
          (SIZEOF(QUERY(tsm <* tiebar_shape_model |
          (ap2d_geometrically_in_tiebar(pcl,tsm)))) > 0)
          )) = SIZEOF(passage_component_location));
        WR4: SIZEOF(QUERY(t <* SELF\Structured_template.templates | 'FABRICATION_TECHNOLOGY_ARM.STRATUM_FEATURE_TEMPLATE' IN TYPEOF(t\Template_location_in_structured_template.template))) > 0;
        WR5: SIZEOF(QUERY(spptt <* SELF\Printed_part_template.access_mechanisms | 
          NOT(SIZEOF(USEDIN(spptt,'PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.' + 'PRINTED_PART_TEMPLATE_CONNECTED_TERMINALS_DEFINITION.CONNECTED_TERMINALS')) = 1)
          )) = 0;
        WR6: SIZEOF(QUERY(spptt1 <* SELF\Printed_part_template.access_mechanisms |
          NOT(SIZEOF(QUERY(spptt2 <* SELF\Printed_part_template.access_mechanisms | 
          (bag_to_set(USEDIN(spptt1,'PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.' + 'PRINTED_PART_TEMPLATE_CONNECTED_TERMINALS_DEFINITION.CONNECTED_TERMINALS')) =
          bag_to_set(USEDIN(spptt2,'PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.' + 'PRINTED_PART_TEMPLATE_CONNECTED_TERMINALS_DEFINITION.CONNECTED_TERMINALS'))))) 
          = SIZEOF(SELF\Printed_part_template.access_mechanisms)))) = 0;
        WR7: SIZEOF(QUERY(tl <* terminal_location |
          (SIZEOF(QUERY(pcl <* passage_component_location |
          ((tl :=: pcl) OR 
          (SIZEOF(QUERY(tsm <* tiebar_shape_model |
          (ap2d_geometrically_in_tiebar(tl,tsm)))) > 0)))) > 0)
          )) = SIZEOF(terminal_location);
  END_ENTITY;
  
  ENTITY Single_stratum_printed_part_template
    SUBTYPE OF (Structured_printed_part_template, Single_stratum_structured_template);
  END_ENTITY;
  
  ENTITY Structured_printed_part_template
    ABSTRACT SUPERTYPE OF (ONEOF (Single_stratum_printed_part_template, 
      Multi_stratum_printed_part_template))
    SUBTYPE OF (Printed_part_template, Structured_template);
    WHERE
      WR1 : SIZEOF(QUERY(t <* access_mechanisms |
            NOT ('PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.STRUCTURED_PRINTED_PART_TEMPLATE_TERMINAL'
                  IN TYPEOF(t)))) = 0;
      WR2 : SIZEOF(QUERY(t <* SELF\Structured_template.templates |
            'PART_TEMPLATE_2D_SHAPE_ARM.STRUCTURED_TEMPLATE' IN TYPEOF(t.template))) = 0;
  END_ENTITY;

  ENTITY Structured_printed_part_template_terminal
    SUBTYPE OF (Printed_part_template_terminal);
      SELF\Printed_part_template_terminal.associated_definition : Structured_printed_part_template;
      associated_composition_relationship : Template_location_in_structured_template;
    WHERE
      WR1 : associated_composition_relationship.assembly :=: associated_definition;
      WR2 : TYPEOF(SELF) <> TYPEOF(SELF\Structured_printed_part_template_terminal);
  END_ENTITY;

  ENTITY Template_material_cross_section_boundary
    SUBTYPE OF (Non_feature_shape_element);
      associated_definition : Printed_part_template_material;
    UNIQUE
      UR1 : associated_definition, SELF\Shape_element.element_name;
    WHERE
      WR1 : SELF\Shape_element.element_name IN ['top', 'bottom', 'left', 'right'];
  END_ENTITY;

  FUNCTION acyclic_printed_part_template_material_link
    (relation : Printed_part_template_material_link; 
    relatives : SET[1:?] OF Template_material_cross_section_boundary; 
    specific_relation : STRING) : BOOLEAN; 
  LOCAL
     x : SET OF Printed_part_template_material_link := [];
  END_LOCAL;

    IF relation.precedent_material IN relatives THEN
      RETURN (FALSE);
    END_IF;
    x := QUERY(pd <* bag_to_set(USEDIN(relation.precedent_material,
      'PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.' +
      'PRINTED_PART_TEMPLATE_MATERIAL_LINK.' +
      'SUBSEQUENT_MATERIAL')) | specific_relation IN TYPEOF(pd));
    REPEAT i := 1 TO HIINDEX(x);
      IF NOT acyclic_printed_part_template_material_link(x[i], relatives +
        relation.precedent_material, specific_relation) THEN
        RETURN (FALSE);
      END_IF;
    END_REPEAT;
    RETURN (TRUE);
  END_FUNCTION;

  FUNCTION pplt_get_pcl_ap2d(input : Printed_tiebar_template) : SET OF Axis_placement_2d; 
    LOCAL
	  ap2d : SET OF Axis_placement_2d := [];  --this gives us access to the information base
    END_LOCAL;
	RETURN(ap2d);
  END_FUNCTION;

  FUNCTION ap2d_geometrically_in_tiebar(input_1 : Axis_placement_2d;
                                        input_2 : Geometric_model) : LOGICAL;
    RETURN(TRUE);
  END_FUNCTION;

  FUNCTION pplt_get_tl_ap2d(input : Printed_tiebar_template) : SET OF Axis_placement_2d; 
    LOCAL
	  ap2d : SET OF Axis_placement_2d := [];  --this gives us access to the information base
    END_LOCAL;
	RETURN(ap2d);
  END_FUNCTION;

  FUNCTION pplt_get_gm(input : Printed_tiebar_template) : SET OF Geometric_model; 
    LOCAL
	  gm : SET OF Geometric_model := [];  --this gives us access to the information base
    END_LOCAL;
	RETURN(gm);
  END_FUNCTION;
  
END_SCHEMA;
