|
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 ; 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 ; FUNCTION restore_mulary ( expr : multiple_arity_generic_expression ; ops : LIST OF generic_expression ) : generic_expression ; expr . operands := ops ; RETURN ( expr ) ; END_FUNCTION ; 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 ; 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 ; 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 ) ; 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 ; IF 'maths_space' IN types THEN RETURN ( simplify_maths_space ( expr ) ) ; END_IF ; IF 'function_application' IN types THEN RETURN ( simplify_function_application ( expr ) ) ; END_IF ; 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 ; 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 ; 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 ( ? ) ; 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 ; 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 ; RETURN ( expr ) ; END_FUNCTION; -- simplify_generic_expression |
|
public class FSimplify_generic_expression public static Value run(SdaiContext _context, Value expr) |