Lean4
/-- Given a `CompSource` `cs`, `cs.flatten` maps an assumption index
to the number of copies of that assumption that appear in the history of `cs`.
For example, suppose `cs` is produced by scaling assumption 2 by 5,
and adding to that the sum of assumptions 1 and 2.
`cs.flatten` maps `1 ↦ 1, 2 ↦ 6`.
-/
def flatten : CompSource → Std.HashMap Nat Nat
| (CompSource.assump n) => (∅ : Std.HashMap Nat Nat).insert n 1
| (CompSource.add c1 c2) => (CompSource.flatten c1).mergeWith (fun _ b b' => b + b') (CompSource.flatten c2)
| (CompSource.scale n c) => (CompSource.flatten c).map (fun _ v => v * n)