Dear Ralf, CY,
in fact, I like this idea even better than mine. In private communication, we
developed the domain below, but your idea is conceptually better, I think. The
full blown thing would then be a category Units, that has as domains Mass,
Time, Length, ... I suppose.
Martin
)abb domain UNITS Units
Units(R: Field): Exports == Implementation where
U == Fraction Polynomial Integer
Exports == with
"*": (%,%) -> %
"+": (%,%) -> %
coerce: % -> OutputForm
withUnits: (R, U) -> %
setUnitSystem!: String -> String
Implementation == add
Rep := Record(expr: R, units: U)
system: String := "MKS"
setUnitSystem! s ==
t := system
system := s
t
transform: U -> Record(scalar: R, units: U)
transform u ==
m := 'm::Symbol::Polynomial(Integer)::U
v := u
if system = "MKS"
then v := eval(u, ['cm, 'dm], _
[m*1/100::U, m*1/10::U])$RationalFunction(Integer)
s: Fraction Integer := leadingCoefficient(numer(v)) _
/ leadingCoefficient(denom(v))
r: U := leadingMonomial(numer(v))::U _
/ leadingMonomial(denom(v))::U _
/ s ::U
[s::R, r]
withUnits(e, u) == [e, u]::Rep
x * y == [(x::Rep).expr * (y::Rep).expr, (x::Rep).units * (y::Rep).units]
x + y ==
ux := transform((x::Rep).units)
uy := transform((y::Rep).units)
if ux.units = uy.units
then [(x::Rep).expr*ux.scalar + (y::Rep).expr*uy.scalar, ux.units]
else error "+: Units have to match"
coerce x == coerce((x::Rep).expr)$R * coerce((x::Rep).units)$U
_______________________________________________
Axiom-developer mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/axiom-developer