June 15, 2026

00:00, Monday, 15 June

After spending the previous week understanding how manualintegrate searched for solutions, I finally started making changes to the integrator itself. Rather than adding completely new capabilities, I decided to focus on something that had bothered me ever since I began reading the integration code: SymPy's symbolic integrators were surprisingly fragmented.

June 08, 2026

00:00, Monday, 08 June

During the second week of Google Summer of Code, I still had not written a single feature that was intended to be merged into SymPy. Instead, I spent most of my time trying to understand why manualintegrate behaves the way it does and, more importantly, what its limitations are. Looking back, this was probably the most valuable decision I could have made.

June 01, 2026

00:00, Monday, 01 June

May 31, 2026

07:00, Sunday, 31 May

Continuing with the implementation of the already discussed function in Week 0. The implementation was done in the PR#29806

Implementation

The implementation of the backtracking function is pretty straight-forward and intutive. The code for it being

def backtrack(self): if not self.bound_history: raise ValueError("Cannot backtrack, bound_history stack is empty") xi, old_bound, upper = self.bound_history.pop() if upper: xi.upper = old_bound else: xi.lower = old_bound for var in self.all_var: var.assign = self.last_assign_snapshot[var] self.is_sat = True self.result = None 

Apart from the function declaration and defination, I had to add two state variables to the LRASolver class, bound_history which is a stack and keeps a track of previous bounds and last_assign_snapshot which is the assignment of the variables in the last valid state.

Testing

A major part of the PR was adding tests to see if the backtracking logic is working correctly. I particularly added 5 tests.

test_example_from_paper()

This particular test is the exact same example as discussed in the 4.6 section of the paper. I have specifically added variable bounds and assignments checks for each state.

Constraints:

  1. $x \le -4$
  2. $x \ge -8$
  3. $-x + y \le 1$
  4. $x + y \ge -3$

test_backtracking_single_variable()

In this particular test, Assert catches the error with the bounds on the variable and there is no need to explicitly call the expensive Check to see if the state is valid or not.

Constraints:

  1. $x \le -4$
  2. $x \ge -8$
  3. $x \ge -2$

test_backtracking_multiple_variables()

This particular test is somewhat similar to the test from the paper just with a set of different constraints.

Constraints:

  1. $2x + 3y \le 12$
  2. $x \ge 3$
  3. $y \ge 3$

test_backtracking_single_variable_multiple_backtracks()

This particular test is made to check if the solver can come back to a particular state after multiple backtracks successfully. In this particular test, similar to test_backtracking_single_variable(), Assert catches the error with the bounds of the variable and Check is not necessary to be called.

Constraints:

  1. $x \le 10$
  2. $x \ge 0$
  3. $x \ge 5$
  4. $x \le 2$

test_backtracking_multiple_variables_multiple_backtracks()

This test is similar to the previous test but with multiple variables. Here, Check should be called to pivot the variables.

Constraints:

  1. $x \le 10$
  2. $x \ge 0$
  3. $y \ge 0$
  4. $x \ge 5$
  5. $y \ge 5$
  6. $x + y \le 4$

Issues faced

EncodedCNF sorts the hashes created for the constraints, which is an issue, as everytime the tests are ran, a new environment is created, so in some instances the tests used to fail while in some it used to pass as I am manually tracing the logic for backtracking.

A fix for this was use the function add_prop so it sequentially adds the constraints thus preserving the order. Another way to reduce this nondeterminism as suggested by Tilo was to testing_mode=True in the LRASolver. By doing these, the tests are consistent for now.

Final Remarks

The PR#29806 has been merged! The next work should be to integrate this backtracking logic with dpll2.py

Another major task in hand is to start with the Phase 1 of the proposal that will be discussed in the next meet. Looking foward to it. :D

Sujal Kumar

May 24, 2026

07:00, Sunday, 24 May

Starting with something new, a little excited as well as nervous with stuff. The incoming blogs will be me describing details of my project and stuff I did over the course of my period in GSoC’26 in SymPy.

Pre-GSoC

I have been contributing to SymPy for some time and was interested in contributing to the assumptions module. I had few merged PRs in the model (with a little different vision with respect to my project).

Mostly it involved me fixing bugs with recursive handlers in ask. A lot of it was also adding appropriate tests to counter various cases and check if the algorithm is working correctly. Soon, I had a talk with one of the collaborators Tilo, discussing various aspects I can make assumptions system better. The conversation. The discussion gave me a much clearer idea on what to work on over the summer and thus framing my proposal. Link to my proposal.

