Actually, it's not necessary to treat differently for
OrderedMonoid/noZeroDivisors.  We can simply have

    a : % * b : % ==
        zero? a or zero? b => 0
        construct! concat! [[[ta.Mn*tb.Mn, ta.Cf*tb.Cf]$Term
            for tb in b] for ta in a]

we collect all the terms and let "construct" do the heavy lifting.
See my updated patch.

It's possible to do better though, for OrderedMonoid, we can do a
k-way merge, but we don't have such algorithm at hand.

My patch should already make this function much faster by
skipping allocation of temporary result of "+".

-- 
You received this message because you are subscribed to the Google Groups 
"FriCAS - computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/fricas-devel/CAGBJN92Dn0Mb5OKZqA3Ckf68qMjmFUnHBomY_5FVAib3XgrWhQ%40mail.gmail.com.
diff --git a/src/algebra/mring.spad b/src/algebra/mring.spad
index 7fd7244a..bc216576 100644
--- a/src/algebra/mring.spad
+++ b/src/algebra/mring.spad
@@ -229,8 +229,8 @@ MonoidRing(R : Ring, M : Monoid) : MonoidRingCategory(R, M) == MRdefinition wher
 
             termless(t1:Term, t2:Term):Boolean == smaller?(t1.k, t2.k)
 
-            construct(x : List Term) : % ==
-                xs : List Term := sort(termless, x)
+            construct!(x : List Term) : % ==
+                xs : List Term := sort!(termless, x)
                 res : List Term := empty()
                 -- find duplicates
                 while not empty? xs repeat
@@ -246,6 +246,8 @@ MonoidRing(R : Ring, M : Monoid) : MonoidRingCategory(R, M) == MRdefinition wher
                         res := cons (t1, res)
                 res
 
+            construct(x : List Term) : % == construct! copy x
+
             if R has CommutativeRing then
                 f : M -> R
                 x : %
@@ -285,59 +287,10 @@ MonoidRing(R : Ring, M : Monoid) : MonoidRingCategory(R, M) == MRdefinition wher
                     if smaller?(t.Mn, m) then return 0
                 0
 
-
-            if M has OrderedMonoid then
-
-            -- we use that multiplying an ordered list of monoid elements
-            -- by a single element respects the ordering
-
-              if R has noZeroDivisors then
-                a : % * b : % ==
-                  +/[[[ta.Mn*tb.Mn, ta.Cf*tb.Cf]$Term
-                    for tb in b ] for ta in reverse a]
-              else
-                a : % * b : % ==
-                  +/[[[ta.Mn*tb.Mn, r]$Term
-                    for tb in b | not zero?(r := ta.Cf*tb.Cf)]
-                      for ta in reverse a]
-            else -- M hasn't OrderedMonoid
-
-            -- we cannot assume that mutiplying an ordered list of
-            -- monoid elements by a single element respects the ordering:
-            -- we have to order and to collect equal terms
-              ge : (Term, Term) -> Boolean
-              ge(s, t) == not smaller? (s.Mn, t.Mn)
-
-              sortAndAdd : List Term -> List Term
-              sortAndAdd(liTe) ==  -- assume liTe not empty
-                liTe := sort(ge, liTe)
-                m : M :=  (first liTe).Mn
-                cf : R := (first liTe).Cf
-                res : List Term := []
-                for te in rest liTe repeat
-                  if m = te.Mn then
-                    cf := cf + te.Cf
-                  else
-                    if not zero? cf then res := cons([m, cf]$Term, res)
-                    m := te.Mn
-                    cf := te.Cf
-                if not zero? cf then res := cons([m, cf]$Term, res)
-                reverse res
-
-
-              if R has noZeroDivisors then
-                a : % * b : % ==
-                  zero? a => a
-                  zero? b => b  -- avoid calling sortAndAdd with []
-                  +/[sortAndAdd [[ta.Mn*tb.Mn, ta.Cf*tb.Cf]$Term
-                    for tb in b ] for ta in reverse a]
-              else
-                a : % * b : % ==
-                  zero? a => a
-                  zero? b => b  -- avoid calling sortAndAdd with []
-                  +/[sortAndAdd [[ta.Mn*tb.Mn, r]$Term
-                    for tb in b | not zero?(r := ta.Cf*tb.Cf)]
-                      for ta in reverse a]
+            a : % * b : % ==
+                zero? a or zero? b => 0
+                construct! concat! [[[ta.Mn*tb.Mn, ta.Cf*tb.Cf]$Term
+                    for tb in b] for ta in a]
 
 
         else -- M hasn't OrderedSet

Reply via email to