Ralf Hemmecke wrote:
> 
> > The point of change is every current user of AbelianMonoidRing
> > optionally gets new functionality: if user proviedes a Ring as an
> > argument that the category should be as before.  If user supplies it
> > with a semiring, then one gets new behaviour.
> 
> Can you give an illustrating use case where your generalization is 
> important? What did you have in mind when you made this generalization?
> 

The direct motivation is SmallOrdinal domain (which I include at
the end of the message).  Whith so called "natural" addition
and multiplication ordinals form a semiring, but not a ring
(there are no additive inverses).  Of course ordinals are
a proper class, so there is no chance to have them all in
the computer.  But one can implement some initial segment.
SmallOrdinal domains implements ordinals smaller than epsilon_0.
Natural representation of such ordinals is as "polynomials"
in omega with exponents which are again ordinals.

More generally, for things like matrices, power series, polynomials
basic definitions works fine if one only assumes that coefficients
come from a semiring.  Actually, definitions work reasonably
well when one only assumes that addition is associative.  Of course,
typically we want to assume more, for example without additive
0 we can not omit zero terms so expressions are going to grow
after each operation.  And many algorithms need subtraction, but
still there are interesting things which can be done just using
addition and mutiplication.

ATM it is hard to say how general we want to make those domains.
Semirings are used a lot: the simplest example is booleans,
with + beeing logical 'or', and * beeing logical 'and' (if you
take 'xor' as + then booleans form a ring, but in many
cases natural operation is 'or').  On ordinals one can define
sum and product via theory of orders.  But "ordered"
operations are noncommutative, and if we take them as base
operations then ordinals would not be a semiring but only
so called near ring.

We discussed some time ago partial operations: many functors
which from rings produce rings have natural extension to
partial case.



-------<cut here>----------------

)abbrev domain SORD SmallOrdinal
++ Author: Waldek Hebisch
++ Description:
++  SmallOrdinal implements ordinal numbers up to epsilon_0.  \spad{+}
++  and \spad{*} are "natural" addition and multiplication of ordinals.
++  Avaliable separately are "ordered" operataions.
SmallOrdinal: Join(OrderedAbelianMonoid, SemiRing, CancellationAbelianMonoid,
                   RetractableTo(NonNegativeInteger)) with
    omega : () -> %
      ++ omega() is the first infinite ordinal
    omegapower : % -> %
      ++ omegapower(p) returns omega^p
    ordinalAdd : (%, %) -> %
      ++ ordinalAdd(o1, o2) returns sum of o1 and o2 as ordered sets
    ordinalMul : (%, %) -> %
      ++ ordinalMul(o1, o2) returns product of o1 and o2 as ordered sets
    ordinalPower : (%, %) -> %
      ++ ordinalPower(o1, o2) returns o1 to power o2, where power
      ++ is inductively defined using succesive ordinal multiplication
      ++ from the left
    integerPart : % -> NonNegativeInteger
      ++ integerPart(o) = n when o = l + n and l is a limit ordinal
    limitPart : % -> %
      ++ limitPart(o) = l when o = l + n and l is a limit ordinal
      ++ and n is a nonnegative integer
    "^" : (%, %) -> %
      ++ o1^o2 returns o1 to power o2, where power is inductively
      ++ defined using succesive natural multiplication from the left

  == add
    N ==> NonNegativeInteger
    PR ==> PolynomialRing(N, %)
    Rep := PR

    0 == 0$Rep

    1 == 1$Rep

    omega() == monomial(1$N, 1$%)$Rep

    omegapower(p) == monomial(1$N, p)$Rep

    zero? p == zero?(p::Rep)$Rep

    one? p == p::Rep =$Rep 1

    p1 = p2  == p1::Rep =$Rep p2::Rep

    coerce(n : N) : % == monomial(n, 0$%)$Rep

    retractIfCan(x : %) : Union(N, "failed") == retractIfCan(x::Rep)$Rep

    o1 < o2 ==
        p1 := o1::Rep
        p2 := o2::Rep
        ground?(p1) =>
            ground?(p2) =>
                ground(p1) <$N ground(p2)
            true
        if ground?(p2) then
            false
        else
            smaller?(p1, p2)$Rep

    p1 + p2  == p1::Rep +$Rep p2::Rep

    p1 * p2  == p1::Rep *$Rep p2::Rep

    subtractIfCan(o1, o2) == subtractIfCan(o1::Rep, o2::Rep)$Rep

    ordinalAdd(o1, o2) ==
        p1 := o1::Rep
        p2 := o2::Rep
        e := degree(p2)
        e = 0 => p1 + p2
        lt : List(Rep) := []
        while (degree(p1) >= e) repeat
            lt := cons(leadingMonomial(p1), lt)
            p1 := reductum(p1)
        for t in lt repeat
            p2 := t + p2
        p2

    integerPart(o : %) : N ==
        p := o::Rep
        while ~ground?(p) repeat p := reductum(p)
        ground(p)

    limitPart(o : %) : % ==
        subtractIfCan(o, integerPart(o)::%)::%

    ordinalMul(o1 : %, o2 : %) : % ==
        e := degree(o1::Rep)
        hi :=
            e > 0 => mapExponents((x : %) : % +-> ordinalAdd(e, x),
                                  limitPart(o2)::Rep)$Rep
            limitPart(o2)::Rep
        lo := o1*integerPart(o2)
        hi + lo::Rep

    sub_one(o : %) : % ==
        ground?(o) =>
            n := ground(o)
            n = 0 => error "sub_one applied to zero ordinal"
            ((n - 1) pretend N)::%
        o

    infinite_power(o1 : %, o2 : %) : % ==
        o1 = 0 => 0
        o1 = 1 => 1
        e1 := degree(o1::Rep)
        e1 > 0 => omegapower(ordinalMul(e1, o2))
        omegapower(mapExponents(sub_one, o2::Rep)$Rep)

    finite_ordinal_power(o : %, n : N) : % ==
        n = 0 => 1
        n = 1 => o
        e := degree(o::Rep)
        e = 0 => ((retract(o)@N)^n)::%
        n1 := (n - 1) pretend N
        ordinalMul(omegapower(e*n1), o)
        
    ordinalPower(o1 : %, o2 : %) : % ==
        ordinalMul(infinite_power(o1, limitPart(o2)),
                   finite_ordinal_power(o1, integerPart(o2)))

    (o1 : %)^(o2 : %) ==
        infinite_power(o1, limitPart(o2))*o1^integerPart(o2)

    coerce(o : %) : OutputForm ==
        p := o::Rep
        ground?(p) => (ground(p))::OutputForm
        l : List OutputForm := []
        v := "omega"::OutputForm
        while p ~= 0$Rep repeat
            c := leadingCoefficient(p)$Rep
            e : % := degree(p)$Rep
            p := reductum(p)
            co := c::OutputForm
            l1 :=
                e = 0 => co
                if e = 1 then
                    mon:= v
                else mon := v ^ e::OutputForm
                c = 1 => mon
                co*mon
            l := cons(l1, l)
        l := reverse!(l)
        reduce("+", l)

----<cut here>-----------
-- 
                              Waldek Hebisch
[email protected] 

-- 
You received this message because you are subscribed to the Google Groups 
"FriCAS - computer algebra system" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/fricas-devel?hl=en.

Reply via email to