Results were announced on 30th April, I got in with 4 of my co-contributors and their projects under SymPy for 2026. I had my final exams for 4th semester were going on, so I did not start immediately. My mentors are Tilo and Aaron. I had my first meet on 18th May, 9:30 PM (Yeah a time which was suitable for both my mentors and me :D)

The Research Paper

The initial meet had us discussing what could be a good start for me to get going with the existing SAT Solvers in SymPy. One idea was to implement the backtracking function from the paper A Fast Linear-Arithmetic Solver for DPLL(T), this is the original paper on which the lra_solver has been developed. The backtracking function has been explained in the section 4.4 of the paper.

Let’s try to understand the research paper:

At a high level DPLL(T) separates the heavy lifting into two parts: a boolean SAT solver that handles the logical structure, and a Theory solver (Linear Real Arithmetic, or LRA) that checks if the current set of mathematical assertions is actually feasible.

The solver tracks three main things at all times:

  • The Tableau: A matrix that defines the relationships between variables. Variables are split into two camps: Basic (dependent) and Non-basic (independent).
  • The Bounds: Every variable has a lower and upper bound (initially $-\infty$ and $\infty$).
  • The Assignment ($\beta$): A mapping that gives every variable a specific numerical value to ensure the equations are always balanced.

Assert

When a constraint is fed into the solver, the Assert operation comes in. It doesn’t look in the matrix and doesn’t care about how variables are related.

It does a superficial check looking at the bounds of the specific variable. It updates the bound in $O(1)$ time and immediately checks for trivial contradictions.

For example - if the solver already knows $x \ge 5$, and we assert $x \le 2$, Assert flags the inconsistency instantly.

Check

Assert only looks at variable in isolation, it might end up passing systemic conflicts.

Check looks at the matrix to see if any basic variables violate their bounds. If a basic variable is out of bounds, Check attempts to fix it by pivoting meaning to swapping a basic variable with a non-basic variable to push the values back into a valid range.

If Check needs to adjust a variable but every single non-basic variable in that row is already maxed out at its own restrictive bound, the solver is trapped. It has mathematically proven that no valid assignment exists, and it raises a systemic conflict.

Backtrack

This is what I had to majorly focus on and implement. Let’s try to understand how it works.

When a conflict is raised, the solver has to back up. If it had to rebuild its entire matrix from scratch every time it hit a dead end, the solver would be impossibly slow.

Section 4.4 of the paper outlines an elegant solution: tracking the state history so that backtracking takes $O(1)$ time.

This is achieved using a state stack. Every time a bound is updated, the previous state is pushed onto the stack. When a conflict is detected, the solver simply pops the most recent update, restores the previous bound, and rolls back the variable assignments ($\beta$) to their last valid state snapshot.

Example

Section 4.6 (Figure 5) of the paper provides a specific sequence using two slack variables ($s_1$ and $s_2$):

  1. $x \le -4$
  2. $x \ge -8$
  3. $-x + y \le 1$ (which asserts $s_1 \le 1$)
  4. $x + y \ge -3$ (which asserts $s_2 \ge -3$)

The first three rules are asserted correctly. When rule 4 is fed into the system, Assert passes it completely fine because $s_2$ has no previous restrictive bounds.

But when Check runs, it is forced to pivot the matrix. During the pivot, it realizes that both $x$ and $s_1$ are maxed out, causing an inconsistency.

We backtrack after this failure and it proves the solver can safely unroll the matrix pivots in $O(1)$ complexity.

Implementation

The implementation will be done in the next week, following the next meet. Something to look forward to! :D

Sujal Kumar

May 12, 2026

00:00, Tuesday, 12 May

Sometime during 2025, on what seemed like just another ordinary day, fate decided to intervene in its mysterious way. During a casual conversation, a friend of mine mentioned GSoC to me. Until that moment, I had never heard of it before, nor did I know about the opportunities it offered. Curious, I started looking into it, and the more I learned, the more interested I became. I have already tried contributing to open-source projects, yet the idea of collaborating with experienced developers felt exciting. So, naturally, I decided to take a chance and apply.

January 23, 2026

00:00, Friday, 23 January

Over the last few years I’ve often tried to make a contribution to LLVM-project but failed to land any contribution in, mostly because I engaged myself in some contract work last year, and because of which I couldn’t devote myself to focusing on it.

I feel I’ve come full-circle back LLVM contribution. I think I should be paving the way forward to keep myself away from all the distractions (AI taking over software development, whether what I’m taking up will lead to paid work or not etc.) and try as much as I can on two simple goals (atleast for the next 2 months or so):

  • learn C++
  • Contribution to LLVM project

Learn C++

