Problem: insertion_sort

Your task is to implement Insertion Sort and verify its correctness in Dafny. The algorithm builds the final sorted array one item at a time. It iterates through the input elements and, for each one, inserts it into its correct position among the previously sorted elements. You must prove: (1) Sortedness: The resulting vector is sorted. (2) Permutation: The resulting vector is a permutation of the input. The key verification challenge is the prefix invariant: at index $i$ of the outer loop, the subarray 0..i is sorted and is a permutation of the first $i$ elements of the original array. The inner loop shifts elements to make room for the current value.

// Following is the block for necessary definitions
// <preamble>
ghost predicate is_sorted(s: seq<int>) {
    forall i, j :: 0 <= i < j < |s| ==> s[i] <= s[j]
}

ghost predicate is_valid_index_permutation(p: seq<int>, n: int) {
    && |p| == n
    && (forall i {:trigger p[i]} :: 0 <= i < n ==> 0 <= p[i] < n)
    && (forall i, j {:trigger p[i], p[j]} :: 0 <= i < j < n ==> p[i] != p[j])
}

ghost predicate is_permutation(v1: seq<int>, v2: seq<int>) {
    exists p: seq<int> :: 
        is_valid_index_permutation(p, |v1|) 
        && |v1| == |v2|
        && (forall i {:trigger p[i]} :: 0 <= i < |v1| ==> v2[i] == v1[p[i]])
}
// </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 insertion_sort(v: seq<int>) returns (v_new: seq<int>)
    ensures is_sorted(v_new)
    ensures is_permutation(v, v_new)
// </spec>
// <code>
{
    // Implement and verify the Insertion Sort algorithm here.
}
// </code>

method main() {}