Solution (source code)

= Solution

Use the supplied pointer-to-record representation and allocate a fresh record:

``
PROCEDURE mkRat(n,d: INTEGER): rational;
VAR z: rational;
BEGIN
  ASSERT(d # 0);
  NEW(z); z.num := n; z.den := d;
  reduce(z);
  RETURN z
END mkRat;
``

The <rational number> constructor returns a value with positive denominator in lowest terms, using part (b). Zero is represented as $0/1$. Arithmetic below uses exact integers, or inputs whose intermediate values fit the chosen implementation; fixed-width overflow would otherwise invalidate exact arithmetic.