resolution of conflicts

11 views
Skip to first unread message

Ralf Hemmecke

unread,
Mar 31, 2025, 3:44:39 PMMar 31
to fricas-devel
Dear Waldek,

suppose I write a domain as follows:
========================
Foo(R: Ring): Exports == Implementation where
Exports ==> Join(SetCategory, CoercibleFrom R) with
_*: (Integer, %) -> %
_*: (R, %) -> %
Implementation ==> add
((z: Integer) * (x: %)): % == (z::R) * x
((r: R) * (x: %)): % == ... -- actual implementation --
========================

I wonder whether I should actually do this.
Does the compiler really produce proper code for Foo(Integer)?
I fear that the compiler might think that implementing

((z: Integer) * (x: %)): %

it, it just needs to call coerce(z)@Integer and then generate code
for (coerce(z)@Integer)*x) basically leading to an infinite loop.

Can the compiler handle that case or must I be more careful with that
definition?

I guess the original designers have thought about this problem and
solved it somehow, but maybe not.

Actually, code like in Foo appears in the library, for example, here

https://github.com/fricas/fricas/blob/master/src/algebra/fr.spad#L222

and here

https://github.com/fricas/fricas/blob/master/src/algebra/pfr.spad#L294

and that does not seem to be a problem.


Thank you in advance.
Ralf

Waldek Hebisch

unread,
Mar 31, 2025, 7:47:37 PMMar 31
to 'Ralf Hemmecke' via FriCAS - computer algebra system
On Mon, Mar 31, 2025 at 09:44:34PM +0200, 'Ralf Hemmecke' via FriCAS - computer algebra system wrote:
> Dear Waldek,
>
> suppose I write a domain as follows:
> ========================
> Foo(R: Ring): Exports == Implementation where
> Exports ==> Join(SetCategory, CoercibleFrom R) with
> _*: (Integer, %) -> %
> _*: (R, %) -> %
> Implementation ==> add
> ((z: Integer) * (x: %)): % == (z::R) * x
> ((r: R) * (x: %)): % == ... -- actual implementation --
> ========================
>
> I wonder whether I should actually do this.
> Does the compiler really produce proper code for Foo(Integer)?
> I fear that the compiler might think that implementing
>
> ((z: Integer) * (x: %)): %
>
> it, it just needs to call coerce(z)@Integer and then generate code
> for (coerce(z)@Integer)*x) basically leading to an infinite loop.
>
> Can the compiler handle that case or must I be more careful with that
> definition?

AFAICS your code should compile as intended. There are similar
situations which may be problematic, but they involve Rep.
Namely, automatic coercions between % and Rep may sometimes give
problems. But normally Spad compiler will not introduce 'coerce' on
its own. Users may define 'autoCoerce', and if it is defined then
compiler may automatically use it, but currently 'autoCoerce' is
only defined for unions.

--
Waldek Hebisch

Ralf Hemmecke

unread,
Apr 1, 2025, 3:27:43 AMApr 1
to fricas...@googlegroups.com
>> ========================
>> Foo(R: Ring): Exports == Implementation where
>> Exports ==> Join(SetCategory, CoercibleFrom R) with
>> _*: (Integer, %) -> %
>> _*: (R, %) -> %
>> Implementation ==> add
>> ((z: Integer) * (x: %)): % == (z::R) * x
>> ((r: R) * (x: %)): % == ... -- actual implementation --
>> ========================

> AFAICS your code should compile as intended.
...
> Namely, automatic coercions between % and Rep ...

Well, I believe that it works, but what I meant was not the problem
of (auto)coercion, but rather how the function selection works.

Clearly, the compiler will produce correct code for
*: (Integer, %) -> % and
*: (R, %) -> %
The problem arises what happens if R is set to Integer when I create the
domain.

Certainly the two functions (let's call them multINT and multR)
have both implementation code in the Foo constructor.
In Foo(Integer), there is however only *$Foo(Integer) with signature
(Integer,%)->%. Will this be the code for multR? Or will it be the code
for multINT which then calls (the not directly accessible code for) multR?

Clearly, one shouln't implement something like

((z: Integer) * (x: %)): % == x
((r: R) * (x: %)): % == -x

Or would it then be predictable or delibarately unspecified whether
17*x returns x or -x in Foo(Integer)?

Ralf

Waldek Hebisch

unread,
Apr 4, 2025, 2:14:07 PMApr 4
to 'Ralf Hemmecke' via FriCAS - computer algebra system
Currently Spad compiler selects a number for each exported signature.
Calls inside domain are based on those numbers. In particular
multINT will always (regardless of R) call multR. For calls from
outside it is really not well defined which one will be called
when R = Integer.

--
Waldek Hebisch
Reply all
Reply to author
Forward
0 new messages