Formalization Blueprint for “An Introduction to Algebraic Combinatorics” by Darij Grinberg

5.4 The Lindström–Gessel–Viennot lemma

5.4.1 Definitions

Definition 5.120
#

We consider the infinite simple digraph with vertex set \(\mathbb {Z}^{2}\) (so the vertices are pairs of integers) and arcs

\[ \left( i,j\right) \rightarrow \left( i+1,j\right) \ \ \ \ \ \ \ \ \ \ \text{for all }\left( i,j\right) \in \mathbb {Z}^{2} \]

and

\[ \left( i,j\right) \rightarrow \left( i,j+1\right) \ \ \ \ \ \ \ \ \ \ \text{for all }\left( i,j\right) \in \mathbb {Z}^{2}. \]

The arcs of the first form are called east-steps or right-steps; the arcs of the second form are called north-steps or up-steps.

The vertices of this digraph will be called lattice points or grid points or simply points.

The entire digraph will be denoted by \(\mathbb {Z}^{2}\) and called the integer lattice or integer grid.

Any path is uniquely determined by its starting point and its step sequence.

5.4.2 Helpers for lattice path infrastructure

Lemma 5.121

Let \(p_1, p_2\) be two lattice paths and \(A\) a starting point. Then the endpoint of the concatenation \(p_1 \cdot p_2\) starting from \(A\) equals the endpoint of \(p_2\) starting from the endpoint of \(p_1\):

\[ \operatorname {endpoint}(p_1 \cdot p_2, A) = \operatorname {endpoint}(p_2, \operatorname {endpoint}(p_1, A)). \]
theorem LGV1.LatticePath.endpoint_append (path1 path2 : LatticePath) (start : LatticePoint) :
(path1 ++ path2).endpoint start = path2.endpoint (path1.endpoint start)
Proof

By induction on \(p_1\): applying the steps of \(p_1 \cdot p_2\) starting from \(A\) is the same as first applying the steps of \(p_1\) (reaching the endpoint of \(p_1\)) and then applying the steps of \(p_2\).

Lemma 5.122

If a path \(p\) goes from \(A\) to \(B\), then for any \(n\), the first \(n\) steps of \(p\) form a path from \(A\) to the intermediate vertex \(M\), and the remaining steps form a path from \(M\) to \(B\).

theorem LGV1.LatticePath.isPathFromTo_take_drop (path : LatticePath) (n : ) (A B : LatticePoint) (h : path.isPathFromTo A B) :
have mid := endpoint (List.take n path) A; isPathFromTo (List.take n path) A mid isPathFromTo (List.drop n path) mid B
Proof

Follows from the fact that \(p\) equals its first \(n\) steps concatenated with its remaining steps, together with Lemma 5.121.

Lemma 5.123

If path \(h\) goes from \(A\) to \(v\) and path \(t\) goes from \(v\) to \(B\), then \(h \cdot t\) goes from \(A\) to \(B\).

theorem LGV1.LatticePath.isPathFromTo_append (head tail : LatticePath) (A v B : LatticePoint) (hhead : head.isPathFromTo A v) (htail : tail.isPathFromTo v B) :
(head ++ tail).isPathFromTo A B
Proof

By Lemma 5.121: \(\operatorname {endpoint}(h \cdot t, A) = \operatorname {endpoint}(t, \operatorname {endpoint}(h, A)) = \operatorname {endpoint}(t, v) = B\).

Lemma 5.124

For any lattice path \(p\) starting at \(A\), the coordinate sum of the endpoint satisfies

\[ \operatorname {cs}(\operatorname {endpoint}(p, A)) = \operatorname {cs}(A) + \ell (p), \]

where \(\ell (p)\) is the number of steps in \(p\).

Proof

By induction on \(p\): each step increases the coordinate sum by exactly \(1\).

Lemma 5.125

The x-coordinate of the endpoint of a path \(p\) starting at \(A\) satisfies

