dummy variable in diffEval

5 views
Skip to first unread message

Qian Yun

unread,
May 22, 2026, 9:39:50 AM (5 days ago) May 22
to fricas-devel
Function "diffEval" in fspace.spad is not called during
creation of formal derivatives.

It is called in situations when k is a %diff kernel,
(operator(k)) (someTransformation argument k)
which is common in recursive simplification functions.

So, I can't think of any reason that a new dummy variable
is required and a substitution is needed here.

Because of alpha substitution, I don't think the old code
is doing anything of value.

- Qian

diffEval l ==
k : K
g := retract(second l)@K
((u := retractIfCan(first l)@Union(K, "failed")) case "failed")
or (u case K and symbolIfCan(k := u@K) case SY) => dfeval(l, g)
op := operator k
(ud := derivative op) case "failed" =>
-- possible trouble
-- make sure it is a dummy var
dumm : % := symsub(gendiff, 1)::%
ss := subst(l.1, l.2 = dumm)
-- output(nl::OutputForm)$OutputPackage
-- output("fixed"::OutputForm)$OutputPackage
nl := [ss, dumm, l.3]
kernel(opdiff, nl)
(n := position(second l, argument k)) < minIndex l =>
dfeval(l, g)
d := ud::List(List % -> %)
eval((d.n)(argument k), g, third l)

Waldek Hebisch

unread,
May 22, 2026, 10:09:53 AM (5 days ago) May 22
to fricas...@googlegroups.com
On Fri, May 22, 2026 at 09:39:46PM +0800, Qian Yun wrote:
> Function "diffEval" in fspace.spad is not called during
> creation of formal derivatives.
>
> It is called in situations when k is a %diff kernel,
> (operator(k)) (someTransformation argument k)
> which is common in recursive simplification functions.
>
> So, I can't think of any reason that a new dummy variable
> is required and a substitution is needed here.
>
> Because of alpha substitution, I don't think the old code
> is doing anything of value.

Representation of derivatives needs a dummy. Kernels may
be nested and we sometimes need to substitute for dummies.
Old code in few other places (not this one) tried to use
the same dummy and this led to obscure bugs. Those bugs
were fixed by consistently using new dummies.

Need for distinct dummies may be unobvious and people believed
that reusing dummy is safe, but it is easy to overlook some
special case. So, I very much prefer current state, that
is consistently using new dummies.

--
Waldek Hebisch

Qian Yun

unread,
May 22, 2026, 10:24:42 AM (5 days ago) May 22
to fricas...@googlegroups.com
On 5/22/26 10:09 PM, Waldek Hebisch wrote:
>
> Representation of derivatives needs a dummy. Kernels may
> be nested and we sometimes need to substitute for dummies.
> Old code in few other places (not this one) tried to use
> the same dummy and this led to obscure bugs. Those bugs
> were fixed by consistently using new dummies.
>
> Need for distinct dummies may be unobvious and people believed
> that reusing dummy is safe, but it is easy to overlook some
> special case. So, I very much prefer current state, that
> is consistently using new dummies.
>

That code has remained the same since the beginning of FriCAS,
so at least unchanged for 20 years, maybe 40 years.

I believe with the introduction of encode_diff/decode_diff,
this usage of new dummy is no longer needed.

In encode_diff, for high order derivatives, same dummy symbols
are reused. If certain rules are followed (i.e alpha
substitution), then transformation of (%diff) kernel will not
mess things up.

For making changes safe, we can add some assertions there.

- Qian

Waldek Hebisch

unread,
May 22, 2026, 10:40:38 AM (5 days ago) May 22
to fricas...@googlegroups.com
The trouble is that such change affects all expression code. Bugs
that I mentioned looked like obviously correct code when viewed in
isolation and were triggered by interaction with other code.

For old bugs we have tests, so hopefully anybody trying to
reintroduce old bug will be warned by failing test. But here
we are likely to see problem only some time after making change.

--
Waldek Hebisch

Qian Yun

unread,
May 23, 2026, 6:18:55 AM (4 days ago) May 23
to fricas...@googlegroups.com
Well, as you said before, current behavior -- excessive
generation of new kernels, is also a problem.
Although it can be mitigated by recycle kernel cache.
As you said, correct behavior should be to avoid
generation of unnecessary kernels.

After run "make all" in src/input, I find one reason
on the new dummy variable substitution:
in src/input/heat.input, there's a "rule" patter matching,
it will mess up the %diff kernel to
%diff(f(z*sqrt(t)),z*sqrt(t), z)

So variable substitution is needed sometimes, and I
still believe that using new dummy every time is not
necessary, dummy variables can be reused.

- Qian
Reply all
Reply to author
Forward
0 new messages