(*
$Id$
ISO TC184/SC4/WG12 N2887 - ISO/IS 10303-41 Fundamentals of product description and support - EXPRESS
*) 


SCHEMA external_reference_schema;

REFERENCE FROM basic_attribute_schema   -- ISO 10303-41
  (description_attribute,
   get_description_value); 

REFERENCE FROM support_resource_schema   -- ISO 10303-41
  (bag_to_set,
   identifier,
   label,
   text); 


TYPE message = STRING;
END_TYPE; 

TYPE source_item = SELECT
   (identifier, 
    message);
END_TYPE; 

ENTITY external_source;
  source_id : source_item;
DERIVE
  description : text := get_description_value (SELF);
WHERE
  WR1: SIZEOF (USEDIN (SELF, 'BASIC_ATTRIBUTE_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
END_ENTITY;

ENTITY external_source_relationship;
  name : label;
  description : OPTIONAL text;
  relating_source : external_source;
  related_source : external_source;
END_ENTITY;

ENTITY externally_defined_item;
  item_id : source_item;
  source : external_source;
END_ENTITY;

ENTITY externally_defined_item_relationship;
  name : label;
  description : OPTIONAL text;
  relating_item : externally_defined_item;
  related_item : externally_defined_item;
END_ENTITY;

ENTITY pre_defined_item;
  name : label;
END_ENTITY;

FUNCTION acyclic_external_source_relationship
 (relation : external_source_relationship; relatives : SET[1:?] OF external_source; specific_relation : STRING) : BOOLEAN; 
  LOCAL
      x : SET OF external_source_relationship;
    END_LOCAL;

    IF relation.relating_source IN relatives THEN
      RETURN (FALSE);
    END_IF;
    x := QUERY(es <* bag_to_set(USEDIN(relation.relating_source, 'EXTERNAL_REFERENCE_SCHEMA.' + 'EXTERNAL_SOURCE_RELATIONSHIP.' + 'RELATED_SOURCE')) | specific_relation IN TYPEOF(es));
    REPEAT i := 1 TO HIINDEX(x);
      IF NOT acyclic_external_source_relationship(x[i], relatives + relation.relating_source, specific_relation) THEN
        RETURN (FALSE);
      END_IF;
    END_REPEAT;
    RETURN (TRUE);
END_FUNCTION; 

FUNCTION acyclic_externally_defined_item_relationship
 (relation : externally_defined_item_relationship; relatives : SET[1:?] OF externally_defined_item; specific_relation : STRING) : BOOLEAN; 
  LOCAL
      x : SET OF externally_defined_item_relationship;
    END_LOCAL;

    IF relation.relating_item IN relatives THEN
      RETURN (FALSE);
    END_IF;
    x := QUERY(edi <* bag_to_set(USEDIN(relation.relating_item, 'EXTERNAL_REFERENCE_SCHEMA.' + 'EXTERNALLY_DEFINED_ITEM_RELATIONSHIP.' + 'RELATED_ITEM')) | specific_relation IN TYPEOF(edi));
    REPEAT i := 1 TO HIINDEX(x);
      IF NOT acyclic_externally_defined_item_relationship(x[i], relatives + relation.relating_item, specific_relation) THEN
        RETURN (FALSE);
      END_IF;
    END_REPEAT;
    RETURN (TRUE);
END_FUNCTION; 

END_SCHEMA;  -- external_reference_schema
