On 6/16/26 7:30 PM, Waldek Hebisch wrote:
> On Tue, Jun 16, 2026 at 05:58:08PM +0800, Qian Yun wrote:
>> New optimization for today:
>>
>> If x and y does not have common algebraic kernels, either:
>>
>> 1. they don't have algebraic kernels at all, so they are
>> canonical under FRAC SMP, so previous check is enough.
>
> That is true for Expression(Integer) and probably also for
> Expression(Complex(Integer)), but may fail for more general
> coefficients. Internally we sometimes use
> Expression(Expression(Integer))...
>
> So any such thing must be conditional, limited to "good"
> coefficients.
Good catch! Yes, limiting to Expression(Integer) is good enough
for 99% situations. See attachment for the updated version.
>> 2. they have different algebraic kernels. Then there's
>> no way they can be equal.
>
> That looks obvious, but I have seen various strange examples,
> so it would be better to have a proof.
>
In EXPR(INT), for x,y doesn't share any common algebraic kernels,
then 'reduc' will do nothing for numer(x)*denom(y)-numer(y)*denom(x).
=$EXPR returns true for x,y
<=> numer(x)*denom(y)-numer(y)*denom(x) = 0
<=> numer(x)/denom(x)=numer(y)/denom(y)
<=> numer(x)=numer(y) and deonm(x)=denom(y)
(Since FRAC will strip gcd from them).
- Qian
--
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 [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/fricas-devel/b8ab3d7b-3948-49be-a264-0ba9019b7468%40gmail.com.
diff --git a/src/algebra/expr.spad b/src/algebra/expr.spad
index ed89a42f..b5dcbac2 100644
--- a/src/algebra/expr.spad
+++ b/src/algebra/expr.spad
@@ -101,11 +101,22 @@ Expression(R : Comparable) : Exports == Implementation where
x : % + y : % == algreduc(x +$Rep y, commonk(x, y))
(x : % - y : %) : % == algreduc(x -$Rep y, commonk(x, y))
x : % / y : % == algreduc(x /$Rep y, commonk(x, y))
- x : % = y : % ==
- denom(x) = denom(y) => numer(x) = numer(y)
- -- we only need to care about the numerator of (x - y)
- res := (numer(x)*denom(y) - numer(y)*denom(x))::Rep
- zero?(reduc(res, commonk(x, y)))$Rep
+
+ if R is Integer then
+ x : % = y : % ==
+ denom(x) = denom(y) => numer(x) = numer(y)
+ lk := commonk(x, y)
+ empty? lk => false
+ -- we only need to care about the numerator of (x - y)
+ res := (numer(x)*denom(y) - numer(y)*denom(x))::Rep
+ zero?(reduc(res, lk))$Rep
+ else
+ -- fallback version, in case R is Expression or AlgebraicNumber
+ x : % = y : % ==
+ denom(x) = denom(y) => numer(x) = numer(y)
+ -- we only need to care about the numerator of (x - y)
+ res := (numer(x)*denom(y) - numer(y)*denom(x))::Rep
+ zero?(reduc(res, commonk(x, y)))$Rep
number?(x : %) : Boolean ==
if R has RetractableTo(Integer) then