By using macros, this avoids code duplication.
One minor question: the exported signature should belong to
IndexedDirectProductCategory or IndexedProductCategory?
They look similar to me...
- Qian
https://github.com/oldk1331/fricas/commit/86e9caf16049955b793e9d1e88a3863bd2cb2352.patch
From 86e9caf16049955b793e9d1e88a3863bd2cb2352 Mon Sep 17 00:00:00 2001
From: Qian Yun <
oldk...@gmail.com>
Date: Wed, 5 Oct 2022 11:10:21 +0800
Subject: [PATCH] add add!
---
src/algebra/indexedp.spad | 37 +++++++++++++++++++++++++++++++++++--
1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/src/algebra/indexedp.spad b/src/algebra/indexedp.spad
index 04c732db3..29051cfe5 100644
--- a/src/algebra/indexedp.spad
+++ b/src/algebra/indexedp.spad
@@ -100,6 +100,12 @@ IndexedDirectProductCategory(A : SetCategory, S :
SetCategory
if A has Comparable and S has Comparable then Comparable
+ if A has AbelianMonoid then
+ add! : (%, %) -> %
+ ++ add!(x, y) returns \spad{x+y}. Note that the structure of
+ ++ x and y may be destructively modified. So use with caution,
+ ++ especillay when part of x or y is shared by other objects.
+
listOfTerms : % -> List Term
++ \spad{listOfTerms(x)} returns a list \spad{lt} of terms
with type
++ \spad{Record(k: S, c: R)} such that \spad{x} equals
@@ -260,10 +266,10 @@ IndexedDirectProductObject(A : SetCategory, S :
SetCategory
x := rest x
y := rest y
else if smaller?(ty.k, tx.k) then
- newcell := cons(tx, empty())
+ newcell := CONSTRUCT_FUN(x, empty())
x := rest x
else
- newcell := cons(ty, empty())
+ newcell := CONSTRUCT_FUN(y, empty())
y := rest y
if not empty? newcell then
if not empty? endcell then
@@ -285,11 +291,18 @@ IndexedDirectProductObject(A : SetCategory, S :
SetCategory
add_gen(x : Rep, y : Rep) : Rep ==
endcell, res, newcell : Rep
+ CONSTRUCT_FUN(a, b) ==> cons(first a, empty())
+ PLUS_BODY
+
+ add_gen!(x : Rep, y : Rep) : Rep ==
+ endcell, res, newcell : Rep
+ CONSTRUCT_FUN(a, b) ==> a
PLUS_BODY
if S is NonNegativeInteger then
add_si(x : RepS, y : RepS) : RepS ==
endcell, res, newcell : RepS
+ CONSTRUCT_FUN(a, b) ==> cons(first a, empty())
PLUS_BODY
x + y ==
@@ -302,12 +315,32 @@ IndexedDirectProductObject(A : SetCategory, S :
SetCategory
add_si(x pretend RepS, y pretend RepS) pretend %
add_gen(x, y)
+ add_si!(x : RepS, y : RepS) : RepS ==
+ endcell, res, newcell : RepS
+ CONSTRUCT_FUN(a, b) ==> a
+ PLUS_BODY
+
+ add!(x, y) ==
+ empty?(x) => y
+ empty?(y) => x
+ degx := (x.first.k) pretend Integer
+ degy := (y.first.k) pretend Integer
+ msi := max()$SingleInteger
+ degx < msi and degy < msi =>
+ add_si!(x pretend RepS, y pretend RepS) pretend %
+ add_gen!(x, y)
+
else
x + y ==
empty?(x) => y
empty?(y) => x
add_gen(x, y)
+ add!(x, y) ==
+ empty?(x) => y
+ empty?(y) => x
+ add_gen!(x, y)
+
(n : NonNegativeInteger) * x ==
n = 0 => 0
n = 1 => x