Bug?

21 views
Skip to first unread message

Ralf Hemmecke

unread,
Jul 19, 2025, 4:03:37 AMJul 19
to fricas-devel
I do not quite understand why this doesn't work.

%%% (225) -> M ==> MultivariatePolynomial(['a,'b], QQ)

Type: Void
%%% (226) -> C ==> Fraction R

Type: Void
%%% (227) -> R ==> MultivariatePolynomial(['a,'b], QQ)

Type: Void
%%% (228) -> C ==> Fraction R

Type: Void
%%% (229) -> U ==> Polynomial C

Type: Void
%%% (230) -> e1 := 1$U

(230) 1
Type:
Polynomial(Fraction(MultivariatePolynomial([a,b],Fraction(Integer))))
%%% (231) -> e1 + e1

(231) 2
Type:
Polynomial(Fraction(MultivariatePolynomial([a,b],Fraction(Integer))))
%%% (232) -> "x"::Symbol :: U

Polynomial(Fraction(MultivariatePolynomial([a,b],Fraction(Integer)))
) is not a valid type.

%%% (232) -> u1: U := 1

Polynomial(Fraction(MultivariatePolynomial([a,b],Fraction(Integer)))
) is not a valid type.

%%% (232) -> u1: U := 1$U

Polynomial(Fraction(MultivariatePolynomial([a,b],Fraction(Integer)))
) is not a valid type.

Waldek Hebisch

unread,
Jul 19, 2025, 8:32:22 AMJul 19
to 'Ralf Hemmecke' via FriCAS - computer algebra system
Look at 'isLegitimateMode' in clammed.boot: it rejects types where
inner and outer polynomial variables intersect. In your case Polynomial
has all variables so there is intersection and the type is rejected.
You may ask why some construct accept such types and other do not?
Coercion above is potentially ambigious, that is probably the reason.
Similarly assigning 1 is potentially ambigious. 1$U looks fine,
but the test is probably too cude.

For me

monomial(1$U, "x"::Symbol, 1)$U

which avoids ambiguity works.

Certiainly, if we want to reject such things error message should
be clearer. And if done such rejection should be smarter (x is
a valid variable only for Polynomial, so really no ambiguity here).

And FriCAS is rather inconsistent here, Expression and series
domains have the same problem with variable capture, but are
handled differently than polynomials.

--
Waldek Hebisch

Ralf Hemmecke

unread,
Jul 22, 2025, 9:30:21 AMJul 22
to fricas...@googlegroups.com
Dear Waldek,

On 7/19/25 14:32, Waldek Hebisch wrote:

>> %%% (227) -> R ==> MultivariatePolynomial(['a,'b], QQ)
>> Type: Void
>> %%% (228) -> C ==> Fraction R
>> Type: Void
>> %%% (229) -> U ==> Polynomial C

%%% (232) -> "x"::Symbol :: U

Polynomial(Fraction(MultivariatePolynomial([a,b],Fraction(Integer)))
) is not a valid type.

> Look at 'isLegitimateMode' in clammed.boot: it rejects types where
> inner and outer polynomial variables intersect.

> For me
>
> monomial(1$U, "x"::Symbol, 1)$U
>
> which avoids ambiguity works.

Hmmmm... that now makes me wonder when the 'isLegitimateMode' actually
is applied/called. I seem to remember that I could achieve a working
situation (though I used Polynomial and below some multivariate
polynomial type) in compiled code.

Your 'monomial' construction and also a working 1$U seems to suggest
that not the type itself is problematic, but the (auto-)coercion.
Understandble.

Anyway, I have looked at 'isLegitimateMode' and must say, that I am
somewhat unhappy with it. The reason is that it lists explicitly some
types like Polynomial, Expression, Complex. I understand that this might
have been done to prevent users from running into troubles later,
however, coding that logic in BOOT and not SPAD, but with explicit
identifiers from the SPAD library, I don't know... If I now go and
invent a new polynomial domain. It is certainly not covered by this boot
logic. Yes, yes, I don't know how to do it better, still I feel uneasy
about it.

Anyway, if I use a construction like your 'monomial', i.e. create an
element of a domain like U that has no ambiguity in its creation, can it
happen that I will ever by bitten later (always assuming that I never
use any of the function that potenially are ambiguous. i.e. depend on
variable names/symbols)?

Technically a type like Polynomial(Polynomial(INT)) is not a problem and

%%% (9) -> PPI ==> Polynomial(Polynomial INT)
%%% (10) -> one := 1$PPI

(10) 1
Type: Polynomial(Polynomial(Integer))

seems to confirm this. But then why doesn't the following work

%%% (12) -> ppi:PPI := 1$PPI

Polynomial(Polynomial(Integer)) is not a valid type.

Obviously, (12) triggers a call to 'isLegitimateMode' whereas
(10) does not.

Suppose, I create a type

Foo(C: Ring): Polynomial C == ...

If I am careful with constructing the element of the return type (like
your 'monomial' above), would such code compile even if I later
instatiate Foo(Polynomial(INT))?
I (as a user) are aware of the potential variable overlap, but take care
of that myself. My question is whether SPAD might prevent me at some
point from doing this or kick in (via BOOT code) at some unexpected places.

Maybe this question is too hard to answer, but maybe you happen to know
and have some experience. For now I could live with a restriction of
being unable to call Foo(Polynomial(INT)), but it would be good to know
whether I must think of something else if ever I have need to call
Foo(Polynomial(INT)).

