Problem: insertion_sort

Your task is to implement Insertion Sort and verify its correctness in Verus. 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.

use vstd::prelude::*;

verus! {
    // Following is the block for necessary definitions
    // <preamble>
    spec fn is_sorted(s: Seq<i32>) -> bool {
        forall|i: int, j: int| 0 <= i < j < s.len() ==> s[i] <= s[j]
    }

    spec fn is_valid_index_permutation(p: Seq<int>, n: int) -> bool {
        p.len() == n
        && (forall|i: int| 0 <= i < n ==> 0 <= #[trigger] p[i] < n)
        && (forall|i: int, j: int| 0 <= i < j < n ==> #[trigger] p[i] != #[trigger] p[j])
    }

    spec fn is_permutation(v1: Seq<i32>, v2: Seq<i32>) -> bool {
        exists|p: Seq<int>| 
            is_valid_index_permutation(p, v1.len() as int) 
            && v1.len() == v2.len()
            && (forall|i: int| 0 <= i < v1.len() ==> v2[i] == v1[#[trigger] p[i]])
    }
    // </preamble>

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

    // </helpers>

    // Following is the block for proofs of lemmas, or functions that help the implementation or verification of the main specification
    // <proofs>

    // </proofs>

    // Following is the block for the main specification
    // <spec>
    fn insertion_sort(v: &mut Vec<i32>)
        ensures
            is_sorted(v@),
            is_permutation(old(v)@, v@),
    // </spec>
    // <code>
    {

    }
    // </code>

    fn main() {}
}