On Thu, Jun 09, 2022 at 08:38:09PM +0200, Ralf Hemmecke wrote:
> On 09.06.22 19:28, Waldek Hebisch wrote:
> >On Thu, Jun 09, 2022 at 05:27:46PM +0200, Ralf Hemmecke wrote:
> >>>AFAICS the expected results are OK. However, the various tests
> >>>are quite repetitive.
> >>
> >>Well, they are. It seems, you want them in just one file.
> >>OK, I can reorganize them.
> >>
> >>>In stream case TESTLIBRARYERROR(A, B) probably should
> >>>expand to testLibraryError(entries complete x(" A ")"), that
> >>>is force computation.
> >>
> >>I do not quite understand. If x is an infinite stream and I call for entries
> >>complete x(2..), then the test will run forever.
> >
> >Well:
> > - AFAICS streams that you test that way are finite
> > - without access to offending entry there should be no error and
> > access should be lazy so to get error we should force access
>
> Ah... now I understand. You want to make sure that the implementation truely
> returns a finite stream and not suddently something else.
> But if I use entries(complete result) then I access every possible entry,
> that excludes the an infinite result. By calling "entries" I get a list.
> What else can I want then requiring that this list is equal to an expected
> list? There is no need for testing "out of range" errors.
> I wouldn't even know how to implement a stream that expands to the right
> list and additionally has an index (bigger than the maxIndex) so that
> x(index) does NOT give an error.
I am affraid that we think quite differently about TESTLIBRARYERROR.
AFAICS you want to have block of tests that is essentially the
same regardless of what you are testing. As I wrote, normally
to get error from stream you need access. Without knowing what
specific stream we have it is somewhat tricky to know what
should trigger access. Actually, AFAICS there are 3 cases:
- immediate error. The only one I can think of is
elt(x, 1.. by 0)
and similar with 0 increment
- error when trying 'complete'. Cases like
elt(x, -1..a)
or when x has less than 6 elements
elt(x, 6..1 by -1)
- getting empty/short stream and error only on access to actual
out of bounds element
Of course using 'complete' in TESTLIBRARYERROR is appropriate
only for the second case. However first case is so rare
and third case does not give errors (without extra access), so
having 'complete' in TESTLIBRARYERROR i
you have simplest solution is to force access
using 'complete' (actually 'entries' is not needed for error
tests, already 'complete' is supposed to evaluate elements).
Note: the 3 cases above correspond to my understanding of
what we agreed before. Arguably 'elt(x, 1.. by 0)' when
'x' has at least one element could give _infinite_ stream
repeating the same value. That would eliminate first case
(replace it by second case). However, 0 increment is
special enough so that error is acceptable too. Again,
one could argue that in second case 'complete' should
return empty or short stream. But dropping elements
at start is IMO could too easily led to undetected
errors, so IMO errors when first index is out of bounds
are better.
Of course, we also want tests which are specific to streams,
but my suggestion was about common block of tests.
> >>For infinite streams I wanted to test for an immediate error, because either
> >>the stepsize is 0
> >
> >OK
> >
> >>or we know from the segment that eventually it will hit a
> >>point below minIndex of the stream, i.e. < 1.
> >
> >This error should be only after actual access. Without access
> >we do not know if there will be error.
>
> st: Stream Integer := [k for k in 1..]
> st(-3..0)
>
> In this case I can immediately say that any access to the stream will be an
> error. So the guideline is "error as early as possible, but no expanding of
> the stream is forbidden until a value is needed.
I would delete 'no' from what you wrote, otherwise I do not know
what it means. I would write "error on access. but not earler".
And 'st(-3..0)' does not count as access.
> t := st(-4..1)
> t(6)
>
> That virtually corresponds to st(1).
First line is essentially the same as previous case. 't(6)' is
and access so gives error.
> I would still say, there should be an
> immediate error for two reasons
> A) In a stream to get t(6) the previous entries should have been
> computed. (Admittedly a questionable reason.)
Yes. 't(6)' should give error. Computing earlier entries is _very_
fundamental for streams.
> B) (-4..1) clearly does not fall into the source domain in the sense of
> "streams are considered as functions from {1,2,..,n} of from all
> positive integers to the coefficients.
>
> Case B is the actual reason why I would want an immediate error.
You mean 'st(-4..1)' is computed? As I wrote, due to lazyness
users may expect that no access mean no erorrs, so I think
that we should get error only at 't(6)' time (or 't(1)' time...).
> To be honest, I do not yet know whether I actually can implement it that
> way, since I first have to test for immediate errors and only then can start
> a delay structure.
I do not think design decision will change difficulty of implementation.
First, we have operations done immediately (possibly none). Then
delay handling first element. Then another delay for the rest.
Clearly first element is special as we must skip some number of
elements, in general different than skip later.
> >>>Also, for better coverage we probably should have test like
> >>>this:
> >>>
> >>> s := ...;
> >>> testEquals("s(3)", "42")
> >>> testLibrarryError("s(4)")
> >>>
> >>>(this may require low enough setting for 'stream calculate').
> >>
> >>Adding such a testcase explicitly says that it is OK to apply a segment that
> >>eventually leads to an "error" index as long as the user does not hit such
> >>an index. I am not so sure whether I would (via explicit testcase) build it
> >>into the specification.
> >
> >Well, without access in general you can not know if there is an error.
> >And our code depends on lazy evaluation. That includes code working
> >when all accessed elements are valid. So regardless of oficial
> >specification code will depend on this.
>
> You mean there might be somewhere some code in our repo that uses s:=x(u)
> already and we should not break it now?
Well, we probably make very little use of 'elt' for streams. But overall
logic of operations on streams is that if streams get enough use,
then code will depend on this property.
--
Waldek Hebisch
--
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/20220609224001.GA20670%40fricas.math.uni.wroc.pl.