Mechanics of function selection

14 views
Skip to first unread message

Grégory Vanuxem

unread,
Apr 2, 2023, 4:18:33 PM4/2/23
to fricas...@googlegroups.com
Hello folks,

I have an exposed domain JuliaDoubleFloat (abbrev JDF), and an exposed
package JuliaSpecialFunctions (abbrev JSF) that implements the 'sin'
function. JDF does not include TrigonometricFunctionCategory as its
exports, contrary to DoubleFloat for example.

I'm wondering why if I issue a 'sin(2)' in the interpreter it chooses
the sin$JSF:

(1) -> )set mess bo on
(1) -> sin 1

Function Selection for sin
Arguments: PI
-> no appropriate sin found in PositiveInteger
-> no appropriate sin found in Integer
-> no appropriate sin found in PositiveInteger
-> no appropriate sin found in Integer

Modemaps from Associated Packages
no modemaps

Remaining General Modemaps
[1] D -> D from D if D has TRIGCAT
[2] JuliaDoubleFloat -> JuliaDoubleFloat from JuliaSpecialFunctions


[1] signature: JDF -> JDF
implemented: slot (JuliaDoubleFloat)(JuliaDoubleFloat) from JSF
[2] signature: EXPR(INT) -> EXPR(INT)
implemented: slot $$ from EXPR(INT)


(1) 0.8414709848078965
Type: JuliaDoubleFloat

If I unexpose JSF I obtain what is expected:
(2) -> )unexpose JSF
JuliaSpecialFunctions is now explicitly hidden in frame initial
(2) -> sin 1

(2) sin(1)
Type: Expression(Integer)

Now, DoubleFloat also implements the 'sin' function, but directly in
the DoubleFloat domain. Not in a separate package.

If I do the same, move 'JSF$sin' to 'JDF$sin', the interpreter now
returns an EXPR INT as expected. Any idea why? And why, for example,
'sin(1)' does not return a DoubleFloat. Is this related to the
exposed.lsp file in src/algebra? If I want to continue to expose JSF
with 'sin' in it, how can I circumvent this choice and have an EXPR
INT returned?
__
Greg

Source, if this is necessary:
https://github.com/gvanuxem/fricas/blob/jlfricas/src/algebra/julia.spad line 281
https://github.com/gvanuxem/fricas/blob/jlfricas/src/algebra/jsf.spad

Waldek Hebisch

unread,
Apr 2, 2023, 8:06:57 PM4/2/23
to fricas...@googlegroups.com
There is a lot of special purpose tricks to get good selection
in "known" cases. General rule is that interpreter prefers
"low complexity constructors" and parameterless package is
deemed low complexity, so it is used in preference to alternatives.

For DoubleFloat interpreter knows that DoubleFloat may loose exactness,
so function selection machinery adds extra penalty to "cost" of
selections involving DoubleFloat. Interpreter does not know that
there is anything special about JuliaSpecialFunctions, you exposed
it so interpreter thinks that you want it.

Also, it looks that you are plying tricks to defeat Spad typechecking.
However, in typeless context type-based overload resolution is
not going to work well: if you can coerce anything to anything,
than interpreter have no way to know what you prefer.

Anyway, for DoubleFloat 'sin' important part is that it is defined
in domain, so to use it intepreter must already have DoubleFloat
argument or must use coercion (which counts as more complex option).

So possiblities seem to be:
- follow intended design and define functions in domais
- or make sure that there is no way to automatically get
JuliaDoubleFloat from integer/integer literal

You could try adding JuliaDoubleFloat to 'isApproximate' in
src/interp/i-funsel.boot, but I doubt that it would help.
IIRC we had similar problem with special functions: we obtained
numeric values instead of symbolic ones. This was fixed adapting
current structure (or, more precisely removing deviations from
used pattern).

BTW: If you name your package JuliaDoubleFloatSpecialFunctions,
then interpreter will treat is as "associated" package to
JuliaDoubleFloat. In such case, having JuliaDoubleFloat
intepreter will consider use of functions from
JuliaDoubleFloatSpecialFunctions, but will not introduce
JuliaDoubleFloat on whim.

--
Waldek Hebisch

Grégory Vanuxem

unread,
Apr 5, 2023, 10:56:15 AM4/5/23
to fricas...@googlegroups.com
Hello Waldek,

Thanks for your detailed explanation. It was very instructive.

I looked deeper into this and the interpreter has several ways to coerce the Integer to JDF. Even if I did not implement this coercion.

I'm still trying to bypass this. The fact that 'sqrt(2)' returns an AlgebraicNumber I totally agree with but not with sin(2) if sin$Domain is implemented in a package and not in the Domain itself. In fact, I do not understand why *trigonometric and other special functions have to be implemented in the domain itself and why this solution was chosen.

More to come on this.
__
Greg
> --
> 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/20230403004949.55n3optn3lkb2qxv%40fricas.math.uni.wroc.pl.

Grégory Vanuxem

unread,
Apr 13, 2023, 10:02:45 AM4/13/23
to fricas...@googlegroups.com
Of course, I have, for SBCL,  some  solutions. Just simple. 
Reply all
Reply to author
Forward
0 new messages