Problem: rod_cutting

Your task is to implement the Rod Cutting algorithm (a classic Dynamic Programming problem from CLRS) and verify its correctness in Dafny. You are given a rod of length n and a table of prices where the $i$-th element represents the price of a rod piece of length $i+1$. The goal is to determine the maximum revenue obtainable by cutting up the rod and selling the pieces.In the incomplete code, the specification defines what constitutes a valid cut strategy (a list of piece lengths that sum up to n) and how to calculate the total revenue of a strategy. Your task is to implement the algorithm and verify that it returns the optimal revenue. Specifically, you must prove: (1) Upper Bound: Any valid set of cuts yields a total revenue less than or equal to the returned result. (2) Existence: There exists a valid set of cuts whose total revenue is exactly equal to the returned result.


// Following is the block for necessary definitions
// <preamble>
// Calculates the total length of the pieces
function sum_lengths(cuts: seq<int>): int
    decreases |cuts|
{
    if |cuts| == 0 then
        0
    else
        cuts[0] + sum_lengths(cuts[1..])
}

// Helper: Safe price lookup that returns 0 for out-of-bounds
function get_price(prices: seq<int>, idx: int): int {
    if 0 <= idx < |prices| then
        prices[idx]
    else
        0
}

// Calculates revenue recursively.
function calculate_revenue(cuts: seq<int>, prices: seq<int>): int
    decreases |cuts|
{
    if |cuts| == 0 then
        0
    else
        // Revenue is price of first piece + revenue of remaining pieces
        get_price(prices, cuts[0] - 1) + 
        calculate_revenue(cuts[1..], prices)
}

// Definition of a valid strategy: positive cuts, valid prices, sums to n
predicate is_valid_strategy(cuts: seq<int>, n: int, prices: seq<int>) {
    (forall i: int :: 0 <= i < |cuts| ==> cuts[i] > 0) &&
    (forall i: int :: 0 <= i < |cuts| ==> cuts[i] - 1 < |prices|) &&
    sum_lengths(cuts) == n
}
// </preamble>

// Following is the block for potential helper specifications
// <helpers>

// </helpers>

// Following is the block for proofs of lemmas
// <proofs>

// </proofs>

// Following is the block for the main specification
// <spec>
method rod_cutting(n: int, prices: seq<int>) returns (result: int)
    requires |prices| >= n
    requires n <= 1000
    // Constraints matching Verus u64/usize unsigned and explicit bounds
    requires forall i: int :: 0 <= i < |prices| ==> 0 <= prices[i] <= 10000
    ensures result >= 0
    // 1. Upper Bound
    ensures forall cuts: seq<int> :: (is_valid_strategy(cuts, n, prices) 
            ==> calculate_revenue(cuts, prices) <= result)
    // 2. Existence
    ensures exists cuts: seq<int> :: (is_valid_strategy(cuts, n, prices) 
            && calculate_revenue(cuts, prices) == result)
// </spec>
// <code>
{
    // Implement and verify the Rod Cutting DP algorithm here.
}
// </code>