\[ \operatorname {x}(\operatorname {endpoint}(p, A)) = \operatorname {x}(A) + (\text{\# of east-steps in } p). \]
theorem LGV1.endpoint_x_eq (path : LatticePath) (start : LatticePoint) :
(path.endpoint start).1 = start.1 + path.eastStepCount
Proof

By induction: each east-step increments the x-coordinate by \(1\), and each north-step leaves it unchanged.

Lemma 5.126

For any two lattice points \(A, B\), the set of lattice paths from \(A\) to \(B\) is finite.

Proof

If \(B\) is not componentwise \(\ge A\), the set is empty. Otherwise, every path from \(A\) to \(B\) has a bounded number of steps (exactly \(\operatorname {cs}(B) - \operatorname {cs}(A)\)), and there are finitely many lists of bounded length over the two-element set \(\{ \text{east}, \text{north}\} \).

Lemma 5.127

If a path \(p\) goes from \(A\) to \(B\), then \(\operatorname {x}(A) \le \operatorname {x}(B)\) and \(\operatorname {y}(A) \le \operatorname {y}(B)\).

theorem LGV1.path_coords_nondecreasing (path : LatticePath) (a b : LatticePoint) (h : path.isPathFromTo a b) :
a.1 b.1 a.2 b.2
Proof

By induction on the path: each east-step increments the x-coordinate and each north-step increments the y-coordinate.

5.4.3 Counting paths from \((a,b)\) to \((c,d)\)

Lemma 5.128

Let \((a,b), (c,d) \in \mathbb {Z}^2\).

Observation 1: Each path from \((a,b)\) to \((c,d)\) has exactly \(c+d-a-b\) steps.

Observation 2: Each path from \((a,b)\) to \((c,d)\) has exactly \(c-a\) east-steps.

theorem LGV1.path_stepCount_eq (path : LatticePath) (a b c d : ) (h : path.isPathFromTo (a, b) (c, d)) :
path.stepCount = c + d - a - b
theorem LGV1.path_eastStepCount_eq (path : LatticePath) (a b c d : ) (h : path.isPathFromTo (a, b) (c, d)) :
path.eastStepCount = c - a
Proof

Observation 1: We define the coordinate sum of a point \((x,y) \in \mathbb {Z}^{2}\) to be \(x+y\), denoted \(\operatorname {cs}(x,y)\). The coordinate sum increases by exactly \(1\) along each arc. If the path visits vertices \(v_0, v_1, \ldots , v_n\) with \(v_0 = (a,b)\) and \(v_n = (c,d)\), then by the telescope principle,

\[ n = \sum _{i=1}^n \bigl(\operatorname {cs}(v_i) - \operatorname {cs}(v_{i-1})\bigr) = \operatorname {cs}(c,d) - \operatorname {cs}(a,b) = c + d - a - b. \]

Observation 2: The x-coordinate of a point increases by exactly \(1\) along each east-step and stays unchanged along each north-step. By telescoping on the x-coordinate:

\[ (\text{\# of east-steps}) = \operatorname {x}(c,d) - \operatorname {x}(a,b) = c - a. \]
Proposition 5.129

Let \(\left( a,b\right) \in \mathbb {Z}^{2}\) and \(\left( c,d\right) \in \mathbb {Z}^{2}\) be two points. Then,

\[ \left( \text{\# of paths from }\left( a,b\right) \text{ to }\left( c,d\right) \right) =\begin{cases} \binom {c+d-a-b}{c-a}, & \text{if }c+d\geq a+b;\\ 0, & \text{if }c+d{\lt}a+b. \end{cases} \]
Proof

Observation 1 immediately shows that no path from \((a,b)\) to \((c,d)\) exists when \(c+d {\lt} a+b\) (it would need a negative number of steps), so the count is \(0\).

Otherwise, \(c + d \ge a + b\), so \(c+d-a-b \in \mathbb {N}\). Observations 1 and 2 show that every path from \((a,b)\) to \((c,d)\) has exactly \(c + d - a - b\) steps, of which exactly \(c - a\) are east-steps.

Observation 3: Let \(p\) be a path that starts at the point \((a,b)\) and has exactly \(c+d-a-b\) steps. Assume that exactly \(c-a\) of these steps are east-steps. Then, this path \(p\) ends at \((c,d)\).

(This follows by applying Observations 1 and 2 to the endpoint of \(p\) and comparing.)

Combining Observations 1, 2 and 3, the paths from \((a,b)\) to \((c,d)\) are precisely the paths that start at \((a,b)\) and have exactly \(c+d-a-b\) steps and exactly \(c-a\) east-steps. Such a path is uniquely determined by which \(c-a\) of its \(c+d-a-b\) steps are east-steps. By the bijection principle,

\[ \left( \text{\# of paths from }\left( a,b\right) \text{ to }\left( c,d\right) \right) = \binom {c+d-a-b}{c-a}. \]

5.4.4 Path tuples, nipats and ipats

Definition 5.130
#

Let \(k\in \mathbb {N}\).

(a) A \(k\)-vertex means a \(k\)-tuple of lattice points.

(b) If \(\mathbf{A}=\left( A_{1},A_{2},\ldots ,A_{k}\right) \) is a \(k\)-vertex, and if \(\sigma \in S_{k}\) is a permutation, then \(\sigma \left( \mathbf{A}\right) \) shall denote the \(k\)-vertex \(\left( A_{\sigma \left( 1\right) },A_{\sigma \left( 2\right) },\ldots ,A_{\sigma \left( k\right) }\right) \).

(c) If \(\mathbf{A}=\left( A_{1},A_{2},\ldots ,A_{k}\right) \) and \(\mathbf{B}=\left( B_{1},B_{2},\ldots ,B_{k}\right) \) are two \(k\)-vertices, then a path tuple from \(\mathbf{A}\) to \(\mathbf{B}\) means a \(k\)-tuple \(\left( p_{1},p_{2},\ldots ,p_{k}\right) \), where each \(p_{i}\) is a path from \(A_{i}\) to \(B_{i}\).

(d) A path tuple \(\left( p_{1},p_{2},\ldots ,p_{k}\right) \) is said to be non-intersecting if no two of the paths \(p_{1},p_{2},\ldots ,p_{k}\) have any vertex in common. We abbreviate “non-intersecting path tuple” as nipat.

(e) A path tuple \(\left( p_{1},p_{2},\ldots ,p_{k}\right) \) is said to be intersecting if it is not non-intersecting (i.e., if two of its paths have a vertex in common). We abbreviate “intersecting path tuple” as ipat.

def LGV1.kVertex.permute {k : } (v : kVertex k) (σ : Equiv.Perm (Fin k)) :
structure LGV1.PathTuple (k : ) (A B : kVertex k) :
def LGV1.PathTuple.isNonIntersecting {k : } {A B : kVertex k} (pt : PathTuple k A B) :

5.4.5 Helpers for path tuple finiteness

Lemma 5.131

For any two \(k\)-vertices \(\mathbf{A}\), \(\mathbf{B}\), the set of path tuples from \(\mathbf{A}\) to \(\mathbf{B}\) is finite.

Proof

The set of path tuples embeds injectively into the product \(\prod _{i=1}^k \{ \text{paths from } A_i \text{ to } B_i\} \), which is finite by Lemma 5.126.

Lemma 5.132

For any two \(k\)-vertices \(\mathbf{A}\), \(\mathbf{B}\), the set of nipats from \(\mathbf{A}\) to \(\mathbf{B}\) is finite.

Proof

Subset of the finite set of all path tuples (Lemma 5.131).

Lemma 5.133

For any two \(k\)-vertices \(\mathbf{A}\), \(\mathbf{B}\), the set of ipats from \(\mathbf{A}\) to \(\mathbf{B}\) is finite.

Proof

Subset of the finite set of all path tuples (Lemma 5.131).

5.4.6 Crowded vertices and the minimum crowded path index

Definition 5.134
#

Let \(\mathbf{p} = (p_1, \ldots , p_k)\) be a path tuple.

(a) A vertex \(v\) is crowded in \(\mathbf{p}\) if \(v\) lies on at least two distinct paths \(p_i, p_j\) with \(i \ne j\).

(b) The crowded path indices of \(\mathbf{p}\) is the set of indices \(i\) such that \(p_i\) contains a vertex shared with some other path \(p_j\).

(c) For an ipat \(\mathbf{p}\), the minimum crowded path index is the smallest \(i\) in the crowded path indices.

(d) The crowded vertices on path \(i\) is the set of vertices on \(p_i\) that also appear on some other path.

def LGV1.PathTuple.isCrowded {k : } {A B : kVertex k} (pt : PathTuple k A B) (v : LatticePoint) :
noncomputable def LGV1.PathTuple.crowdedPathIndices {k : } {A B : kVertex k} (pt : PathTuple k A B) :
noncomputable def LGV1.PathTuple.minCrowdedPathIndex {k : } {A B : kVertex k} (pt : PathTuple k A B) (hip : pt.isIntersecting) :
Fin k
Lemma 5.135

A path tuple is intersecting if and only if it has at least one crowded vertex. Equivalently, a path tuple is intersecting if and only if its set of crowded path indices is nonempty.

Proof

Immediate from the definitions: the negation of “all pairs of paths are disjoint” is equivalent to the existence of a shared vertex.

5.4.7 The LGV lemma for two paths

Signed path tuple infrastructure

Definition 5.136
#

Given four lattice points \(A, A', B, B'\):

(a) A signed path tuple is a pair of paths \((p_0, p_1)\) together with a sign flag indicating whether the destinations are \((B, B')\) (sign \(+1\)) or \((B', B)\) (sign \(-1\)).

(b) The path count matrix is the \(2 \times 2\) integer matrix with entries \(\# \mathrm{paths}(A_i \to B_j)\).

(c) The number of nipats from \((A, A')\) to \((B, B')\).

structure LGV1.SignedPathTuple2 (A A' B B' : LatticePoint) :
def LGV1.SignedPathTuple2.sign {A A' B B' : LatticePoint} (spt : SignedPathTuple2 A A' B B') :
def LGV1.pathMatrix2 (A A' B B' : LatticePoint) :
Matrix (Fin 2) (Fin 2)
noncomputable def LGV1.numNipats2 (A A' B B' : LatticePoint) :
Lemma 5.137

The sets of signed path tuples (all, non-intersecting, and intersecting) are finite.

Proof

The signed path tuples inject into the product of two finite path sets times a two-element set. All three subsets are finite as subsets of this finite set.

First intersection point

Lemma 5.138

Given an intersecting signed path tuple \((p_0, p_1)\), the first intersection index is the smallest index \(i\) such that the \(i\)-th vertex of \(p_0\) belongs to the vertices of \(p_1\). This index is strictly less than the number of vertices of \(p_0\).

noncomputable def LGV1.firstIntersectionIdx {A A' B B' : LatticePoint} (spt : SignedPathTuple2 A A' B B') (_h : spt.isIntersecting) :
Proof

The existence of a shared vertex guarantees that a valid index is found before the end of the vertex list.

Lemma 5.139

The first intersection point \(v\) of an intersecting signed path tuple \((p_0, p_1)\) satisfies:

  1. \(v\) lies on \(p_0\) (at the first intersection index).

  2. \(v\) lies on \(p_1\).

  3. \(v\) is first: no vertex of \(p_0\) at an earlier index belongs to \(p_1\).

theorem LGV1.firstIntersection_is_first {A A' B B' : LatticePoint} (spt : SignedPathTuple2 A A' B B') (h : spt.isIntersecting) :
have v := firstIntersection spt h; let idx := firstIntersectionIdx spt h; (spt.path0.vertices A)[idx] = v ∀ (i : ) (hi : i < idx), (spt.path0.vertices A)[i]spt.path1.vertices A'
Proof

Property (1) is by definition. Property (2) follows from the search semantics: the predicate tested is membership in \(p_1\)’s vertices. Property (3) follows from the minimality of the search: all earlier indices fail the predicate.

Lemma 5.140

Splitting a path at a vertex \(v\) (by taking the first steps up to the index of \(v\) and the remaining steps after) produces a head ending at \(v\) and a tail starting at \(v\).

noncomputable def LGV1.splitPathAt (path : LatticePath) (start v : LatticePoint) (_hv : v path.vertices start) :
  • One or more equations did not get rendered due to their size.
Proof

By Lemma 5.122, taking \(n\) steps gives a path from \(A\) to the intermediate point, and dropping \(n\) steps gives a path from that point to \(B\). The key fact is that the vertex at the split position equals \(v\), so the intermediate point is \(v\).

Lemma 5.141

After applying the ipat involution (exchanging tails at the first intersection point \(v\)), the first intersection point of the resulting path tuple is still \(v\).

This is the key technical lemma for proving the involution is involutive. It relies on:

  • The prefix of \(p_0\) up to the split index is unchanged.

  • \(v\) is at the same index in the new path.

  • No earlier vertex of \(p_0\) lies in \(p_1\)’s vertices (by minimality).

  • Vertices at distinct positions on a lattice path are distinct (because the coordinate sum strictly increases).

Proof

The new path \(q_0 = \mathrm{head}(p_0) \cdot \mathrm{tail}(p_1)\) shares the same prefix as \(p_0\) up to the split index. The value \(v\) at this index is preserved. For \(j\) less than the split index, the \(j\)-th vertex of \(q_0\) equals the \(j\)-th vertex of \(p_0\), which is not among the new \(p_1\)’s vertices (the head of old \(p_1\) is a subset of old \(p_1\)’s vertices, and the tail of old \(p_0\) cannot contain an earlier vertex because coordinate sums strictly increase). Thus the search on \(q_0\) returns the same index.

Lemma 5.142

The sign-reversing involution on intersecting path tuples for \(k = 2\).

Given an intersecting path tuple \((p, p')\) in the set \(\mathcal{X}\) of ipats from \((A, A')\) to \((B, B')\) or to \((B', B)\):

  1. Since \((p, p') \in \mathcal{X}\), the paths \(p\) and \(p'\) have a vertex in common. Let \(v\) be the first one. (The first one on \(p\) or the first one on \(p'\)? These are the same, since our digraph is acyclic.) We call this vertex \(v\) the first intersection of \((p, p')\).

  2. Split each path at \(v\) into a head (before \(v\)) and a tail (after \(v\)).

  3. Exchange the tails: \(q = (\text{head of } p) \cup (\text{tail of } p')\) and \(q' = (\text{head of } p') \cup (\text{tail of } p)\).

  4. Define \(f(p, p') = (q, q')\).

Then \(f\) is a sign-reversing involution on \(\mathcal{X}\) with no fixed points.

noncomputable def LGV1.ipatInvolution {A A' B B' : LatticePoint} (spt : SignedPathTuple2 A A' B B') (h : spt.isIntersecting) :
  • One or more equations did not get rendered due to their size.
theorem LGV1.ipatInvolution_sign {A A' B B' : LatticePoint} (spt : SignedPathTuple2 A A' B B') (h : spt.isIntersecting) :
theorem LGV1.ipatInvolution_involutive {A A' B B' : LatticePoint} (spt : SignedPathTuple2 A A' B B') (h : spt.isIntersecting) :
have spt' := ipatInvolution spt h; ∃ (h' : spt'.isIntersecting), ipatInvolution spt' h' = spt
noncomputable def LGV1.splitPathAt (path : LatticePath) (start v : LatticePoint) (_hv : v path.vertices start) :
  • One or more equations did not get rendered due to their size.
Proof

If \((p, p')\) is an ipat from \((A, A')\) to \((B, B')\), then \(f(p, p') = (q, q')\) is an ipat from \((A, A')\) to \((B', B)\) (exchanging tails swaps the endpoints), and vice versa. Thus \(f\) is well-defined and sign-reversing.

To show \(f \circ f = \operatorname {id}\): after exchanging tails, the heads are unchanged, so \(v\) is still the first intersection point (Lemma 5.141). Exchanging tails again undoes the swap.

Since \(f\) is sign-reversing, it has no fixed points.

Lemma 5.143

For any four lattice points \(A, A', B, B'\),

\[ \sum _{(p,p') \in \mathcal{X}} \operatorname {sign}(p, p') = 0, \]

where \(\mathcal{X}\) is the set of intersecting path tuples and the sign is \(+1\) for path tuples to \((B, B')\) and \(-1\) for path tuples to \((B', B)\).

theorem LGV1.sum_signedIpats2_eq_zero (A A' B B' : LatticePoint) (hfin : (signedIpats2 A A' B B').Finite) :
spthfin.toFinset, spt.sign = 0
Proof

By Lemma 4.10 applied to the sign-reversing involution of Lemma 5.142.

Lemma 5.144

The sum over all signed path tuples decomposes as:

\begin{align*} & \bigl(\text{\# of path tuples from } (A,A’) \text{ to } (B,B’)\bigr) - \bigl(\text{\# of path tuples from } (A,A’) \text{ to } (B’,B)\bigr) \\ & = \sum _{(p,p') \in \mathcal{A}} \operatorname {sign}(p,p’), \end{align*}

and the sum over nipats gives:

\begin{align*} \sum _{(p,p') \in \mathcal{A} \setminus \mathcal{X}} \operatorname {sign}(p,p’) & = \bigl(\text{\# of nipats from } (A,A’) \text{ to } (B,B’)\bigr) \\ & \quad - \bigl(\text{\# of nipats from } (A,A’) \text{ to } (B’,B)\bigr). \end{align*}
theorem LGV1.sum_signedPathTuples2 (A A' B B' : LatticePoint) (hfin : (signedPathTuples2 A A' B B').Finite) :
spthfin.toFinset, spt.sign = (numPaths A B) * (numPaths A' B') - (numPaths A B') * (numPaths A' B)
theorem LGV1.sum_signedNipats2 (A A' B B' : LatticePoint) (hfin : (signedNipats2 A A' B B').Finite) :
spthfin.toFinset, spt.sign = (numNipats2 A A' B B') - (numNipats2 A A' B' B)
Proof

The first identity follows from the product rule: the product of path counts equals the count of path tuples.

The second identity is immediate from the definitions: among the nipats, those going to \((B,B')\) contribute \(+1\) each and those going to \((B',B)\) contribute \(-1\) each.

Proposition 5.145 LGV lemma for two paths

Let \(\left( A,A^{\prime }\right) \) and \(\left( B,B^{\prime }\right) \) be two \(2\)-vertices (i.e., let \(A,A^{\prime },B,B^{\prime }\) be four lattice points). Then,

\begin{align*} & \det \left( \begin{array}[c]{cc}\left( \text{\# of paths from }A\text{ to }B\right) & \left( \text{\# of paths from }A\text{ to }B^{\prime }\right) \\ \left( \text{\# of paths from }A^{\prime }\text{ to }B\right) & \left( \text{\# of paths from }A^{\prime }\text{ to }B^{\prime }\right) \end{array} \right) \\ & =\left( \text{\# of nipats from }\left( A,A^{\prime }\right) \text{ to }\left( B,B^{\prime }\right) \right) \\ & \ \ \ \ \ \ \ \ \ \ -\left( \text{\# of nipats from }\left( A,A^{\prime }\right) \text{ to }\left( B^{\prime },B\right) \right) . \end{align*}
theorem LGV1.lgv_two_paths (A A' B B' : LatticePoint) :
(pathMatrix2 A A' B B').det = (numNipats2 A A' B B') - (numNipats2 A A' B' B)
Proof

We have

\begin{align*} & \det \left( \begin{array}[c]{cc}\left( \text{\# of paths from }A\text{ to }B\right) & \left( \text{\# of paths from }A\text{ to }B^{\prime }\right) \\ \left( \text{\# of paths from }A^{\prime }\text{ to }B\right) & \left( \text{\# of paths from }A^{\prime }\text{ to }B^{\prime }\right) \end{array} \right) \\ & =\left( \text{\# of path tuples from }\left( A,A^{\prime }\right) \text{ to }\left( B,B^{\prime }\right) \right) \\ & \ \ \ \ \ \ \ \ \ \ -\left( \text{\# of path tuples from }\left( A,A^{\prime }\right) \text{ to }\left( B^{\prime },B\right) \right) \end{align*}

(by the product rule). By Lemma 5.144, the right hand side equals \(\sum _{(p,p') \in \mathcal{A}} \operatorname {sign}(p,p')\).

By Lemma 4.10, using the sign-reversing involution of Lemma 5.142 (which uses Lemma 5.143), we obtain

\[ \sum _{\left( p,p^{\prime }\right) \in \mathcal{A}}\operatorname {sign}\left( p,p^{\prime }\right) =\sum _{\left( p,p^{\prime }\right) \in \mathcal{A}\setminus \mathcal{X}}\operatorname {sign}\left( p,p^{\prime }\right). \]

The right hand side equals

\begin{align*} & \left( \text{\# of nipats from }\left( A,A^{\prime }\right) \text{ to }\left( B,B^{\prime }\right) \right) \\ & \ \ \ \ \ \ \ \ \ \ -\left( \text{\# of nipats from }\left( A,A^{\prime }\right) \text{ to }\left( B^{\prime },B\right) \right) \end{align*}

by Lemma 5.144.

5.4.8 The baby Jordan curve theorem

Proposition 5.146 baby Jordan curve theorem

Let \(A\), \(B\), \(A^{\prime }\) and \(B^{\prime }\) be four lattice points satisfying

\begin{align*} \operatorname {x}\left( A^{\prime }\right) & \leq \operatorname {x}\left( A\right) ,\ \ \ \ \ \ \ \ \ \ \operatorname {y}\left( A^{\prime }\right) \geq \operatorname {y}\left( A\right) ,\\ \operatorname {x}\left( B^{\prime }\right) & \leq \operatorname {x}\left( B\right) ,\ \ \ \ \ \ \ \ \ \ \operatorname {y}\left( B^{\prime }\right) \geq \operatorname {y}\left( B\right) . \end{align*}

(That is, \(A'\) is weakly northwest of \(A\), and \(B'\) is weakly northwest of \(B\).)

Let \(p\) be any path from \(A\) to \(B^{\prime }\). Let \(p^{\prime }\) be any path from \(A^{\prime }\) to \(B\). Then, \(p\) and \(p^{\prime }\) have a vertex in common.

In particular, there are no nipats from \((A, A')\) to \((B', B)\).

theorem LGV1.baby_jordan_curve (A A' B B' : LatticePoint) (hA : isWeaklyNorthwestOf A' A) (hB : isWeaklyNorthwestOf B' B) (p p' : LatticePath) (hp : p.isPathFromTo A B') (hp' : p'.isPathFromTo A' B) :
vp.vertices A, v p'.vertices A'
theorem LGV1.no_nipats_under_nw (A A' B B' : LatticePoint) (hA : isWeaklyNorthwestOf A' A) (hB : isWeaklyNorthwestOf B' B) :
numNipats2 A A' B' B = 0
Proof

The proof is by strong induction on \(\ell (p) + \ell (p')\), the sum of path lengths.

Case 3 (\(A' = A\)): Then \(A\) is a common vertex of both paths and we are done.

Case 1 (\(\operatorname {y}(A') {\gt} \operatorname {y}(A)\)): Let \(P\) be the second vertex of \(p\). Every vertex of the subpath \(r\) from \(P\) to \(B'\) is a vertex of \(p\), so \(r\) and \(p'\) have no vertex in common. Also \(\ell (r) + \ell (p') {\lt} \ell (p) + \ell (p')\). If \(\operatorname {y}(A') \ge \operatorname {y}(P)\), then we could apply the induction hypothesis to \(r\) and \(p'\), contradicting \(r \cap p' = \emptyset \). Hence \(\operatorname {y}(A') {\lt} \operatorname {y}(P)\), so \(\operatorname {y}(A') \le \operatorname {y}(P) - 1\). If the arc from \(A\) to \(P\) were an east-step, we would have \(\operatorname {y}(P) = \operatorname {y}(A)\), contradicting \(\operatorname {y}(A) \le \operatorname {y}(A') {\lt} \operatorname {y}(P)\). So the arc is a north-step, giving \(\operatorname {y}(P) = \operatorname {y}(A) + 1\), hence \(\operatorname {y}(A') \le \operatorname {y}(A)\), contradicting \(\operatorname {y}(A') {\gt} \operatorname {y}(A)\).

Case 2 (\(\operatorname {x}(A') {\lt} \operatorname {x}(A)\)): Symmetric to Case 1, looking at the first step of \(p'\) and using reflection across the line \(x = y\).

The consequence that there are no nipats from \((A, A')\) to \((B', B)\) follows immediately: if any pair of paths (one from \(A\) to \(B'\), one from \(A'\) to \(B\)) must intersect, then there can be no nipats from \((A, A')\) to \((B', B)\).

5.4.9 Log-concavity of binomial coefficients

Corollary 5.147

Let \(n,k\in \mathbb {N}\). Then, \(\binom {n}{k}^{2}\geq \binom {n}{k-1}\cdot \binom {n}{k+1}\).

theorem LGV1.binom_log_concave (n k : ) (hk : 1 k) :
n.choose k * n.choose k n.choose (k - 1) * n.choose (k + 1)
Proof

Combinatorial proof (from the source text, using LGV): Define four lattice points \(A=\left( 1,0\right) \) and \(A^{\prime }=\left( 0,1\right) \) and \(B=\left( k+1,n-k\right) \) and \(B^{\prime }=\left( k,n-k+1\right) \). Then, Proposition 5.145 yields

\begin{align*} & \det \left( \begin{array}[c]{cc}\left( \text{\# of paths from }A\text{ to }B\right) & \left( \text{\# of paths from }A\text{ to }B^{\prime }\right) \\ \left( \text{\# of paths from }A^{\prime }\text{ to }B\right) & \left( \text{\# of paths from }A^{\prime }\text{ to }B^{\prime }\right) \end{array} \right) \\ & =\left( \text{\# of nipats from }\left( A,A^{\prime }\right) \text{ to }\left( B,B^{\prime }\right) \right) -\underbrace{\left( \text{\# of nipats from }\left( A,A^{\prime }\right) \text{ to }\left( B^{\prime },B\right) \right) }_{=0}\\ & =\left( \text{\# of nipats from }\left( A,A^{\prime }\right) \text{ to }\left( B,B^{\prime }\right) \right) \geq 0. \end{align*}

(Here, the second term is \(0\) by Proposition 5.146.) However, Proposition 5.129 yields

\[ \left( \begin{array}[c]{cc}\left( \text{\# of paths from }A\text{ to }B\right) & \left( \text{\# of paths from }A\text{ to }B^{\prime }\right) \\ \left( \text{\# of paths from }A^{\prime }\text{ to }B\right) & \left( \text{\# of paths from }A^{\prime }\text{ to }B^{\prime }\right) \end{array} \right) =\left( \begin{array}[c]{cc}\binom {n}{k} & \binom {n}{k-1}\\ \binom {n}{k+1} & \binom {n}{k}\end{array} \right), \]

so the determinant is \(\binom {n}{k}^{2}-\binom {n}{k-1}\cdot \binom {n}{k+1}\geq 0\).

Lean formalization (algebraic proof): The Lean proof avoids the LGV machinery and proceeds purely algebraically, using the recurrences

\begin{align*} \binom {n}{k+1}(k+1) & = \binom {n}{k}(n-k), \\ \binom {n}{k} \cdot k & = \binom {n}{k-1}(n-k+1). \end{align*}

These allow rewriting both sides after multiplying by \(k(k+1) {\gt} 0\). The inequality reduces to \((n-k+1)(k+1) \ge (n-k) \cdot k\), which holds because the difference is \(n + 1 \ge 0\). This proof is complete.

5.4.10 The LGV lemma for \(k\) paths

Definitions for general \(k\)

Definition 5.148
#

Let \(k \in \mathbb {N}\) and let \(\mathbf{A}, \mathbf{B}\) be two \(k\)-vertices.

(a) The path count matrix \(M\) is the \(k \times k\) integer matrix with entries \(M_{i,j} = \# \mathrm{paths}(A_i \to B_j)\).

(b) For \(\sigma \in S_k\), the number of nipats from \(\mathbf{A}\) to \(\sigma (\mathbf{B})\).

(c) For \(\sigma \in S_k\), the number of ipats from \(\mathbf{A}\) to \(\sigma (\mathbf{B})\).

def LGV1.pathMatrixK {k : } (A B : kVertex k) :
Matrix (Fin k) (Fin k)
noncomputable def LGV1.numNipatsK {k : } (A B : kVertex k) (σ : Equiv.Perm (Fin k)) :
noncomputable def LGV1.numIpatsK {k : } (A B : kVertex k) (σ : Equiv.Perm (Fin k)) :

Bridge between LGV1 and LGV2

Lemma 5.149

The lattice step types in LGV1 and LGV2 are equivalent: the two representations of lattice steps are isomorphic, and this equivalence preserves the step application function. Lattice paths can be converted between representations, preserving endpoints and vertices.

Proof

Both types are two-element enumerations with the same constructors. The equivalence and endpoint preservation follow by case analysis.

Lemma 5.150

The ipat count (defined via one representation of path tuples) equals the cardinality of the ipat set (defined via the other representation). This is the key bridge that allows the proof to invoke the sign-reversing involution from the weighted LGV formalization.

Proof

The proof constructs an equivalence between the two representations of intersecting path tuples, converting between list-of-steps and list-of-vertices representations, then verifies that the intersection property is preserved at each step.

Product rule and partition lemmas

Lemma 5.151

Let \(k \in \mathbb {N}\) and let \(\mathbf{A}, \mathbf{B}\) be two \(k\)-vertices. Then:

(a) (Product rule) For any \(\sigma \in S_k\),

\[ \prod _{i=1}^k \bigl(\text{\# of paths from } A_i \text{ to } B_{\sigma (i)}\bigr) = \bigl(\text{\# of path tuples from } \mathbf{A} \text{ to } \sigma (\mathbf{B})\bigr). \]

(b) (Partition) Each path tuple is either a nipat or an ipat, so

\[ \bigl(\text{\# of path tuples}\bigr) = \bigl(\text{\# of nipats}\bigr) + \bigl(\text{\# of ipats}\bigr). \]

(c) (Determinant expansion)

\[ \det \bigl(\bigl(\text{\# of paths from } A_i \text{ to } B_j\bigr)_{1 \le i,j \le k}\bigr) = \sum _{\sigma \in S_k} (-1)^\sigma \prod _{i=1}^k \bigl(\text{\# of paths from } A_i \text{ to } B_{\sigma (i)}\bigr). \]
Proof

(a) A path tuple from \(\mathbf{A}\) to \(\sigma (\mathbf{B})\) is just a tuple of independent choices (one path per index), so by the product rule the count is the product.

(b) Every path tuple is intersecting or not (classical logic); the sets are disjoint and their union is the set of all path tuples.

(c) This is the Leibniz formula \(\det (M) = \sum _\sigma (-1)^\sigma \prod _i M_{i,\sigma (i)}\).

Lemma 5.152

The ipat cancellation lemma for general \(k\):

\[ \sum _{\sigma \in S_k} (-1)^\sigma \cdot \bigl(\text{\# of ipats from } \mathbf{A} \text{ to } \sigma (\mathbf{B})\bigr) = 0. \]

This is proved by a sign-reversing involution on pairs \((\sigma , \mathbf{p})\) where \(\mathbf{p}\) is an ipat from \(\mathbf{A}\) to \(\sigma (\mathbf{B})\). The involution:

  1. A point \(u\) is crowded if it is contained in at least two of the paths \(p_1, p_2, \ldots , p_k\).

  2. Pick the smallest \(i \in [k]\) such that \(p_i\) contains a crowded point.

  3. Let \(v\) be the first crowded point on \(p_i\).

  4. Let \(j {\gt} i\) be the largest index such that \(v \in p_j\).

  5. Exchange the tails of \(p_i\) and \(p_j\) at \(v\).

  6. Replace \(\sigma \) by \(\sigma \cdot t_{i,j}\) (composing with the transposition swapping \(i\) and \(j\)), which flips the sign (by Proposition 3.110 (b) and (d)).

The map \(f : (\sigma , \mathbf{p}) \mapsto (\sigma ', \mathbf{q})\) is an involution because the heads of \(p_i\) and \(p_j\) are unchanged, so the same \(v\), \(i\), \(j\) are selected again.

Proof

The proof uses:

  • The partition of path tuples (Lemma 5.151).

  • The sign-reversing involution described above.

  • Lemma 4.10 to cancel the signed sum of ipats.

  • The bridge Lemma 5.150 to invoke the sign-reversing involution from the weighted LGV formalization.

Proposition 5.153 LGV lemma, lattice counting version

Let \(k\in \mathbb {N}\). Let \(\mathbf{A}=\left( A_{1},A_{2},\ldots ,A_{k}\right) \) and \(\mathbf{B}=\left( B_{1},B_{2},\ldots ,B_{k}\right) \) be two \(k\)-vertices. Then,

\begin{align*} & \det \left( \left( \text{\# of paths from }A_{i}\text{ to }B_{j}\right) _{1\leq i\leq k,\ 1\leq j\leq k}\right) \\ & =\sum _{\sigma \in S_{k}}\left( -1\right) ^{\sigma }\left( \text{\# of nipats from }\mathbf{A}\text{ to }\sigma \left( \mathbf{B}\right) \right) . \end{align*}
theorem LGV1.lgv_k_paths {k : } (A B : kVertex k) :
(pathMatrixK A B).det = σ : Equiv.Perm (Fin k), (Equiv.Perm.sign σ) * (numNipatsK A B σ)
Proof

Define \(\mathcal{A}:=\left\{ \left( \sigma ,\mathbf{p}\right) \ \mid \ \sigma \in S_{k}\text{, and}\ \mathbf{p}\text{ is a path tuple from }\mathbf{A}\text{ to }\sigma \left( \mathbf{B}\right) \right\} \) and \(\mathcal{X}:=\left\{ \left( \sigma ,\mathbf{p}\right) \in \mathcal{A}\ \mid \ \mathbf{p}\text{ is intersecting}\right\} \). Set \(\operatorname {sign}\left( \sigma ,\mathbf{p}\right) :=\left( -1\right) ^{\sigma }\).

By Lemma 4.10 applied to the sign-reversing involution of Lemma 5.152,

\[ \sum _{\left( \sigma ,\mathbf{p}\right) \in \mathcal{A}}\left( -1\right) ^{\sigma }=\sum _{\left( \sigma ,\mathbf{p}\right) \in \mathcal{A}\setminus \mathcal{X}}\left( -1\right) ^{\sigma }. \]

The left hand side equals

\begin{align*} \sum _{\sigma \in S_{k}}\left( -1\right) ^{\sigma }\prod _{i=1}^{k}\left( \text{\# of paths from }A_{i}\text{ to }B_{\sigma \left( i\right) }\right) & =\det \left( \left( \text{\# of paths from }A_{i}\text{ to }B_{j}\right) _{1\leq i\leq k,\ 1\leq j\leq k}\right) \end{align*}

(by Lemma 5.151(a) and the definition of the determinant), and the right hand side equals

\[ \sum _{\sigma \in S_{k}}\left( -1\right) ^{\sigma }\left( \text{\# of nipats from }\mathbf{A}\text{ to }\sigma \left( \mathbf{B}\right) \right). \]