strange bug

26 views
Skip to first unread message

Ralf Hemmecke

unread,
Feb 19, 2020, 6:09:54 AM2/19/20
to fricas-devel
Can somebody tell me why the attached program does not compile?

The error message looks not very helpful.

Is that a bug?

Ralf

(1) -> )co bug.spad
Compiling FriCAS source code from file
/home/hemmecke/backup/git/qeta/src/bug.spad using old system
compiler.
FOO abbreviates domain Foo
------------------------------------------------------------------------
initializing NRLIB FOO for Foo
compiling into NRLIB FOO
compiling exported foo : () -> Boolean
****** comp fails at level 3 with expression: ******
error in function foo

(SEQ (|:=| (|:| |a| (|List| (|List| (|Integer|)))) (|empty|))
(|:=| (|:| |b| (|List| (|List| (|Integer|)))) (|empty|))
(|exit| 1 | << | (< |a| |b|) | >> |))
****** level 3 ******
$x:= (< a b)
$m:= (Boolean)
$f:=
((((|b| # #) (|a| # #) (|foo| #) (|$DomainsInScope| # # #) ...)))

>> Apparent user error:
not known that (List (List (Integer))) has (AND (has (List (List
(Integer))) (finiteAggregate)) (has (List (Integer)) (OrderedSet)))
bug.spad

Waldek Hebisch

unread,
Feb 19, 2020, 8:42:55 AM2/19/20
to fricas...@googlegroups.com
On Wed, Feb 19, 2020 at 12:09:52PM +0100, Ralf Hemmecke wrote:
> Can somebody tell me why the attached program does not compile?
>
> The error message looks not very helpful.
>
> Is that a bug?
>
> Ralf
>
> (1) -> )co bug.spad
> Compiling FriCAS source code from file
> /home/hemmecke/backup/git/qeta/src/bug.spad using old system
> compiler.
> FOO abbreviates domain Foo
> ------------------------------------------------------------------------
> initializing NRLIB FOO for Foo
> compiling into NRLIB FOO
> compiling exported foo : () -> Boolean
> ****** comp fails at level 3 with expression: ******
> error in function foo
>
> (SEQ (|:=| (|:| |a| (|List| (|List| (|Integer|)))) (|empty|))
> (|:=| (|:| |b| (|List| (|List| (|Integer|)))) (|empty|))
> (|exit| 1 | << | (< |a| |b|) | >> |))
^^^^^^^^^

This tells you that offending part is

a < b

> ****** level 3 ******
> $x:= (< a b)
> $m:= (Boolean)
> $f:=
> ((((|b| # #) (|a| # #) (|foo| #) (|$DomainsInScope| # # #) ...)))
>
> >> Apparent user error:
> not known that (List (List (Integer))) has (AND (has (List (List
> (Integer))) (finiteAggregate)) (has (List (Integer)) (OrderedSet)))
^^^^^^^^^^^

This is compiler's way of saying that it does not have ordering
predicate for List(List(Integer)). A would say that this
message is better than average -- not to say that it is good
but that generally we should think about improving error
messages. OTOH given information that compiler has (it does
not know about user input), it is hard to do better.

OK, one thing that we should do is to track offending expression
back to user input. With current compiler this is essentially
unsolvable problem. It would be easy with different compiler
structure. More precisely, every subexpression should have
attached "birth certificate", that is info about original
location in source. From one point of view this is trivial,
but essentially requires complete compiler rewrite.

Another thing is wording of error messages. If you have
proposals for better wording I would like to hear them.

And, BTW what you think about interpreter error messages?
In a sense interpreter uses more advaned approach, for example
it says you at which place it thinks that syntax error
happended (but also interpretes looses info about source
locations when dealing with type errors). This is relevant
as I would like to unify interpeter with Spad compiler,
hopefuly preserving good features of both.

--
Waldek Hebisch

Ralf Hemmecke

unread,
Feb 19, 2020, 3:10:30 PM2/19/20
to fricas-devel
> This tells you that offending part is
>
> a < b
>
>> ****** level 3 ******
>> $x:= (< a b)
>> $m:= (Boolean)
>> $f:=
>> ((((|b| # #) (|a| # #) (|foo| #) (|$DomainsInScope| # # #) ...)))
>>
>> >> Apparent user error:
>> not known that (List (List (Integer))) has (AND (has (List (List
>> (Integer))) (finiteAggregate)) (has (List (Integer)) (OrderedSet)))
> ^^^^^^^^^^^

Yes, clearly a<b is the problem in

foo(): Boolean ==
a: List List Integer := empty()
b: List List Integer := empty()
a < b

So, finding the exact source position of the problem was not the issue.

But why is it a problem?


(4) -> Integer has OrderedSet
true

(5) -> List Integer has OrderedSet
true

(6) -> List List Integer has OrderedSet
true

Furthermore, I find the expression

>> not known that (List (List (Integer))) has (AND (has (List (List
>> (Integer))) (finiteAggregate)) (has (List (Integer)) (OrderedSet)))

a bit strange. There is an AND part that can either be true or false. As
I understand it, the compiler tells me that List(List Integer) is not
of the category true or false. Perhaps, I have to interpret the above
"... has (AND (has ...) (has ...))".

> This is compiler's way of saying that it does not have ordering
> predicate for List(List(Integer)).

As you see from the session above, OrderedSet shouldn't be a problem.

> Another thing is wording of error messages. If you have
> proposals for better wording I would like to hear them.

No the wording was not the problem. But I would have expected a category
in place X when it says: "not know that ... has X".

> And, BTW what you think about interpreter error messages?

Oh, sorry, but I haven't systematically investigated it. You can be sure
that I report back if something bothers me too much, but otherwise I
simply cannot say.

What I care more about currently, are compiler messages that throw a
lisp expression at me. It is managable if I see << ... >> and thus can
locate the error. But sometimes that marker is missing.

Well my dream would be Aldor error messages with the speed of the Spad
compiler. ;-)

Ralf

Ralf Hemmecke

unread,
Feb 19, 2020, 4:19:48 PM2/19/20
to fricas-devel
Since we are at interpreter error messages.
I get ...

(210) -> onetnStep! ycomp

>> System error:
The function BOOT::|*1;onetnStep!;1;initial| is undefined.

It's hard to track this down. Maybe there is a generic solution to it
that I don't know of.

The definition is

onetnStep!(y: Yn): Yn == (oneTracedStep!$Yn)(ytracen, rEntern, rLoopn,
rReturnn)(y)

inside a .input file.

oneTraceStep! is defined in a .spad file.

The parameters ytracen, rEntern, rLoopn, rReturnn are all functions that
return Void. The effectively print something. These are also defined
just before onetnStep! in the same .input file.

The definitions are not wrong, because seemingly after calling the
"parameter functions" separately, then also onetnStep!(y) works.

So my question is, how can I convince the interpreter to properly
initialize all these functions just before they are used without calling
each of these functions manually?

Thank you
Ralf

Waldek Hebisch

unread,
Feb 21, 2020, 10:41:38 AM2/21/20
to fricas...@googlegroups.com
I forgot that we define order on List.

> Furthermore, I find the expression
>
> >> not known that (List (List (Integer))) has (AND (has (List (List
> >> (Integer))) (finiteAggregate)) (has (List (Integer)) (OrderedSet)))
>
> a bit strange. There is an AND part that can either be true or false. As
> I understand it, the compiler tells me that List(List Integer) is not
> of the category true or false. Perhaps, I have to interpret the above
> "... has (AND (has ...) (has ...))".

That is really dump of internal data structure. 'has' above is
a shortcut for 'satifies property', where property is eiter a
Boolean expression built from base tests. So this is really

(List(List(List(Integer))) has finiteAggregate) and
(List(Integer) has OrderedSet)

Both are true, but apparenty at this point compiler does not
know this. So the problem looks like compiler limitation
(bug if you prefer
).

--
Waldek Hebisch

Waldek Hebisch

unread,
Feb 21, 2020, 10:53:47 AM2/21/20
to fricas...@googlegroups.com
On Wed, Feb 19, 2020 at 10:19:45PM +0100, Ralf Hemmecke wrote:
> Since we are at interpreter error messages.
> I get ...
>
> (210) -> onetnStep! ycomp
>
> >> System error:
> The function BOOT::|*1;onetnStep!;1;initial| is undefined.

I consider this as interpreter bug. Interpreter is producing
specialized versions of functions on demand, but in some
cases this machinery fails.

> It's hard to track this down. Maybe there is a generic solution to it
> that I don't know of.

Write simpler code :( Unfortunatly interpreter is buggy and
more complicated code is more likely to find bugs.

I have fixed a bunch of interpreter bugs, but may feeling is that
to make definite progress we need to rewrite it almost from
scratch. The diffeculty of rewrite is mostly that current
interpreter also have nice features and we would like to
preserve them.

--
Waldek Hebisch

Kurt Pagani

unread,
Feb 21, 2020, 11:00:06 AM2/21/20
to fricas...@googlegroups.com
When we add Join(finiteAggregate) it works; strange isn't it. Why?

)abbrev domain FOO Foo
Foo(): Exports == Implementation where
Exports == Join(finiteAggregate) with
foo: () -> Boolean
Implementation == add
foo(): Boolean ==
a: List List Integer := empty()
b: List List Integer := empty()
a < b

; compilation finished in 0:00:00.008
------------------------------------------------------------------------
Foo is now explicitly exposed in frame initial
Foo will be automatically loaded when needed from
/Users/kfp/Desktop/work/spad/FOO.NRLIB/FOO

(2) -> )sh FOO
Foo is a domain constructor.
Abbreviation for Foo is FOO
This constructor is exposed in this frame.
1 Names for 1 Operations in this Domain.
------------------------------- Operations --------------------------------

foo : () -> Boolean

(2) -> foo()

(2) false
Type: Boolean
(3) ->

Kurt Pagani

unread,
Feb 21, 2020, 11:32:01 AM2/21/20
to fricas...@googlegroups.com
After some thinking I don't find it so strange anymore that adding
'finiteAgggregate' is a remedy. The domain FOOX (only one List) works without
this because S=Integer, whereas in FOO we have S=List Integer where some info
may be get lost in the recursion.

ListAggregate(S : Type) : Category == Join(StreamAggregate S,
FiniteLinearAggregate S, ExtensibleLinearAggregate S) with
FiniteLinearAggregate(S : Type) : Category == Join(LinearAggregate S,
finiteAggregate)

)abbrev domain FOOX Foox
Foox(): Exports == Implementation where
Exports == with
foox: () -> Boolean
Implementation == add
foox(): Boolean ==
a: List Integer := empty()
b: List Integer := empty()
a < b

Ralf Hemmecke

unread,
Feb 21, 2020, 4:21:55 PM2/21/20
to fricas-devel
On 2/21/20 4:53 PM, Waldek Hebisch wrote:
> On Wed, Feb 19, 2020 at 10:19:45PM +0100, Ralf Hemmecke wrote:
>> Since we are at interpreter error messages. I get ...
>>
>> (210) -> onetnStep! ycomp
>>
>>>> System error:
>> The function BOOT::|*1;onetnStep!;1;initial| is undefined.
>
> I consider this as interpreter bug. Interpreter is producing
> specialized versions of functions on demand, but in some cases this
> machinery fails.
>
>> It's hard to track this down. Maybe there is a generic solution to
>> it that I don't know of.
>
> Write simpler code :(

;-) That's a cool hint. But hey, I love FriCAS, because I can write such
parametrized code. Obviously, I shouldn't mix .spad code with .input
code in such a way.

> Unfortunatly interpreter is buggy and more complicated code is more
> likely to find bugs.

OK, that means that I should continue writing complicated code. ;-)

> I have fixed a bunch of interpreter bugs, but may feeling is that to
> make definite progress we need to rewrite it almost from scratch.
> The diffeculty of rewrite is mostly that current interpreter also
> have nice features and we would like to preserve them.

Oh... if the Aldor compiler could help... Unfortunately, Peter is not
eager to write such a thing. Currently, "aldor -gloop" is not really a
replacement for the FriCAS interpreter.

Ralf

Reply all
Reply to author
Forward
0 new messages