(*
   $Id$
   ISO TC184/SC4/WG12 N4212 - ISO/TS 10303-1755 Physical connectivity definition - EXPRESS ARM
   Supersedes ISO TC184/SC4/WG12 N3666
*)

SCHEMA Physical_connectivity_definition_arm;

	USE FROM Part_external_reference_arm;	-- ISO/TS 10303-1711
	USE FROM Physical_component_feature_arm;	-- ISO/TS 10303-1721
	USE FROM Requirement_decomposition_arm;	-- ISO/TS 10303-1740

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

	TYPE pcd_groupable_item = SELECT BASED_ON groupable_item WITH 
	   (Physical_connectivity_definition);
	END_TYPE; 

	TYPE pcd_requirement_assignment_item = EXTENSIBLE GENERIC_ENTITY SELECT BASED_ON requirement_assignment_item WITH 
	    (Physical_connectivity_element,
	    Physical_connectivity_definition,
	    Physical_connectivity_definition_relationship);
	END_TYPE; 

	TYPE pcd_documented_element_select = EXTENSIBLE GENERIC_ENTITY SELECT BASED_ON documented_element_select WITH 
		(Physical_connectivity_element,
		 Physical_connectivity_definition);
	END_TYPE;

	TYPE termination_or_junction = EXTENSIBLE GENERIC_ENTITY SELECT
    	(Component_terminal,
    	 Topological_junction);
  	END_TYPE;

  ENTITY Physical_connectivity_definition
    SUPERTYPE OF (Physical_connectivity_structure_definition)
    SUBTYPE OF (Shape_element);
      associated_terminals  : SET[2:?] OF Physical_component_terminal;
      SELF\Shape_element.element_name : STRING;
      SELF\Shape_element.containing_shape RENAMED associated_definition : Physical_unit_network_definition;
    UNIQUE
      UR1 : SELF\Shape_element.element_name, associated_definition;
  END_ENTITY;

  ENTITY Physical_connectivity_definition_relationship;
      first_definition  : Physical_connectivity_definition;
      second_definition : Physical_connectivity_definition;
      purpose           : STRING;
    INVERSE
      requirement : SET[1:1] OF Requirement_assignment FOR assigned_to;
  END_ENTITY;

  ENTITY Physical_connectivity_element;
      name                 : STRING; 
      start_terminus       : termination_or_junction;
      end_terminus         : termination_or_junction;
      connectivity_context : Physical_connectivity_structure_definition;
    UNIQUE
      UR1 : name, connectivity_context;
    WHERE
      WR1 : start_terminus <> end_terminus;
  END_ENTITY;

  ENTITY Physical_connectivity_make_from_relationship;
      reusable_definition  : Physical_connectivity_definition;
      resultant_definition : Physical_connectivity_definition;
  END_ENTITY;

  ENTITY Physical_connectivity_structure_definition
    SUBTYPE OF (Physical_connectivity_definition);
    DERIVE
      structural_terminal_nodes : SET OF Physical_component_terminal := get_pct(structural_element);
      structural_junction_nodes : SET OF Topological_junction := get_tj(structural_element);
      tree_structure : LOGICAL := ((SIZEOF(structural_terminal_nodes) + SIZEOF(structural_junction_nodes)) = (SIZEOF(structural_element) + 1));
    INVERSE
      structural_element : SET[1:?] OF Physical_connectivity_element FOR connectivity_context;
    WHERE
      WR1 : SIZEOF(QUERY(stn <* structural_terminal_nodes |
                   NOT(stn IN SELF\Physical_connectivity_definition.associated_terminals)
                   )) = 0;
      WR2 : SIZEOF(structural_terminal_nodes) = 
            SIZEOF(SELF\Physical_connectivity_definition.associated_terminals);
  END_ENTITY;

  ENTITY Physical_unit_network_definition
    SUBTYPE OF (Part_design_view);
    DERIVE
      terminals : SET [0:?] OF Component_terminal := 
      get_terminals(bag_to_set(USEDIN(SELF,'PHYSICAL_CONNECTIVITY_DEFINITION_ARM.PHYSICAL_CONNECTIVITY_DEFINITION.ASSOCIATED_DEFINITION')));
    WHERE
      WR1 : NOT (SIZEOF(terminals) > 1) OR
           (SIZEOF(QUERY(t <* terminals | NOT(SIZEOF(USEDIN(t, 'PHYSICAL_CONNECTIVITY_DEFINITION_ARM.' + 
                          'PHYSICAL_CONNECTIVITY_DEFINITION.ASSOCIATED_TERMINALS')) = 1))) = 0);
  END_ENTITY;

  ENTITY Topological_junction;
      name  : STRING;   
      scope : Physical_connectivity_structure_definition;
    UNIQUE
      UR1 : name, scope;
  END_ENTITY; 

  FUNCTION get_terminals(input : SET OF Physical_connectivity_definition) : SET OF Component_terminal;
  LOCAL
   ct : SET OF Component_terminal := [];
    i : INTEGER := 0;
  END_LOCAL;
  REPEAT  i := 1 TO SIZEOF(input) BY 1;
   ct := ct + input[i].associated_terminals;
  END_REPEAT;
  RETURN(ct);
  END_FUNCTION;
  
  FUNCTION get_pct(input : SET OF Physical_connectivity_element) : SET OF Physical_component_terminal;
  LOCAL
   pct : SET OF Physical_component_terminal := [];
    i : INTEGER := 0;
  END_LOCAL;
  REPEAT  i := 1 TO SIZEOF(input) BY 1;
   IF ('PHYSICAL_COMPONENT_FEATURE_ARM.PHYSICAL_COMPONENT_TERMINAL' IN TYPEOF(input[i].start_terminus)) THEN
   pct := pct + input[i].start_terminus;
   END_IF;
   IF ('PHYSICAL_COMPONENT_FEATURE_ARM.PHYSICAL_COMPONENT_TERMINAL' IN TYPEOF(input[i].end_terminus)) THEN
   pct := pct + input[i].end_terminus;
   END_IF;
  END_REPEAT;
  RETURN(pct);
  END_FUNCTION;


  FUNCTION get_tj(input : SET OF Physical_connectivity_element) : SET OF Topological_junction;
  LOCAL
   tj : SET OF Topological_junction := [];
    i : INTEGER := 0;
  END_LOCAL;
  REPEAT  i := 1 TO SIZEOF(input) BY 1;
   IF ('PHYSICAL_CONNECTIVITY_DEFINITION_ARM.TOPOLOGICAL_JUNCTION' IN TYPEOF(input[i].start_terminus)) THEN
   tj := tj + input[i].start_terminus;
   END_IF;
   IF ('PHYSICAL_CONNECTIVITY_DEFINITION_ARM.TOPOLOGICAL_JUNCTION' IN TYPEOF(input[i].end_terminus)) THEN
   tj := tj + input[i].end_terminus;
   END_IF;
  END_REPEAT;
  RETURN(tj);
  END_FUNCTION;

END_SCHEMA;
