Possible compiler bug: "Cannot coerce" error while trying to use ^ on Float and Integer arguments

51 views
Skip to first unread message

Neven Sajko

unread,
Oct 30, 2020, 6:44:45 AM10/30/20
to fricas...@googlegroups.com
Hello,

I am getting the following error with the attached Spad code, in the
implementation of lab1method1 while trying to create a matrix of Float
values:

Apparent user error: Cannot coerce i of mode (NonNegativeInteger) to
mode (Fraction (Integer))

I don't know how to proceed. It seems as if the ^ operation from
Domain Float, the one that takes Float and Integer as input, is not
available.

Thank you,
Neven
lab1.spad

Ralf Hemmecke

unread,
Oct 30, 2020, 7:53:20 AM10/30/20
to fricas...@googlegroups.com
Hi Neven,

thank you. You hit another problem that is not clearly enough described
in the book. When I started with AXIOM, it took some time until I
understood, that not everything that works in the interpreter also works
for the compiler. You have hit such a case here. Another thing that
should go to the FAQs.

Maybe someone corrects me if I am wrong, but I am not aware of a mehtod
to define a recursive function in a .spad file in the way you did (and
which would probably work in a .input file. (BTW, do not use TABs in
your files, not forbidden, but ugly. Convince your editor to replace
them by spaces.)

r : NonNegativeInteger -> Float
r(0) == a.1
r(1) == a.2
r(2) == a.3
r(m) == (x.1+x.2+x.3)*r(m-1) - (x.1*x.2+x.2*x.3+x.3*x.1)*r(m-2) +
x.1*x.2*x.3*r(m-3)
r(n)

> I don't know how to proceed. It seems as if the ^ operation from
> Domain Float, the one that takes Float and Integer as input, is not
> available.

The error message is indeed not very helpful. But you also have quite
some errors in it.

Note that in contrast to the interpreter, you have to be quite explicit
for the compiler. The site http://fricas.github.io/api should help you.
Just type your function/type into the search field.

As you see in the attachment, I have introduced other "tricks" like
using macros to abbreviate types or even some functions like "asN".

This "asN" is special, since subtraction is not generally defined in
NonNegativeInteger. When I look at
http://fricas.github.io/api/NonNegativeInteger.html, I cannot even find
it. The compiler knows that NonNegativeInteger is a subdomain of Integer
and thus computes that "m-1" inside Integer. The "qcoerce(m-1)@N" then
simply says: "Compiler, believe me, that integer is a NonNegativeInteger."

I have also added types. They are not always necessary, but when you
read your program in a year, then you will find it helpful to recognize
the types from the program text. A particular problem was
"particularSolution". Contrary to the interpreter, the compiler has
fewer things in scope, so you must add

$LinearSystemMatrixPackage1(Float)

in order to tell the compiler in which package it should look to find a
function with name "particularSolution".

The compiler does not like guessing and that is fine, since otherwise
your program might compute other things than you intended to compute.
Note that in FriCAS there is heavy overloading of names.

For lab1method2 I introduced lab1m2 just to show that a function can
return a function and that one can can define a function inside another
function.

Of course, lab1m2 is not needed and you can directly define r insied
labimethod 2 and then return r(n).

Hope that helps.

Ralf
lab1.spad

Neven Sajko

unread,
Oct 30, 2020, 11:41:49 AM10/30/20
to fricas...@googlegroups.com
Thank you very much for your thoughtful responses, Ralf, I understand
Spad a bit better now thanks to you. However it seems that another
roadblock has appeared: while your lab1method1 works fine, lab1method2
does not. At the end of the compilation there are warnings about the
function BOOT::|DMLAB1;r| (which surely refers to the local function
r) being undefined. Indeed, when I try to execute lab1method2 as I had
lab1method1, I get the System error "The function BOOT::|DMLAB1;r| is
undefined." and no other output.

Do you know why this happens?

Thanks,
Neven

Ralf Hemmecke

unread,
Oct 30, 2020, 1:10:28 PM10/30/20
to fricas...@googlegroups.com
Indeed.

D ==> DirectProduct(3, Float)
x := directProduct(vector [1.1, 2.2, 3.3])$D
a := directProduct(vector [2.1, 3.2, 4.3])$D

(7) -> lab1method2(x, a, 2)

(7) 4.3
Type: Float
(8) -> lab1method2(x, a, 1)

(8) 3.2
Type: Float
(9) -> lab1method2(x, a, 3)

>> System error:
The function BOOT::|DMLAB1;r| is undefined.

Arrrrhhhh. Obviously the SPAD compiler is unable to deal with recursive
local functions. :-(

Waldek?

Ralf

PS: With a bit of macro magic, I have changed to making lab1method2
recursive. That seems to work, see attachment.
lab1.spad

Neven Sajko

unread,
Oct 30, 2020, 1:29:04 PM10/30/20
to fricas...@googlegroups.com
Hmm, I tried to implement lab1method2 with iteration with a for loop
instead of with recursion, but now Fricas tells me this:

Internal Error
Unexpected error in call to system function compColon

The package is again attached.

Thank you,
Neven
lab1.spad

Ralf Hemmecke

unread,
Oct 30, 2020, 1:36:11 PM10/30/20
to fricas...@googlegroups.com
That's a nasty error that I cannot resolve without seeing the code.
Usually when I get this, it is an identation problem in the code.

Ralf

Bill Page

unread,
Oct 30, 2020, 5:45:06 PM10/30/20
to fricas-devel
Two problems: First, unlike the interpreter, SPAD does not have
multiple assignment. The error message about "compColon" is the
compiler's poor way of trying to say that. Secondly, the DirectProduct
domain does not have a direction coercion from (...) tuple, List or
other similar domain. You need to explicitly call the 'directProduct'
function to create an instance. It would probably be better if
DirectProduct exported a suitable function called 'construct'.

wspage@desktop:~/Downloads$ diff -au lab1.spad 'lab1(1).spad'
--- lab1.spad 2020-10-30 17:20:50.432221061 -0400
+++ lab1(1).spad 2020-10-30 17:20:18.928826110 -0400
@@ -20,8 +20,10 @@
zero? n => a.1
n = 1 => a.2
n = 2 => a.3
- (c1, c2, c3): Float := (x.1+x.2+x.3,
-(x.1*x.2+x.2*x.3+x.3*x.1), x.1*x.2*x.3)
+ c1: Float := x.1+x.2+x.3
+ c2: Float := -(x.1*x.2+x.2*x.3+x.3*x.1)
+ c3: Float := x.1*x.2*x.3
for i in 3..n repeat
b: D := a
- a := (b.2, b.3, c1*b.3 + c2*b.2 + c3*b.1)
+ a := directProduct([b.2, b.3, c1*b.3 + c2*b.2 + c3*b.1])
a.3
> --
> 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...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/fricas-devel/CAL%2BbK4M_BMeYA197K9YAKJvDVvXf705smyyk-Mwc%3D%2BQ4oF7G5w%40mail.gmail.com.

Neven Sajko

unread,
Oct 31, 2020, 9:29:49 AM10/31/20
to fricas...@googlegroups.com
Thank you for your insight, Bill.

Does somebody know why does DirectProduct not have setelt! and qsetelt! ?

Thanks,
Neven

Bill Page

unread,
Oct 31, 2020, 10:00:18 AM10/31/20
to fricas-devel
The elements of DirectProduct are intended to be immutable
mathematical values, i.e a "tuple" in a n-tuple product, not a data
container.

Ralf Hemmecke

unread,
Oct 31, 2020, 10:50:25 AM10/31/20
to fricas...@googlegroups.com
Yes, this "immutability" seems sometime difficult to accept, but since
it is easy to convert back and forth to Vector and use setelt! from
there, it's not a big deal. Perhaps it it sometimes costs more copying
than you wish to have.

Ralf

Neven Sajko

unread,
Oct 31, 2020, 11:32:54 AM10/31/20
to fricas...@googlegroups.com
Yes, indeed, in the end I converted the DirectProduct to Vector (with
an extra variable) before entering the loop. The code is here:
https://github.com/nsajko/discrete-math-lab1

Thanks, everyone.

Neven

Waldek Hebisch

unread,
Nov 1, 2020, 12:19:17 PM11/1/20
to fricas...@googlegroups.com
On Fri, Oct 30, 2020 at 06:10:25PM +0100, Ralf Hemmecke wrote:
>
> Arrrrhhhh. Obviously the SPAD compiler is unable to deal with recursive
> local functions. :-(

Yes, this is current limitation.


--
Waldek Hebisch

Mark Clements

unread,
Nov 2, 2020, 8:13:38 AM11/2/20
to fricas...@googlegroups.com
As a follow-up, anonymous recursive functions in Axiom are described at:

https://rosettacode.org/wiki/Anonymous_recursion#Axiom

For the example:

lab1method2(x: D, a: D, n: N): Float ==
zero? n => a.1
n = 1 => a.2
n = 2 => a.3
c := vector([x.1+x.2+x.3, -(x.1*x.2+x.2*x.3+x.3*x.1),
x.1*x.2*x.3])$V
f : Reference((D, N) -> D) := ref((d, n) +-> d) -- dummy
definition required
f() := (v,i) +-> if i=n+1 then v else _
f()(directProduct(vector([v.2, v.3, c.1*v.3 + c.2*v.2 +
c.3*v.1])$V)$D,i+1)
(f()(a,3)).3

Kindly, Mark.

On 31/10/20 4:32 pm, Neven Sajko wrote:
> Yes, indeed, in the end I converted the DirectProduct to Vector (with
> an extra variable) before entering the loop. The code is here:
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnsajko%2Fdiscrete-math-lab1&data=04%7C01%7Cmark.clements%40ki.se%7Cbc6633bf80bf427e2dca08d87db23d2f%7Cbff7eef1cf4b4f32be3da1dda043c05d%7C0%7C0%7C637397552701816541%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=3TxfzvnLetINBcrAvKOgTpqTzEP3KNmniXeNhVgtYGg%3D&reserved=0
>
> Thanks, everyone.
>
> Neven
>



När du skickar e-post till Karolinska Institutet (KI) innebär detta att KI kommer att behandla dina personuppgifter. Här finns information om hur KI behandlar personuppgifter<https://ki.se/medarbetare/integritetsskyddspolicy>.


Sending email to Karolinska Institutet (KI) will result in KI processing your personal data. You can read more about KI’s processing of personal data here<https://ki.se/en/staff/data-protection-policy>.
Reply all
Reply to author
Forward
0 new messages