In connection to the bug I send yesterday, there is at another bug, in
documentation and code, namely here:

https://github.com/fricas/fricas/blob/master/src/algebra/sups.spad#L30

    makeSeries : (REF, ST) -> %
      ++ makeSeries(refer, str) creates a power series from the reference
      ++ \spad{refer} and the stream \spad{str}.

It claims that I can simply create a series that way. It says nothing
about a restriction for "refer".

makeSeries is simply implemented as

    Rep := Record(%ord : REF, %str : Stream Term)
    makeSeries(refer, x) == [refer, x]
    getRef ups == ups.%ord

However that plays not well with

    getRef : % -> REF
      ++ getRef(f) returns a reference containing the order to which the
      ++ terms of f have been computed.

Solution is to clearly state in the docstring for makeSeries.

BUT...

With the bugfix of Qian, iSeries returns a completely unexpanded series
(because of the "delay"). It should either return 0 or expand the stream
to the first entry.

Look at the following:

========================================================================
(1) -> Z ==> Integer
                                                                   Type:
Void
(2) -> Q ==> Fraction Z
                                                                   Type:
Void
(3) -> R ==> Record(k: Z, c: Q)
                                                                   Type:
Void
(4) -> S ==> Stream R
                                                                   Type:
Void
(5) -> REF  ==> Reference OrderedCompletion Integer
                                                                   Type:
Void
(6) -> h(r: R): R == [r.k+1, 2*r.c]$R
   Function declaration h : Record(k: Integer,c: Fraction(Integer)) ->
      Record(k: Integer,c: Fraction(Integer)) has been added to
      workspace.
                                                                   Type:
Void
(7) -> s: S := stream(h, [1, 1]$R);
   Compiling function h with type Record(k: Integer,c: Fraction(Integer
      )) -> Record(k: Integer,c: Fraction(Integer))

                        Type: Stream(Record(k: Integer,c:
Fraction(Integer)))
(8) -> isups:=series(s)$InnerSparseUnivariatePowerSeries(Q);

                    Type:
InnerSparseUnivariatePowerSeries(Fraction(Integer))
(9) -> refer := getRef(isups)

   (9)  ref(1)
                                  Type:
Reference(OrderedCompletion(Integer))
(10) -> st := getStream isups;

                        Type: Stream(Record(k: Integer,c:
Fraction(Integer)))
(11) -> explicitlyEmpty? st

   (11)  false
                                                                Type:
Boolean
(12) -> explicitEntries? st

   (12)  false
                                                                Type:
Boolean
========================================================================

It's the same as if I would simply say:

rord: REF := ref 1
isups := makeSeries(rord, s)$InnerSparseUnivariatePowerSeries(Q);

s and st are unexpanded although getRef(isups) returns ref(1).

BUT NO, it's not the same!

In fact, the docstring for makeSeries is telling effectively nothing
about how makeSeries actually is supposed to create an
InnerSparseUnivariatePowerSeries.

Namely, makeSeries(refer, st) should only be called with refer and st
being tightly connected in such a way that whenever "st" is expanded,
then (magically), "refer" is updated as well.

If this is not the case then one can easily crash FriCAS.

Z ==> Integer
Q ==> Fraction Z
REF  ==> Reference OrderedCompletion Integer
h(r: R): R == [r.k+1, 2*r.c]$R
s: S := stream(h, [1, 1]$R);
rord: REF := ref 1
isups := makeSeries(rord, s)$InnerSparseUnivariatePowerSeries(Q);
coefficient(isups,0)
coefficient(isups,1)
coefficient(isups,2)

This is, because
https://github.com/fricas/fricas/blob/master/src/algebra/sups.spad#L228

    iExtend(st, n, refer) ==
      (elt refer) < n =>
        explicitlyEmpty? st => (setelt!(refer, plusInfinity()); st)
        explicitEntries? st => iExtend(rst st, n, refer)
        iExtend(lazyEvaluate st, n, refer)
      st

relies on this side effect of updating "refer" while "lazyEvaluate st"
is called.

So in someway, it would be preferrable to have iExtend! and extend!
(with exclamation mark), because (although not explicitly visible not
only refer is changed but also st.

Yes, I agree, InnerSparseUnivariatePowerSeries is (by convention)
nothing that an end-user should actually use, but nonetheless, would be
nice to also tell the developers about how this domain actually works
without the need to deeply analyse the code. I would nearly have
proposed to modify iExtend to update "refer" to "refer+1".

Suggestion (see atttachment)

Ralf

-- 
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 fricas-devel+unsubscr...@googlegroups.com.
To post to this group, send email to fricas-devel@googlegroups.com.
Visit this group at https://groups.google.com/group/fricas-devel.
For more options, visit https://groups.google.com/d/optout.
From 50e28e6426b57261c6289e03d68e017341acf7e0 Mon Sep 17 00:00:00 2001
From: Ralf Hemmecke <r...@hemmecke.org>
Date: Fri, 23 Mar 2018 10:20:30 +0100
Subject: fix docstring for makeSeries

---
 src/algebra/sups.spad | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/algebra/sups.spad b/src/algebra/sups.spad
index b8765c66..3a8dcb28 100644
--- a/src/algebra/sups.spad
+++ b/src/algebra/sups.spad
@@ -30,6 +30,10 @@ InnerSparseUnivariatePowerSeries(Coef) : Exports == Implementation where
     makeSeries : (REF, ST) -> %
       ++ makeSeries(refer, str) creates a power series from the reference
       ++ \spad{refer} and the stream \spad{str}.
+      ++ Note that because of the way this domain works internally,
+      ++ makeSeries assumes that refer is automatically updated during
+      ++ expansion of st, so that refer corresponds to the exponent in
+      ++ str up to which the stream is expanded.
     getRef : % -> REF
       ++ getRef(f) returns a reference containing the order to which the
       ++ terms of f have been computed.
-- 
2.14.1

From ca3b80d626072306016ab40cdcfdae6a54629ac8 Mon Sep 17 00:00:00 2001
From: Ralf Hemmecke <r...@hemmecke.org>
Date: Fri, 23 Mar 2018 13:00:14 +0100
Subject: fix documentation of getRef

---
 src/algebra/sups.spad | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/algebra/sups.spad b/src/algebra/sups.spad
index 3a8dcb28..017e7029 100644
--- a/src/algebra/sups.spad
+++ b/src/algebra/sups.spad
@@ -35,8 +35,17 @@ InnerSparseUnivariatePowerSeries(Coef) : Exports == Implementation where
       ++ expansion of st, so that refer corresponds to the exponent in
       ++ str up to which the stream is expanded.
     getRef : % -> REF
-      ++ getRef(f) returns a reference containing the order to which the
-      ++ terms of f have been computed.
+      ++ \spad{getRef(f)} returns a reference containing the order up to
+      ++ which there is full knowlegde about the terms of the series.
+      ++ \spad{explicitlyEmpty?(f)} and \spad{explicitEntries?(f)}
+      ++ should always studied before \spad{getRef(f)}.
+      ++ \spad{explicitlyEmpty?(f)} eventually refers
+      ++ to \spad{deref(getRef f)=plusInfinity()}.
+      ++ If \spad{explicitEntries?(f)} is true, then \spad{deref(getRef f)}
+      ++ is the order up to which \spad{getStream(f)} is computed;
+      ++ otherwise, it is known that all coefficients smaller than
+      ++  \spad{deref(getRef f)} are zero, i.e., it is a lower bound of
+      ++ the order of the series.
     getStream : % -> ST
       ++ getStream(f) returns the stream of terms representing the series f.
     series : ST -> %
-- 
2.14.1

Reply via email to