FUNCTION assoc_product_space
(ts1 : tuple_space, ts2 : tuple_space) : tuple_space;
LOCAL types1 : SET OF STRING := stripped_typeof (ts1); types2 : SET OF STRING := stripped_typeof (ts2); up1, up2 : uniform_product_space := make_uniform_product_space(the_reals,1); lp1, lp2, lps : listed_product_space := the_zero_tuple_space; et1, et2, ets : extended_tuple_space := the_tuples; use_up1, use_up2, use_lp1, use_lp2 : BOOLEAN; factors : LIST OF maths_space := []; tspace : tuple_space; END_LOCAL; -- Identify TYPE OF first operand IF 'UNIFORM_PRODUCT_SPACE' IN types1 THEN up1 := ts1; use_up1 := true; use_lp1 := false; ELSE IF 'LISTED_PRODUCT_SPACE' IN types1 THEN lp1 := ts1; use_up1 := false; use_lp1 := true; ELSE IF NOT ('EXTENDED_TUPLE_SPACE' IN types1) THEN -- Unreachable when this FUNCTION was written. RETURN (?); END_IF; et1 := ts1; use_up1 := false; use_lp1 := false; END_IF; END_IF; -- Identify TYPE OF second operand IF 'UNIFORM_PRODUCT_SPACE' IN types2 THEN up2 := ts2; use_up2 := true; use_lp2 := false; ELSE IF 'LISTED_PRODUCT_SPACE' IN types2 THEN lp2 := ts2; use_up2 := false; use_lp2 := true; ELSE IF NOT ('EXTENDED_TUPLE_SPACE' IN types2) THEN -- Unreachable when this FUNCTION was written. RETURN (?); END_IF; et2 := ts2; use_up2 := false; use_lp2 := false; END_IF; END_IF; -- Construction FOR each combination OF cases IF use_up1 THEN IF use_up2 THEN IF up1.base = up2.base THEN tspace := make_uniform_product_space(up1.base, up1.exponent + up2.exponent); ELSE factors := [up1.base : up1.exponent, up2.base : up2.exponent]; tspace := make_listed_product_space(factors); END_IF; ELSE IF use_lp2 THEN -- Avoid compiler confusion BY breaking into two lines. factors := [up1.base : up1.exponent]; factors := factors + lp2.factors; tspace := make_listed_product_space(factors); ELSE tspace := assoc_product_space(up1, et2.base); tspace := make_extended_tuple_space(tspace, et2.extender); END_IF; END_IF; ELSE IF use_lp1 THEN IF use_up2 THEN -- Avoid compiler confusion BY breaking into two lines. factors := [up2.base : up2.exponent]; factors := lp1.factors + factors; tspace := make_listed_product_space(factors); ELSE IF use_lp2 THEN tspace := make_listed_product_space(lp1.factors + lp2.factors); ELSE tspace := assoc_product_space(lp1, et2.base); tspace := make_extended_tuple_space(tspace, et2.extender); END_IF; END_IF; ELSE IF use_up2 THEN IF et1.extender = up2.base THEN tspace := assoc_product_space(et1.base, up2); tspace := make_extended_tuple_space(tspace, et1.extender); ELSE -- No SUBTYPE is available TO represent this cartesian product. RETURN (?); END_IF; ELSE IF use_lp2 THEN factors := lp2.factors; REPEAT i := 1 TO SIZEOF (factors); IF et1.extender <> factors[i] THEN -- No SUBTYPE available TO represent this cartesian product. RETURN (?); END_IF; END_REPEAT; tspace := assoc_product_space(et1.base, lp2); tspace := make_extended_tuple_space(tspace, et1.extender); ELSE IF et1.extender = et2.extender THEN -- Next line may assign indeterminate (?) TO tspace. tspace := assoc_product_space(et1, et2.base); ELSE -- No SUBTYPE available TO represent this cartesian product. RETURN (?); END_IF; END_IF; END_IF; END_IF; END_IF; RETURN (tspace); END_FUNCTION; -- assoc_product_space
|