(* 
 $Id$
 ISO TC184/SC4/WG12 N2552 - ISO/TS 10303-1341 Generic expression - EXPRESS ARM
 Supersedes ISO TC184/SC4/WG12 N1793
*)

SCHEMA Generic_expression_arm;

ENTITY Binary_generic_expression
ABSTRACT SUPERTYPE
SUBTYPE OF(Generic_expression);
	operands: LIST [2:2] OF Generic_expression;
END_ENTITY;


ENTITY Environment;
	syntactic_representation: Generic_variable;
	semantics: Variable_semantics;
END_ENTITY;


ENTITY Generic_expression
ABSTRACT SUPERTYPE OF(ONEOF(Simple_generic_expression,
			    Unary_generic_expression,
			    Binary_generic_expression,
			    Multiple_arity_generic_expression));
WHERE 
WR1: Is_Acyclic(SELF);
END_ENTITY;


ENTITY Generic_literal
ABSTRACT SUPERTYPE
SUBTYPE OF (Simple_generic_expression);
END_ENTITY; 


ENTITY Generic_variable
ABSTRACT SUPERTYPE OF(Variable)
SUBTYPE OF (Simple_generic_expression);
INVERSE
	interpretation : Environment FOR syntactic_representation;
END_ENTITY;


ENTITY Multiple_arity_generic_expression
ABSTRACT SUPERTYPE
SUBTYPE OF(Generic_expression);
	operands: LIST [2:?] OF Generic_expression;
END_ENTITY;


ENTITY Simple_generic_expression
ABSTRACT SUPERTYPE OF (ONEOF(Generic_literal, Generic_variable))
SUBTYPE OF (Generic_expression);
END_ENTITY;


ENTITY Unary_generic_expression
ABSTRACT SUPERTYPE
SUBTYPE OF(Generic_expression);
	operand: Generic_expression;
END_ENTITY;


ENTITY Variable
ABSTRACT SUPERTYPE
SUBTYPE OF(Generic_variable);
END_ENTITY;


ENTITY Variable_semantics
ABSTRACT SUPERTYPE;
END_ENTITY;


FUNCTION Acyclic (arg1: Generic_expression; 
			arg2: SET OF Generic_expression): BOOLEAN;
LOCAL
	result: BOOLEAN;
END_LOCAL;

IF ('GENERIC_EXPRESSION_ARM.SIMPLE_GENERIC_EXPRESSION'
	IN TYPEOF (arg1)) 
THEN
	RETURN (TRUE);
END_IF;

IF arg1 IN arg2 
THEN 
	RETURN (FALSE);
END_IF;

IF 'GENERIC_EXPRESSION_ARM.UNARY_GENERIC_EXPRESSION' 
	IN TYPEOF (arg1) 
THEN 
	RETURN 
	(Acyclic(arg1\Unary_generic_expression.operand,arg2+[arg1]));
END_IF;

IF 'GENERIC_EXPRESSION_ARM.BINARY_GENERIC_EXPRESSION' 
	IN TYPEOF (arg1) 
THEN 
	RETURN 
	(Acyclic(arg1\Binary_generic_expression.operands[1],arg2+[arg1])
	AND
	Acyclic(arg1\Binary_generic_expression.operands[2],arg2+[arg1]));
END_IF;

IF 
'GENERIC_EXPRESSION_ARM.MULTIPLE_ARITY_GENERIC_EXPRESSION' 
	IN TYPEOF (arg1) 
THEN 
	result := TRUE;
	REPEAT i := 1 TO 
			SIZEOF (arg1\Multiple_arity_generic_expression.operands);
		result := result AND
		Acyclic(arg1\Multiple_arity_generic_expression.operands[i], arg2+[arg1]);
	END_REPEAT;

	RETURN (result);
END_IF;

END_FUNCTION; 

FUNCTION Is_Acyclic (arg: Generic_expression): BOOLEAN;
RETURN (Acyclic (arg, []));
END_FUNCTION ; 

FUNCTION Used_variables (arg : Generic_expression) : 
			SET OF Generic_variable;

LOCAL
	result : SET OF Generic_variable := [];
END_LOCAL;

IF 'GENERIC_EXPRESSION_ARM.GENERIC_VARIABLE' 
	IN TYPEOF (arg) 
THEN 
	RETURN ([arg]);
END_IF;

IF 'GENERIC_EXPRESSION_ARM.UNARY_GENERIC_EXPRESSION' 
	IN TYPEOF (arg)
THEN 
	RETURN (Used_variables (arg\Unary_generic_expression.operand));
END_IF;

IF 'GENERIC_EXPRESSION_ARM.BINARY_GENERIC_EXPRESSION'
	IN TYPEOF (arg)
THEN 
	RETURN(Used_variables(arg\Binary_generic_expression.operands[1])
		+ Used_variables (arg\Binary_generic_expression.operands[2]));
END_IF;

IF
'GENERIC_EXPRESSION_ARM.MULTIPLE_ARITY_GENERIC_EXPRESSION' 
	IN TYPEOF (arg)
THEN
	REPEAT i := 1 TO 
		SIZEOF(arg\Multiple_arity_generic_expression.operands);
		result := result + Used_variables(
			arg\Multiple_arity_generic_expression.operands[i]);
	END_REPEAT;
	
	RETURN (result);
END_IF;
RETURN ([ ]);      
			            
END_FUNCTION; 

END_SCHEMA;
