Pattern matching in FriCAS

11 views
Skip to first unread message

Ralf Hemmecke

unread,
Apr 9, 2024, 12:03:49 PM4/9/24
to fricas-devel
I have no great experience with pattern matching.

While constructing

combineRadicals := rule (_
sqrt(-(x|integer? x and positive? integer x)) *_
sqrt(-(y|integer? y and positive? integer y))_
== -sqrt(x*y);_
sqrt((x|integer? x)) *_
sqrt((y|integer? y and positive? integer y))_
== sqrt(x*y))

I initially hat quite some difficulties, because one cannot simply write
"x>0" instead of "positive? integer x". I basically guessed "positive?".

The FriCAS book is quite silent about what expressions can actually
occur in a suchThat expression of a rule.

Can someone point me to the source code where I can find the
implementation of that "positive?" (and maybe "negative?", etc.)

Maybe we should list all these possible functions in the patter matching
section of the FriCAS book.

Ralf

PS: Would it make sense to include the above rule (even though it is
very limited) as a function rootCombine along the functions rootSplit
rootFactor and rootSimp in AlgebraicManipulation?

If yes, I will try to provide a patch.

Furthermore, the documentation of rootSplit says that it is generally
not valid. Agreed, but can we at least implement it in such a way (maybe
it is already) that the documentation can say that for positive integers
a, b it splits sqrt(-a/b) as sqrt(-a)/sqrt(b) and maybe even as
sqrt(-1)*sqrt(a)/sqrt(b). If one can rely at least on that, it would
allow (on a big subset of expressions) to split the expression into a
real and imaginary part. Maybe it is not only me who would find that useful.

Waldek Hebisch

unread,
Apr 9, 2024, 4:43:57 PM4/9/24
to fricas...@googlegroups.com
On Tue, Apr 09, 2024 at 06:03:45PM +0200, Ralf Hemmecke wrote:
> I have no great experience with pattern matching.
>
> While constructing
>
> combineRadicals := rule (_
> sqrt(-(x|integer? x and positive? integer x)) *_
> sqrt(-(y|integer? y and positive? integer y))_
> == -sqrt(x*y);_
> sqrt((x|integer? x)) *_
> sqrt((y|integer? y and positive? integer y))_
> == sqrt(x*y))
>
> I initially hat quite some difficulties, because one cannot simply write
> "x>0" instead of "positive? integer x". I basically guessed "positive?".
>
> The FriCAS book is quite silent about what expressions can actually occur in
> a suchThat expression of a rule.

Well, AFAICS you need an expression which can be evaluated to a boolean
value. At lower level predicate is just a boolean valued function.
Interpreter makes a function from expression. Part which may be
confusing is that you need predicate on _expressions_, which may
interfere with intepreter type guessing. And popular predicates
like '>' are not defined for expressions.

>
> Can someone point me to the source code where I can find the implementation
> of that "positive?" (and maybe "negative?", etc.)

AFAICS you are using 'positive?' from OrderedRing. I do not know
why '> 0' does not work for you, maybe you need '> 0$Integer'.

> Maybe we should list all these possible functions in the patter matching
> section of the FriCAS book.

Predicate can use _any_ function. The only condition is that it
must type check (in particular final value must be Boolean).
I affraid that you want "How to write my expression so that
FriCAS uses types that I have in mind" guide.

> PS: Would it make sense to include the above rule (even though it is very
> limited) as a function rootCombine along the functions rootSplit rootFactor
> and rootSimp in AlgebraicManipulation?

I am not sure. My plan is to add a combine function to RootSimplification.
I want it to do much more than your rule is doing. Part of it is
that I want rule that works on functions. Part is that doing it
at lower level I will be able do discover things that are impossible
to find using simple patterns (patterns can be powerful, but this
power causes complexity).

> If yes, I will try to provide a patch.
>
> Furthermore, the documentation of rootSplit says that it is generally not
> valid. Agreed, but can we at least implement it in such a way (maybe it is
> already) that the documentation can say that for positive integers
> a, b it splits sqrt(-a/b) as sqrt(-a)/sqrt(b) and maybe even as
> sqrt(-1)*sqrt(a)/sqrt(b).

Well, 'rootSplit' is supposed to work for arbitrary Expression space
over an integral domain. Look at:

ef := Expression(Fraction(Integer))
a := -1/2
sqrt(a)$ef
rootSplit(%)$AlgebraicManipulations(Fraction(Integer), ef)

this gives:

+---+
| 1
(4) |- -
\| 2
Type: Expression(Fraction(Integer))

that is no splitting at all. And 'rootSplit' does not factor out
imaginary unit. For Expression(Integer) internal form has denominator
with positive leading coefficient. And 'rootSplit' uses this internal
form, so inded, in this case we get positive denominator.

> If one can rely at least on that, it would allow
> (on a big subset of expressions) to split the expression into a real and
> imaginary part.

Well, for this we have different functions.

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