GENERIC MODULEResidueClassBasic (R, GCD);
Arithmetic for Modula-3, see doc for detailsAbstract: ResidueClass numbers and basic operations
IMPORT Arithmetic; <* UNUSED *> CONST Module = "ResidueClassBasic."; PROCEDURENewZero (d: R.T; ): T = BEGIN <* ASSERT NOT R.IsZero(d) *> RETURN T{R.Zero, d}; END NewZero; PROCEDURENewOne (d: R.T; ): T = BEGIN <* ASSERT NOT R.IsZero(d) *> RETURN T{R.One, d}; END NewOne; PROCEDUREFromRepresentative (x, d: R.T; ): T = <* FATAL Arithmetic.Error *> (* d must not be zero *) BEGIN <* ASSERT NOT R.IsZero(d) *> RETURN T{R.Mod(x, d), d}; END FromRepresentative; PROCEDUREToRepresentative (READONLY x: T; ): R.T = BEGIN RETURN x.r; END ToRepresentative; PROCEDUREAssertEqualIdeal (READONLY x, y: T; ) = BEGIN <* ASSERT R.Equal(x.d, y.d) *> END AssertEqualIdeal; PROCEDUREAdd (READONLY x, y: T; ): T = <* FATAL Arithmetic.Error *> (* d must not be zero *) BEGIN AssertEqualIdeal(x, y); RETURN T{R.Mod(R.Add(x.r, y.r), x.d), x.d}; END Add; PROCEDURESub (READONLY x, y: T; ): T = <* FATAL Arithmetic.Error *> (* d must not be zero *) BEGIN AssertEqualIdeal(x, y); RETURN T{R.Mod(R.Sub(x.r, y.r), x.d), x.d}; END Sub; PROCEDURENeg (READONLY x: T; ): T = <* FATAL Arithmetic.Error *> (* d must not be zero *) BEGIN RETURN T{R.Mod(R.Neg(x.r), x.d), x.d}; END Neg; PROCEDUREIsZero (READONLY x: T; ): BOOLEAN = BEGIN RETURN R.IsZero(x.r); END IsZero; PROCEDUREEqual (READONLY x, y: T; ): BOOLEAN = BEGIN AssertEqualIdeal(x, y); RETURN R.Equal(x.r, y.r); END Equal; PROCEDUREMul (READONLY x, y: T; ): T = <* FATAL Arithmetic.Error *> (* d must not be zero *) BEGIN AssertEqualIdeal(x, y); RETURN T{R.Mod(R.Mul(x.r, y.r), x.d), x.d}; END Mul; PROCEDUREDiv (READONLY x, y: T; ): T RAISES {Arithmetic.Error} = VAR c: ARRAY [0 .. 1], [0 .. 1] OF R.T; BEGIN AssertEqualIdeal(x, y); GCD.Bezout(x.r, x.d, y.r, c); RETURN T{c[0, 0], x.d}; END Div; PROCEDURERec (READONLY x: T; ): T RAISES {Arithmetic.Error} = VAR c: ARRAY [0 .. 1], [0 .. 1] OF R.T; BEGIN GCD.Bezout(x.r, x.d, R.One, c); RETURN T{c[0, 0], x.d}; END Rec; PROCEDURESquare (READONLY x: T; ): T = <* FATAL Arithmetic.Error *> (* d must not be zero *) BEGIN RETURN T{R.Mod(R.Mul(x.r, x.r), x.d), x.d}; END Square; PROCEDUREScale (READONLY x: T; y: R.T; ): T = <* FATAL Arithmetic.Error *> (* d must not be zero *) BEGIN RETURN T{R.Mod(R.Mul(x.r, y), x.d), x.d}; END Scale; BEGIN END ResidueClassBasic.