[{"content":"","date":"8 August 2026","externalUrl":null,"permalink":"/tags/attention/","section":"Tags","summary":"","title":"Attention","type":"tags"},{"content":"","date":"8 August 2026","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"I am a fifth-year Integrated MSc Mathematics student at NISER, with a minor in computer science. I work on formal verification and automated reasoning: writing machine-checked proofs in Lean 4 and asking what it takes to trust a piece of software.\nMost recently I was a research intern at FP Launchpad, IIT Madras, with Dr. KC Sivaramakrishnan, verifying replicated data types for distributed systems. Before that I spent a summer on logic and automated reasoning at IMSc Chennai with Dr. Meena Mahajan.\nResearch Research interests, internships, and publications.\nWriting Notes on mathematics, CS, and proof assistants.\nAbout Background, interests, and contact.\n","date":"8 August 2026","externalUrl":null,"permalink":"/","section":"Harisankar B","summary":"I am a fifth-year Integrated MSc Mathematics student at NISER, with a minor in computer science. I work on formal verification and automated reasoning: writing machine-checked proofs in Lean 4 and asking what it takes to trust a piece of software.\n","title":"Harisankar B","type":"page"},{"content":"","date":"8 August 2026","externalUrl":null,"permalink":"/tags/mind/","section":"Tags","summary":"","title":"Mind","type":"tags"},{"content":"","date":"8 August 2026","externalUrl":null,"permalink":"/categories/personal/","section":"Categories","summary":"","title":"Personal","type":"categories"},{"content":"","date":"8 August 2026","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"I\u0026rsquo;ve caught myself thinking the same thought all of us have had at some point: \u0026ldquo;Maybe I am just not good enough for this.\u0026rdquo;\nIt feels convincing in the moment. The problem seems impossible. Everyone else appears to have understood it. You don\u0026rsquo;t.\nBut then I realized something fascinating. For thousands of years, we humans have been solving problems. We have solved problems that were so hard they seemed impossible. And yet, we solved them.\nHumans didn\u0026rsquo;t become the apex of the food chain by being the strongest, or the fastest, or the most agile. We became the apex of the food chain because we are problem solvers. We are the peak of evolution because we are the best problem solvers. We have been solving problems for thousands of years, and we will continue to do so for thousands more.\nNot just our ancestors, but you and I. We are problem solvers. Think about your own life. You learned to walk and talk. You learned to make sense of symbols that once looked meaningless. A machine can do things much more efficiently than us, but what it can never replicate is the human mind. The human mind is still the strangest thing we know of, and every one of us is walking around with one.\nWhat the machines are doing # I use these tools every day, and I would be a hypocrite if I wrote this as an attack on them. They are useful. They are getting better.\nBut it is worth being clear about what they are made of. A model is a compression of everything we have already written down. When it answers me, it is rearranging things that people worked out first, sometimes over centuries. It can move around inside that space very fast. It has never had to stand at the edge of it.\nSomebody had to look up at the sky before there was any such thing as astronomy, and stay confused for years with no promise that the confusion was going anywhere. That is slow, it is uncomfortable, and it doesn\u0026rsquo;t look like progress while it is happening. It is also the only way anything genuinely new has ever turned up.\nSo when a machine answers in two seconds what took me a week, I try to remember what the week was for. The confusion, the mistakes, the dead ends: that was the real learning. The machine can give me the answer, but it cannot give me the experience of getting there.\nWhat worries me # It isn\u0026rsquo;t that machines will out-think us. It\u0026rsquo;s that we are quietly giving up the habit of thinking for ourselves, outsourcing our thinking to machines.\nThink about how much effort went into the app you last opened without deciding to open it. Millions of dollars of psychology research. Rooms full of people whose whole job is to win one more second of your attention. Endless testing of what goes in front of you next, and how long it should run before the thing after it starts. None of that is an accident of design. That is the product.\nIt works on me. I have opened an app, closed it, and opened it again inside the same minute without knowing what I was looking for. That is not a personal failure of discipline. It was engineered, by people who understand my reward system considerably better than I do.\nA mind that gets interrupted every few minutes never reaches the interesting part. Every hard thing I have ever worked out needed a long, dull stretch where nothing was happening and I had to sit inside not knowing. That stretch runs on attention. And we are spending our attention in small pieces, all day, on things built to reward us for spending it.\nYou don\u0026rsquo;t need a conspiracy theory here. Nobody sat down and decided they wanted a distracted public. Somebody decided to keep you on the app thirty seconds longer, because that is what the business gets paid for, and the rest followed on its own. A distracted person is a better customer. A distracted person is also easier to govern, easier to sell a story to, slower to ask why. Not because anyone chose that, but because it is what falls out when enough companies are all pulling in the same direction. That is what makes it hard to fight. There is nobody to argue with.\nWe should not hand it over # We are the same species that measured the Earth with a stick and a shadow. Losing our attention to a feed would be an embarrassing way to go.\nI don\u0026rsquo;t think the answer is to throw your phone in a river and move to the hills (although that does sound nice). That is mostly a fantasy about escaping, and it\u0026rsquo;s its own way of not paying attention.\nWhat has worked for me is much smaller. Catching the reach for the phone before my hand gets there. Reading something long enough that it starts to get difficult. Staying with a problem after it stops being fun. Being bored on purpose once in a while, just to see what my head does when nothing is being handed to it.\nNone of that makes anyone special. It just gives you back the thing you already had.\nBeing mindful again # Humanity has been the best and the worst thing that ever happened to this planet. We made art that still moves people centuries later, yet we burned the forests that we needed. We cured diseases that used to kill children by the thousand, and we built the weapons that could finish us off. All of it came out of the same equipment: a mind that can hold a problem and keep turning it over.\nWhich is why I keep coming back to the word mindful, in the plain sense of knowing what you\u0026rsquo;re doing while you\u0026rsquo;re doing it, not the version that comes with a subscription.\nThere are a lot of problems left that need us, and most of them are not the kind a model can pattern-match its way through. Somebody has to sit with a friend who is coming apart. Somebody has to notice the person in the room that nobody is talking to, and be willing to be inconvenient about things that are wrong.\nWhat\u0026rsquo;s the point of having all this intelligence if we aren\u0026rsquo;t empathetic enough? Empathy is harder than intelligence, and it\u0026rsquo;s the skill that decides what we do with all the cleverness.\nSo this is a reminder to me as much as to you. You are probably not too dumb for the problem in front of you. You come from a very long line of people who felt exactly the same way and solved it anyway.\nThere is work to do, and it needs your attention. Try not to give all of it away.\nAll of humanity\u0026rsquo;s problems stem from man\u0026rsquo;s inability to sit quietly in a room alone.\n— Blaise Pascal, Pensées ","date":"8 August 2026","externalUrl":null,"permalink":"/blogs/problem-solvers/","section":"Writing","summary":"A reminder that we are problem solvers, and that the human mind is still the strangest thing we know of.","title":"We are Problem Solvers","type":"blogs"},{"content":"This section collects notes on formal verification, mathematics, theoretical computer science, machine learning, and other technical (or fun) topics, as well as writings on my personal experiences and reflections on research, learning and life in general.\n","date":"8 August 2026","externalUrl":null,"permalink":"/blogs/","section":"Writing","summary":"This section collects notes on formal verification, mathematics, theoretical computer science, machine learning, and other technical (or fun) topics, as well as writings on my personal experiences and reflections on research, learning and life in general.\n","title":"Writing","type":"blogs"},{"content":"","date":"30 July 2026","externalUrl":null,"permalink":"/tags/collaborative-editing/","section":"Tags","summary":"","title":"Collaborative Editing","type":"tags"},{"content":" A warning up front: this is going to be a long and technical post. It is also the one I most wanted to write.\nThis summer I had the opportunity to work with Prof. KC Sivaramakrishnan at FP Launchpad, IIT Madras. The project lived in Sal: the Lean 4 port of the F* framework Neem (Soundarapandian, Nagar, Rastogi, Sivaramakrishnan, OOPSLA 2025), for verifying state-based CRDTs and Mergeable Replicated Data Types (MRDTs).\nMy work was with RGA, the sequence CRDT behind Automerge and Yjs.It has to keep every character you ever deleted, forever. An MRDT\u0026rsquo;s merge gets to see the common ancestor of the two states it is merging. Could that extra information pay for the graveyard?\nI spent the summer answering that. The short version is that we got a design, proved it correct in Lean with zero sorrys, and then proved that it is wrong. Not wrong in the proof; wrong in what the proof was about. A single backspace reorders text the user never touched, and the theorem could not see it, because it was checking the implementation against itself.\nThat turned out to be the most useful thing I learned all summer, so it gets its own section rather than a footnote. The rest of the post is the road there and the fix on the other side.\nThe arc is:\nWhy collaborative editing is hard, and why indices are the wrong vocabulary. RGA, and what its tombstones are actually paying for. MRDTs: a merge that gets to see the common ancestor, and the question that opens. A tombstone-free RGA that rehomes survivors, and its proof. The defect, as a theorem. Why the proof could not see it. Why it is not patchable. EmbedRGA: make position an immutable birth constant, and everything gets easier. 1. The problem # I don\u0026rsquo;t need to mention why collaborative text editing is useful in today\u0026rsquo;s world, especially as students or researchers. Google Docs and Overleaf is almost indispensable if you\u0026rsquo;re working with a team. Those late night edits before an assignment deadline, watching the cursor lobby around the document and seeing the changes made by your teammates in real time is a great experience. But what happens when you are working on a document and your internet connection drops? Or when two people are editing the same paragraph at the same time? How do we ensure that everyone sees the same document, and that no edits are lost? It would be incredibly frustrating to lose your work because of a network issue.\nSo the product requirement is: always writable, never lost, everyone eventually sees the same document, and it should be the document people meant.\nEach client is a full replica. The edit is applied to the local copy first, with no round trip on the critical path. So documents will diverge, but we have a decent way to reconcile. They just need to eventually converge. Strong Eventual Consistency\nsequenceDiagram participant A as Replica A (plane, offline) participant B as Replica B (office) participant C as Replica C (phone) Note over A,C: all three replicas hold AB A-\u003e\u003eA: ins X — applied locally, 0 ms B-\u003e\u003eB: ins Y — applied locally, 0 ms C-\u003e\u003eC: del B — applied locally, 0 ms B-\u003e\u003eC: ins Y C-\u003e\u003eB: del B Note over B,C: B and C reconcile with each otherwhile A is still in the air A-\u003e\u003eB: ins X (hours late) A-\u003e\u003eC: ins X B-\u003e\u003eA: ins Y, del B (one batch, on reconnect) Note over A,C: the same three edits, a different arrival order at every replicaSEC: all three must still read the same document Four facts make this genuinely hard, and they are all consequences of choosing availability:\nNo global order. No clock and no leader that both replicas trust. \u0026ldquo;Which edit came first?\u0026rdquo; often has no answer at all. Arbitrary delays. Tuesday\u0026rsquo;s edit can arrive after Friday\u0026rsquo;s. Local-first. You cannot wait for consensus. Availability during a partition is the whole point. Concurrency is genuine. Any rule that resolves two mutually unaware edits must give the same answer at every replica, in any arrival order. Sequential reasoning (\u0026ldquo;apply the operations in order\u0026rdquo;) is precisely what we are not allowed to assume.\n2. Indices are not identities # The obvious protocol is to ship what the editor already knows: a position and a character.\ninsert(index = 2, char = \u0026#39;X\u0026#39;) delete(index = 0) This is the vocabulary of String.insert and splice, the API every editor has. It is also broken, because an index is a coordinate in a document that is changing underneath it. It means something only relative to one replica\u0026rsquo;s state at one instant.\nBreak #1: two documents, forever # flowchart TD S[\"AB — both replicas start here\"] S --\u003e|\"A: ins(1,'X')\"| L[\"AXB\"] S --\u003e|\"B: ins(1,'Y')\"| R[\"AYB\"] L --\u003e|\"then applies ins(1,'Y')\"| L2[\"AYXB\"] R --\u003e|\"then applies ins(1,'X')\"| R2[\"AXYB\"] Same two operations, same causal history, two different documents, and the replicas will never agree again.\nBreak #2: the index stops referring to anything # This one is worse, and it is a different failure: there are not two answers, there is no answer at all.\nflowchart TD S[\"CAT — insert positions 0…3\"] S --\u003e|\"A: del(0), del(0)\"| L[\"T — insert positions 0…1\"] S --\u003e|\"B: ins(3,'S') — meaning at the end\"| R[\"CATS\"] L --\u003e|\"now ins(3,'S') arrives at A\"| X[\"position 3 does not exist\"] X --\u003e|\"reject it\"| X1[\"T — the author's S is silently lost\"] X --\u003e|\"clamp to the end\"| X2[\"TS — a position nobody asked for\"] ins(3,'S') was perfectly legal when it was issued. By the time it lands, T has two positions. The operation is not wrong so much as meaningless.\nEvery repair here is a guess about intent. A rule that forces the replicas to agree just makes them agree on the guess. This is the first hint that convergence was never the goal. The fix in principle: name characters, don\u0026rsquo;t count them # broken fixed insert at position 2 insert after character id₇ position 2 of whose document, when? id₇ means the same thing at every replica, forever Give every inserted character a globally unique, immutable identifier: a (timestamp, replica id) pair, minted locally with no coordination. An insertion names its anchor: the character it goes after. The operation is now context-free: it can be applied at any replica, in any order, and still mean the same thing.\nThe document is no longer a string. It is a tree of identities, read out by a deterministic traversal. That is what a sequence CRDT is.\n3. CRDTs and RGA # A state-based CRDT is a state space with a merge\n$$\\mathsf{merge} : \\Sigma \\to \\Sigma \\to \\Sigma$$that is commutative, associative and idempotent, i.e. a join-semilattice. It is easy to see that this merge buys Strong Eventual Consistency: any two replicas that have received the same set of updates are in the same state, regardless of order, duplication or delay.\nRGA (Replicated Growable Array; Roh, Jeon, Kim, Lee, JPDC 71(3), 2011) is the sequence CRDT underlying Automerge and Yjs. Its state is a grow-only set of records\n$$(\\mathit{id},\\; \\mathit{char},\\; \\mathit{afterId})$$plus a grow-only set of tombstones: ids that have been deleted. Insert adds a record anchored at an existing id; Remove adds an id to the tombstone set; merge is componentwise union. Both components are grow-only, so merge is trivially a semilattice join.\nAll the interesting content is in the read. The read is a depth-first traversal from the root, where among siblings sharing an anchor, the newest id goes first:\nflowchart TD root((\"⊥\")) --\u003e n1[\"1 · 'A'\"] n1 --\u003e n6[\"6 · 'Y'\"] n1 --\u003e n5[\"5 · 'X'\"] n1 --\u003e n2[\"2 · 'B'\"] (Arrows read \u0026ldquo;is the anchor of\u0026rdquo;; the stored pointer runs the other way.) Ids 6 \u0026gt; 5 \u0026gt; 2 are all anchored at 'A', so the document reads A Y X B at every replica. Notice that this is exactly what settles Break #1\u0026rsquo;s race, deterministically and without a tie-breaking authority.\nIn Sal, that order is an inductive relation visible_lt with four rules (RGA_ReadSide.lean):\nrule meaning parent_child an anchor comes before its children sibling among siblings, the larger id comes first left_desc_of_sib a sibling\u0026rsquo;s whole subtree stays together trans transitive closure and three kernel-checked intent theorems on top of it, on both the CRDT and the MRDT: causal_order_visible_lt, tombstone_monotone_under_remove, concurrent_insert_tiebreak_deterministic.\nReal documents are rich text # Real documents are not plain text, it is rich text with Bold, Italics, links, comments. So formatting by index range breaks for exactly the reason that inserting by index breaks: concurrent inserts shift every index, so \u0026ldquo;bold characters 5 to 14\u0026rdquo; denotes a different span at each replica.\nPeritext (Litt, Lim, Kleppmann, van Hardenberg, CSCW 2022) fixes the span the same way RGA fixes the insert: a mark is not a range of positions, it is a pair of anchors, each naming a character and a side.\nT h e f o x j u m p e d start: before 5@A end: after 14@B 1@A 5@A 14@B each character is a tile with an identity A mark as a pair of anchors. The side bit (before vs after) is what decides whether text typed at the boundary joins the span, and it is why bold expands while a link contracts.\n{ \u0026#34;action\u0026#34;: \u0026#34;addMark\u0026#34;, \u0026#34;markType\u0026#34;: \u0026#34;bold\u0026#34;, \u0026#34;start\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;before\u0026#34;, \u0026#34;opId\u0026#34;: \u0026#34;5@A\u0026#34; }, \u0026#34;end\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;after\u0026#34;, \u0026#34;opId\u0026#34;: \u0026#34;14@B\u0026#34; } } Peritext is then just RGA + a grow-only set of marks. Alice\u0026rsquo;s bold is the mark above, on fox jumped; say Bob concurrently italicises The fox. The two overlap and simply merge; the render is a left-to-right fold over reading order, opening and closing marks:\n[ {text: \u0026#34;The \u0026#34;, format: {italic}}, {text: \u0026#34;fox\u0026#34;, format: {bold, italic}}, {text: \u0026#34; jumped\u0026#34;, format: {bold}} ] The merge is where the anchoring earns its keep. Alice bolds the whole sentence, and concurrently Bob types a word into the middle of it:\nAlice bolds the whole sentence — one mark added, not a character touched start: before 1@A end: after 14@B The fox jum ped 1@A 4@A 14@B Bob, concurrently — types brown after 4@A, having never seen the mark The fox jum ped bro wn six fresh ids, 20@B … 25@B merge — chars ∪ chars, marks ∪ marks. Both anchors still exist, so the mark still means something before 1@A after 14@B The fox jum ped bro wn ✓ the six new characters landed between the anchors, so they are inside the span — bold, with nobody asking for it the same merge, had the mark been the index range 1–14 instead of a pair of anchors The fox bro wn jum ped ✗ 1–14 is now The brown fox — the range never moved, so the last six characters fall out of the span Nothing in Alice\u0026rsquo;s operation mentions brown; it could not, the word did not exist when she issued it. The mark names only its two endpoints, so whatever lands between them in reading order is inside the span. Six characters in, six characters off the end: the bottom row loses exactly what Bob inserted.\nThe merge itself has nothing to arbitrate: chars and marks are both grow-only, so it is componentwise union, exactly as in §3. The delicate case is not this one but text typed at a boundary rather than strictly inside it, which is what the side bits decide, and why bold grows to swallow it while a link does not.\n4. MRDTs: git, but for data types # Everything above is a CRDT: merge sees two states. An MRDT\u0026rsquo;s merge additionally sees their lowest common ancestor:\n$$\\mathsf{merge} : \\Sigma \\to \\Sigma \\to \\Sigma \\to \\Sigma, \\qquad \\mathsf{merge}\\;\\ell\\;a\\;b$$That third argument is worth a lot. With ℓ in hand, the merge can distinguish \u0026ldquo;x was never there\u0026rdquo; from \u0026ldquo;x was there and was deleted\u0026rdquo;, which is exactly the information a CRDT has to encode in tombstones. So the LCA can pay for the tombstones instead.\nThe canonical demonstration is OR-Set, which drops its remove-set entirely:\n$$\\mathsf{merge}\\;\\ell\\;a\\;b \\;=\\; (\\ell \\cap a \\cap b) \\;\\cup\\; (a \\setminus \\ell) \\;\\cup\\; (b \\setminus \\ell)$$ flowchart TD L[\"ℓ = {(1,a)}\"] L --\u003e|\"A: Add a @ ts 2\"| A[\"A = {(1,a), (2,a)}\"] L --\u003e|\"B: Rem a\"| B[\"B = { }\"] A --\u003e M[\"merge = {(2,a)} — a is live, add wins\"] B --\u003e M Term by term: ℓ∩a∩b = {} (B removed it), a∖ℓ = {(2,a)} (the new tag), b∖ℓ = {}. Every add stakes a fresh, globally unique id that each replica mints for itself, so (2,a) is a different tag from (1,a). (1,a) was in ℓ, so B\u0026rsquo;s remove observed it. (2,a) was not, so B cannot have seen it, and it survives.\nThe question this project starts from. If the LCA can replace OR-Set\u0026rsquo;s tombstones, can it replace RGA\u0026rsquo;s? 5. What \u0026ldquo;correct\u0026rdquo; means: Neem, Sal, RA-linearizability # To reason about correctness, we need a framework to prove things about our Replicated Data Types. Neem (OOPSLA'25) reduces the correctness of a data type to a fixed, discharge-able set of obligations. You supply a signature\n$$\\langle\\, \\Sigma,\\; \\sigma_0,\\; \\mathsf{do},\\; \\mathsf{merge},\\; \\mathsf{rc} \\,\\rangle$$where rc resolves non-commuting operation pairs (Fst_then_snd / Snd_then_fst / Either). Neem\u0026rsquo;s metatheorem: discharge 24 verification conditions (some algebraic properties) over do, merge and rc (rc_non_comm, no_rc_chain, merge_comm, merge_idem, base_1op, base_2op, ind_lca_2op, inter_left_1op, lem_0op, …) and replication-aware linearizability (the notion of correctness we will be working with) follows for every execution.\nSal is the Lean 4 port, plus a multi-modal tactic that stages automation by trustworthiness (dsimp+grind → lean-blaster/Z3 → interactive), and a counterexample pipeline that turns an invalid VC into an inspectable execution trace (Plausible + ProofWidgets). The suite currently holds 29 RDTs (17 CRDTs, 12 MRDTs) and 648 VCs for state convergence, the vast majority kernel-checked.\nRA-linearizability, in words # Every state a replica can ever hold must be explainable as the result of running its operations one at a time, in some order, an order that respects causality and obeys the data type\u0026rsquo;s own tie-breaking rule.\nflowchart LR D[\"the replica's event set Ea partial order under vis\"] D --\u003e|\"∃ π: a permutation of Erespecting vis and rc\"| P[\"π = o₁ · o₃ · o₂\"] P --\u003e|\"applySeq from σ₀, using do_\"| S[\"s — the replica's actual state\"] So a merged state is never \u0026ldquo;some third thing\u0026rdquo;: it is always a sequential history someone could have executed. In Lean (Sal/ConditionedMRDTs/Metatheory/Adequacy.lean):\ndef IsRALinearizable3 (C : Configuration D) : Prop := ∀ (v : Version) (s : D.State) (E : Set (Op D.AppOp)), C.ver v = some (s, E) → ∃ π : List (Op D.AppOp), listPermOf π E ∧ -- π enumerates exactly E respects π (lo (Configuration.core C)) ∧ -- causality + rc applySeq D.toCRDTSig D.init π = s -- replaying π gives s It is quantified over every version in the configuration: replica heads and historical versions used as LCAs. lo is visibility together with the rc arbitration; its acyclicity is exactly what no_rc_chain gives you.\nRemember this shape. The reference sequence is the data type\u0026rsquo;s own do-fold. Section 8 is about what that does not buy. Convergence is not enough # merge ℓ a b := ∅ is commutative, associative, idempotent, and satisfies SEC. It is also useless. So is \u0026ldquo;ignore all operations\u0026rdquo;. Convergence is a necessary condition that any number of wrong data types satisfy.\nFor sequences the problem is sharper, and it is worth being blunt about where in the suite the VCs carry real content:\nTier Character Examples The 24 VCs prove… A state is the semantic content LWW-/Max-/Min-Register, PN-Counter lattice join, arithmetic: real content B merge does real computation MVR, LWW-Map, LWW-Element-Set conflict collection: real content C state is a grow-only bag; meaning lives in the read OR-Set, RGA, Add-Win-PQ, Peritext grow-only union: near-trivial Roughly half the suite, and all the interesting data types, are Tier C. For RGA, the 24 VCs prove that two grow-only sets converge under union. They never mention the traversal that turns those sets into a document.\nHence the house rule: every RDT in Sal carries a *_ReadSide.lean companion, and the Tier-C ones carry intent-preservation theorems matched to their papers. The honest claim is intent preservation against a published specification, not \u0026ldquo;proven correct\u0026rdquo;.\n6. Tombstones, and why you cannot just delete the record # A tombstone is a deleted character we cannot throw away, because other characters are positioned relative to it.\nlive tombstones what the reader sees vs. what the replica stores A heavily revised paper is mostly graveyard: state grows with the total number of edits, not with the document size.\nGarbage collection would need to know that every replica has seen the delete, which needs consensus, which is exactly what we gave up in §1. So the goal is: make Remove physically remove the record, so state is bounded by live characters. And the MRDT\u0026rsquo;s LCA is the extra information that might pay for it.\nWhy not simply delete the record, then? Because a survivor anchored at the deleted node is left pointing at an id that is not in the state: its position becomes undefined, and it has nowhere to render.\nTombstones in OR-Set and in RGA carry different kinds of information. OR-Set\u0026rsquo;s tombstone is a boolean (membership history), so an LCA can recompute it. RGA\u0026rsquo;s tombstone is a graph node (structural position), and it is load-bearing geometry. 7. The rehoming RGA # Sal/MRDTs/RGA_Rehoming/. State is map ℕ (α × ℕ): id ↦ (element, anchor). Deletion really removes the record. Two halves, deliberately parallel:\nIn merge: climb the LCA. Survivorship is the OR-Set formula, yielding a survivor set I. A survivor whose recorded anchor is dead walks up the ancestor chain the LCA already knows, until it reaches a node that also survives, or the root.\nlet ancL := fun y =\u0026gt; anc l y -- the ancestor function, read out of the LCA def climb_aux (ancL) (I) : ℕ → ℕ → ℕ | 0, x =\u0026gt; x | fuel+1, x =\u0026gt; if x = 0 || I x then x else climb_aux ancL I fuel (ancL x) what the LCA ℓ knows — every node on the chain still has a position ⊥ P Q R Y Y's recorded anchor is R after the merge — only P and Y are in the survivor set I ∈ I ∉ I ∉ I ∈ I ⊥ P Q R Y climb from Y: R ∉ I, then Q ∉ I, then P ∈ I — so P becomes Y's anchor Arrows read is the anchor of, so Y\u0026rsquo;s ancestor chain is that path walked backwards: R, Q, P, ⊥, exactly the order climb_aux tries. merge reads no operation and no path: the dead nodes\u0026rsquo; positions are still in ℓ, and that is what pays for the tombstone.\nIn do there is no LCA. A single replica applying an operation has no third state to consult. So the operation carries its target\u0026rsquo;s ancestor chain in its payload, and resolve takes the first entry still live. Both halves together give rc = Either at every reachable state (rc_non_comm').\nIt was proved, and the schema had to be widened # Commutation here holds only on reachable states: the operation\u0026rsquo;s claimed path must really be its ancestor chain (accurate), timestamps must be fresh, the root is never stored. That is a conditioned commutativity, and the plain 24 VCs quantify over all states. (A prefix-free variant of the design is outright impossible; see RGA_PrefixFree_Impossible.lean.)\nSo we built the conditioned metatheory and proved the theorem directly:\nrga_ra_linearizable3_eq: RA-linearizability up to observational ≈ at every reachable configuration, under a single honest-delivery assumption. Kernel-clean, 0 sorry. 8. …and it is still wrong # Four operations on one replica, with no concurrency and no merge anywhere. Just a backspace.\nbefore — ins 1 after ⊥ ; ins 2 after ⊥ ; ins 3 after 1 ⊥ 2 1 3 reads [2, 1, 3] at ⊥: ids 2 \u0026gt; 1, so 2 comes first Del 1 — one backspace after — record 1 is physically gone, so 3 rehomes to ⊥ and becomes its first child ⊥ 3 2 3's anchor was 1; the climb rehomes it to ⊥ reads [3, 2] should be [2, 3] ⊥'s children are now {2, 3} — and 3 \u0026gt; 2 the survivors swapped 3 was buried under 1, so its timestamp never competed with 2\u0026rsquo;s. The splice promotes it to the root, where it wins the tiebreak, and text the user never touched changes order.\nThis is a theorem rather than an anecdote, and it is stated against a specification written independently of the implementation: a delete removes its target and nothing else moves.\n-- The independent intent spec. def DeleteOrderPreserving : Prop := ∀ (s : concrete_st) (t r x : ℕ) (p ids : List ℕ), List.Pairwise (· \u0026gt; ·) ids → (∀ i, contains s i = true → i ∈ ids) → document (do_ s (t, r, .Del p x)) (ids.filter (· ≠ x)) = (document s ids).filter (· ≠ x) theorem tombstone_free_violates_delete_order : ¬ DeleteOrderPreserving := by -- witness: s_bac with the complete, strictly-descending candidate list [3,2,1] ... exact absurd key (by native_decide) The candidate list is guarded descending and complete, so the discrepancy cannot be an artifact of how we chose to read. There is a companion, del_a_breaks_survivor_order, and, importantly, the positive contrast is a theorem too: remove_preserves_visible_lt holds for the tombstoned RGA.\nThe rehoming RGA converges, is RA-linearizable, is kernel-clean, and does not implement a text buffer. A single backspace reorders text the user never touched. Why the proof did not see it # flowchart LR DO[\"do_ — the step function\"] DO --\u003e|\"merge ℓ a b\"| M[\"what the replica computed\"] DO --\u003e|\"fold of a witness sequence π\"| F[\"the certified reference\"] M -.-\u003e|\"the VC checks only this =\"| F Both sides are computed with the same do_. If do_ is wrong, both sides are wrong the same way, and the VC passes.\nOwn-fold RA-linearizability certifies convergence and self-consistency. It does not certify fidelity to the intended sequence semantics. This is the verification analogue of \u0026ldquo;your tests pass but the code is wrong\u0026rdquo;: a proof checks itself against the spec you wrote, and nothing checks the spec.\nCatching it requires a specification independent of the implementation\u0026rsquo;s own fold; here, the published RGA\u0026rsquo;s traversal order. We had hit the same failure mode once before, in Peritext: in_span_boundary encoded the opposite of the paper\u0026rsquo;s §3.3, and roughly 400 lines of perfectly correct proofs about it had to be deleted.\nIs it patchable? No, and that is informative # A fooling-pair argument settles it. Consider two executions whose live characters and live geometry agree, but whose deleted history differs. RGA\u0026rsquo;s traversal distinguishes them. A tombstone-free state cannot.\nNo bounded tombstone-free state can preserve RGA order. If the geometry you need is the dead nodes, you must either keep them, or stop needing them. There is also a structural reason the obvious repair, \u0026ldquo;let merge notice the orphan and rewrite its anchor\u0026rdquo;, cannot be made to work inside the framework, and the framework says so. The VC\nlem_0op : eq (merge (do_ l ol) (do_ a ol) (do_ b ol)) (do_ (merge l a b) ol) fails for ol = Remove X under any rehab scheme whose orphan test consults the merged domain, because do and merge disagree about who is an orphan. Delete first, and X is absent from the merged domain, so Y is an orphan and gets rewritten. Merge first, and all three inputs still have X, so Y is not an orphan, and the outer delete then strands it. The lattice-join merges the 24 VCs were designed around touch ℓ only through set algebra; rehabilitation is a structural query on ℓ, and that is precisely what an outer do can invalidate.\nSo the culprit is not the merge. It is the representation:\nY stores a mutable anchor: \u0026ldquo;my parent is X\u0026rdquo; a claim that gets rewritten Y stores an immutable coordinate: \u0026ldquo;I am here\u0026rdquo; nothing to rewrite Delete reorders survivors because survivors\u0026rsquo; positions are stored relatively, and a relative position must be recomputed when its reference dies. Rewriting a position is reordering.\nFix the representation, not the merge. Make position a birth constant.\n9. EmbedRGA: immutable birth coordinates # Sal/MRDTs/RGA_Embed/. State is map ℕ (α × List Bool): id ↦ (element, coordinate). On insert, mint the newcomer\u0026rsquo;s coordinate from its anchor\u0026rsquo;s, once and forever:\n$$\\mathsf{coord}(t) \\;=\\; \\mathsf{coord}(a) \\,\\Vert\\, \\Gamma.\\mathsf{enc}(t-a)$$where a is the anchor id, t the new timestamp, t − a the delta, and Γ any order-preserving, prefix-free code.\nthe same document, with absolute coordinates ⊥ 2 1 3 ⟨2⟩ ⟨1⟩ ⟨1,2⟩ reads [2, 1, 3] Del 1 — no path, no rehoming after — the record is gone; every survivor's coordinate is a birth constant ⊥ 2 1 3 ⟨2⟩ ⟨1,2⟩ 3's coordinate is untouched reads [2, 3] The same witness that broke the rehoming design. Del carries no path and rehomes nothing; merge never climbs, and is just OR-Set survival with values copied. The delete is a filter.\nA pleasant side effect: do on Ins never reads the state, so every operation pair commutes unconditionally enough that rc = Either discharges with no path algebra at all.\nSorting coordinates is the RGA traversal # Compare two coordinates as delta sequences (chainBefore):\nIf one is a prefix of the other, the prefix comes first. → this is RGA\u0026rsquo;s parent_child rule. Otherwise, at the first differing delta, the larger delta comes first. → this is RGA\u0026rsquo;s sibling rule (a larger delta under a shared anchor means a newer timestamp). Reading the figure above: ⟨2⟩ ≺ ⟨1⟩ ≺ ⟨1,2⟩, so the document is [2,1,3]; after the delete, [2,3]. Order preserved.\nMechanically it is one lexicographic compare. Concatenate the codewords, append a terminator symbol above the digit alphabet, and sort descending:\ndef key (c : coord) : List ℕ := (c.map fun b =\u0026gt; if b then 2 else 1) ++ [3] The terminator is the trick that makes rule 1 fall out of rule 2: where one key ends, it shows a 3, which beats any digit the longer key can offer, so a prefix always sorts ahead of its extensions. The supporting theorems:\ntheorem what it says display_iff_chainBefore the key comparison computes exactly chainBefore coordOf_inj prefix-freeness gives unique decodability: distinct birth chains, distinct coordinates subtree_convex a subtree is a coordinate prefix, hence a contiguous block of the display: non-interleaving, for free before_do_stable axiom-free step stability; at Del this is general delete-order preservation, the clause the rehoming RGA refutes before_merge_stable pairwise display order is stable at merges too, from value immutability alone The two capstones # 1. Convergence. embed_ra_linearizable3: RA-linearizability per version at every honestly reachable configuration, with strict =, not ≈.\nRoute: the mergeable-queue hook, whose join needs canonical states unique per event set. Supplied by e_fold_canon: any two well-formed enumerations of one event set fold to the same state.\n2. Fidelity. rga_read_eq_embed_read, the compaction theorem. On honest executions, EmbedRGA\u0026rsquo;s read equals the published, tombstoned RGA\u0026rsquo;s read, element for element.\nThe second one is the point of the whole exercise: the specification is now external. It is RGA\u0026rsquo;s own visible_lt, not our fold. A by-product the published side never proved falls out along the way. visible_lt_total says RGA\u0026rsquo;s relational order is total on the birth tree.\nTwo further notes on the engineering:\nThe development is parametric in the code. Unary, binary-δ and Elias-δ instances are all proved, with zero new proof content each: every datatype theorem consumes only OrderedPrefixCode (monotone + prefix-free). Coordinates cost roughly 1.4 to 1.8 bits per level on real traces. Axioms used: propext, Classical.choice, Quot.sound. No sorryAx. Tombstone-free, and provably the same document as RGA.\n10. Rich text inherits the fix, and inherited the defect # The fused design puts the mark boundaries into the sequence, so rich text is one RGA:\ninductive PeritextElt | char : ℕ → PeritextElt | bound : ℕ → Mark → Bool → PeritextElt -- markId mark isStart Because the payload is opaque to the kernel, convergence is a one-line instantiation with no new proof:\ntheorem peritextEmbed_ra_linearizable3 (hReach : EReach Γ C) : IsRALinearizable3 C := embed_ra_linearizable3 hReach And the defect of §8 reappears here in the form a user would actually notice. Delete one plain character on the rehoming kernel, and an untouched character silently changes formatting:\nbefore ⟨b⟩ X ⟨/b⟩ P C 124 35 renders: X bold; P, C plain — the span is exactly {X} Del P — one plain character after ⟨b⟩ X C ⟨/b⟩ 12 54 renders: X bold, C bold — an untouched character changed formatting C rehomes onto X, out-ranks the close boundary (5 \u0026gt; 4) and leapfrogs inside the span. In Lean: fused_delete_reformats_survivor.\nOn the embed kernel there is nothing to say, which is the point: renderIds_del states that the post-delete render is the pre-delete render minus exactly the deleted entries, so the formatting of every survivor is preserved bitwise.\nBoth shapes are in the repo: marks in a separate set (as published), and marks fused into the sequence. The fused one rides the embed kernel for free.\n12. What we learned # 1. Indices are not identities. Collaborative editing works because characters are named, and the document is a tree read by a deterministic traversal.\n2. Convergence is a substrate, not correctness. \u0026ldquo;All replicas agree on the empty document\u0026rdquo; satisfies SEC. For grow-only sequence state, the 24 VCs prove that union commutes; the meaning lives entirely in the read.\n3. The specification must be external. Own-fold RA-linearizability cannot see a broken do, because both sides of merge = fold use it. Fidelity needed a theorem against the published RGA.\n4. Mechanization pays in refutations. It produced a machine-checked negative: a proved, converging, RA-linearizable tombstone-free RGA that reorders text under a single backspace, plus seven over-strong premises and a criss-cross countermodel we would never have found on paper.\n5. Design for the proof. Making position an immutable birth constant turned Del into a filter, merge into a lattice join, and the read into a sort. Only then did both a strict-equality convergence proof and read-equivalence with the published RGA become available.\nPointers # the framework Sal, a Lean 4 port of Neem (F*, OOPSLA 2025) the paper kcsrk.info/papers/sal_jan26.pdf the designs Sal/MRDTs/RGA_with_tombstones/, RGA_Rehoming/, RGA_Embed/ the defect Sal/MRDTs/RGA_Rehoming/RGA_Tombstone_Free_SPOT.lean the fix RGA_Embed_ChainLex.lean, RGA_Embed_ReadEquiv.lean the capstones Sal/ConditionedMRDTs/MRDT_Instances/EmbedRGA/ References. Roh, Jeon, Kim, Lee, Replicated abstract data types, JPDC 71(3), 2011 · Shapiro, Preguiça, Baquero, Zawirski, A comprehensive study of CRDTs, INRIA RR-7506, 2011 · Litt, Lim, Kleppmann, van Hardenberg, Peritext, CSCW 2022 · Soundarapandian, Nagar, Rastogi, Sivaramakrishnan, OOPSLA 2025.\nWith thanks to Prof. KC Sivaramakrishnan for the supervision, and to Vimala Soundarapandian and Pranav Ramesh. FP Launchpad, IIT Madras.\n","date":"30 July 2026","externalUrl":null,"permalink":"/blogs/replicated-growable-array/","section":"Writing","summary":"Notes on a tombstone-free RGA: proved RA-linearizable in Lean 4, then found to reorder your text on delete. Why convergence is not correctness.","title":"Collaborative text editing with RGA","type":"blogs"},{"content":"","date":"30 July 2026","externalUrl":null,"permalink":"/tags/crdt/","section":"Tags","summary":"","title":"CRDT","type":"tags"},{"content":"","date":"30 July 2026","externalUrl":null,"permalink":"/tags/distributed-systems/","section":"Tags","summary":"","title":"Distributed Systems","type":"tags"},{"content":"","date":"30 July 2026","externalUrl":null,"permalink":"/tags/formal-verification/","section":"Tags","summary":"","title":"Formal Verification","type":"tags"},{"content":"","date":"30 July 2026","externalUrl":null,"permalink":"/tags/lean/","section":"Tags","summary":"","title":"Lean","type":"tags"},{"content":"","date":"30 July 2026","externalUrl":null,"permalink":"/categories/notes/","section":"Categories","summary":"","title":"Notes","type":"categories"},{"content":"","date":"14 July 2026","externalUrl":null,"permalink":"/tags/llm/","section":"Tags","summary":"","title":"LLM","type":"tags"},{"content":" I spent five days at the LeanLang Summer School at the Indian Institute of Science in Bangalore, run by Emergence. The week was a mix of lab sessions and talks, all focused on Lean, formal verification, and the emerging ecosystem around it.\nThis is one of the most exciting places to be right now, because it is grappling with a question that has quietly become urgent: what does it mean to actually trust a piece of software - and now that we are handing real decisions to AI agents, what would it mean to trust them?\nThis post is a set of notes and reflections from the week, and I will try to make it accessible to a general audience. If you are already familiar with these topics, you may find the content elementary; if you are new to them, I hope it gives you a sense of what is happening in this space. Kindly let me know if you spot any errors or misrepresentations, and I will correct them.\nHow I got here # I am an Int. MSc student at NISER, majoring in mathematics with a minor in computer science. A maths degree trains you to care about precise definitions and airtight arguments, and at some point that taste for rigour collided with computers.\nMy first real encounter with Lean came during a summer internship at IMSc under Dr. Meena Mahajan, where I studied some introductory logic and automated reasoning. The idea that you could take a mathematical argument and express it precisely enough that a machine could check it with no hand-wavy arguments was very fascinating for me.\nThese days I am continuing down that road as a summer intern in FP Launchpad under Prof. KC Sivaramakrishnan at IIT Madras, working on formal verification in distributed systems - specifically, using Lean for pragmatic verification of replicated data types (blog post here) The work is done in Sal (PaPoC 2026), a framework for verifying replicated data types. Sal’s multi-modal tactic stack is directly inspired by Loom, a multi-modal proof-orchestration layer built by Ilya Sergey\u0026rsquo;s group at VERSE Lab. So when I saw that Sergey himself would be teaching, applying was not a difficult decision.\nWhy this matters now: the promise of verified autonomy # It is worth pausing on why a company would fund a week of theorem proving in the first place.\nFully funded, down to the tote bag and merch Emergence sent us home with. Emergence frames it bluntly: \u0026ldquo;the defining challenge of this moment in computing is not capability, it\u0026rsquo;s control.\u0026rdquo; Models are already powerful enough to plan, reason, and act at enterprise speed; what is missing, they argue, is \u0026ldquo;the critical infrastructure to ensure they act within verified bounds.\u0026rdquo; Their research lab in India puts the thesis on a bumper sticker - \u0026ldquo;solve scalable correctness, unlock scalable autonomy\u0026rdquo; - and it rests on a bet that two things have quietly become true at the same time. First, \u0026ldquo;proof assistants like Lean have reached production maturity.\u0026rdquo; Second, \u0026ldquo;LLMs can now translate natural language to formal specifications.\u0026rdquo;\nPut those together and you get a genuinely appealing architecture. A language model is a wonderful, creative, deeply untrustworthy proposer. A proof checker is a humourless, uncreative, utterly trustworthy judge. So you let the model do what it is good at - propose a plan, a patch, a move, a config change - and then you refuse to act on that proposal until it comes with a machine-checkable proof that it is safe. Thus defining the title of this post The LLM proposes, and Lean disposes.\nSo what is Lean, anyway? # If you have not met it before: Lean is two things at once. It is a functional programming language, and it is an interactive theorem prover. The trick that lets it be both is the Curry–Howard correspondence: propositions are types, and proofs are programs. Proving a theorem and writing a program that type-checks turn out to be the same activity. Once you accept that, a proof assistant is just a very pedantic compiler.\nIn practice, you rarely write proof terms by hand. You write tactics - small commands that transform the goal in front of you. Our morning lab sessions, led by Siddhartha Gadgil (a mathematics faculty member at IISc who has been an energetic advocate for Lean and a key collaborator with Emergence), were mostly spent walking through his teaching repository, LeanLangur, and getting comfortable with the staples: rfl, simp, rw, induction, cases, exact, decide, and the heavier automation of grind and aesop. A recurring theme was that this toolbox is not fixed: Lean lets you define your own tactics with macros, extending the language as you go.\nUnderneath the tactics sit the ideas that make dependent type theory tick, and Prof. Gadgil\u0026rsquo;s labs covered them in turn: polymorphism, structures, inductive types and type families, type-class inference, and monads. Monads show up as a single abstraction unifying wildly different things: lists and other collections, mutable State, Option/Except for failure, side effects, and long-running computation. The common shape is a type constructor m with a pure : α → m α, a functorial map, and the star of the show, bind (flat-map). Bind is what powers Lean\u0026rsquo;s do notation - and Lean pushes that notation impressively far, letting you write let mut, while loops, and early returns that all desugar back down to this functional core. It is a lovely reminder that the friendly imperative syntax is monadic underneath.\nIf this has made you curious enough to try Lean yourself, there is no shortage of on-ramps:\nThe Lean community\u0026rsquo;s Learn page is the best starting hub - it lays out different routes depending on where you are coming from, whether that is mathematical theorem proving, computer science, or everyday programming. My personal favourite way to actually start is the Natural Number Game: you build the natural numbers up from the axioms and prove real theorems within minutes. The same group has sibling games for set theory, real analysis, and more. For something with a programming and CS flavour, the Hitchhiker\u0026rsquo;s Guide to Logical Verification is an excellent book - and it comes with a companion GitHub repository of exercises you can work through as you read. The week itself # The rhythm was consistent: morning were mostly hands-on lab sessions with Prof. Gadgil where he walked us through the LeanLangur repository, and afternoons were talks, Q\u0026amp;A, and more lab sessions. The talks were a mix of theory and practice, with a strong emphasis on how Lean can be used to verify real-world systems.\nThe Department of Mathematics at IISc, where the labs and talks were held. Day 1 we had Ra D\u0026rsquo;Souza on the foundations of Hoare logic - the original theory of what it means for a program to be correct. He laid out the intellectual lineage cleanly: inductive annotations come from Floyd, the proof system from Hoare, and the weakest-precondition calculus from Dijkstra. The central object is the Hoare triple \\(\\{P\\}\\,S\\,\\{Q\\}\\): if statement \\(S\\) starts in a state satisfying precondition \\(P\\), then it will not crash, and if it terminates it lands in a state satisfying postcondition \\(Q\\). He closed on Cook\u0026rsquo;s 1974 completeness result - Hoare logic is complete provided the assertion language can express the weakest precondition for any program and postcondition (slides here).\nThen Ilya Sergey picked up almost exactly where D\u0026rsquo;Souza left off, showing how that classical theory becomes something you can actually run in Lean through the Velvet framework from VERSE Lab. The clever move is that Velvet is not a standalone tool but a verifier embedded in Lean 4: unlike Dafny or Verus, which check programs in their own closed worlds, Velvet lets you verify genuinely imperative code - loops, mutable state, exceptions - from inside Lean\u0026rsquo;s full mathematical universe. Under the hood it is Floyd-Hoare logic made mechanical: you annotate a program with a postcondition and loop invariants (which, as Sergey put it, play much the same role as induction hypotheses), and Velvet generates the verification conditions for you. By Rice\u0026rsquo;s theorem there is no general way to infer those invariants automatically, so supplying them is the price of admission.\nWhat makes it multi-modal is how the resulting proof obligations get discharged. The routine ones are handed to automated back-ends - SMT solvers like Z3 and cvc5, or Lean\u0026rsquo;s own grind and aesop. The genuinely hard, mathematical ones are left to interactive Lean proof scripts.\nHe also pointed us to WybeCoder, a project from Meta\u0026rsquo;s FAIR that pushes this to its extreme: an LLM generates the whole thing - the Velvet code, its loop invariants, and the proofs - refining against compiler feedback until Lean accepts the result, a loop its authors call prove-as-you-generate. It is the post\u0026rsquo;s thesis in its purest form - the model proposes an entire program, and Lean decides whether to trust it.\nSergey framed the larger goal as a future where \u0026ldquo;rigorous program verification becomes accessible to a much wider audience of non-experts.\u0026rdquo;\nDay 2 was a highlight for me personally, because the first afternoon talk was by my own summer advisor, KC Sivaramakrishnan, on the Neem and Sal work - pragmatic verification of replicated data types. He started from the everyday problem: when several people edit a Google Doc or a Notion page at once, or work offline and sync later, every replica has to accept edits on its own and still end up agreeing with the others. A replicated data type is a data structure engineered so those divergent copies always reconcile. The work was in MRDTs (mergeable RDTs), where reconciliation is a three-way merge. merge takes the two diverged replicas \\(a\\) and \\(b\\), plus \\(\\ell\\), their lowest common ancestor, the last state both agreed on before they split - exactly like a three-way merge in version control. For a counter, the intended merge is \\(\\ell + (a - \\ell) + (b - \\ell)\\): take the common ancestor and re-apply the change each side made on its own.\nIn this setup, convergence is nice, but not sufficient. Convergence is not confidence. Merging the counter by taking the per-replica maximum also converges, yet it reports the wrong total the instant both sides increment; a merge that throws both states away and returns a constant converges too. What you really want is for the merged state to mean something - to behave as if the concurrent operations had been applied in some sequential order - a property called replication-aware (RA) linearizability. That is the intent a good merge has to preserve. Neem (OOPSLA 2025) showed that once a type\u0026rsquo;s merge and rc satisfy a certain set of algebraic properties - its verification conditions (VCs) - RA-linearizability follows. Sal ports this into Lean with a three-stage proof tactic: first, dsimp + grind - pure rewriting plus Lean\u0026rsquo;s bit-level automation; if this closes the goal, the proof term is checked by the Lean kernel and the trusted base (TCB) is just Lean. If it does not, Sal hands the goal to Z3 via lean-blaster - fast, but Z3 is now in the trusted base, so Sal records the step with a Blaster_admit annotation to keep the borrowed trust visible. And if that does not close it either, an AI agent (Claude Code or Aristotle) tries to write a proof term, which Lean then kernel-checks - and the TCB shrinks back to just Lean. I will write a detailed post on this work soon.\nSergey then returned for a talk on multi-modal verification of distributed systems with Veil. He set it up with the classics - Lamport\u0026rsquo;s Time, Clocks, and the Ordering of Events, the fault-tolerant lineage of Viewstamped Replication, Paxos and Raft, and the adversarial world of the Byzantine Generals Problem - plus a sobering pointer to a running list of bugs found in published distributed protocols. The properties you care about are safety (\u0026ldquo;a bad thing will not happen\u0026rdquo;) and liveness (\u0026ldquo;a good thing will eventually happen\u0026rdquo;), and it is the second kind, especially under Byzantine faults, where conventional testing and model checking start to run out of road.\nThe heart of the talk was a single chart: formalisation effort on one axis, correctness - how many bugs you would actually catch - on the other. Lightweight tools like TLA+ give fast feedback (model-check the protocol and get back a tick or a concrete counterexample) but plateau in what they can establish; the heavyweight interactive frameworks (IronFleet, Verdi, Velisarios, Igloo, LiDO) reach the top of the correctness axis at the cost of enormous manual effort and no fast feedback; and SMT-based tools like Ivy and mypyvy automate proofs only by staying inside a decidable first-order fragment. Sergey\u0026rsquo;s \u0026ldquo;we want to be here\u0026rdquo; pointed at the corner everyone else misses - undecidable, higher-order properties with fast feedback - and Veil is the attempt to live there. It is a shallowly-embedded DSL in Lean that models a protocol as a transition system (states, transitions, and an inductive invariant that every step must preserve) and then attacks it from every mode at once: explicit-state and symbolic model checking for fast feedback and counterexamples, external SMT solvers to discharge the routine first-order goals, and out-of-the-box interactive Lean proofs for the genuinely hard, higher-order ones. On his feature-comparison slide, Veil was the only tool with a green tick in every column. He used Ring Leader Election as the running example; his group writes it all up beautifully at proofsandintuitions.net.\nDay 3 brought KV Raghavan on abstract interpretation - the art of soundly approximating what a program does - alongside more lab.\nDays 4 and 5 We had project demos from the LeanLang Hackathon crowd and from Emergence, and nearly every one was some flavour of AI proposes, Lean checks:\nFlowGuard (Dev Soni), memorably subtitled \u0026ldquo;I will, unfortunately, enter your house.\u0026rdquo; The point: the composition of agents need not be safe even when every individual capability was tested and works fine - it is the union that bites you. He drew on information flow in multi-agent systems, prompt injection (a term coined by Simon Willison), the FIDES taint-tracking approach with a quarantined LLM, and AWS Cedar for policy. \u0026ldquo;Who sacked my cluster!\u0026rdquo; (Sachin Singh, a senior engineer at DigitalOcean, and the hackathon winner). This was the cleanest verified-autonomy story of the week. Managing Kubernetes clusters is painful, and an SRE agent to do it is non-deterministic and cannot be trusted to be safe. So he put a Lean-checked admission gate in front of it: the agent\u0026rsquo;s proposed action is only executed if it comes with a machine-checkable proof, and when the proof fails, the structured rejection reason is fed back as an RL signal. Control theory meets proof theory. Chess Provers in Lean (Saachi, MARS team): feed in a position in FEN notation, let an LLM propose moves, and verify their legality in Lean - success only when the validated sequence ends in checkmate. LeanDatabase (Ajay Kumar Nair): a neat trick for trusting LLM-generated SQL. When you ask a model to turn a natural-language question into a SQL query, you have no easy way to know the query it hands back is correct. So instead of asking once, LeanDatabase asks several times and uses Lean to check whether the resulting queries are all semantically equivalent - Lean metaprogramming elaborates each SQL query into a Lean term capturing its meaning, and then the queries are proven to denote the same thing. The insight is probabilistic: a model might well produce a wrong query, but it is very unlikely to produce the same wrong query across several independent tries, so provable agreement between the samples is strong evidence the translation is right. A cluster of others in the same spirit: PastaLean (Anirudh Gupta), transpiling Python through its AST into Lean so you can \u0026ldquo;write in Python and get the guarantees of a proof assistant\u0026rdquo;; Bulletproof Templates, a templating approach that parses templates into a context-preserving tree to make XSS impossible by construction; and VerifyTheVector, checking that an LLM\u0026rsquo;s claim actually matches the SVG it generated. What I\u0026rsquo;m taking home # More than any single talk, what I am taking home is the people. Over five days of coffee breaks and long lunches I got to talk with students, PhD students, postdocs, faculty, and folks from industry - each carrying a different perspective and a different problem they were excited about. Those conversations, as much as the lectures, made me realise just how genuinely I am invested in this field.\nSo a big thank you to Emergence for organising such a wonderful event, and to Siddhartha Gadgil, KC Sivaramakrishnan, Ilya Sergey, Deepak D\u0026rsquo;Souza, KV Raghavan, and everyone working behind the scenes for putting together such a generous and genuinely inspiring week. I came for the Lean; I left with a much clearer sense of why I want to keep doing this.\nProof of completion ","date":"14 July 2026","externalUrl":null,"permalink":"/blogs/leanlang-summer-school/","section":"Writing","summary":"In July 2026 I spent a week at IISc Bangalore for the LeanLang Summer School, run by Emergence. Here is how I got there, what Lean actually is, why formally verified autonomy suddenly matters, and a tour of the week.","title":"LLM Proposes, Lean Disposes: A Week at the LeanLang Summer School","type":"blogs"},{"content":"","date":"14 July 2026","externalUrl":null,"permalink":"/tags/summer-school/","section":"Tags","summary":"","title":"Summer School","type":"tags"},{"content":"","date":"14 July 2026","externalUrl":null,"permalink":"/tags/theorem-proving/","section":"Tags","summary":"","title":"Theorem Proving","type":"tags"},{"content":"","date":"16 May 2026","externalUrl":null,"permalink":"/tags/differential-geometry/","section":"Tags","summary":"","title":"Differential Geometry","type":"tags"},{"content":"","date":"16 May 2026","externalUrl":null,"permalink":"/tags/gauss/","section":"Tags","summary":"","title":"Gauss","type":"tags"},{"content":"","date":"16 May 2026","externalUrl":null,"permalink":"/tags/gaussian-curvature/","section":"Tags","summary":"","title":"Gaussian Curvature","type":"tags"},{"content":"","date":"16 May 2026","externalUrl":null,"permalink":"/categories/mathematics/","section":"Categories","summary":"","title":"Mathematics","type":"categories"},{"content":" Introduction # Most geometric properties seem to require an outside observer. To tell whether a wire is bent, you look at it from the side. To tell whether a road curves, you look at a map. Curvature feels like something that can only be seen from the outside.\nGauss discovered that, for surfaces, this intuition is wrong.\nImagine you are a 2-dimensional ant living on a surface with no access to the surrounding space. You can walk around, measure distances, and study the geometry of your world, but you can never step outside and look at it from above.\nCould you determine whether your world is curved?\nIn 1827, Gauss proved that you can. The Gaussian curvature of a surface is completely determined by measurements made within the surface itself. No external viewpoint is needed.\nHe called the result Theorema Egregium, the Remarkable Theorem.\nThat is the heart of the theorem:\n$$ \\text { Gaussian Curvature is determined entirely by the First Fundamental Form.} $$ Why It Looks Extrinsic At First # Classically, Gaussian curvature first appears through the First and Second Fundamental Forms. For a parametrized surface \\(\\boldsymbol{\\sigma}(u,v)\\), the First Fundamental Form is\n$$ I = E\\,du^2 + 2F\\,du\\,dv + G\\,dv^2, $$where\n$$ E = \\boldsymbol{\\sigma}_u \\cdot \\boldsymbol{\\sigma}_u,\\quad F = \\boldsymbol{\\sigma}_u \\cdot \\boldsymbol{\\sigma}_v,\\quad G = \\boldsymbol{\\sigma}_v \\cdot \\boldsymbol{\\sigma}_v. $$The Second Fundamental Form is\n$$ \\Pi = L\\,du^2 + 2M\\,du\\,dv + N\\,dv^2. $$where\n$$ L = \\boldsymbol{\\sigma}_{uu}\\cdot\\bar{N},\\quad M = \\boldsymbol{\\sigma}_{uv}\\cdot\\bar{N},\\quad N = \\boldsymbol{\\sigma}_{vv}\\cdot\\bar{N}. $$and \\(\\bar{N}\\) is the unit normal vector to the surface.\nThe Gaussian curvature is then\n$$ K = \\frac{LN - M^2}{EG - F^2}. $$At first, this looks extrinsic. The coefficients \\(L\\), \\(M\\), and \\(N\\) are computed using the unit normal vector to the surface. They measure how the surface bends in ambient three-dimensional space. So it seems natural to expect \\(K\\) to depend on the embedding.\nGauss proved that this expectation is wrong.\nChristoffel Symbols # The bridge from extrinsic curvature to intrinsic geometry is built from the Christoffel symbols. Let the surface patch be \\(\\boldsymbol{\\sigma}(u_1,u_2)\\), where \\(u_1 = u\\) and \\(u_2 = v\\). Write\n$$ \\boldsymbol{\\sigma}_1 = \\boldsymbol{\\sigma}_u,\\qquad \\boldsymbol{\\sigma}_2 = \\boldsymbol{\\sigma}_v. $$The coefficients of the First Fundamental Form are\n$$ g_{ij} = \\boldsymbol{\\sigma}_i \\cdot \\boldsymbol{\\sigma}_j. $$Thus \\(g_{11} = E\\), \\(g_{12} = g_{21} = F\\), and \\(g_{22} = G\\). For \\(1 \\leq i,j,k \\leq 2\\), the Christoffel symbols \\(\\Gamma^k_{ij}\\) are scalar functions defined by\n$$ \\begin{pmatrix} \\Gamma^1_{ij} \\\\ \\Gamma^2_{ij} \\end{pmatrix} {}= \\begin{pmatrix} g_{11} \u0026 g_{12} \\\\ g_{21} \u0026 g_{22} \\end{pmatrix}^{-1} \\begin{pmatrix} \\boldsymbol{\\sigma}_{ij} \\cdot \\boldsymbol{\\sigma}_1 \\\\ \\boldsymbol{\\sigma}_{ij} \\cdot \\boldsymbol{\\sigma}_2 \\end{pmatrix}. $$In words, they give the tangent part of the second derivative \\(\\boldsymbol{\\sigma}_{ij}\\). They can also be computed directly from the metric:\n$$ \\Gamma^k_{ij} {}= \\frac{1}{2} \\sum_{l=1}^{2} g^{kl} \\left( \\frac{\\partial g_{il}}{\\partial u_j} + \\frac{\\partial g_{lj}}{\\partial u_i} {}- \\frac{\\partial g_{ij}}{\\partial u_l} \\right), $$where \\(g^{kl}\\) denotes the \\((k,l)\\)-entry of the inverse matrix \\((g_{ij})^{-1}\\).\nThis is the crucial intrinsic point: Christoffel symbols are determined entirely by the first fundamental form and its derivatives. A surface-dweller could compute them by measuring lengths on the surface. They are not, however, intrinsic invariants: their numerical values depend on the coordinate system.\nWith these symbols, the second derivatives of the surface patch split into tangent and normal pieces:\n$$ \\boldsymbol{\\sigma}_{ij} {}= \\Gamma^1_{ij}\\boldsymbol{\\sigma}_1 + \\Gamma^2_{ij}\\boldsymbol{\\sigma}_2 + b_{ij}\\bar{N}. $$This is the Formula of Gauss. The first two terms are tangent to the surface, and the final term is normal to it. Here \\(b_{ij}\\) are the coefficients of the Second Fundamental Form and \\(\\bar{N}\\) is the unit normal.\nHow They Enter Theorema Egregium # The Gaussian curvature can be written as\n$$ K {}= \\frac{\\det(b_{ij})}{\\det(g_{ij})}. $$Since \\(\\det(g_{ij}) = EG - F^2\\) is already intrinsic, Gauss only had to show that \\(\\det(b_{ij})\\) can also be expressed intrinsically.\nStart with the Formula of Gauss,\n$$ \\boldsymbol{\\sigma}_{ij} {}= \\sum_{m=1}^{2}\\Gamma^m_{ij}\\boldsymbol{\\sigma}_m + b_{ij}\\bar{N}, $$and differentiate with respect to \\(u_k\\). This gives expressions for the third derivatives \\(\\boldsymbol{\\sigma}_{ijk}\\). Since mixed partial derivatives commute, we have\n$$ \\boldsymbol{\\sigma}_{ijk} = \\boldsymbol{\\sigma}_{ikj}. $$Taking dot products with a tangent vector \\(\\boldsymbol{\\sigma}_l\\) and expanding introduces the Riemann symbol:\n$$ \\begin{aligned} R^l_{jki} ={}\u0026 \\sum_{m=1}^{2} \\left( \\frac{\\partial \\Gamma^m_{ij}}{\\partial u_k}g_{ml} + \\Gamma^m_{ij}\\,\\boldsymbol{\\sigma}_{mk}\\cdot\\boldsymbol{\\sigma}_l \\right) \\\\ \u0026{}- \\sum_{m=1}^{2} \\left( \\frac{\\partial \\Gamma^m_{ik}}{\\partial u_j}g_{ml} + \\Gamma^m_{ik}\\,\\boldsymbol{\\sigma}_{mj}\\cdot\\boldsymbol{\\sigma}_l \\right). \\end{aligned} $$This quantity is built from Christoffel symbols, their partial derivatives, and first fundamental form data. The symmetry of mixed partial derivatives yields\n$$ R^l_{jki} {}- b_{ij}b_{lk} + b_{ik}b_{lj} = 0. $$Choosing \\(i=1\\), \\(j=2\\), \\(k=1\\), and \\(l=2\\), we get\n$$ R^2_{121} {}= b_{11}b_{22} {}- b_{12}b_{21} {}= \\det(b_{ij}). $$Therefore \\(\\det(b_{ij})\\) is expressible in terms of intrinsic data. Consequently,\n$$ K {}= \\frac{\\det(b_{ij})}{\\det(g_{ij})} $$is intrinsic. This is the remarkable content of Gauss\u0026rsquo;s theorem: the curvature that first appeared to depend on bending in 3D space is completely determined by measurements made on the surface itself.\nA Cleaner Formula In Orthogonal Coordinates # When the coordinate curves meet at right angles, \\(F = 0\\). In that case, the intrinsic expression becomes much more readable:\n$$ K = -\\frac{1}{2\\sqrt{EG}} \\left[ \\frac{\\partial}{\\partial u} \\left( \\frac{G_u}{\\sqrt{EG}} \\right) + \\frac{\\partial}{\\partial v} \\left( \\frac{E_v}{\\sqrt{EG}} \\right) \\right]. $$This formula is beautiful because it contains no reference to a normal vector or to 3D space. The curvature is extracted from the coefficients \\(E\\) and \\(G\\) alone.\nWhy The Theorem Is So Powerful # The biggest consequence is that Gaussian curvature is preserved by local isometries.\nA local isometry is a transformation that preserves distances. Since distances determine \\(E\\), \\(F\\), and \\(G\\), and since \\(K\\) is determined by those coefficients, curvature must be preserved as well.\nThis explains a familiar impossibility: there is no perfect flat map of the Earth.\nA plane has\n$$ K = 0, $$while a sphere of radius \\(R\\) has\n$$ K = \\frac{1}{R^2}. $$Because their Gaussian curvatures differ, no map from the sphere to the plane can preserve all distances, even locally, without distortion. Something must stretch, tear, or compress.\nThe same idea explains why paper can be rolled into a cylinder. A sheet of paper and a cylinder both have \\(K = 0\\). The cylinder looks curved from outside, but intrinsically it remains flat.\nThe Remarkable Moral # Gauss revealed that curvature has an internal life. It is not merely how a surface sits in the world around it. It is encoded in the surface\u0026rsquo;s own measurements.\nThat insight changed geometry. It prepared the ground for Riemannian geometry, where one studies curved spaces without needing a larger space to contain them. It also echoes through general relativity, where curvature is not something observed from outside the universe, but something measured from within it.\nThe theorem is remarkable because it turns a question about shape into a question about distance.\n","date":"16 May 2026","externalUrl":null,"permalink":"/blogs/remarkable-theorem-of-gauss/","section":"Writing","summary":"Gauss’s Theorema Egregium reveals that Gaussian curvature is intrinsic: it can be read from distances measured on a surface, without looking at the surrounding 3D space.","title":"The Remarkable Theorem of Gauss","type":"blogs"},{"content":" \u0026ldquo;Hello, World!\u0026rdquo;\nBe it print(\u0026quot;Hello, World!\u0026quot;) in Python, putStrLn \u0026quot;Hello, World!\u0026quot; in Haskell, or #eval \u0026quot;Hello, World!\u0026quot; in Lean, the very first successful output from a new programming language is a rite of passage. That trimphant message signals that the language is set up correctly and ready for exploration.\nThis post is my own \u0026ldquo;Hello, World!\u0026rdquo; - the first entry on a blog that I hope will become a collection of notes, ideas, projects, and occasional ramblings about the things I find fascinating.\nOver the past few years, I\u0026rsquo;ve found myself increasingly drawn to the intersection of mathematics and computer science. Lately, that curiosity has led me into automated reasoning, formal methods, theorem proving, and the broader landscape of theoretical computer science. There is something deeply satisfying about taking an informal idea and expressing it with enough precision that a machine can understand, verify, and reason about it.\nThrough this blog, I plan to document that journey. You\u0026rsquo;ll find notes on automated reasoning and proof assistants such as Lean, explorations in mathematics and theoretical computer science, thoughts on machine learning, and write-ups of projects, internships, and research work. I also hope to share interesting things I encounter during my coursework at NISER and through the various technical communities and collaborations I am fortunate to be part of.\nOf course, this blog serves a non-academic purpose as well. It\u0026rsquo;s a good excuse for me to sit down every once in a while and write about things that excite me. Create content instead of consuming content mindlessly! Letting those creative juices flow is something I want to encourage!\nThank you for visiting, and I hope you find something interesting here!\n","date":"9 May 2026","externalUrl":null,"permalink":"/blogs/first-note/","section":"Writing","summary":"Welcome to my blog! Here I’ll share notes on automated reasoning, formal methods, theoretical computer science, mathematics, machine learning, and more.","title":"Hello, World!","type":"blogs"},{"content":"I am currently a fifth-year Integrated MSc student at the National Institute of Science Education and Research (NISER), majoring in Mathematics and a minor in Computer Science.\nI work on formal verification and automated reasoning — see Research for my internships and publications, and Projects for things I have built.\nEducation # Integrated MSc in Mathematics\nNational Institute of Science Education and Research, Bhubaneswar\nFifth year\nHigher Secondary Education Sarvodaya Central Vidyalaya, Thiruvananthapuram, Kerala\nSkills # Area Tools and Technologies Proof Assistants and Formal Methods Lean 4, Mathlib Programming Languages Python, JavaScript Machine Learning and AI PyTorch, TensorFlow, scikit-learn Scientific Computing NumPy, Pandas, Matplotlib, Mathematica, LaTeX Web and Tooling Flask, Django, React, HTML, CSS Outside of this I play the violin, with an interest in classical and contemporary music.\nRelevant Courses # Mathematics: Real Analysis, Linear Algebra, Discrete Mathematics, Group Theory, Probability Theory, Metric Spaces, Differential Equations, Multivariate Calculus, Rings and Modules, Measure Theory, Complex Analysis, Graph Theory, Number Theory, Functional Analysis, Topology.\nComputer Science: Data Structures and Algorithms, Theory of Computation, Discrete Structures and Computation, Design and Analysis of Algorithms, Advanced Machine Learning, Algorithmic Coding Theory, Computational Geometry.\nCommunity # As the Head of the Coding Club at NISER, I organize events, oversee activities, and plan initiatives that promote coding and technology. I am also a core member of the MathematiX Club, where I help foster interest in mathematics through events and competitions.\nSelected activities include:\nCode N Coffee: Started casual meetups for coding enthusiasts to talk about whatever they find interesting, from algorithms to side projects. Switcheroo Coding Event: Organized the event, developed the competition website, and supported execution. Event details Pi Day Celebration 2024: Organized a mathematics-focused event with puzzles, quizzes, and talks. SUMS, SRS, and AXIOM: Helped organize talks within the club and participated in related events. Contact # Email: harisankar.b@niser.ac.in Personal Email: harisankarbinodss@gmail.com ORCID: 0009-0008-1359-7367 LinkedIn: Harisankar B GitHub: Methaphur ","externalUrl":null,"permalink":"/about/","section":"About","summary":"I am currently a fifth-year Integrated MSc student at the National Institute of Science Education and Research (NISER), majoring in Mathematics and a minor in Computer Science.\nI work on formal verification and automated reasoning — see Research for my internships and publications, and Projects for things I have built.\n","title":"About","type":"about"},{"content":" 2026 # May–July - Research intern at FP Launchpad, IIT Madras, under Dr. KC Sivaramakrishnan, working on formal verification of distributed systems using Lean. (Blog Post)\n30 July - Gave my internship presentation, Convergence is Not Enough: Verifying a Tombstone-Free Sequence MRDT in Lean 4, at FP Launchpad, IIT Madras. (Slides)\n5–10 July - Attended the LeanLang Summer School at IISc, Bangalore, organised by EmergenceAI. (Blog Post)\n15–27 June - Attended the Foundational Lecture Series in Theoretical Computer Science at IMSc, Chennai.\n16–18 April - Attended the LeanLang for Verified Autonomy hackathon organised by EmergenceAI at IISc, Bangalore. (blog post soon™)\n2025 # 8 November - Presented a PoseDetection simulation (Github Repo) at the Open Day outreach programme at NISER.\n25 October - First Prize at the MathematiX club event at Umang (website done by me), the annual college fest at NISER.\nSummer - Research intern at IMSc, Chennai, under Dr. Meena Mahajan, on an introduction to Logic and Automated Reasoning.\n18 April - Gave a talk on Transformers Learn Shortcuts to Automata with Yash Chauhan, as part of the Advanced Machine Learning course at NISER. (Slides, Report)\n29 March - Organised a talk on cybersecurity and hacking awareness for school students, as part of Prerna, a science exposure event run by the Zariya club.\n22 March - Organised Against Time a competitive programming event at NISER.\n2024 # 26 October - Started the Problem of the Week initiative, where participants submit solutions online for a moderator to score, with a live leaderboard.\n20 October - Presented an introduction to path finding algorithms at the Open Day outreach programme at NISER, walking school students through Dijkstra\u0026rsquo;s algorithm and A*, and showing how code turns an idea into something usable.\n19 September - Gave an introductory talk on Turing machines, building a barebones Turing machine in Python, as part of the Code N Coffee sessions.\n16 September - Organised Switcheroo, a paired coding competition where teammates swap places partway through and finish each other\u0026rsquo;s problems, with no comments allowed. I built the Flask server that handled submissions and kept the running tally.\n22 June - Started Code N Coffee, a casual meetup for coding enthusiasts at NISER to talk about whatever they find interesting. Informal and fun, and a space for us to gather and share our enthusiasm for computer science.\n","externalUrl":null,"permalink":"/news/","section":"News","summary":"2026 # May–July - Research intern at FP Launchpad, IIT Madras, under Dr. KC Sivaramakrishnan, working on formal verification of distributed systems using Lean. (Blog Post)\n","title":"News","type":"news"},{"content":" Research code # Tombstone-free sequence MRDT in Lean 4\nContributed a tombstone-free RGA and its successor EmbedRGA to Sal, the Lean 4 verification framework for replicated data types developed at FP Launchpad, IIT Madras. The tombstone-free variant was proved RA-linearizable and then found to reorder text on delete regardless; EmbedRGA repairs this with immutable coordinates. Write-up · Slides\nCommunity and student projects # QR Coupon for Event Management\nA lightweight website for sending QR codes for event participation through email with Google Apps Script, plus a static verification page for organizers. GitHub Repo\nUmang \u0026lsquo;25 Fest Website\nThe official site for Umang, the annual intra-college fest at NISER, held 23–26 October 2025. Alongside event listings and a schedule organised by club, it ran a live results board that sorted events into completed, ongoing, and upcoming, refreshing itself every five minutes so winners appeared as each event wrapped up rather than after the fest. View Website\nProblem of the Week Platform\nA website for weekly competitive programming problems with automated leaderboard management for community coding engagement. View Project\nSwitcheroo Website\nA Flask-based web server for a coding event where teams collaborate by switching systems and solving problems together, with integrated timing and scoring. GitHub Repo\nNISER Mess Menu Website\nA website that presents the weekly NISER mess menu, with staff uploads through Google Forms and automatic display for students. View Website\nEvent Management\nAn event scheduling system concept that integrates with Google Calendar to reduce scheduling conflicts and support a public NISER club calendar. Project Link\nTimetable Generator\nA work-in-progress system for minimizing course conflicts using constraint satisfaction, graph coloring, and scheduling algorithms.\nCompetition Website\nA work-in-progress coding competition platform using Django and React for NISER students, including leaderboards, point tracking, and team participation. GitHub Repo\n","externalUrl":null,"permalink":"/projects/","section":"Projects","summary":"Research code # Tombstone-free sequence MRDT in Lean 4\nContributed a tombstone-free RGA and its successor EmbedRGA to Sal, the Lean 4 verification framework for replicated data types developed at FP Launchpad, IIT Madras. The tombstone-free variant was proved RA-linearizable and then found to reorder text on delete regardless; EmbedRGA repairs this with immutable coordinates. Write-up · Slides\n","title":"Projects","type":"projects"},{"content":"My research interests lie at the intersection of automated reasoning, formal methods, theoretical computer science, and machine learning. I am particularly interested in developing systems that can reason about, verify, and synthesize correct software and mathematical artifacts. My current work focuses on automated theorem proving, proof assistants such as Lean, and the formal verification of distributed systems. More broadly, I am fascinated by the foundations of computation, logic, programming languages, and the ways in which formal reasoning techniques can be combined with modern machine learning methods to build more reliable and trustworthy intelligent systems.\nPublications # ORCID: 0009-0008-1359-7367\nHarisankar Binod, T. Shithij, A. Tichy, and S. Mishra. Artificial Intelligence in Oral Health. In Artificial Intelligence for Oral Health Care: Applications and Future Prospects, eds. F. Schwendicke, P.K. Chaudhari, K. Dhingra, S.E. Uribe, M. Hamdan. Springer Nature Switzerland, Cham, 2025, pp. 1-21. https://doi.org/10.1007/978-3-031-84047-0_1\nTalks # Convergence is Not Enough: Verifying a Tombstone-Free Sequence MRDT in Lean 4\nJuly 2026 · FP Launchpad, IIT Madras\nClosing presentation for my internship under Dr. KC Sivaramakrishnan. The talk builds from collaborative text editing and why replication makes it hard, through CRDTs and RGA, to RA-linearizability as a statement of what \u0026ldquo;correct\u0026rdquo; should mean for a sequence — convergence alone is not enough. It then presents a tombstone-free RGA mechanized in Lean 4 with the Sal framework: proved RA-linearizable, and then shown to reorder text on delete regardless. It closes with EmbedRGA, which repairs this using immutable coordinates.\nSlides · Write-up\nTransformers Learn Shortcuts to Automata\nApril 2025 · Advanced Machine Learning course, NISER · with Yash Chauhan\nA talk on Liu et al. (2022), which asks how shallow, non-recurrent Transformers manage computations that appear to require sequential processing. Rather than iterating a transition function step by step, Transformers learn shortcut solutions that compress the whole sequence into a few parallel layers. The talk covers the construction behind this — Krohn-Rhodes decomposition and results from circuit complexity — along with why such shortcuts are brittle and generalize poorly to longer inputs.\nSlides · Report · Paper\nResearch and Internships # Research Intern at FP Launchpad, IIT Madras # May–July 2026\nI was a Research Intern at FP Launchpad at the Indian Institute of Technology Madras, working under the guidance of Dr. KC Sivaramakrishnan. My research focused on formal verification of replicated data types, using Lean to verify correctness of distributed systems. (Write-up)\nSummer Research Program, IMSc Chennai # Summer 2025\nIn the summer of 2025, I participated in the Summer Research Program at the Institute of Mathematical Sciences (IMSc), Chennai, under the guidance of Dr. Meena Mahajan, Professor in the Theoretical Computer Science group. My work focused on automated reasoning, where I explored topics in formal logic, experimented with Lean, and studied automated theorem proving.\nWinter Internship, IISc Bangalore # Winter 2023\nIn the winter of 2023, I did a small reading project under the guidance of Dr. L Sunil Chandra at the Indian Institute of Science (IISc), Bangalore. The project involved reading and summarizing a research paper on Graph Theory.\nAI in Oral Health, NISER # Summer 2023\nIn the summer of 2023, I completed an internship under the guidance of Dr. Subhankar Mishra on a research project related to Artificial Intelligence in Oral Health. This work contributed to a book chapter on applications of AI in diagnosis, treatment, and patient care in dentistry.\n","externalUrl":null,"permalink":"/research/","section":"Research","summary":"My research interests lie at the intersection of automated reasoning, formal methods, theoretical computer science, and machine learning. I am particularly interested in developing systems that can reason about, verify, and synthesize correct software and mathematical artifacts. My current work focuses on automated theorem proving, proof assistants such as Lean, and the formal verification of distributed systems. More broadly, I am fascinated by the foundations of computation, logic, programming languages, and the ways in which formal reasoning techniques can be combined with modern machine learning methods to build more reliable and trustworthy intelligent systems.\n","title":"Research","type":"research"}]