You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-**Project in one sentence:** Rule-based symbolic integration in Julia
22
22
23
-
This project aimed to implement symbolic integration (i.e. finding primitives of functions, not numerical integration) in Symbolics.jl, the Julia package for symbolic manipulation. The chosen algorithm was rule-based integration, which uses a large number of integration rules that specify how to integrate various expressions. I chose this strategy thanks to the [Mathematica](https://www.wolfram.com/mathematica/) package [RUBI](https://rulebasedintegration.org/), which already contains more than 6000 integration rules and is open source.
23
+
With this project I implemented symbolic integration (i.e. finding primitives of functions, not numerical integration) in [Symbolics.jl](https://docs.sciml.ai/Symbolics/stable/), the Julia package for symbolic manipulation. The chosen algorithm was rule-based integration, which uses a large number of integration rules that specify how to integrate various mathematical expressions. I chose this strategy thanks to the [Mathematica](https://www.wolfram.com/mathematica/) package [RUBI](https://rulebasedintegration.org/), which already contains more than 6000 integration rules and is open source.
24
24
25
25
The main challenges I encountered were:
26
-
-**Rule translation:** The rules are written in Mathematica files with Mathematica syntax (very different from Julia syntax). I tackled this challenge by creating a translator script that automatically translates the rules into Julia syntax using regex and other string manipulation functions that I wrote. It's described in detail in the sections below
26
+
-**Translation of integration rules:** The integration rules are written in Mathematica syntax (very different from Julia syntax). I tackled this challenge by creating a translator script that automatically translates them into Julia syntax using regexes and other fancy string manipulation functions that I wrote (it's described in detail in the sections below). Even with this script, I had to manually test the rules and this was time conusming.
27
27
28
-
-**Utility functions:** There are many rules in RUBI, but also many utility functions used in the rule conditions, including both base Mathematica functions and custom functions made for the RUBI package (the file where they are defined contains 7842 lines of code). The translation of these could not be automated, so I had to: 1) understand what each utility function did (not always easy) and 2) rewrite it in Julia.
28
+
-**Utility functions:** There are many integration rules in RUBI, but also many utility functions used in the rule conditions, including both base Mathematica functions (usually not present in Symbolics.jl) and custom functions made for the RUBI package (the file where they are defined contains 7842 lines of code). The translation of these could not be automated and was a lot time consumning and error prone as I had to both understand what each utility function did (not always easy), rewrite it in Julia, and test its behaviour with lots of different rules.
29
29
30
-
-**Rule application:** Julia's Symbolics.jl already had a pattern matching functionality, with the `@rule` macro, but it was not sufficient for symbolic integration to work well, so I improved it. There was not one single big improvement but many small ones, described in detail in the sections below.
30
+
-**Rule application:** Julia's Symbolics.jl already had a pattern matching functionality, with the `@rule` macro, but it was not sufficiently good for this package to work well, so I improved it. There was not one single big improvement but many small ones, described in detail in the sections below.
31
31
32
-
As of september 2025, end of GSoC, I translated 3000+ rules from 90+ files and the system can integrate a vast class of expressions, involving normal algebraic functions
32
+
As of september 2025, end of GSoC, I translated more than 3400 rules and the system can integrate a vast class of expressions, involving normal algebraic functions:
33
33
```julia
34
34
julia>integrate(sqrt(4-12*x +9*x^2)+sqrt(1+x),x)
35
35
┌-------Applied rule 0_1_0 on ∫(sqrt(1+ x) +sqrt(4-12x +9(x^2)), x)
and much more. I also added 27585 tests (integrals with their correct solution) from the RUBI package that can be used to test the package.
108
+
and much more. I also added 27585 tests (integrals with their correct solution) from the RUBI package and an automated testing procedure that can be used to test the package.
109
109
110
110
While this shows impressive integration capabilities, there is still work left to do, which I briefly list here and describe in detail below.
111
-
-First, there are still some problems with the SymbolicUtils `@rule` macro that prevent some expressions from being integrated even though the rules are present.
112
-
- There are still some rules not translated, mainly those involving trigonometric functions, hyperbolic functions, and special functions.
113
-
- Finally, during the summer, a Julia package has been revived that performs symbolic integration using various algorithms, and we decided to create one unified package where the user can choose which integration strategy to use. I thus need to move all my code to that repository, the pr is underway: [pr](https://github.com/JuliaSymbolics/SymbolicIntegration.jl/pull/12).
111
+
-Most importantly, there are still some problems with the SymbolicUtils `@rule` macro that prevent some expressions from being integrated even though the rules are present, and that slow down the package.
112
+
- There are still some rules not translated, mainly those involving trigonometric functions, hyperbolic functions, and special functions.
113
+
- Finally, during the summer, a Julia package has been revived that performs symbolic integration using various algorithms, and we decided to create one unified package where the user can choose which integration strategy to use. I thus need to move all my code to that repository, the [pull request](https://github.com/JuliaSymbolics/SymbolicIntegration.jl/pull/12) is underway.
114
114
115
115
# Detailed report of work done
116
116
Here is a detailed report of the work done with links to code and pull requests (pr), if you really want to deep dive in the technical details. The code I have written is mainly in this repo, SymbolicIntegration.jl, and in the SymbolicUtils.jl repo where I improved the `@rule` macro.
added commutative checks, <br> negative exponent matching, <br> `sqrt` and `exp` support <br> and new simplify behaviour (yes, all in one pr) | [pr](https://github.com/JuliaSymbolics/SymbolicUtils.jl/pull/752)
In the second case, it differs from the one defined in the rule (sin first, then cos). So I made the operations `+` and `*` commutative in rules.
180
181
181
182
### Negative Exponent Support
182
-
Previously, a rule like `(~x)^(~m)` didn't match an expression like `1/x^3` with `~m=-3`, and this was crucial for the correct functioning of my package. So I changed this behavior, and now exponents can match divisions using a negative value as the exponent.
183
+
Previously, a rule like `(~x)^(~m)` didn't match an expression like `1/x^3` with `~m=-3`, and this was crucial for the correct functioning of my package. So I changed this behavior, and now exponents can match divisions using a negative value as the exponent. This was trickier than it seems, because a division in SymbolicUtils can be represented in many ways: `(1/...)^(...))`, `1/(...)^(...)`, `1/(...)`, `(...)/(...)` and in fact in some rare cases this is still not working properly (read neim problem section below).
0 commit comments