Problem: merge_sort

Your task is to implement Merge Sort and verify its correctness in Verus. Merge Sort is a divide-and-conquer algorithm that divides the input array into two halves, calls itself for the two halves, and then merges the two sorted halves. You might implement two functions: (1) merge: Takes two sorted vectors and combines them into one sorted vector. (2) merge_sort: The recursive driver, which is the function to be verified. There are several verification challenges: (1) Proving that merge maintains the permutation property (the sum of counts in inputs equals counts in output). (2) Proving merge produces a sorted output. (3) Proving termination of the recursion (using a decrement on length). Note that you are not allowed to write new axioms (for example, writing seemingly correct property for multisets), and maybe directly using permutation is a better option.

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 merge_sort(v: &mut Vec<i32>)
        ensures
            is_sorted(v@),
            is_permutation(old(v)@, v@),
    // </spec>
    // <code>
    {

    }
    // </code>

    fn main() {}
}