Problem: polymul_naive

Your task is to implement the standard $O(N^2)$ algorithm for multiplying two polynomials and verify its correctness in Dafny.  Preconditions: Inputs a and b are seq<int> representing polynomial coefficients. Size Constraint: The sum of lengths is at most 1000. Value Constraint: Every coefficient is between -1,000,000 and 1,000,000. This ensures that the result fits within a standard 64-bit integer range without overflow. Requirements: Implement poly_multiply to return the product polynomial. (1) Algorithm: Initialize a result sequence of size |a| + |b| - 1 with zeros. Use a nested loop: for every i in a and j in b, add a[i] * b[j] to res[i+j]. (2) Functional Correctness: Prove that the final sequence matches the convolution specification: res[k] = sum_{p+q=k} a[p] * b[q]. (3) Safety: You must prove that the intermediate additions and multiplications never exceed the simulated 64-bit bounds. Verification Challenges: (1) Accumulation Invariant: The naive algorithm updates the same index res[k] multiple times. You need a loop invariant that characterizes the partial sum stored in res at any point in the nested loops. (2) Overflow Proof: You must prove that given the input bounds ($|c| \le 10^6$) and length bound ($N \le 1000$), the maximum possible coefficient ($N \times 10^{12}$) is strictly within safe limits.

// <preamble>
// Helper to convert inputs. In Dafny, we use int directly, so this is identity.
function to_int(s: seq<int>): seq<int> {
    s
}

// Helper: Enforce bounds on coefficients to prevent overflow.
predicate coeffs_bounded(s: seq<int>) {
    forall i :: 0 <= i < |s| ==> -1_000_000 <= s[i] <= 1_000_000
}

// Recursive definition of the convolution sum
function spec_convolution_sum(a: seq<int>, b: seq<int>, k: int, current_i: int): int
    decreases if current_i < 0 then 0 else current_i + 1
{
    if current_i < 0 then
        0
    else
        // Calculate the term for the current index i
        var term := if current_i < |a| && (k - current_i) < |b| && (k - current_i) >= 0 then
            a[current_i] * b[k - current_i]
        else
            0;
        // Recursive step
        term + spec_convolution_sum(a, b, k, current_i - 1)
}

// Wrapper for the full convolution coefficient at index k
function spec_poly_mul_coeff(a: seq<int>, b: seq<int>, k: int): int {
    spec_convolution_sum(a, b, k, k)
}
// </preamble>

// <helpers>

// </helpers>

// <proofs>

// </proofs>

// <spec>
method poly_multiply(a: seq<int>, b: seq<int>) returns (res: seq<int>)
    requires |a| > 0
    requires |b| > 0
    requires |a| + |b| <= 1000
    // Safety Precondition: Coefficients are bounded
    requires coeffs_bounded(a)
    requires coeffs_bounded(b)
    
    ensures |res| == |a| + |b| - 1
    // Functional Correctness
    ensures forall k :: 0 <= k < |res| ==> res[k] == spec_poly_mul_coeff(a, b, k)
// </spec>
// <code>
{
    // Implement and verify the naive polynomial multiplication here.
}
// </code>

method Main() {}