Pairwise sequence alignment
AbbreviationAlignment#✓fully proved
An alignment over an alphabet \(\alpha\) is a finite list of columns, where each column is a pair \((u, v)\) and each of \(u\) and \(v\) is either a letter of \(\alpha\) or a gap.
Whether an alignment is valid for two given sequences is a separate condition.
Used by 80
DefinitionValid alignment of two sequences#✓fully proved
A list \(A\) of columns, each a pair of optional letters, is an alignment of sequences \(x\) and \(y\) when no column has both entries empty, the letters present in the first entries of the columns, read in order, form \(x\), and the letters present in the second entries, read in order, form \(y\).
def IsAlignment (A : Alignment α) (xs ys : List α) : Prop :=
(∀ c ∈ A, c ≠ (none, none)) ∧ A.filterMap Prod.fst = xs ∧ A.filterMap Prod.snd = ys
abbrev Alignment (α : Type*) := List (Option α × Option α)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:69
Uses 1 · Used by 44
DefinitionScore of an alignment column#✓fully proved
Given a substitution score \(\sigma\), which assigns an integer \(\sigma(a, b)\) to all letters \(a, b \in \alpha\), and a gap score \(g \in \mathbb{Z}\), a column pairing letters \(a\) and \(b\) scores \(\sigma(a, b)\), a column pairing a letter with a gap (on either side) scores \(g\), and a column with a gap on both sides scores \(0\).
def columnScore (σ : α → α → ℤ) (gap : ℤ) : Option α × Option α → ℤ
| (some a, some b) => σ a b
| (some _, none) => gap
| (none, some _) => gap
| (none, none) => 0
Used by 20
DefinitionScore of an alignment#✓fully proved
Given a substitution score \(\sigma\), which assigns an integer \(\sigma(a, b)\) to all letters \(a, b \in \alpha\), and a gap score \(g \in \mathbb{Z}\), the score of an alignment \(A\) over \(\alpha\) is the sum, over all columns of \(A\), of the score of the column with respect to \(\sigma\) and \(g\).
def alignmentScore (σ : α → α → ℤ) (gap : ℤ) (A : Alignment α) : ℤ :=
(A.map (columnScore σ gap)).sum
abbrev Alignment (α : Type*) := List (Option α × Option α)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:69
def columnScore (σ : α → α → ℤ) (gap : ℤ) : Option α × Option α → ℤ
| (some a, some b) => σ a b
| (some _, none) => gap
| (none, some _) => gap
| (none, none) => 0
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:77
Uses 2 · Used by 31
TheoremConcatenation of alignments#✓fully proved
If \(A_1\) is an alignment of sequences \(x_1\) and \(y_1\), and \(A_2\) is an alignment of sequences \(x_2\) and \(y_2\), then the concatenation of \(A_1\) and \(A_2\) is an alignment of the concatenation of \(x_1\) and \(x_2\) and the concatenation of \(y_1\) and \(y_2\).
theorem isAlignment_append {A1 A2 : Alignment α} {xs1 ys1 xs2 ys2 : List α}
(h1 : IsAlignment A1 xs1 ys1) (h2 : IsAlignment A2 xs2 ys2) :
IsAlignment (A1 ++ A2) (xs1 ++ xs2) (ys1 ++ ys2)
abbrev Alignment (α : Type*) := List (Option α × Option α)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:69
def IsAlignment (A : Alignment α) (xs ys : List α) : Prop :=
(∀ c ∈ A, c ≠ (none, none)) ∧ A.filterMap Prod.fst = xs ∧ A.filterMap Prod.snd = ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:73
DefinitionFuel-bounded Needleman–Wunsch recursion#✓fully proved
Fix a substitution score \(\sigma : \alpha \to \alpha \to \mathbb{Z}\) and a gap score \(g \in \mathbb{Z}\), and write \(|x|\) for the length of a sequence \(x\) and \(ax\) for the sequence with first element \(a\) followed by \(x\). For a fuel \(n \in \mathbb{N}\) and sequences \(x, y\) over \(\alpha\), the value \(N_n(x, y) \in \mathbb{Z}\) is defined by \(N_0(x, y) = 0\), by \(N_{n+1}(x, y) = g\,|y|\) if \(x\) is empty and \(N_{n+1}(x, y) = g\,|x|\) if \(y\) is empty, and by
The Needleman–Wunsch score of \(x\) and \(y\) is \(N_{|x|+|y|}(x, y)\); this fuel suffices because every recursive call shortens the pair. This is an exponential-time specification, not a memoized table.
def nwScoreAux : ℕ → List α → List α → ℤ
| 0, _, _ => 0
| _ + 1, [], [] => 0
| _ + 1, [], b :: ys => gap * ((b :: ys).length : ℤ)
| _ + 1, a :: xs, [] => gap * ((a :: xs).length : ℤ)
| n + 1, a :: xs, b :: ys =>
max (max (nwScoreAux n xs ys + σ a b) (nwScoreAux n xs (b :: ys) + gap))
(nwScoreAux n (a :: xs) ys + gap)
DefinitionNeedleman–Wunsch score#✓fully proved
Given a type \(\alpha\), a substitution score \(\sigma : \alpha \to \alpha \to \mathbb{Z}\) and a gap score \(g \in \mathbb{Z}\), the Needleman–Wunsch score \(\mathrm{NW}(xs, ys)\) of two lists over \(\alpha\) is defined by recursion on their total length: if one of the lists is empty, it is \(g\) times the length of the other; and for lists \(a\,xs\) and \(b\,ys\) with heads \(a\), \(b\) and tails \(xs\), \(ys\),
By the Needleman–Wunsch optimality theorem, this is the optimal global alignment score of the two lists.
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
def nwScoreAux : ℕ → List α → List α → ℤ
| 0, _, _ => 0
| _ + 1, [], [] => 0
| _ + 1, [], b :: ys => gap * ((b :: ys).length : ℤ)
| _ + 1, a :: xs, [] => gap * ((a :: xs).length : ℤ)
| n + 1, a :: xs, b :: ys =>
max (max (nwScoreAux n xs ys + σ a b) (nwScoreAux n xs (b :: ys) + gap))
(nwScoreAux n (a :: xs) ys + gap)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:118
Uses 1 · Used by 56
TheoremAligning the empty sequence with a sequence#✓fully proved
For every substitution score \(\sigma : \alpha \to \alpha \to \mathbb{Z}\), gap score \(g \in \mathbb{Z}\) and sequence \(y\) over \(\alpha\) of length \(|y|\), the Needleman–Wunsch score of the empty sequence and \(y\) with respect to \(\sigma\) and \(g\) is \(g\,|y|\): one gap per letter.
theorem nwScore_nil_left (ys : List α) : nwScore σ gap [] ys = gap * ys.length
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
Uses 2 · Used by 9
TheoremAligning a sequence with the empty sequence#✓fully proved
For every substitution score \(\sigma : \alpha \to \alpha \to \mathbb{Z}\), gap score \(g \in \mathbb{Z}\) and sequence \(x\) over \(\alpha\) of length \(|x|\), the Needleman–Wunsch score of \(x\) and the empty sequence with respect to \(\sigma\) and \(g\) is \(g\,|x|\): one gap per letter.
theorem nwScore_nil_right (xs : List α) : nwScore σ gap xs [] = gap * xs.length
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
Uses 2 · Used by 6
TheoremThe Needleman–Wunsch recurrence#✓fully proved
Let \(\sigma : \alpha \to \alpha \to \mathbb{Z}\) be a substitution score and \(g \in \mathbb{Z}\) a gap score, and write \(N(x, y)\) for the Needleman–Wunsch score of sequences \(x, y\) over \(\alpha\) with respect to \(\sigma\) and \(g\). For all letters \(a, b \in \alpha\) and sequences \(x, y\), writing \(ax\) for the sequence with first element \(a\) followed by \(x\),
theorem nwScore_eq (a b : α) (xs ys : List α) :
nwScore σ gap (a :: xs) (b :: ys) =
max (max (nwScore σ gap xs ys + σ a b) (nwScore σ gap xs (b :: ys) + gap))
(nwScore σ gap (a :: xs) ys + gap)
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
Uses 2 · Used by 4
DefinitionFuel-bounded enumeration of alignments#✓fully proved
Given a fuel \(n \in \mathbb{N}\) and sequences \(x\) and \(y\) over \(\alpha\), this lists alignments column by column from the front. With fuel \(0\) the list is empty. With fuel \(n + 1\): two empty sequences give the single empty alignment; if only \(y\) is nonempty, with first letter \(b\) and rest \(y'\), each alignment of \(x\) and \(y'\) with fuel \(n\) is preceded by the column pairing a gap with \(b\); if only \(x\) is nonempty, with first letter \(a\) and rest \(x'\), each alignment of \(x'\) and \(y\) with fuel \(n\) is preceded by the column pairing \(a\) with a gap; and if both are nonempty, \(x\) with first letter \(a\) and rest \(x'\) and \(y\) with first letter \(b\) and rest \(y'\), the list consists of the alignments of \(x'\) and \(y'\) preceded by the column \((a, b)\), then those of \(x'\) and \(y\) preceded by the column pairing \(a\) with a gap, then those of \(x\) and \(y'\) preceded by the column pairing a gap with \(b\), each computed with fuel \(n\).
With fuel at least \(|x| + |y| + 1\) the fuel never runs out before both sequences are used up; with less fuel some alignments are missing from the list.
def alignmentsAux : ℕ → List α → List α → List (Alignment α)
| 0, _, _ => []
| _ + 1, [], [] => [[]]
| n + 1, [], b :: ys => (alignmentsAux n [] ys).map fun A => (none, some b) :: A
| n + 1, a :: xs, [] => (alignmentsAux n xs []).map fun A => (some a, none) :: A
| n + 1, a :: xs, b :: ys =>
(alignmentsAux n xs ys).map (fun A => (some a, some b) :: A) ++
(alignmentsAux n xs (b :: ys)).map (fun A => (some a, none) :: A) ++
(alignmentsAux n (a :: xs) ys).map (fun A => (none, some b) :: A)
abbrev Alignment (α : Type*) := List (Option α × Option α)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:69
Uses 1 · Used by 3
DefinitionThe list of all alignments#✓fully proved
For sequences \(x\) and \(y\) over \(\alpha\), this is the list produced by the fuel-bounded enumeration of alignments of \(x\) and \(y\) with fuel \(|x| + |y| + 1\).
This fuel suffices: an alignment belongs to the list exactly when it is a valid alignment of \(x\) and \(y\).
def alignments (xs ys : List α) : List (Alignment α) :=
alignmentsAux (xs.length + ys.length + 1) xs ys
abbrev Alignment (α : Type*) := List (Option α × Option α)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:69
def alignmentsAux : ℕ → List α → List α → List (Alignment α)
| 0, _, _ => []
| _ + 1, [], [] => [[]]
| n + 1, [], b :: ys => (alignmentsAux n [] ys).map fun A => (none, some b) :: A
| n + 1, a :: xs, [] => (alignmentsAux n xs []).map fun A => (some a, none) :: A
| n + 1, a :: xs, b :: ys =>
(alignmentsAux n xs ys).map (fun A => (some a, some b) :: A) ++
(alignmentsAux n xs (b :: ys)).map (fun A => (some a, none) :: A) ++
(alignmentsAux n (a :: xs) ys).map (fun A => (none, some b) :: A)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:215
Uses 2 · Used by 10
TheoremThe enumerated alignments are exactly the valid ones#✓fully proved
For sequences \(x\) and \(y\) and a list \(A\) of columns, \(A\) occurs in the enumerated list of all alignments of \(x\) and \(y\) if and only if \(A\) is an alignment of \(x\) and \(y\).
theorem mem_alignments (xs ys : List α) (A : Alignment α) :
A ∈ alignments xs ys ↔ IsAlignment A xs ys
abbrev Alignment (α : Type*) := List (Option α × Option α)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:69
def alignments (xs ys : List α) : List (Alignment α) :=
alignmentsAux (xs.length + ys.length + 1) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:226
def IsAlignment (A : Alignment α) (xs ys : List α) : Prop :=
(∀ c ∈ A, c ≠ (none, none)) ∧ A.filterMap Prod.fst = xs ∧ A.filterMap Prod.snd = ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:73
Uses 4 · Used by 6
TheoremNeedleman–Wunsch is optimal#✓fully proved
Let \(\sigma : \alpha \to \alpha \to \mathbb{Z}\) be a substitution score and \(g \in \mathbb{Z}\) a gap score. For all sequences \(x\) and \(y\) over \(\alpha\) and every valid alignment \(A\) of \(x\) and \(y\), the score of \(A\) with respect to \(\sigma\) and \(g\) is at most the Needleman–Wunsch score of \(x\) and \(y\).
theorem alignmentScore_le_nwScore (xs ys : List α) (A : Alignment α)
(hA : IsAlignment A xs ys) :
alignmentScore σ gap A ≤ nwScore σ gap xs ys
abbrev Alignment (α : Type*) := List (Option α × Option α)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:69
def IsAlignment (A : Alignment α) (xs ys : List α) : Prop :=
(∀ c ∈ A, c ≠ (none, none)) ∧ A.filterMap Prod.fst = xs ∧ A.filterMap Prod.snd = ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:73
def alignmentScore (σ : α → α → ℤ) (gap : ℤ) (A : Alignment α) : ℤ :=
(A.map (columnScore σ gap)).sum
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:84
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
Uses 9 · Used by 12
TheoremNeedleman–Wunsch is attained#✓fully proved
Let \(\sigma : \alpha \to \alpha \to \mathbb{Z}\) be a substitution score and \(g \in \mathbb{Z}\) a gap score. For all sequences \(x\) and \(y\) over \(\alpha\) there is a valid alignment \(A\) of \(x\) and \(y\) whose score with respect to \(\sigma\) and \(g\) equals the Needleman–Wunsch score of \(x\) and \(y\).
theorem exists_alignmentScore_eq_nwScore (xs ys : List α) :
∃ A : Alignment α, IsAlignment A xs ys ∧ alignmentScore σ gap A = nwScore σ gap xs ys
abbrev Alignment (α : Type*) := List (Option α × Option α)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:69
def IsAlignment (A : Alignment α) (xs ys : List α) : Prop :=
(∀ c ∈ A, c ≠ (none, none)) ∧ A.filterMap Prod.fst = xs ∧ A.filterMap Prod.snd = ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:73
def alignmentScore (σ : α → α → ℤ) (gap : ℤ) (A : Alignment α) : ℤ :=
(A.map (columnScore σ gap)).sum
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:84
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
Uses 9 · Used by 11
DefinitionFuel-bounded Smith–Waterman recursion#✓fully proved
Fix a substitution score \(\sigma : \alpha \to \alpha \to \mathbb{Z}\) and a gap score \(g \in \mathbb{Z}\), and write \(ax\) for the sequence with first element \(a\) followed by \(x\). For a fuel \(n \in \mathbb{N}\) and sequences \(x, y\) over \(\alpha\), the value \(F_n(x, y) \in \mathbb{Z}\) is defined by \(F_0(x, y) = 0\), by \(F_{n+1}(x, y) = 0\) if \(x\) or \(y\) is empty, and by
This is an exponential-time specification, not a memoized table.
DefinitionThe terminal Smith–Waterman cell#✓fully proved
Given a substitution score \(\sigma(a, b) \in \mathbb{Z}\) for letters \(a, b\) and a gap score \(g \in \mathbb{Z}\), and writing \(sc\) for a sequence \(s\) followed by a letter \(c\), the terminal Smith–Waterman cell \(H(x, y)\) of two sequences \(x\) and \(y\) is the integer defined by \(H(x, y) = 0\) when \(x\) or \(y\) is empty, and
for all sequences \(x, y\) and letters \(a, b\). It is the entry \(H(|x|, |y|)\) of the Smith–Waterman dynamic-programming table.
For \(g \le 0\) it equals the maximum Needleman–Wunsch score over pairs of suffixes of \(x\) and \(y\); for \(g > 0\) it can be strictly smaller (for one-letter sequences with \(\sigma = -100\) and \(g = 1\) the cell is \(1\), while the alignment with two gap columns scores \(2\)). It is not the optimal local alignment score over all positions; that is the Smith–Waterman score, the maximum of this cell over all pairs of prefixes.
def swCellScore (xs ys : List α) : ℤ :=
swCellFront σ gap (xs.length + ys.length) xs.reverse ys.reverse
def swCellFront : ℕ → List α → List α → ℤ
| 0, _, _ => 0
| _ + 1, [], _ => 0
| _ + 1, _, [] => 0
| n + 1, a :: xs, b :: ys =>
max 0 (max (max (swCellFront n xs ys + σ a b) (swCellFront n xs (b :: ys) + gap))
(swCellFront n (a :: xs) ys + gap))
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:973
Uses 1 · Used by 14
TheoremThe terminal Smith–Waterman cell is nonnegative#✓fully proved
For every substitution score \(\sigma\), every gap score \(g\) and all sequences \(x\) and \(y\), the terminal Smith–Waterman cell \(H(x, y)\) satisfies \(H(x, y) \ge 0\).
theorem swCellScore_nonneg (xs ys : List α) : 0 ≤ swCellScore σ gap xs ys
def swCellScore (xs ys : List α) : ℤ :=
swCellFront σ gap (xs.length + ys.length) xs.reverse ys.reverse
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:988
Uses 2 · Used by 1
TheoremThe terminal cell vanishes when the first sequence is empty#✓fully proved
For a substitution score \(\sigma\), a gap score \(g\) and every sequence \(y\), the terminal Smith–Waterman cell of the empty sequence and \(y\) is \(0\).
theorem swCellScore_nil_left (ys : List α) : swCellScore σ gap [] ys = 0
def swCellScore (xs ys : List α) : ℤ :=
swCellFront σ gap (xs.length + ys.length) xs.reverse ys.reverse
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:988
Uses 2 · Used by 3
TheoremThe terminal cell vanishes when the second sequence is empty#✓fully proved
For a substitution score \(\sigma\), a gap score \(g\) and every sequence \(x\), the terminal Smith–Waterman cell of \(x\) and the empty sequence is \(0\).
theorem swCellScore_nil_right (xs : List α) : swCellScore σ gap xs [] = 0
def swCellScore (xs ys : List α) : ℤ :=
swCellFront σ gap (xs.length + ys.length) xs.reverse ys.reverse
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:988
Uses 2 · Used by 2
TheoremThe Smith–Waterman recurrence#✓fully proved
Let \(\sigma\) be a substitution score and \(g\) a gap score, and for a sequence \(s\) and a letter \(c\) write \(sc\) for \(s\) followed by \(c\). For all sequences \(x\) and \(y\) and all letters \(a\) and \(b\), the terminal Smith–Waterman cell \(H\) satisfies
theorem swCellScore_eq (xs ys : List α) (a b : α) :
swCellScore σ gap (xs ++ [a]) (ys ++ [b]) =
max 0 (max (max (swCellScore σ gap xs ys + σ a b)
(swCellScore σ gap xs (ys ++ [b]) + gap))
(swCellScore σ gap (xs ++ [a]) ys + gap))
def swCellScore (xs ys : List α) : ℤ :=
swCellFront σ gap (xs.length + ys.length) xs.reverse ys.reverse
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:988
Uses 2 · Used by 3
TheoremSuffixes of a list with an element appended#✓fully proved
If \(s\) is a suffix of the list obtained by appending an element \(a\) at the end of a list \(xs\), then either \(s\) is empty, or there is a suffix \(s'\) of \(xs\) such that \(s\) is \(s'\) with \(a\) appended at the end.
theorem suffix_of_snoc {xs : List α} {a : α} {s : List α} (h : s <:+ xs ++ [a]) :
s = [] ∨ ∃ s', s' <:+ xs ∧ s = s' ++ [a]
Used by 1
TheoremAppending an element preserves suffixes#✓fully proved
If a list \(s\) is a suffix of a list \(xs\), then for every element \(a\), the list \(s\) with \(a\) appended at the end is a suffix of \(xs\) with \(a\) appended at the end.
theorem suffix_append_snoc {s xs : List α} {a : α} (h : s <:+ xs) : s ++ [a] <:+ xs ++ [a]
TheoremReversing an alignment#✓fully proved
For a list of columns \(A\) and sequences \(x\) and \(y\), \(A\) is an alignment of the reversal of \(x\) and the reversal of \(y\) if and only if the reversal of \(A\) (its columns in reverse order) is an alignment of \(x\) and \(y\).
theorem isAlignment_reverse {A : Alignment α} {xs ys : List α} :
IsAlignment A xs.reverse ys.reverse ↔ IsAlignment A.reverse xs ys
abbrev Alignment (α : Type*) := List (Option α × Option α)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:69
def IsAlignment (A : Alignment α) (xs ys : List α) : Prop :=
(∀ c ∈ A, c ≠ (none, none)) ∧ A.filterMap Prod.fst = xs ∧ A.filterMap Prod.snd = ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:73
Uses 2 · Used by 1
TheoremReversal preserves alignment score#✓fully proved
For every substitution score \(\sigma : \alpha \to \alpha \to \mathbb{Z}\), gap score \(g \in \mathbb{Z}\) and alignment \(A\), the alignment obtained by listing the columns of \(A\) in reverse order has the same score as \(A\).
theorem alignmentScore_reverse (A : Alignment α) :
alignmentScore σ gap A.reverse = alignmentScore σ gap A
abbrev Alignment (α : Type*) := List (Option α × Option α)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:69
def alignmentScore (σ : α → α → ℤ) (gap : ℤ) (A : Alignment α) : ℤ :=
(A.map (columnScore σ gap)).sum
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:84
Uses 3 · Used by 1
TheoremNeedleman–Wunsch is reversal-invariant#✓fully proved
Reversing both sequences preserves the optimal global score.
theorem nwScore_reverse (xs ys : List α) :
nwScore σ gap xs.reverse ys.reverse = nwScore σ gap xs ys
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
Uses 8 · Used by 1
TheoremThe Needleman–Wunsch recurrence, end-peeling#✓fully proved
Let \(\sigma : \alpha \to \alpha \to \mathbb{Z}\) be a substitution score and \(g \in \mathbb{Z}\) a gap score, and write \(N(x, y)\) for the Needleman–Wunsch score of sequences \(x, y\) over \(\alpha\) with respect to \(\sigma\) and \(g\). For all sequences \(x, y\) and letters \(a, b \in \alpha\), writing \(xa\) for the sequence \(x\) followed by the letter \(a\),
theorem nwScore_snoc (xs ys : List α) (a b : α) :
nwScore σ gap (xs ++ [a]) (ys ++ [b]) =
max (max (nwScore σ gap xs ys + σ a b) (nwScore σ gap xs (ys ++ [b]) + gap))
(nwScore σ gap (xs ++ [a]) ys + gap)
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
Uses 3 · Used by 3
DefinitionMaximum of an integer list with floor zero#✓fully proved
For a list \(l\) of integers, this is the largest of \(0\) and the entries of \(l\); in particular the empty list gives \(0\).
It is used to define the suffix maximum, the local score and the Smith–Waterman score.
Used by 17
DefinitionPairs of suffixes#✓fully proved
For lists \(xs\) and \(ys\), the list of all pairs \((u, v)\) where \(u\) is a suffix of \(xs\) and \(v\) is a suffix of \(ys\), the empty lists and \(xs\), \(ys\) themselves included.
Used by 8
DefinitionSuffix maximum of Needleman–Wunsch scores#✓fully proved
Given a substitution score \(\sigma\) and an integer gap score \(g\), the suffix maximum of lists \(xs\) and \(ys\) is the maximum of the Needleman–Wunsch scores of all pairs \((u, v)\) with \(u\) a suffix of \(xs\) and \(v\) a suffix of \(ys\).
The maximum is taken with floor \(0\), which changes nothing, since the pair of empty suffixes scores \(0\).
def suffixMax (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((suffixPairs xs ys).map (fun p => nwScore σ gap p.1 p.2))
def listMax (xs : List ℤ) : ℤ := xs.foldr (max ·) 0
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1187
def suffixPairs (xs ys : List α) : List (List α × List α) :=
xs.tails.product ys.tails
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1222
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
Uses 3 · Used by 8
TheoremSuffix pairs score at most the suffix maximum#✓fully proved
Let \(\sigma : \alpha \to \alpha \to \mathbb{Z}\) be a substitution score and \(g \in \mathbb{Z}\) a gap score. If \((x', y')\) is a suffix pair of sequences \(x\) and \(y\) over \(\alpha\), that is, \(x'\) is a suffix of \(x\) and \(y'\) is a suffix of \(y\), then the Needleman–Wunsch score of \(x'\) and \(y'\) is at most the suffix maximum of \(x\) and \(y\), both with respect to \(\sigma\) and \(g\).
theorem nwScore_le_suffixMax {xs' ys' xs ys : List α}
(h : (xs', ys') ∈ suffixPairs xs ys) :
nwScore σ gap xs' ys' ≤ suffixMax σ gap xs ys
def suffixPairs (xs ys : List α) : List (List α × List α) :=
xs.tails.product ys.tails
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1222
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
def suffixMax (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((suffixPairs xs ys).map (fun p => nwScore σ gap p.1 p.2))
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1230
Uses 4 · Used by 2
TheoremUpper bounds on the suffix maximum#✓fully proved
Let \(\sigma\) be a substitution score, \(g\) an integer gap score, \(xs\) and \(ys\) lists and \(y\) an integer. If every pair \((u, v)\) with \(u\) a suffix of \(xs\) and \(v\) a suffix of \(ys\) has Needleman–Wunsch score at most \(y\), then the maximum Needleman–Wunsch score over all such suffix pairs is at most \(y\).
theorem suffixMax_le {xs ys : List α} {y : ℤ}
(h : ∀ p ∈ suffixPairs xs ys, nwScore σ gap p.1 p.2 ≤ y) :
suffixMax σ gap xs ys ≤ y
def suffixPairs (xs ys : List α) : List (List α × List α) :=
xs.tails.product ys.tails
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1222
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
def suffixMax (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((suffixPairs xs ys).map (fun p => nwScore σ gap p.1 p.2))
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1230
Uses 5 · Used by 1
TheoremThe suffix maximum is attained#✓fully proved
For a substitution score \(\sigma : \alpha \to \alpha \to \mathbb{Z}\), a gap score \(g \in \mathbb{Z}\) and sequences \(x\) and \(y\) over \(\alpha\), there is a suffix pair \((x', y')\) of \(x\) and \(y\), that is, a suffix \(x'\) of \(x\) and a suffix \(y'\) of \(y\), whose Needleman–Wunsch score equals the suffix maximum of \(x\) and \(y\).
theorem exists_nwScore_eq_suffixMax (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) :
∃ p ∈ suffixPairs xs ys, nwScore σ gap p.1 p.2 = suffixMax σ gap xs ys
def suffixPairs (xs ys : List α) : List (List α × List α) :=
xs.tails.product ys.tails
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1222
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
def suffixMax (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((suffixPairs xs ys).map (fun p => nwScore σ gap p.1 p.2))
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1230
Uses 5 · Used by 2
TheoremThe suffix maximum is nonnegative#✓fully proved
For every scoring function \(\sigma : \alpha \to \alpha \to \mathbb{Z}\), every gap score \(g \in \mathbb{Z}\) and all lists \(x\) and \(y\) over \(\alpha\), the suffix maximum of \(x\) and \(y\) (the largest Needleman–Wunsch score, under \(\sigma\) and \(g\), of a suffix of \(x\) against a suffix of \(y\)) is at least \(0\), since the pair of empty suffixes scores \(0\).
theorem zero_le_suffixMax (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) :
0 ≤ suffixMax σ gap xs ys
def suffixMax (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((suffixPairs xs ys).map (fun p => nwScore σ gap p.1 p.2))
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1230
Uses 3 · Used by 1
TheoremExtending an alignment by a letter of the first sequence#✓fully proved
If \(A\) is an alignment of sequences \(x\) and \(y\) and \(a\) is a letter, then \(A\) followed by the column with \(a\) in the first row and a gap in the second row is an alignment of \(x\) followed by \(a\) and of \(y\).
theorem isAlignment_append_some_none {A : Alignment α} {xs ys : List α} {a : α}
(hA : IsAlignment A xs ys) :
IsAlignment (A ++ [(some a, none)]) (xs ++ [a]) ys
abbrev Alignment (α : Type*) := List (Option α × Option α)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:69
def IsAlignment (A : Alignment α) (xs ys : List α) : Prop :=
(∀ c ∈ A, c ≠ (none, none)) ∧ A.filterMap Prod.fst = xs ∧ A.filterMap Prod.snd = ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:73
Uses 2 · Used by 1
TheoremExtending an alignment by a letter of the second sequence#✓fully proved
If \(A\) is an alignment of sequences \(x\) and \(y\) and \(b\) is a letter, then \(A\) followed by the column with a gap in the first row and \(b\) in the second row is an alignment of \(x\) and of \(y\) followed by \(b\).
theorem isAlignment_append_none_some {A : Alignment α} {xs ys : List α} {b : α}
(hA : IsAlignment A xs ys) :
IsAlignment (A ++ [(none, some b)]) xs (ys ++ [b])
abbrev Alignment (α : Type*) := List (Option α × Option α)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:69
def IsAlignment (A : Alignment α) (xs ys : List α) : Prop :=
(∀ c ∈ A, c ≠ (none, none)) ∧ A.filterMap Prod.fst = xs ∧ A.filterMap Prod.snd = ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:73
Uses 2 · Used by 1
TheoremAppending to the first sequence loses at most one gap#✓fully proved
Let \(\sigma : \alpha \to \alpha \to \mathbb{Z}\) be a substitution score, \(g \in \mathbb{Z}\) a gap score, and write \(N(x, y)\) for the Needleman–Wunsch score of sequences \(x, y\) over \(\alpha\) with respect to \(\sigma\) and \(g\). For all sequences \(x, y\) and every letter \(a \in \alpha\), writing \(xa\) for \(x\) with \(a\) appended at the end, \(N(x, y) + g \le N(xa, y)\).
An optimal alignment of \(x\) and \(y\) followed by the gap column pairing \(a\) with nothing is an alignment of \(xa\) and \(y\).
theorem nwScore_le_nwScore_snoc_left (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) (a : α) :
nwScore σ gap xs ys + gap ≤ nwScore σ gap (xs ++ [a]) ys
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
Uses 8 · Used by 1
TheoremAppending to the second sequence loses at most one gap#✓fully proved
Let \(\sigma : \alpha \to \alpha \to \mathbb{Z}\) be a substitution score, \(g \in \mathbb{Z}\) a gap score, and write \(N(x, y)\) for the Needleman–Wunsch score of sequences \(x, y\) over \(\alpha\) with respect to \(\sigma\) and \(g\). For all sequences \(x, y\) and every letter \(b \in \alpha\), writing \(yb\) for \(y\) with \(b\) appended at the end, \(N(x, y) + g \le N(x, yb)\).
An optimal alignment of \(x\) and \(y\) followed by the gap column pairing nothing with \(b\) is an alignment of \(x\) and \(yb\).
theorem nwScore_le_nwScore_snoc_right (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) (b : α) :
nwScore σ gap xs ys + gap ≤ nwScore σ gap xs (ys ++ [b])
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
Uses 8 · Used by 1
TheoremSuffix pairs score at most the terminal Smith–Waterman cell#✓fully proved
Let \(\sigma : \alpha \to \alpha \to \mathbb{Z}\) be a substitution score and \(g \le 0\) a gap score. If \(x'\) is a suffix of a sequence \(x\) and \(y'\) is a suffix of a sequence \(y\) over \(\alpha\), then the Needleman–Wunsch score of \(x'\) and \(y'\) is at most the terminal Smith–Waterman cell score of \(x\) and \(y\), both with respect to \(\sigma\) and \(g\).
theorem nwScore_le_swCellScore_of_suffix (hgap : gap ≤ 0) {xs' ys' xs ys : List α}
(hxs : xs' <:+ xs) (hys : ys' <:+ ys) :
nwScore σ gap xs' ys' ≤ swCellScore σ gap xs ys
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
def swCellScore (xs ys : List α) : ℤ :=
swCellFront σ gap (xs.length + ys.length) xs.reverse ys.reverse
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:988
Uses 9 · Used by 2
TheoremThe terminal cell is at most the suffix maximum#✓fully proved
For every substitution score \(\sigma\), every gap score \(g\) of either sign and all sequences \(x\) and \(y\), the terminal Smith–Waterman cell \(H(x, y)\) is at most the maximum Needleman–Wunsch score over all pairs of a suffix of \(x\) and a suffix of \(y\).
Only the reverse inequality needs \(g \le 0\).
theorem swCellScore_le_suffixMax (xs ys : List α) :
swCellScore σ gap xs ys ≤ suffixMax σ gap xs ys
def swCellScore (xs ys : List α) : ℤ :=
swCellFront σ gap (xs.length + ys.length) xs.reverse ys.reverse
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:988
def suffixMax (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((suffixPairs xs ys).map (fun p => nwScore σ gap p.1 p.2))
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1230
Uses 14 · Used by 1
TheoremThe suffix maximum is at most the terminal Smith–Waterman cell#✓fully proved
Let \(\sigma\) be a substitution score and \(g \le 0\) an integer gap score. For all lists \(xs\) and \(ys\), the maximum Needleman–Wunsch score over all pairs of a suffix of \(xs\) and a suffix of \(ys\) is at most the terminal Smith–Waterman cell score of \(xs\) and \(ys\).
theorem suffixMax_le_swCellScore (hgap : gap ≤ 0) (xs ys : List α) :
suffixMax σ gap xs ys ≤ swCellScore σ gap xs ys
def suffixMax (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((suffixPairs xs ys).map (fun p => nwScore σ gap p.1 p.2))
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1230
def swCellScore (xs ys : List α) : ℤ :=
swCellFront σ gap (xs.length + ys.length) xs.reverse ys.reverse
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:988
Uses 5 · Used by 1
TheoremFor nonpositive gaps, the terminal Smith–Waterman cell is the best suffix-pair score#✓fully proved
For a substitution score \(\sigma\), a gap score \(g \le 0\) and all sequences \(x\) and \(y\), the terminal Smith–Waterman cell \(H(x, y)\) equals the maximum Needleman–Wunsch score over all pairs of a suffix of \(x\) and a suffix of \(y\) (the empty suffixes included).
theorem swCellScore_eq_suffixMax (hgap : gap ≤ 0) (xs ys : List α) :
swCellScore σ gap xs ys = suffixMax σ gap xs ys
def swCellScore (xs ys : List α) : ℤ :=
swCellFront σ gap (xs.length + ys.length) xs.reverse ys.reverse
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:988
def suffixMax (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((suffixPairs xs ys).map (fun p => nwScore σ gap p.1 p.2))
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1230
Uses 4 · Used by 1
DefinitionPairs of prefixes#✓fully proved
For lists \(xs\) and \(ys\), the list of all pairs \((p, q)\) where \(p\) is a prefix of \(xs\) and \(q\) is a prefix of \(ys\), the empty lists and \(xs\), \(ys\) themselves included.
Used by 9
DefinitionInfix pairs#✓fully proved
For sequences \(x\) and \(y\) over \(\alpha\), the list of infix pairs of \(x\) and \(y\) is obtained by going through each prefix \(p\) of \(x\) and each prefix \(q\) of \(y\) and, for each such \((p, q)\), listing all pairs \((x', y')\) of a suffix \(x'\) of \(p\) and a suffix \(y'\) of \(q\).
So \((x', y')\) occurs in the list exactly when \(x'\) is a contiguous block of \(x\) and \(y'\) is a contiguous block of \(y\); a pair may occur more than once.
def infixPairs (xs ys : List α) : List (List α × List α) :=
(prefixPairs xs ys).flatMap (fun p => p.1.tails.product p.2.tails)
def prefixPairs (xs ys : List α) : List (List α × List α) :=
xs.inits.product ys.inits
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1508
Uses 1 · Used by 6
DefinitionLocal alignment score#✓fully proved
For an integer substitution score \(\sigma\), an integer gap score \(g\) and sequences \(x\) and \(y\), the local score of \(x\) and \(y\) is the maximum of the Needleman–Wunsch score of \((x', y')\) over all pairs of an infix \(x'\) of \(x\) and an infix \(y'\) of \(y\) (contiguous and possibly empty).
def localScore (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((infixPairs xs ys).map (fun p => nwScore σ gap p.1 p.2))
def listMax (xs : List ℤ) : ℤ := xs.foldr (max ·) 0
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1187
def infixPairs (xs ys : List α) : List (List α × List α) :=
(prefixPairs xs ys).flatMap (fun p => p.1.tails.product p.2.tails)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1516
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
Uses 3 · Used by 6
TheoremInfix pairs score at most the local score#✓fully proved
Let \(\sigma : \alpha \to \alpha \to \mathbb{Z}\) be a substitution score and \(g \in \mathbb{Z}\) a gap score. If \((x', y')\) is an infix pair of sequences \(x\) and \(y\) over \(\alpha\), that is, \(x'\) is a suffix of a prefix of \(x\) and \(y'\) is a suffix of a prefix of \(y\), then the Needleman–Wunsch score of \(x'\) and \(y'\) is at most the local score of \(x\) and \(y\), both with respect to \(\sigma\) and \(g\).
theorem nwScore_le_localScore {xs' ys' xs ys : List α}
(h : (xs', ys') ∈ infixPairs xs ys) :
nwScore σ gap xs' ys' ≤ localScore σ gap xs ys
def infixPairs (xs ys : List α) : List (List α × List α) :=
(prefixPairs xs ys).flatMap (fun p => p.1.tails.product p.2.tails)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1516
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
def localScore (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((infixPairs xs ys).map (fun p => nwScore σ gap p.1 p.2))
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1539
Uses 4 · Used by 3
TheoremUpper bounds on the local score#✓fully proved
Let \(\sigma\) be an integer substitution score, \(g\) an integer gap score, \(x\) and \(y\) sequences and \(c\) an integer. If the Needleman–Wunsch score of every pair \((x', y')\) with \(x'\) an infix of \(x\) and \(y'\) an infix of \(y\) is at most \(c\), then the local score of \(x\) and \(y\) is at most \(c\).
theorem localScore_le {xs ys : List α} {y : ℤ}
(h : ∀ p ∈ infixPairs xs ys, nwScore σ gap p.1 p.2 ≤ y) :
localScore σ gap xs ys ≤ y
def infixPairs (xs ys : List α) : List (List α × List α) :=
(prefixPairs xs ys).flatMap (fun p => p.1.tails.product p.2.tails)
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1516
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
def localScore (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((infixPairs xs ys).map (fun p => nwScore σ gap p.1 p.2))
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1539
Uses 6 · Used by 1
DefinitionThe Smith–Waterman score#✓fully proved
Given a substitution score \(\sigma\) and a gap score \(g\), the Smith–Waterman score of two sequences \(x\) and \(y\) is the maximum of the terminal Smith–Waterman cell \(H(p, q)\) over all pairs of a prefix \(p\) of \(x\) and a prefix \(q\) of \(y\) (the empty prefixes included).
For \(g \le 0\) this is the optimal local alignment score, the maximum Needleman–Wunsch score over pairs of infixes; for \(g > 0\) it can be smaller.
def swScore (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((prefixPairs xs ys).map (fun p => swCellScore σ gap p.1 p.2))
def listMax (xs : List ℤ) : ℤ := xs.foldr (max ·) 0
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1187
def prefixPairs (xs ys : List α) : List (List α × List α) :=
xs.inits.product ys.inits
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1508
def swCellScore (xs ys : List α) : ℤ :=
swCellFront σ gap (xs.length + ys.length) xs.reverse ys.reverse
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:988
Uses 3 · Used by 5
TheoremEach prefix-pair cell is at most the Smith–Waterman score#✓fully proved
For a substitution score \(\sigma\), a gap score \(g\), sequences \(x\) and \(y\), a prefix \(p\) of \(x\) and a prefix \(q\) of \(y\), the terminal Smith–Waterman cell \(H(p, q)\) is at most the Smith–Waterman score of \(x\) and \(y\).
theorem swCellScore_le_swScore {px py xs ys : List α}
(h : (px, py) ∈ prefixPairs xs ys) :
swCellScore σ gap px py ≤ swScore σ gap xs ys
def prefixPairs (xs ys : List α) : List (List α × List α) :=
xs.inits.product ys.inits
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1508
def swCellScore (xs ys : List α) : ℤ :=
swCellFront σ gap (xs.length + ys.length) xs.reverse ys.reverse
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:988
def swScore (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((prefixPairs xs ys).map (fun p => swCellScore σ gap p.1 p.2))
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1568
Uses 4 · Used by 2
TheoremBounding the Smith–Waterman score by its cells#✓fully proved
For a substitution score \(\sigma\), a gap score \(g\), sequences \(x\) and \(y\) and an integer \(c\), if the terminal Smith–Waterman cell \(H(p, q)\) is at most \(c\) for every prefix \(p\) of \(x\) and every prefix \(q\) of \(y\), then the Smith–Waterman score of \(x\) and \(y\) is at most \(c\).
theorem swScore_le {xs ys : List α} {y : ℤ}
(h : ∀ p ∈ prefixPairs xs ys, swCellScore σ gap p.1 p.2 ≤ y) :
swScore σ gap xs ys ≤ y
def prefixPairs (xs ys : List α) : List (List α × List α) :=
xs.inits.product ys.inits
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1508
def swCellScore (xs ys : List α) : ℤ :=
swCellFront σ gap (xs.length + ys.length) xs.reverse ys.reverse
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:988
def swScore (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((prefixPairs xs ys).map (fun p => swCellScore σ gap p.1 p.2))
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1568
Uses 5 · Used by 2
TheoremThe local score equals the Smith–Waterman score#✓fully proved
Let \(\sigma\) be an integer-valued substitution score on letters and let \(g\) be an integer gap score with \(g \le 0\). Then for all sequences \(x\) and \(y\), the local score of \(x\) and \(y\) (the maximum Needleman–Wunsch score over pairs of infixes) equals their Smith–Waterman score (the maximum terminal-cell score over pairs of prefixes).
The proof uses that an infix is a suffix of a prefix and that the terminal cell is a maximum over pairs of suffixes.
theorem localScore_eq_swScore (hgap : gap ≤ 0) (xs ys : List α) :
localScore σ gap xs ys = swScore σ gap xs ys
def localScore (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((infixPairs xs ys).map (fun p => nwScore σ gap p.1 p.2))
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1539
def swScore (σ : α → α → ℤ) (gap : ℤ) (xs ys : List α) : ℤ :=
listMax ((prefixPairs xs ys).map (fun p => swCellScore σ gap p.1 p.2))
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:1568
Uses 15 · Used by 1
DefinitionRemaining cells of a Needleman–Wunsch table row#✓fully proved
The cells F[i+1][j+1], F[i+1][j+2], … of a row from the remaining letters b :: ys of the
second sequence, the remaining cells up :: prev of the previous row, the previous row's cell
diag to the upper left and the cell left just computed. A previous row that is too short ends
the row early (this does not happen for rows of the table, nextRow_eq).
def nextRowAux (a : α) : List α → List ℤ → ℤ → ℤ → List ℤ
| [], _, _, _ => []
| _ :: _, [], _, _ => []
| b :: ys, up :: prev, diag, left =>
max (max (diag + σ a b) (up + gap)) (left + gap) ::
nextRowAux a ys prev up (max (max (diag + σ a b) (up + gap)) (left + gap))
Used by 2
DefinitionNext row of the Needleman–Wunsch table#✓fully proved
The row of the table for the prefix extended by a, from the previous row: the first cell is
one more gap than the previous row's first cell, then the recurrence left to right.
def nextRow (a : α) (ys : List α) (prev : List ℤ) : List ℤ :=
(prev.headD 0 + gap) :: nextRowAux σ gap a ys prev.tail (prev.headD 0) (prev.headD 0 + gap)
def nextRowAux (a : α) : List α → List ℤ → ℤ → ℤ → List ℤ
| [], _, _, _ => []
| _ :: _, [], _, _ => []
| b :: ys, up :: prev, diag, left =>
max (max (diag + σ a b) (up + gap)) (left + gap) ::
nextRowAux a ys prev up (max (max (diag + σ a b) (up + gap)) (left + gap))
CSLibExt/Bioinformatics/Alignment/NeedlemanWunschTable.lean:63
Uses 1 · Used by 3
DefinitionRow-by-row filling of the Needleman–Wunsch table#✓fully proved
The rows of the table, filled top to bottom over the letters of the first sequence; the
result is the last row. Row 0 is F[0][j] = j * gap.
def nwRowsAux (ys : List α) : List α → List ℤ → List ℤ
| [], row => row
| a :: xs, row => nwRowsAux ys xs (nextRow σ gap a ys row)
def nextRow (a : α) (ys : List α) (prev : List ℤ) : List ℤ :=
(prev.headD 0 + gap) :: nextRowAux σ gap a ys prev.tail (prev.headD 0) (prev.headD 0 + gap)
CSLibExt/Bioinformatics/Alignment/NeedlemanWunschTable.lean:72
Uses 1 · Used by 2
DefinitionLast row of the Needleman–Wunsch table#✓fully proved
The last row F[|xs|][·] of the Needleman–Wunsch table.
def nwRows (xs ys : List α) : List ℤ :=
nwRowsAux σ gap ys xs ((List.range (ys.length + 1)).map fun j : ℕ => gap * (j : ℤ))
def nwRowsAux (ys : List α) : List α → List ℤ → List ℤ
| [], row => row
| a :: xs, row => nwRowsAux ys xs (nextRow σ gap a ys row)
CSLibExt/Bioinformatics/Alignment/NeedlemanWunschTable.lean:77
Uses 1 · Used by 3
DefinitionThe Needleman–Wunsch table#✓fully proved
Its last cell F[|xs|][|ys|].
def nwTab (xs ys : List α) : ℤ :=
(nwRows σ gap xs ys).getLastD 0
def nwRows (xs ys : List α) : List ℤ :=
nwRowsAux σ gap ys xs ((List.range (ys.length + 1)).map fun j : ℕ => gap * (j : ℤ))
CSLibExt/Bioinformatics/Alignment/NeedlemanWunschTable.lean:82
Uses 1 · Used by 1
TheoremOne row of the table#✓fully proved
From the row of the prefix px, nextRow computes the row of
px ++ [a]: the cells nwScore (px ++ [a]) py for the prefixes py of ys, shortest first.
theorem nextRow_eq (a : α) (px ys : List α) :
nextRow σ gap a ys (ys.inits.map (nwScore σ gap px)) =
ys.inits.map (nwScore σ gap (px ++ [a]))
def nextRow (a : α) (ys : List α) (prev : List ℤ) : List ℤ :=
(prev.headD 0 + gap) :: nextRowAux σ gap a ys prev.tail (prev.headD 0) (prev.headD 0 + gap)
CSLibExt/Bioinformatics/Alignment/NeedlemanWunschTable.lean:72
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
Uses 5 · Used by 1
TheoremThe last row of the table#✓fully proved
The last row of the table is F[|xs|][j] = nwScore xs (ys.take j): the cells
nwScore xs py over the prefixes py of ys, shortest first.
theorem nwRows_eq (xs ys : List α) :
nwRows σ gap xs ys = ys.inits.map (nwScore σ gap xs)
def nwRows (xs ys : List α) : List ℤ :=
nwRowsAux σ gap ys xs ((List.range (ys.length + 1)).map fun j : ℕ => gap * (j : ℤ))
CSLibExt/Bioinformatics/Alignment/NeedlemanWunschTable.lean:82
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
Uses 6 · Used by 1
TheoremThe table computes the optimal global alignment score#✓fully proved
The table computes the optimal global alignment score (Needleman–Wunsch 1970), for every
substitution score σ and gap score gap.
theorem nwTab_eq_nwScore (xs ys : List α) : nwTab σ gap xs ys = nwScore σ gap xs ys
def nwTab (xs ys : List α) : ℤ :=
(nwRows σ gap xs ys).getLastD 0
CSLibExt/Bioinformatics/Alignment/NeedlemanWunschTable.lean:86
def nwScore (xs ys : List α) : ℤ := nwScoreAux σ gap (xs.length + ys.length) xs ys
CSLibExt/Algorithms/Lean/DynamicProgramming/SequenceAlignment.lean:128
Uses 4
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.