(*
   $Id$
   ISO TC184/SC4/WG12 N4047 - ISO/TS 10303-1700 Layered interconnect module with printed component design - EXPRESS ARM
   Supersedes ISO TC184/SC4/WG12 N3486
*)

SCHEMA Layered_interconnect_module_with_printed_component_design_arm;   

	USE FROM Layered_interconnect_module_design_arm;	-- ISO/TS 10303-1698
	USE FROM Printed_physical_layout_template_arm;	-- ISO/TS 10303-1737

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

 	TYPE limwpcd_external_identification_item = EXTENSIBLE GENERIC_ENTITY SELECT BASED_ON external_identification_item WITH  
		(Printed_component);
	END_TYPE;

 	TYPE conductor_or_conductive_filled_area = SELECT
		(Conductor, 
		 Conductive_filled_area);
	END_TYPE;

	SUBTYPE_CONSTRAINT limwpcd_assembly_component_subtypes FOR Assembly_component; 
	    (ONEOF (Physical_component,
		 Printed_component,
	 	Laminate_component));
	END_SUBTYPE_CONSTRAINT;

	SUBTYPE_CONSTRAINT limwpcd_structured_layout_component_subtypes FOR Structured_layout_component; 
		(ONEOF (Footprint_occurrence,
			Material_removal_structured_component,
            Multi_stratum_printed_component, 
			Multi_stratum_special_symbol_component,
			Padstack_occurrence,
			Single_stratum_printed_component,
			Single_stratum_special_symbol_component));
	END_SUBTYPE_CONSTRAINT; 

  ENTITY Basic_multi_stratum_printed_component 
    SUBTYPE OF (Printed_component);
      material_stack : Stratum_feature_based_derived_pattern;
      SELF\Printed_component.derived_from : Basic_multi_stratum_printed_part_template;
    DERIVE
      stratum_feature_implementation : Stratum_feature := material_stack.reference_stratum_feature;
  END_ENTITY;

  ENTITY Tiebar_printed_component 
    SUBTYPE OF (Printed_component, Structured_layout_component);
      SELF\Printed_component.derived_from : Printed_tiebar_template;
    DERIVE
      joined_networks : SET OF Generic_physical_network := get_gpn(SELF\Printed_component.access_mechanism);
      tiebar_component : SET OF Area_component := limdwpcd_get_ac(components);
      padstack_component : SET OF Laminate_component := limdwpcd_get_lc(components);
      passage_component : SET OF Plated_passage := QUERY(pc <* padstack_component | ('LAYERED_INTERCONNECT_MODULE_DESIGN_ARM.PLATED_PASSAGE' IN TYPEOF(pc)));
      tiebar_resident_stratum : SET OF Stratum := limdwpcd_get_tbrs(tiebar_component);
      passage_resident_stratum : SET OF Stratum := limdwpcd_get_prs(passage_component, SELF\Assembly_component.assemblies);
      passage_dependent_land_component : SET OF Plated_passage_dependent_land := limdwpcd_get_ppdl(passage_component);  
   INVERSE
    SELF\Assembly_group_component.components  : 
             SET [1:?] OF Structured_layout_component_sub_assembly_relationship FOR relating_view;
    WHERE
     WR1 : (SIZEOF(tiebar_component) + SIZEOF(passage_component)) > 0;
     WR2 : SIZEOF(components) = (SIZEOF(tiebar_component) + SIZEOF(padstack_component));             
     WR3 : SIZEOF(padstack_component) > SIZEOF(passage_component);             
     WR4 : SIZEOF(QUERY(tc <* tiebar_component |
                  NOT('LAYERED_INTERCONNECT_MODULE_DESIGN_ARM.STRATUM_FEATURE' IN TYPEOF
                      (tc\Stratum_feature_template_component.implementation_or_resident_stratum))
                 )) = 0;       
     WR5 : SIZEOF(tiebar_component) = SIZEOF(tiebar_resident_stratum);       
     WR6 : SIZEOF(joined_networks) > 1;
     WR7 : SIZEOF(QUERY(jn <* joined_networks |
                 NOT(SIZEOF(SELF\Printed_component.access_mechanism * jn\Generic_physical_network.connectivity_requirement_element) = 1 )
                 )) = 0;               
     WR8 : SIZEOF(QUERY(tc <* tiebar_component |
           NOT(SIZEOF(USEDIN(tc,'COMPONENT_FEATURE_ARM.COMPONENT_FEATURE.ASSOCIATED_COMPONENT')) = 0)
              )) = 0;
    WR9 : NOT(SIZEOF(passage_component) = 1) OR
             (SIZEOF(QUERY(pc <* passage_component | NOT((SIZEOF(tiebar_component) = 0) OR
                (SIZEOF(tiebar_resident_stratum * passage_resident_stratum) = SIZEOF(tiebar_resident_stratum))
                )
               )) = 0);
    WR10 : NOT(SIZEOF(passage_component) >= 1) OR
              (SIZEOF(QUERY(pc <* passage_component | NOT
                (SIZEOF(tiebar_resident_stratum * passage_resident_stratum) = SIZEOF(tiebar_resident_stratum))
               )) = 0);
   WR11 : SIZEOF(QUERY(am <* SELF\Printed_component.access_mechanism |
           NOT('PRINTED_PHYSICAL_LAYOUT_TEMPLATE_ARM.STRUCTURED_PRINTED_PART_TEMPLATE_TERMINAL' IN TYPEOF(am.definition))
            )) = 0;