Overall the last 1 year, I think I’ve degraded as a software engineer, and something I’m sure I work on it. I intend to focus on learning a of C++ concepts from C++ reference and learn cpp, there are many concepts which I have never been able to think clearly about, the idea is to majorly use the above C++ reference to learn C++, and taking help from an AI-agent as less as possible. I’m one of those software engineer who thinks that using AI substantially isn’t good to move forward as a software engineer, and that’s been my stance from the last 4 years (I’m not sure if it’s just pure denial of it’s capabilities though).

Contribution to LLVM project

I think one of the biggest hurdle one faces when starting to work on LLVM project is figuring out how to build LLVM, and since my laptop isn’t very powerful (Macbook Air M4 - 256 GB), I need to be careful with using it’s resources, I’ve been maintaining this LLVM debug build listing the way I built LLVM for difference issues, and it help’s me make sure I document my way of building LLVM (with various configuration options), so I can re-use specific feature if needed.

Currently, I’m looking at an issue https://github.com/llvm/llvm-project/issues/121952 from the LLVM project, which I’m able to reproduce locally and I’m trying to follow the comment left by one of the maintainer of the project. I’ve already understood many things that I wasn’t aware of before approaching this issue (e.g. Fuzzer), and many C++ features that I haven’t used in a while and re-visiting those helps.

I’ll try my best to keep this blog of mine continuously updated, and which will probably help me in writing better blog posts as well. See ya mate.

August 28, 2025

16:00, Thursday, 28 August

Final Weeks I’ve been juggling college work and the final stretch of the project, so things have been busy. My mentor and I agreed that the elastic-pendulum-cone example will be the final PR for the GSoC coding period. Everything is basically done only a small change to the example is holding the PR up at the moment, and I will finish that. What’s next I’ll wrap up that small example change t...

August 17, 2025

17:00, Sunday, 17 August

Hello everyone, the GSoC is getting close to the end.

August 07, 2025

16:00, Thursday, 07 August

WrappingCone Status Me and my mentor Hwayeon, had a longer sync-up meeting this week to discuss everything in more detail. She told me to add the complete worked out math of the cable car model and send it publicly on github so that she could view it. I finally learnt some latex in order to get the math to render nicely and not have to rely on any external sources. I worked out all of the math...

July 30, 2025

16:00, Wednesday, 30 July

After a brief slowdown due to the start of college and on-campus internship drives (in which I secured an internship with DE Shaw & Co for Summer of 2026!), progress on SymPy’s WrappingCone is back on track. WrappingCone Status The core of the WrappingCone class is complete except for the geodesic_end_vectors method. All other methods, have been implemented and tested. Symbolic testing fo...

July 26, 2025

12:10, Saturday, 26 July

Hello everyone, a month has passed since the last update.

July 12, 2025

16:00, Saturday, 12 July

Highlights Both PRs finally merged in a single day Setup a new direction to continue Merging the PRs After some internal discussion between my immediate mentor Hwayeon and Jason, the two PRs were finally deemed to be worthy of being in the master branch of SymPy. And they were merged. I was so happy to finally see my examples and code in the dev documentation, informing new users of t...

July 06, 2025

16:00, Sunday, 06 July

Highlights Polished two open pull requests and added new unit tests. Updated point_on_surface to return a symbolic expression instead of a boolean, per Jason Moore’s suggestion. Refactored the WrappingSphere example: improved explanations, reorganized code, and added a hands-on use-case. Pull Request: point_on_surface Enhancement Symbolic Output: Changed the method signature to ...

June 23, 2025

10:30, Monday, 23 June

Hello everyone, PR #28115(Open) is closed to being merged.

June 13, 2025

17:05, Friday, 13 June

Hello everyone, I’m in my second week of GSoC and I’ve almost finished writing the transfer function classes #28115(Open).

June 02, 2025

09:55, Monday, 02 June

Hello everyone, the Community Bonding period has concluded, and I want to share my progress with SymPy.

June 01, 2025

00:00, Sunday, 01 June

This phase I began extensively deep diving into exploring SymPy’s assumptions system, researching and understanding implementations of SAT solvers and SAT handlers.

May 13, 2025

00:00, Tuesday, 13 May

Hello everyone, welcome to my blog. I will be sharing all major updates and progress on my GSoC project through this blog. Stay tuned.

May 08, 2025

14:30, Thursday, 08 May

April 26, 2024

00:00, Friday, 26 April

LLVM Intermediate Representation is an a low-level programming language (more lower than C++, Python etc.).

October 03, 2022

10:00, Monday, 03 October

This will be my last post with a full overview of all my contributions during GSoC 2022.

September 16, 2022

16:00, Friday, 16 September

