I've been obsessed with the idea of making a spreadsheet where you can update both inputs and outputs, instead of regular spreadsheets where you can only update inputs.
Please let me know what you think! Especially if you find bugs or good example use cases.
One way to make this less surprising might be to flip the default: treat all cells as fixed unless explicitly marked as solver variables, and give a lightweight visualization of “these are the cells that will move if you edit this one.” That keeps the power of a general constraint solver while preserving the mental model spreadsheet users already have, and it opens the door to more serious use cases (financial models, physics, scheduling) without feeling like spooky action at a distance.
I am a huge fan of the concept though. It's been bugging me for years that my spreadsheet doesn't allow editing text fields after filtering and sorting them down to the subset I want. I have to go all the way back to the mess of unsorted input rows to actually edit them.
Does one stay locked in place? Unclear.
If you set C1=A1+B1 then, when you set a value for C1, A1 and B1 are each half of that value, even if they started off unbalanced.It also doesn't help that in the example, the expected outcome of 53.3333/46.6667 isn't even considered.
A1 = 1.0 // the scale, your variable
A2 = 6 * A1 // intermediate values
A3 = 8 * A1
A4 = A2 + A3 // the sum
Now update A4 (or any other cell!) and the scale (A1, the only variable) will update as you expect.In the future I'd like to support more user input constraints, in particular domain constraints for variables. So you could tell the solver that this cell must remain in some interval, and it would respect that interval instead of assigning any real value.
As a more substantive comment: You may find the thesis "Propagation networks : a flexible and expressive substrate for computation" by Alexey Radul interesting. https://dspace.mit.edu/handle/1721.1/54635
Enter these formulas:
distance = time / pace
time = distance * pace
pace = time / distance
Drag fill everything down. At this point you get reference errors, but once you enter any two values (thereby overwriting the formulas in those cells), you get your result.This particular example may be unlikely, but it's a very fun idea.
Primarily because the learnings you make are the same as the original “discoverer”. Without those learnings, you might not be able to arrive at your true destination.
Luckily no one is suggesting that.
I remember reading, about a year or two ago, about a medical doctor that published a paper rediscovering calculus (I just looked it up, it happened in 1994, there’s been many articles and videos about it)
This is such a great story
This is also true with patents.
Anyone remember?
This functionality is called ‘break back’ in a lot of enterprise modelling software. See [IBM TM1](https://www.ibm.com/docs/en/cognos-planning/10.2.1?topic=bre...) and [Anaplan](https://help.anaplan.com/breakback-1b7aa87d-aa13-49f6-8f7d-d...). They generally work in terms of scaling the inputs to match the new output though, which is a bit more basic than this approach.
Good for every situation when you need to solve equations!
In the context of using spreadsheets I think about solving simple financial or maybe construction/mechanical design problems where you don’t want to solve it manually or program it and a spreadsheet is a quick and useful interface.
If this was usual it would help a lot with people's tendency to hard code the correct answer rather than fix formulae. Just that aspect of it would be a huge improvement. People do this all the time with simple financial problem, for example.
A lot of what people use spreadsheets for is not all that simple. Again, especially with financial applications. People manage huge amounts of money using horribly complex models implemented in Excel.
I think you should be able to use bidi-calc to train a neural net, altough I haven't tried. You'd define a neural net, and then change it's random output to what you want it to output. However as I understand it, it won't find a good solution. It might find a least squares solution to the last layer, then you'd want previous layer to output something that reduces error of the last layer, but bidi-calc will no longer consider last layer at all.
The term of interest is "backpropagation".
Wasn’t Prolog invented to formalise these kinds of problems of making the inputs match what the desired output should be.
Constraint propagation from SICP is a great reference here:
But how do you handle the case where multiple variables can be changed? If multiple input cells is the key difference from Goal seek, i think some more rigor should be placed into the algorithm here
e.g. setting A1 + B1 and wanting the result to be 5. Currently it bumps both A1 and B1 equally. What's the thought process behind this?
Makes me imagine plotting a inverted pendulum and other real time systems. Could a cell variable be set to Time?
What's the point of calculating backwards non-invertible operations such as addition? Isn't the result just arbitrary?
You are right that there is some arbitrariness involved when picking a solution, however it's a bit more subtle than that.
Let's say our problem has N free variables.
Step 1 is finding the subset of R^N that is the solution to the root finding problem. If this subset is a point, we are done (return that point). Note that if there is no solution at all bidicalc should correctly report it.
Step 2 is if the solution subset is not a point. Then there is multiple (maybe even an infinity of) solutions, and picking one is indeed arbitrary.
> Even a normal spreadsheet is fairly complex beast. But the novel thing about bidicalc is the backwards solver. Mathematically, updating a spreadsheet "backward" is a (potentially underdetermined) root finding problem, because we are trying to find a vector of unknowns such that , where F is the function computed by the cells formulas, and G is the objective value entered in the cell. Note that F is not necessarily a single formula, but the result of composing an upstream graph of cells into a single function.
> The actual root-finding solver is a custom algorithm that I made. It a general purpose algorithm that will find one root of any continuous-almost-everywhere function for which a complete syntactic expression is known. It uses a mix of continuous constraint propagation on interval union arithmetic , directional Newton's method and dichotomic search. It is of course limited by floating point precision and available computation time.
But that really doesn't answer your question. I see no reason why the solver wouldn't decide every time it had a two-variable summation that ADD(X+Y) doesn't reverse to X=-90 and Y=100.
The user hints principle is preferred fixed so they can see what rate is needed for a givem amount of interest.
Hints could have a precedence order (then prefer to fix earlier terms on an operation on a tie breaker.)
Commercial products are run by product managers: they do whatever the business needs that day, and if it doesn't work for most inputs, "that's fine, our users will only ever need addition". Fun open source projects, run by the same programmer who does the implementation, obsess over finding the generic solution to inverting a function and end up with a version that isn't useful for anyone's specific case.
I think one issue will be that trig functions are kinda weird because they are non-injective. So they work but they are awkward (try solving cos(A1) = 0.5). Inverse kinematics is so well studied, you're probably better off using a dedicated algorithm.
A = B + C
Where A, B, C are the lengths of 3 parallel lines. Within the sketcher you can drag the length of any one of those lines and the other two will adjust to keep the constraints.
I'd love to see a version where cells are "torn off" and named as they were in Lotus Improv and one had a "formula pane" where one could see all the formulae for a spreadsheet.
Would it be possible to create this in Python so that it could be a part of pyspread?
set C1 = A1 + B1 = 7
now change C1 = 14 expected A1 = 6 expected B1 = 8
what it did A1 = 7 B1 = 7
great
This is a nice exploration.
I think what's pretty unique about the bidicalc solver that I made is that it does not depend on the previous input values to update backwards. It's truly solving the root finding problem. The advantage is that there are never any "stuck in a local optimum" problems with the solver. So you can solve difficult problems like polynomials, etc.
So much so that Credit Suisse, which basically was running everything on heavily modded Excel, created a full language whose outputs were Excel spreadsheets capable of doing that. That thing called “paradise” was a total monstrosity but showed how much people wanted this.
That said, you really need a way to set which cells are fixed and which cells are allowed to move if you want to move past basic examples.
Most times you know what you want to do. like => if the user modifies that cell, find a solution for those specific ones.
If you can enter that info, then you have a lot more constrains for your solver and will avoid a lot of edge cases where everything goes to 0, and you can check that the calculation entered is indeed reversible or not, or if it could have multiple solutions, and so on.
People want them in general programming languages too. I can't count the number of times I had to implement the same function multiple times, but backwards in various ways.
I'd like to add more constraints in the future like a domain constraint for variables.
I told Gemini that spreadsheets were actually not doing that and that I had ways to implement that behavior without the complexity.
Just writing that to show the rabbit hole people are going to fall into if they let their llms go brrr. ;D
In any case, the problem is interesting. The point was to include bi-directionality inside a graph of computations so that we didn't get bogged down by cycles. The benefit being that it would handle float precision issues.
My more manual solution expect that floats precision issues are handled explicitly. I think that this level of explicitness is needed anyway for proper floating point error mitigation.
Excerpt from the initial convo with gemini: Thinking with 3 Pro December 11, 2025 at 09:59 PM
2. Propagators (Constraint Networks)The Problem: Your valueref binder and watch logic handle one-way data flow well. But complex forms (e.g., "Start Date must be before End Date," or "Fahrenheit <-> Celsius") require messy, cyclic event handlers to keep everything in sync.The Academic Concept: Propagators (Alexey Radul / Gerald Sussman, MIT).Instead of functions ($A \rightarrow B$), you define Constraints. A network of constraints seeks a consistent value for all connected nodes. It is "multi-directional" by design.
I see my message above being downvoted, I don't even know why ;D
In the end Gemini did agree that it was not necessary to introduce this level of complexity for my use case.
To be fair, Victor goes further because he adds a solver on top. In the research of a solution that might make sense. The issue in general is that not everything has a reverse operation so, in a sense, it is but an approximation.