END_ENTITY;

FUNCTION limdwpcd_get_ac(input : SET OF Structured_layout_component_sub_assembly_relationship) : SET OF Area_component; 
LOCAL
	sspc : SET OF Stratum_feature_template_component := [];  --this gives us access to the information base
	slcsar : SET OF Structured_layout_component_sub_assembly_relationship :=
                 (QUERY(inp <* input |
                 ('LAYERED_INTERCONNECT_MODULE_DESIGN_ARM.AREA_COMPONENT' IN TYPEOF(inp.related_view)) AND NOT
                 ('LAND_ARM.LAND' IN TYPEOF(inp.related_view)) AND NOT
  ('LAYERED_INTERCONNECT_MODULE_DESIGN_ARM.CONDUCTIVE_INTERCONNECT_ELEMENT_WITH_PRE_DEFINED_TRANSITIONS' IN TYPEOF(inp.related_view)) AND NOT
  ('LAYERED_INTERCONNECT_MODULE_DESIGN_ARM.INTERFACE_ACCESS_STRATUM_FEATURE_TEMPLATE_COMPONENT' IN TYPEOF(inp.related_view))
                 ));
END_LOCAL;

	REPEAT i := 1 to SIZEOF(slcsar) by 1;
	      sspc := sspc + slcsar[i]\Structured_layout_component_sub_assembly_relationship.related_view;
	END_REPEAT;

	RETURN(sspc);
END_FUNCTION;
(*
 desc: limdwpcd_get_ac has as input a set of  
Structured_layout_component_sub_assembly_relationship 
The function returns the set of Area_component that are referenced as the 
related_view for each member of the input. The function does not return an Area_component if that component is one of
Land, Conductive_interconnect_element_with_pre_defined_transitions, Interface_access_stratum_feature_template_component.       
*)

FUNCTION limdwpcd_get_lc(input : SET OF Structured_layout_component_sub_assembly_relationship) : SET OF Laminate_component; 
LOCAL
	sspc : SET OF Laminate_component := [];  --this gives us access to the information base
	slcsar : SET OF Structured_layout_component_sub_assembly_relationship :=
                 (QUERY(inp <* input |
                 ('LAYERED_INTERCONNECT_MODULE_DESIGN_ARM.PADSTACK_DEFINITION' IN TYPEOF
(inp\Structured_layout_component_sub_assembly_relationship.second_location\Template_location_in_structured_template.assembly))
                 ));
END_LOCAL;

	REPEAT i := 1 to SIZEOF(slcsar) by 1;
	      sspc := sspc + slcsar[i]\Structured_layout_component_sub_assembly_relationship.related_view;
	END_REPEAT;

	RETURN(sspc);
END_FUNCTION;
(*
 desc: limdwpcd_get_lc has as input a set of Structured_layout_component_sub_assembly_relationship.
The function returns the set of Laminate_component that are referenced as a related_view for each member of input when a second_location is provided and 
that second_location references a Padstack_definition as an assembly. 
*)

FUNCTION limdwpcd_get_ppdl(input : SET OF Plated_passage) : SET OF Plated_passage_dependent_land; 
LOCAL
	sspc : SET OF Plated_passage_dependent_land := [];  --this gives us access to the information base
END_LOCAL;

	REPEAT i := 1 to SIZEOF(input) by 1;
	      sspc := sspc + bag_to_set(USEDIN(input[i],'LAND_ARM.PLATED_PASSAGE_DEPENDENT_LAND.REFERENCE_PLATED_PASSAGE'));
	END_REPEAT;

	RETURN(sspc);
END_FUNCTION;
(*
 desc: limdwpcd_get_ppdl has as input a set of Plated_passage.
The function returns the set of Plated_passage_dependent_land for which a member of the input is in the role of referenced_plated_passage.
*)

