FUNCTION substitute
(expr : generic_expression, vars : LIST [1:?] OF generic_variable, vals : LIST [1:?] OF maths_value) : generic_expression;
LOCAL types : SET OF STRING := stripped_typeof(expr); opnds : LIST OF generic_expression; op1, op2 : generic_expression; qvars : LIST OF generic_variable; srcdom : maths_space_or_function; prpfun : LIST [1:?] OF maths_function; finfun : maths_function_select; END_LOCAL; IF SIZEOF (vars) <> SIZEOF (vals) THEN RETURN (?); END_IF; IF 'GENERIC_LITERAL' IN types THEN RETURN (expr); END_IF; IF 'GENERIC_VARIABLE' IN types THEN REPEAT i := 1 TO SIZEOF (vars); IF expr :=: vars[i] THEN RETURN (vals[i]); END_IF; END_REPEAT; RETURN (expr); END_IF; IF 'QUANTIFIER_EXPRESSION' IN types THEN qvars := expr\quantifier_expression.variables; -- Variables subject TO a quantifier do NOT participate IN this kind of -- substitution process. REPEAT i := SIZEOF (vars) TO 1 BY -1; IF vars[i] IN qvars THEN REMOVE (vars, i); REMOVE (vals, i); END_IF; END_REPEAT; opnds := expr\multiple_arity_generic_expression.operands; REPEAT i := 1 TO SIZEOF (opnds); IF NOT (opnds[i] IN qvars) THEN expr\multiple_arity_generic_expression.operands[i] := substitute(opnds[i],vars,vals); -- This technique will NOT work on subtypes OF quantifier_expression -- which DERIVE their operands FROM other attributes! END_IF; END_REPEAT; RETURN (expr); -- operands modified! END_IF; IF 'UNARY_GENERIC_EXPRESSION' IN types THEN op1 := expr\unary_generic_expression.operand; expr\unary_generic_expression.operand := substitute(op1, vars, vals); -- This technique will NOT work on subtypes OF unary_generic_expression -- which DERIVE their operands FROM other attributes! END_IF; IF 'BINARY_GENERIC_EXPRESSION' IN types THEN op1 := expr\binary_generic_expression.operands[1]; expr\binary_generic_expression.operands[1] := substitute(op1, vars, vals); op2 := expr\binary_generic_expression.operands[2]; expr\binary_generic_expression.operands[2] := substitute(op2, vars, vals); -- This technique will NOT work on subtypes OF binary_generic_expression -- which DERIVE their operands FROM other attributes! END_IF; IF 'PARALLEL_COMPOSED_FUNCTION' IN types THEN -- SUBTYPE OF multiple_arity_generic_expression which derives its operands. srcdom := expr\parallel_composed_function.source_of_domain; prpfun := expr\parallel_composed_function.prep_functions; finfun := expr\parallel_composed_function.final_function; srcdom := substitute(srcdom,vars,vals); REPEAT i := 1 TO SIZEOF (prpfun); prpfun[i] := substitute(prpfun[i],vars,vals); END_REPEAT; IF 'MATHS_FUNCTION' IN stripped_typeof(finfun) THEN finfun := substitute(finfun,vars,vals); END_IF; RETURN (make_parallel_composed_function(srcdom,prpfun,finfun)); END_IF; IF 'MULTIPLE_ARITY_GENERIC_EXPRESSION' IN types THEN opnds := expr\multiple_arity_generic_expression.operands; REPEAT i := 1 TO SIZEOF (opnds); expr\multiple_arity_generic_expression.operands[i] := substitute(opnds[i],vars,vals); -- This technique will NOT work on subtypes OF multiple_arity_generic_ -- expression which DERIVE their operands FROM other attributes! END_REPEAT; END_IF; RETURN (expr); END_FUNCTION; -- substitute
|