FUNCTION simplify_generic_expression

(* SCHEMA Ap242_managed_model_based_3d_engineering_mim_LF; *)
FUNCTION simplify_generic_expression(expr : generic_expression) : maths_value;
  FUNCTION restore_unary(expr : unary_generic_expression;
                         opnd : generic_expression) : generic_expression;
    expr.operand := opnd;
    RETURN (expr);
  END_FUNCTION;  -- restore_unary
  FUNCTION restore_binary(expr       : binary_generic_expression;
                          opd1, opd2 : generic_expression) : generic_expression;
    expr.operands[1] := opd1;
    expr.operands[2] := opd2;
    RETURN (expr);
  END_FUNCTION;  -- restore_binary
  FUNCTION restore_mulary(expr : multiple_arity_generic_expression;
                          ops  : LIST OF generic_expression) : generic_expression;
    expr.operands := ops;
    RETURN (expr);
  END_FUNCTION;  -- restore_mulary
  FUNCTION make_number_literal(nmb : NUMBER) : generic_literal;
    IF 'INTEGER' IN TYPEOF (nmb) THEN  RETURN (make_int_literal(nmb));  END_IF;
    RETURN (make_real_literal(nmb));
  END_FUNCTION;  -- make_number_literal;
  LOCAL
    types : SET OF STRING := stripped_typeof (expr);
    v1, v2 : maths_value;
    vlist : LIST OF maths_value := [];
    op1, op2 : generic_expression;
    oplist : LIST OF generic_expression := [];
    opnds : LIST [2:?] OF generic_expression;
    n, m : INTEGER;
    finfun : maths_function_select;
    boo : BOOLEAN;
    str : STRING;
    nmb : NUMBER;
  END_LOCAL;
  -- Unwrap the elementary kinds of literals
  IF 'INT_LITERAL' IN types THEN
    RETURN (convert_to_maths_value (expr\int_literal.the_value));
  END_IF;
  IF 'REAL_LITERAL' IN types THEN
    RETURN (convert_to_maths_value (expr\real_literal.the_value));
  END_IF;
  IF 'BOOLEAN_LITERAL' IN types THEN
    RETURN (convert_to_maths_value (expr\boolean_literal.the_value));
  END_IF;
  IF 'STRING_LITERAL' IN types THEN
    RETURN (convert_to_maths_value (expr\string_literal.the_value));
  END_IF;
  IF 'COMPLEX_NUMBER_LITERAL' IN types THEN
    RETURN (expr);  -- No simpler expression available
  END_IF;
  IF 'LOGICAL_LITERAL' IN types THEN
    RETURN (convert_to_maths_value (expr\logical_literal.lit_value));
  END_IF;
  IF 'BINARY_LITERAL' IN types THEN
    RETURN (convert_to_maths_value (expr\binary_literal.lit_value));
  END_IF;
  IF 'MATHS_ENUM_LITERAL' IN types THEN
    RETURN (expr\maths_enum_literal.lit_value);
  END_IF;
  IF 'REAL_TUPLE_LITERAL' IN types THEN
    RETURN (convert_to_maths_value (expr\real_tuple_literal.lit_value));
  END_IF;
  IF 'INTEGER_TUPLE_LITERAL' IN types THEN
    RETURN (convert_to_maths_value (expr\integer_tuple_literal.lit_value));
  END_IF;
  IF 'ATOM_BASED_LITERAL' IN types THEN
    RETURN (expr\atom_based_literal.lit_value);
  END_IF;
  IF 'MATHS_TUPLE_LITERAL' IN types THEN
    RETURN (convert_to_maths_value (expr\maths_tuple_literal.lit_value));
  END_IF;
  -- Simplify one special class of literals
  IF 'MATHS_SPACE' IN types THEN
    RETURN (simplify_maths_space(expr));
  END_IF;
  -- Simplify one special kind of expression
  IF 'FUNCTION_APPLICATION' IN types THEN
    RETURN (simplify_function_application(expr));
  END_IF;
  -- Separate and simplify the operands
  IF 'UNARY_GENERIC_EXPRESSION' IN types THEN
    v1 := simplify_generic_expression(expr\unary_generic_expression.operand);
    op1 := convert_to_operand(v1);
  END_IF;
  IF 'BINARY_GENERIC_EXPRESSION' IN types THEN
    v1 := simplify_generic_expression(expr\binary_generic_expression.operands[1]);
    op1 := convert_to_operand(v1);
    v2 := simplify_generic_expression(expr\binary_generic_expression.operands[2]);
    op2 := convert_to_operand(v2);
  END_IF;
  IF 'MULTIPLE_ARITY_GENERIC_EXPRESSION' IN types THEN
    opnds := expr\multiple_arity_generic_expression.operands;
    REPEAT i := 1 TO SIZEOF (opnds);
      v1 := simplify_generic_expression(opnds[i]);
      INSERT (vlist, v1, i-1);
      INSERT (oplist, convert_to_operand(v1), i-1);
    END_REPEAT;
  END_IF;
  -- Simplify the one kind of maths_function which derives its operands.
  IF 'PARALLEL_COMPOSED_FUNCTION' IN types THEN
    v1 := vlist[1];
    n := SIZEOF (vlist);
    finfun := vlist[n];
    REMOVE (vlist, n);
    REMOVE (vlist, 1);
    RETURN (make_parallel_composed_function(v1,vlist,finfun));
  END_IF;
  -- Simplify individual kinds of expressions.  It is not necessary to cover all cases.
  IF ('ABS_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
    RETURN (convert_to_maths_value (ABS(v1)));
  END_IF;
  IF ('ACOS_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
    RETURN (convert_to_maths_value (ACOS(v1)));
  END_IF;
  IF 'AND_EXPRESSION' IN types THEN
    REPEAT i := SIZEOF (vlist) TO 1 BY -1;
      IF 'BOOLEAN' IN TYPEOF (vlist[i]) THEN
        boo := vlist[i];
        IF NOT boo THEN  RETURN (convert_to_maths_value(FALSE));  END_IF;
        REMOVE (oplist, i);
      END_IF;
    END_REPEAT;
    IF SIZEOF (oplist) = 0 THEN  RETURN (convert_to_maths_value(TRUE));  END_IF;
    IF SIZEOF (oplist) = 1 THEN  RETURN (oplist[1]);  END_IF;
  END_IF;
  IF ('ASIN_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
    RETURN (convert_to_maths_value (ASIN(v1)));
  END_IF;
  IF ('ATAN_EXPRESSION' IN types) AND
    ('NUMBER' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2)) THEN
    RETURN (convert_to_maths_value (ATAN(v1,v2)));
  END_IF;
  IF ('COMPARISON_EXPRESSION' IN types) AND (
    (('NUMBER' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2))) OR
    (('STRING' IN TYPEOF (v1)) AND ('STRING' IN TYPEOF (v2))) OR
    (('BOOLEAN' IN TYPEOF (v1)) AND ('BOOLEAN' IN TYPEOF (v2))) ) THEN
    IF      'COMPARISON_EQUAL'         IN types THEN  boo := bool(v1 = v2);
    ELSE IF 'COMPARISON_GREATER'       IN types THEN  boo := bool(v1 > v2);
    ELSE IF 'COMPARISON_GREATER_EQUAL' IN types THEN  boo := bool(v1 >= v2);
    ELSE IF 'COMPARISON_LESS'          IN types THEN  boo := bool(v1 < v2);
    ELSE IF 'COMPARISON_LESS_EQUAL'    IN types THEN  boo := bool(v1 <= v2);
    ELSE IF 'COMPARISON_NOT_EQUAL'     IN types THEN  boo := bool(v1 <> v2);
    ELSE IF 'LIKE_EXPRESSION'          IN types THEN  boo := bool(v1 LIKE v2);
    ELSE  RETURN (?);  -- Unreachable
    END_IF;  END_IF;  END_IF;  END_IF;  END_IF;  END_IF;  END_IF;
    RETURN (convert_to_maths_value (boo));
  END_IF;
  IF 'CONCAT_EXPRESSION' IN types THEN
    str := '';
    REPEAT i := SIZEOF (vlist) TO 1 BY -1;
      IF 'STRING' IN TYPEOF (vlist[i]) THEN
        str := vlist[i] + str;
        REMOVE (oplist, i);
      ELSE IF LENGTH(str) > 0 THEN
        INSERT (oplist, make_string_literal(str), i);
        str := '';
      END_IF;  END_IF;
    END_REPEAT;
    IF SIZEOF (oplist) = 0 THEN  RETURN (convert_to_maths_value(str));  END_IF;
    IF LENGTH(str) > 0 THEN  INSERT (oplist, make_string_literal(str), 0);  END_IF;
    IF SIZEOF (oplist) = 1 THEN  RETURN (oplist[1]);  END_IF;
  END_IF;
  IF ('COS_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
    RETURN (convert_to_maths_value (COS(v1)));
  END_IF;
  IF ('DIV_EXPRESSION' IN types) AND
    ('NUMBER' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2)) THEN
    RETURN (convert_to_maths_value (v1 DIV v2));
  END_IF;
  IF 'EQUALS_EXPRESSION' IN types THEN
    opnds := expr\binary_generic_expression.operands;
    RETURN (convert_to_maths_value (opnds[1] :=: opnds[2]));
  END_IF;
  IF ('EXP_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
    RETURN (convert_to_maths_value (EXP(v1)));
  END_IF;
  IF ('FORMAT_EXPRESSION' IN types) AND
    ('NUMBER' IN TYPEOF (v1)) AND ('STRING' IN TYPEOF (v2)) THEN
    RETURN (convert_to_maths_value (FORMAT(v1,v2)));
  END_IF;
  IF ('INDEX_EXPRESSION' IN types) AND
    ('STRING' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2)) THEN
    str := v1;  n := v2;
    RETURN (convert_to_maths_value (str[n]));
  END_IF;
  IF ('INT_VALUE_EXPRESSION' IN types) AND ('STRING' IN TYPEOF (v1)) THEN
    RETURN (convert_to_maths_value (VALUE(v1)));
  END_IF;
  IF 'INTERVAL_EXPRESSION' IN types THEN
    str := '';
    IF 'NUMBER'  IN TYPEOF (vlist[1]) THEN str := 'NUMBER';   END_IF;
    IF 'STRING'  IN TYPEOF (vlist[1]) THEN str := 'STRING';   END_IF;
    IF 'BOOLEAN' IN TYPEOF (vlist[1]) THEN str := 'BOOLEAN';  END_IF;
    IF (LENGTH (str) > 0) AND (str IN TYPEOF (vlist[2])) AND
      (str IN TYPEOF (vlist[3])) THEN
      RETURN (convert_to_maths_value ({vlist[1] <= vlist[2] <= vlist[3]}));
    END_IF;
  END_IF;
  IF ('LENGTH_EXPRESSION' IN types) AND ('STRING' IN TYPEOF (v1)) THEN
    RETURN (convert_to_maths_value (LENGTH(v1)));
  END_IF;
  IF ('LOG_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
    RETURN (convert_to_maths_value (LOG(v1)));
  END_IF;
  IF ('LOG10_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
    RETURN (convert_to_maths_value (LOG10(v1)));
  END_IF;
  IF ('LOG2_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
    RETURN (convert_to_maths_value (LOG2(v1)));
  END_IF;
  IF 'MAXIMUM_EXPRESSION' IN types THEN
    boo := FALSE;
    REPEAT i := SIZEOF (vlist) TO 1 BY -1;
      IF 'NUMBER' IN TYPEOF (vlist[i]) THEN
        IF boo THEN
          IF nmb < vlist[i] THEN  nmb := vlist[i];  END_IF;
        ELSE
          nmb := vlist[i];  boo := TRUE;
        END_IF;
        REMOVE (oplist, i);
      END_IF;
    END_REPEAT;
    IF SIZEOF (oplist) = 0 THEN  RETURN (convert_to_maths_value(nmb));  END_IF;
    IF boo THEN  INSERT (oplist, make_number_literal(nmb), 0);  END_IF;
  END_IF;
  IF 'MINIMUM_EXPRESSION' IN types THEN
    boo := FALSE;
    REPEAT i := SIZEOF (vlist) TO 1 BY -1;
      IF 'NUMBER' IN TYPEOF (vlist[i]) THEN
        IF boo THEN
          IF nmb > vlist[i] THEN  nmb := vlist[i];  END_IF;
        ELSE
          nmb := vlist[i];  boo := TRUE;
        END_IF;
        REMOVE (oplist, i);
      END_IF;
    END_REPEAT;
    IF SIZEOF (oplist) = 0 THEN  RETURN (convert_to_maths_value(nmb));  END_IF;
    IF boo THEN  INSERT (oplist, make_number_literal(nmb), 0);  END_IF;
  END_IF;
  IF ('MINUS_EXPRESSION' IN types) AND
    ('NUMBER' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2)) THEN
    RETURN (convert_to_maths_value (v1 - v2));
  END_IF;
  IF ('MOD_EXPRESSION' IN types) AND
    ('NUMBER' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2)) THEN
    RETURN (convert_to_maths_value (v1 MOD v2));
  END_IF;
  IF 'MULT_EXPRESSION' IN types THEN
    nmb := 1;
    REPEAT i := SIZEOF (vlist) TO 1 BY -1;
      IF 'NUMBER' IN TYPEOF (vlist[i]) THEN
        nmb := nmb * vlist[i];
        REMOVE (oplist, i);
      END_IF;
    END_REPEAT;
    IF SIZEOF (oplist) = 0 THEN  RETURN (convert_to_maths_value(nmb));  END_IF;
    IF nmb <> 1 THEN  INSERT (oplist, make_number_literal(nmb), 0);  END_IF;
    IF SIZEOF (oplist) = 1 THEN  RETURN (oplist[1]);  END_IF;
  END_IF;
  IF ('NOT_EXPRESSION' IN types) AND ('BOOLEAN' IN TYPEOF (v1)) THEN
    boo := v1;
    RETURN (convert_to_maths_value (NOT(boo)));
  END_IF;
  IF ('ODD_EXPRESSION' IN types) AND ('INTEGER' IN TYPEOF (v1)) THEN
    RETURN (convert_to_maths_value (ODD(v1)));
  END_IF;
  IF 'OR_EXPRESSION' IN types THEN
    REPEAT i := SIZEOF (vlist) TO 1 BY -1;
      IF 'BOOLEAN' IN TYPEOF (vlist[i]) THEN
        boo := vlist[i];
        IF boo THEN  RETURN (convert_to_maths_value(TRUE));  END_IF;
        REMOVE (oplist, i);
      END_IF;
    END_REPEAT;
    IF SIZEOF (oplist) = 0 THEN  RETURN (convert_to_maths_value(FALSE));  END_IF;
    IF SIZEOF (oplist) = 1 THEN  RETURN (oplist[1]);  END_IF;
  END_IF;
  IF 'PLUS_EXPRESSION' IN types THEN
    nmb := 0;
    REPEAT i := SIZEOF (vlist) TO 1 BY -1;
      IF 'NUMBER' IN TYPEOF (vlist[i]) THEN
        nmb := nmb + vlist[i];
        REMOVE (oplist, i);
      END_IF;
    END_REPEAT;
    IF SIZEOF (oplist) = 0 THEN  RETURN (convert_to_maths_value(nmb));  END_IF;
    IF nmb <> 0 THEN  INSERT (oplist, make_number_literal(nmb), 0);  END_IF;
    IF SIZEOF (oplist) = 1 THEN  RETURN (oplist[1]);  END_IF;
  END_IF;
  IF ('POWER_EXPRESSION' IN types) AND
    ('NUMBER' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2)) THEN
    RETURN (convert_to_maths_value (v1 ** v2));
  END_IF;
  IF ('SIN_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
    RETURN (convert_to_maths_value (SIN(v1)));
  END_IF;
  IF ('SLASH_EXPRESSION' IN types) AND
    ('NUMBER' IN TYPEOF (v1)) AND ('NUMBER' IN TYPEOF (v2)) THEN
    RETURN (convert_to_maths_value (v1 / v2));
  END_IF;
  IF ('SQUARE_ROOT_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
    RETURN (convert_to_maths_value (SQRT(v1)));
  END_IF;
  IF ('SUBSTRING_EXPRESSION' IN types) AND
    ('STRING' IN TYPEOF (vlist[1])) AND ('NUMBER' IN TYPEOF (vlist[2])) AND
    ('NUMBER' IN TYPEOF (vlist[3])) THEN
    str := vlist[1];  n := vlist[2];  m := vlist[3];
    RETURN (convert_to_maths_value (str[n:m]));
  END_IF;
  IF ('TAN_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
    RETURN (convert_to_maths_value (TAN(v1)));
  END_IF;
  IF ('UNARY_MINUS_EXPRESSION' IN types) AND ('NUMBER' IN TYPEOF (v1)) THEN
    nmb := v1;
    RETURN (convert_to_maths_value (-nmb));
  END_IF;
  IF ('VALUE_EXPRESSION' IN types) AND ('STRING' IN TYPEOF (v1)) THEN
    RETURN (convert_to_maths_value (VALUE(v1)));
  END_IF;
  IF ('XOR_EXPRESSION' IN types) AND
    ('BOOLEAN' IN TYPEOF (v1)) AND ('BOOLEAN' IN TYPEOF (v2)) THEN
    RETURN (convert_to_maths_value (v1 XOR v2));
  END_IF;
  -- No special simplification defined, return same with simplified operands.
  IF 'UNARY_GENERIC_EXPRESSION' IN types THEN
    RETURN (restore_unary(expr,op1));
  END_IF;
  IF 'BINARY_GENERIC_EXPRESSION' IN types THEN
    RETURN (restore_binary(expr,op1,op2));
  END_IF;
  IF 'MULTIPLE_ARITY_GENERIC_EXPRESSION' IN types THEN
    RETURN (restore_mulary(expr,oplist));
  END_IF;
  -- Should be unreachable, but for safety, return unsimplified expression.
  RETURN (expr);
END_FUNCTION;  -- simplify_generic_expression

Referenced By

Defintion simplify_generic_expression is references by the following definitions:
DefinitionType
 simplify_function_application FUNCTION
 simplify_maths_value FUNCTION


[Top Level Definitions] [Exit]

Generated by STEP Tools® EXPRESS to HTML Converter
2012-03-27T17:20:10-04:00