FUNCTION limdwpcd_get_tbrs(input : SET OF Stratum_feature_template_component) : SET OF Stratum; 
LOCAL
	s : SET OF Stratum := [];  --this gives us access to the information base
END_LOCAL;

	REPEAT i := 1 to SIZEOF(input) by 1;
	      s := s + input[i]\Stratum_feature_template_component.resident_stratum;
	END_REPEAT;

	RETURN(s);
END_FUNCTION;
(*
desc: limdwpcd_get_tbrs has as input a set of Stratum_feature_template_component. 
The function returns a set of Stratum where each Stratum is the associated stratum for a member of the input. 
NOTE: If more than one member of input reference the same Stratum, only one member of Stratum will be returned.
*)

FUNCTION limdwpcd_get_prs(input1 : SET OF Plated_passage;
                          input2 : SET OF Product_view_definition) : SET OF Stratum; 
LOCAL
	s : SET OF Stratum := [];  --this gives us access to the information base
	stol : SET OF Stratum_technology_occurrence_link := [];  --this gives us access to the information base
	ptatsm : SET OF Passage_technology_allocation_to_stack_model := [];  --this gives us access to the information base
END_LOCAL;

	REPEAT i := 1 to SIZEOF(input1) by 1;
             ptatsm := ptatsm + input1[i]\Inter_stratum_feature.vertical_extent;
	END_REPEAT;

	REPEAT i := 1 to SIZEOF(ptatsm) by 1;
             stol := stol + ptatsm[i]\Stratum_sub_stack.stratum_technology_sequence;
	END_REPEAT;

             s := limdwpcd_get_stolrs(stol, input2);
	RETURN(s);
END_FUNCTION;
(*
desc: limdwpcd_get_prs has as input a set of Plated_passage. 
The function returns a set of Stratum where each member of that set is in the vertical extent of the input. 
*)

FUNCTION limdwpcd_get_stolrs(input1 : SET OF Stratum_technology_occurrence_link;
                             input2 : SET OF Product_view_definition) : SET OF Stratum; 
LOCAL
	s0 : SET OF Stratum := [];  --this gives us access to the information base for stratum that reference sto
	sto : SET OF Stratum_technology_occurrence := [];  --this gives us access to the information base
	imsar : SET OF Interconnect_module_stratum_assembly_relationship := [];
	s1 : SET OF Stratum := [];  --this gives us access to the information base for stratum that are referenced by the assembly relationship to the input2
	s2 : SET OF Stratum := [];  --this gives us access to the information base for stratum that are related to both input1 and input2
	i : INTEGER := 0; -- variable representing the member of input2 that is the context for the function
END_LOCAL;
(* initial implementation only supports examining the first Product_view_definition as the stratum stack is not expected to change over the design cycle. *)
(* depends on the unique constraint on stratum.definition in an assembly context *)

REPEAT i := 1 to 1 by 1;
	REPEAT j := 1 to SIZEOF(input1) by 1;
	      sto := sto + input1\Stratum_technology_occurrence_relationship.sto_1 +
	                   input1\Stratum_technology_occurrence_relationship.sto_2;
	END_REPEAT;
	
	REPEAT j := 1 to SIZEOF(sto) by 1;
      	     s0 := s0 + bag_to_set(USEDIN(sto[j], 'LAYERED_INTERCONNECT_MODULE_DESIGN_ARM.STRATUM.DEFINITION'));
    END_REPEAT;

    imsar := imsar + bag_to_set(USEDIN(input2[i], 'LAYERED_INTERCONNECT_MODULE_DESIGN_ARM.INTERCONNECT_MODULE_STRATUM_ASSEMBLY_RELATIONSHIP.ASSEMBLY'));

    REPEAT j := 1 to SIZEOF(imsar) by 1;
     s1 := s1 + imsar[j]\Interconnect_module_stratum_assembly_relationship.component;
    END_REPEAT;

    s2 := s0 * s1; -- The intersection of the Stratum that reference the sto and the stratum that are part of the pcb.
END_REPEAT;

	RETURN(s2);
END_FUNCTION;
(*
desc: limdwpcd_get_stolrs has as input a set of Stratum_technology_occurrence_link. 
The function returns a set of Stratum where each member of that set is referenced by a member of Interconnect_module_stratum_assembly_relationship 
that corresponsds to a member of the input. 
NOTE 1 The uniqueness constraint on Stratum permits a set intersection operation to determine the relevant members of Stratum.
NOTE 2 This function assumes that the definition of the Design_stack_model does not change during the detailed design of the interconnect; therefore only 
the first member of input2 establishes the context.
*)

FUNCTION get_gpn(
	input : SET OF printed_component_join_terminal) : SET OF Generic_physical_network; 