Thanks in advance.

Ralf

Waldek Hebisch

unread,
Jul 22, 2025, 8:45:14 PMJul 22
to 'Ralf Hemmecke' via FriCAS - computer algebra system
On Tue, Jul 22, 2025 at 03:30:17PM +0200, 'Ralf Hemmecke' via FriCAS - computer algebra system wrote:
> Dear Waldek,
>
> On 7/19/25 14:32, Waldek Hebisch wrote:
>
> > > %%% (227) -> R ==> MultivariatePolynomial(['a,'b], QQ)
> > > Type: Void
> > > %%% (228) -> C ==> Fraction R
> > > Type: Void
> > > %%% (229) -> U ==> Polynomial C
>
> %%% (232) -> "x"::Symbol :: U
>
> Polynomial(Fraction(MultivariatePolynomial([a,b],Fraction(Integer)))
> ) is not a valid type.
>
> > Look at 'isLegitimateMode' in clammed.boot: it rejects types where
> > inner and outer polynomial variables intersect.
>
> > For me
> >
> > monomial(1$U, "x"::Symbol, 1)$U
> >
> > which avoids ambiguity works.
>
> Hmmmm... that now makes me wonder when the 'isLegitimateMode' actually is
> applied/called. I seem to remember that I could achieve a working situation
> (though I used Polynomial and below some multivariate polynomial type) in
> compiled code.

AFAICS isLegitimateMode' is only used by interpreter.

> Your 'monomial' construction and also a working 1$U seems to suggest that
> not the type itself is problematic, but the (auto-)coercion. Understandble.
>
> Anyway, I have looked at 'isLegitimateMode' and must say, that I am somewhat
> unhappy with it. The reason is that it lists explicitly some types like
> Polynomial, Expression, Complex. I understand that this might have been done
> to prevent users from running into troubles later, however, coding that
> logic in BOOT and not SPAD, but with explicit identifiers from the SPAD
> library, I don't know... If I now go and invent a new polynomial domain. It
> is certainly not covered by this boot logic. Yes, yes, I don't know how to
> do it better, still I feel uneasy about it.

Yes, I feel the same.

> Anyway, if I use a construction like your 'monomial', i.e. create an element
> of a domain like U that has no ambiguity in its creation, can it happen that
> I will ever by bitten later (always assuming that I never use any of the
> function that potenially are ambiguous. i.e. depend on variable
> names/symbols)?
>
> Technically a type like Polynomial(Polynomial(INT)) is not a problem and
>
> %%% (9) -> PPI ==> Polynomial(Polynomial INT)
> %%% (10) -> one := 1$PPI
>
> (10) 1
> Type: Polynomial(Polynomial(Integer))
>
> seems to confirm this. But then why doesn't the following work
>
> %%% (12) -> ppi:PPI := 1$PPI
>
> Polynomial(Polynomial(Integer)) is not a valid type.
>
> Obviously, (12) triggers a call to 'isLegitimateMode' whereas
> (10) does not.

I am not sure how to trigger all places that call 'isLegitimateMode'.
But some are below:

1@PPI

that is check in 'upTARGET'

1::PPI

that is check in 'upCOERCE'

ppi : PPI

that is check in 'upDeclare'

There are 3 uses in i-coerce.boot and 1 use in i-funsel.boot that do not
produce error message (they just refuse to use some signatures).

Of the above they may be related. IIUC implementation of '@' has
restrictions and original authors probably preffered to avoid some
hairy cases. Declaration later works in similar way to '@' (I did
not check if code is shared, but effect is similar). Coercion
may have more problems.

You could try to comment out the checks above and see what happens.

> Suppose, I create a type
>
> Foo(C: Ring): Polynomial C == ...
>
> If I am careful with constructing the element of the return type (like your
> 'monomial' above), would such code compile even if I later instatiate
> Foo(Polynomial(INT))?
>
> I (as a user) are aware of the potential variable overlap, but take care of
> that myself. My question is whether SPAD might prevent me at some point from
> doing this or kick in (via BOOT code) at some unexpected places.
>
> Maybe this question is too hard to answer, but maybe you happen to know and
> have some experience. For now I could live with a restriction of being
> unable to call Foo(Polynomial(INT)), but it would be good to know whether I
> must think of something else if ever I have need to call
> Foo(Polynomial(INT)).

AFAICS Spad compiler is not affected by 'isLegitimateMode'. When
compiling Spad will accept such types with ususal disclaimer, that
is when resolving overloads Spad will you first function that it
finds. But overload resolution happens at compile time. Later
one may be affected by search order, but search order is reasonably
well defined and with sane implementation I would not expect
troubles here. Anyway, the point is that when compiler sees
Polynomial(Polynomial(INT)) and later 'monomial' it will try
'monomial' both from Polynomial(INT) and Polynomial(Polynomial(INT)).

Type rejected by 'isLegitimateMode' are used is several places
in algebra, so I would not expect serious troubles using them
(only some care to ensure correct choice of overloads).

--
Waldek Hebisch

Ralf Hemmecke

unread,
Jul 23, 2025, 6:26:55 AMJul 23
to fricas...@googlegroups.com
Dear Waldek,

> AFAICS Spad compiler is not affected by 'isLegitimateMode'.

thanks a lot for sharing your insight with me. That's very helpful.

Ralf
Reply all
Reply to author
Forward
0 new messages