Imports
import Mathlib

CLRS Section 15.1 - Rod cutting

This section formalizes the mathematical core of the rod-cutting dynamic program. Instead of committing immediately to one array implementation, it defines the Bellman first-cut recurrence as a specification for a revenue function. The main theorem proves that any revenue function satisfying that recurrence upper-bounds the value of every concrete cutting plan. Consequently, any plan whose value attains the recurrence value is optimal among plans of the same total length.

Main results:

  • Theorem firstCutValue_le_of_rodCutRecurrence: every admissible first cut is bounded by the recurrence value.

  • Theorem rodRevenue_le_of_firstCutValue_bounds: the recurrence value is the least upper bound induced by first-cut candidates.

  • Theorem bottomUpRodRevenue_rodCutRecurrence: the executable recurrence-valued rod-cutting function satisfies the CLRS Bellman recurrence.

  • Theorem planValue_le_table_of_rodCutTableRecurrence: any finite table filled by the bottom-up recurrence is an upper bound for every positive-piece cutting plan within its filled prefix.

  • Theorem planValue_le_revenue_of_rodCutRecurrence: every positive-piece cutting plan is bounded by the recurrence value of its total length.

  • Theorem planValue_le_optimalPlanValue_of_same_length: a plan attaining the recurrence value is optimal among plans of the same length.

Current gaps:

  • This file proves the mathematical bottom-up table-certificate layer, but not yet a mutable-array implementation or memoized cache refinement.

  • Matrix-chain multiplication, LCS, and optimal binary-search trees remain future dynamic-programming targets.

namespace CLRSnamespace Chapter15

Rod-cutting model

The total length of a concrete cutting plan.

def planLength (pieces : List Nat) : Nat := pieces.sum

The value of a cutting plan under the given price table.

def planValue (price : Nat Nat) (pieces : List Nat) : Nat := (pieces.map price).sum

Every piece in the cutting plan has positive length.

def PositivePieces (pieces : List Nat) : Prop := piece, piece pieces 0 < piece

The value obtained by making cut the first cut of a rod of length n.

def FirstCutValue (price revenue : Nat Nat) (n cut : Nat) : Nat := price cut + revenue (n - cut)

The CLRS rod-cutting recurrence: length zero has value zero, and every positive length is the maximum over all possible first cuts.

def RodCutRecurrence (price revenue : Nat Nat) : Prop := revenue 0 = 0 n, revenue (n + 1) = (Finset.Icc 1 (n + 1)).sup (fun cut => FirstCutValue price revenue (n + 1) cut)

Bottom-up table and executable recurrence

A finite bottom-up rod-cutting table is correct through limit when entry zero is zero and every positive entry up to limit is filled by the CLRS first-cut recurrence using earlier table entries.

def RodCutTableRecurrence (price table : Nat Nat) (limit : Nat) : Prop := table 0 = 0 n, n < limit table (n + 1) = (Finset.Icc 1 (n + 1)).sup (fun cut => FirstCutValue price table (n + 1) cut)

The canonical executable rod-cutting value function obtained by recursively evaluating the CLRS first-cut recurrence. The recurrence is written over Finset.attach so Lean sees that each recursive call is made at a strictly smaller rod length.

def bottomUpRodRevenue (price : Nat Nat) : Nat Nat | 0 => 0 | n + 1 => (Finset.Icc 1 (n + 1)).attach.sup (fun cut => price cut.1 + bottomUpRodRevenue price ((n + 1) - cut.1)) termination_by n => n decreasing_by
private theorem finset_attach_sup_eq (s : Finset Nat) (f : Nat Nat) : s.attach.sup (fun x => f x.1) = s.sup f :=

The executable recurrence unfolds to the textbook first-cut maximum.

The executable recurrence-valued function satisfies the CLRS recurrence.

theorem bottomUpRodRevenue_rodCutRecurrence (price : Nat Nat) : RodCutRecurrence price (bottomUpRodRevenue price) :=

A global recurrence function induces a correct finite table prefix.

theorem rodCutTableRecurrence_of_rodCutRecurrence {price revenue : Nat Nat} (hrec : RodCutRecurrence price revenue) (limit : Nat) : RodCutTableRecurrence price revenue limit :=

Every prefix of the executable recurrence-valued function is a correct table.

theorem bottomUpRodRevenue_rodCutTableRecurrence (price : Nat Nat) (limit : Nat) : RodCutTableRecurrence price (bottomUpRodRevenue price) limit := rodCutTableRecurrence_of_rodCutRecurrence (bottomUpRodRevenue_rodCutRecurrence price) limit

First-cut recurrence facts

Every admissible first cut is bounded by the recurrence value.

If a number bounds every first-cut candidate, then it bounds the recurrence value. This is the upper-bound half of the Bellman maximum principle.

Selling the whole rod as one piece is one admissible first-cut candidate.

Bottom-up table facts

Every admissible first cut is bounded by the value stored in a correct finite bottom-up table, provided the queried rod length lies inside the filled prefix.

If a number bounds every first-cut candidate inside a correct finite table prefix, then it bounds the stored table value.

Selling the whole rod is also bounded by a correct finite table prefix.

Plan optimality

Every concrete cutting plan with positive pieces is bounded by the recurrence value of its total length.

Every concrete cutting plan whose total length is inside a correct finite bottom-up table prefix is bounded by the table value at that total length.

Every positive-piece cutting plan is bounded by the executable recurrence value of its total length.

theorem planValue_le_bottomUpRodRevenue (price : Nat Nat) : pieces, PositivePieces pieces planValue price pieces bottomUpRodRevenue price (planLength pieces) := planValue_le_revenue_of_rodCutRecurrence (price := price) (revenue := bottomUpRodRevenue price) (bottomUpRodRevenue_rodCutRecurrence price)

If a cutting plan attains the recurrence value for its length, then every other positive-piece plan of the same total length has value at most that plan.

If a cutting plan attains the table value inside a correct finite bottom-up prefix, then every other positive-piece plan of the same length has value at most that plan.

If a cutting plan attains the executable recurrence value for its length, then every other positive-piece plan of the same length has value at most that plan.

theorem planValue_le_bottomUpRodPlanValue_of_same_length {price : Nat Nat} {candidate other : List Nat} (hother_pos : PositivePieces other) (hlen : planLength other = planLength candidate) (hcandidate_value : planValue price candidate = bottomUpRodRevenue price (planLength candidate)) : planValue price other planValue price candidate := planValue_le_optimalPlanValue_of_same_length (price := price) (revenue := bottomUpRodRevenue price) (bottomUpRodRevenue_rodCutRecurrence price) hother_pos hlen hcandidate_value
end Chapter15end CLRS