LOCAL
	gpn : SET[0:?] OF Generic_physical_network := [];  --this gives us access to the information base
END_LOCAL;

	REPEAT i := 1 to SIZEOF(input) by 1;
		gpn := gpn + bag_to_set(USEDIN(input[i],'LAYERED_INTERCONNECT_MODULE_DESIGN_ARM.GENERIC_PHYSICAL_NETWORK.CONNECTIVITY_REQUIREMENT_ELEMENT'));
	END_REPEAT;

	RETURN(gpn);
END_FUNCTION;
  
  ENTITY Multi_stratum_printed_component
    SUBTYPE OF (Printed_component, Structured_layout_component);
      SELF\Printed_component.derived_from : Multi_stratum_printed_part_template;
  END_ENTITY;

  ENTITY Single_stratum_printed_component
    SUBTYPE OF (Printed_component, Structured_layout_component);
      SELF\Printed_component.derived_from : Single_stratum_printed_part_template;
      stratum_feature_implementation : SET [1:?] OF Stratum_feature;
   WHERE
    WR1 : SIZEOF(QUERY(sfi <* stratum_feature_implementation |
         NOT(sfi.resident_stratum = stratum_feature_implementation[1].resident_stratum)
               )) = 0;
  END_ENTITY;

  ENTITY Printed_component
     ABSTRACT SUPERTYPE OF (ONEOF (Single_stratum_printed_component, 
    Basic_multi_stratum_printed_component,
    Multi_stratum_printed_component))
    SUBTYPE OF (Assembly_component, Single_instance);
      SELF\Definition_based_product_occurrence.derived_from : printed_part_template;
    INVERSE
      access_mechanism : SET[1:?] OF printed_component_join_terminal FOR associated_component;
      cad_layer	: SET[0:1] OF External_source_identification FOR item;
    WHERE
      WR5 : NOT EXISTS(SELF\Product_view_definition.name);
  END_ENTITY;

  ENTITY Printed_component_join_terminal
    SUBTYPE OF (Laminate_component_join_terminal);
      SELF\Component_feature.definition           : Printed_part_template_join_terminal;
      SELF\Component_feature.associated_component : Printed_component;
      stratum_concept_implementation              : Stratum_feature_template_component;
    WHERE
      WR1 : NOT EXISTS(SELF\Shape_element.description);
      WR2 : associated_component.derived_from :=: definition\Printed_part_template_terminal.associated_definition;
  END_ENTITY;

  ENTITY Printed_connector_component
    SUBTYPE OF (Printed_component);
      SELF\Definition_based_product_occurrence.derived_from : Printed_connector_template;
    INVERSE
      interface_access_mechanism : SET[1:?] OF Printed_connector_component_interface_terminal FOR associated_component;
  END_ENTITY;

  ENTITY Printed_connector_component_interface_terminal
    SUBTYPE OF (Laminate_component_interface_terminal);
      SELF\Component_feature.definition           : Printed_part_template_interface_terminal;
      SELF\Component_feature.associated_component : Printed_connector_component;
      stratum_concept_implementation              : Stratum_feature_template_component;
    WHERE
      WR1 : NOT EXISTS(SELF\Shape_element.description);
  END_ENTITY;

  ENTITY Routed_transmission_line
    SUBTYPE OF (Assembly_component, Single_instance);
      routed_centreline_shape                  : Curve;
      SELF\Definition_based_product_occurrence.derived_from : Printed_part_cross_section_template;
      component_extent                         : Inter_stratum_extent;
      curve_parameters                         : Curve_style_parameters;
  END_ENTITY;

  FUNCTION limdwpcd_get_sspc(
	input : SET OF Structured_layout_component_sub_assembly_relationship) : 
      SET OF Single_stratum_printed_component; 
    LOCAL
	  sspc : SET[0:?] OF Single_stratum_printed_component := [];  --this gives us access to the information base
    END_LOCAL;
	REPEAT i := 1 to SIZEOF(input) by 1;
	      sspc := sspc + input[i]\Structured_layout_component_sub_assembly_relationship.related_view;
	END_REPEAT;

	RETURN(sspc);
  END_FUNCTION;

  FUNCTION limdwpcd_get_s(
	input : SET OF Single_stratum_printed_component) : SET OF Stratum; 
    LOCAL
	  s : SET[0:?] OF Stratum := [];  --this gives us access to the information base
    END_LOCAL;

	REPEAT i := 1 to SIZEOF(input) by 1;
	      s := s + input[i]\Single_stratum_printed_component.stratum_feature_implementation[1]\Stratum_feature.resident_stratum;
	END_REPEAT;

	RETURN(s);
  END_FUNCTION;

END_SCHEMA; 
