Fraction(R:GcdDomain): FractionFieldCategory R == add {
Rep == Record(Numer:R, Denom:R);
local mkquot(a:R, b:R):% == { import from Rep; per [a, b]; }
local numden(x:%):(R, R) == { import from Rep; explode rep x; }
0:% == { import from R; mkquot(0, 1); }
1:% == { import from R; mkquot(1, 1); }
numerator(x:%):R == { import from Rep; rep(x).Numer; }
denominator(x:%):R == { import from Rep; rep(x).Denom; }
coerce(a:R):% == mkquot(a, 1);
coerce(a:Z):% == a::R::%;
normalize(x:%):% == x;
local canon(n:R, d:R):% == {
assert(~zero? d);
assert(unit? gcd(n, d));
mkquot(n, d);
}
(a:R) / (b:R):% == {
assert(~zero? b);
zero? a => 0;
one? b => a::%;
(g, a1, b1) := gcdquo(a, b);
canon(a1, b1);
}
(x:%) = (y:%):Boolean == {
import from R;
(u, v) := numden x;
(w, t) := numden y;
u = w and v = t => true;
u * t = v * w;
}
.......................................