Here is a short overview of the PRs merged and the ones opened: Merged PR [#24028] implementing a generic coordinate generation helper, which is ready for merging. merged PR [#24037] implementing the CylindricalJoint, which will be ready for review as soon as [#24028] is merged. Opened PR [#24046] implementing the PlanarJoint, which is almost ready for merging. Currently a decision should be made what inputs for defining the rotation_axis and planar_vectors will be supported Opened draft PR [#24053] implementing the SphericalJoint, which will be ready for review as soon as [#24046] is merged.

September 09, 2022

16:00, Friday, 09 September

Decided to make my posts on Friday, so it is more of a reflection of past week (in this case a little more). Besides that I’m also gonna try to keep using the format of my midterm overview. So what has happened: Merged PR [#23981] adding an optional frame argument to RigidBody.parallel_axis and implementing Body.parallel_axis. Merged PR [#23982] changing Body to always have an inertia, also when representing a Particle. This will partially solve issue [#23269]. Merged PR [#23920] changing the definition of a Joint to use intermediate frames. Something that was specifically added last week was the support for supplying an axis with which the interframe should align its X axis. Something which surprisingly gives the exact same results as parent_axis and child_axis did (means that those rotations were actually chosen more logical than I thought). Closed issue [#23913] on the problem that the use of temporary relationships between ReferenceFrames in the Joint class can lead to deleting correct relations. Was also fixed in [#23920]. Raised issue [#1929] in the symengine on the problem of stackability of null Matrices. Raised and closed issue [#24005] on the problem that a CI slow test 2 failed due to a timeout. However due to irreproducibility this issue was also closed. Opened PR [#24028] implementing a generic coordinate generation helper, which is ready for merging. Opened draft PR [#24037] implementing the CylindricalJoint, which will be ready for review as soon as [#24028] is merged.

August 29, 2022

12:35, Monday, 29 August

It seemed good to me to make a midterm overview of what I have done. It would have been better if I would have done this a week earlier, before my midterm, but this will in the end also be helpful for the final evaluation.

06:22, Monday, 29 August

This week I finally set this PR on intermediate frames as ready to review. Besides that I have also created a PR, which adds the optional frame argument to RigidBody.parallel_axis and also implements the parallel_axis method for the Body class. As well as a PR which partially fixes the issue of KanesMethod not being compatible with Body objects, which represents a Particle. This is done by changing the inertia of a Body representing a Particle to zero. Besides that this PR also adds a central inertia setter to RigidBody. As a last thing I have been working on is the implementation of new joint types, mainly the SphericalJoint. However I have not yet published a PR for this, since my implementation is currently dependent on the PR on intermediate frames.

August 22, 2022

13:45, Monday, 22 August

Still working this draft PR, which is now close to ready to really get reviewed. Besides the change to the intermediate frames. This PR now also proposes to replace the parent_joint_pos and child_joint_pos arguments by parent_point and child_point, since that is way more intuitive. Besides that I’ve also opened this issue, which is about a dependency between two tests (an easy fix).

August 15, 2022

09:55, Monday, 15 August

Just before I went on vacation the documentation PRs, i.e. PR about adding a four bar linkage example and the PR explaining the joints framework using figures were merged. Also the PR, which improves the Point.acc method, was merged. However, after my holiday I heard the request of making these figures a bit smaller in filesize. So, this last week I converted them to SVGs in this already merged PR. After this I mainly did some reading up and investigating how we could introduce a Mobilizer joint as described in this paper by Seth, A., Sherman, M., Eastman, P., & Delp, S.

July 14, 2022

18:15, Thursday, 14 July

This is a short post, since I was busy this week with my last exam and preparing for my vacation next few weeks. This also means that I won’t make posts for the next few weeks. As for now I am currently focused partially on making the Body class better integrated within the mechanics, while awaiting reviews on some documentation PRs.

July 08, 2022

18:15, Friday, 08 July

This is finally the first week that I could work full time on GSoC. Started this week with reviewing a PR for the first time. Furthermore I mostly focused this week on documentation. You already saw the draft of the four bar linkage example last week. During which I ran into various other things. First of the amazing dark theme available in the SymPy dev documentation causes some images to be barely readable (raised #23706). Another thing I already new I wanted to do is that there should be a real guide on the Joints Framework. So I made a draft PR about implementing a real guide on the Joints Framework in the physics/mechanics module (checkout the image below for a quick preview). Yesterday, I presented this to my mentors and got positive feedback. We also had a discussion about consistency within the code which raised this issue. Also the planning is to have either next week or after my holiday a discussion about what we actually have within the Mechanics module and what we actually want.