📥 Download raw
{-# OPTIONS --cubical-compatible #-}
open import Padova2025.ProgrammingBasics.Lists
open import Padova2025.ProvingBasics.Connectives.Disjunction

module Padova2025.VerifiedAlgorithms.InsertionSort.PostHoc
  (A : Set) (_≤_ : A  A  Set) (cmp? : (x y : A)  x  y  y  x) where

Post-hoc verification

open import Padova2025.VerifiedAlgorithms.InsertionSort.Implementation A _≤_ cmp?

Output lists are ordered

As a first step, let us prove that the lists produced by the sort function are always ascendingly ordered. To express such an assertion, we need to introduce a type IsOrdered xs of witnesses that a given list xs is ordered.

data IsOrdered : List A  Set where
  empty     : IsOrdered []
  singleton : {x : A}  IsOrdered (x  [])
  cons      : {x y : A} {ys : List A}  x  y  IsOrdered (y  ys)  IsOrdered (x  (y  ys))
lemma₀ : (x y : A) (ys : List A)  y  x  IsOrdered (y  ys)  IsOrdered (y  insert x ys)
lemma₀ = {!!}
lemma : (x : A) (ys : List A)  IsOrdered ys  IsOrdered (insert x ys)
lemma = {!!}
theorem : (xs : List A)  IsOrdered (sort xs)
theorem = {!!}

Output lists are permutations of the input lists

It is nice that a full proof of theorem : (xs : List A) → IsOrdered (sort xs), developed above, is just one screenful of code. However, this theorem does not yet express all aspects of the sorting function working correctly:

cheatsort : List A  List A
cheatsort xs = []
cheattheorem : (xs : List A)  IsOrdered (cheatsort xs)
cheattheorem xs = empty

We need to verify that sort xs is a permutation of the input list xs. To express such an assertion, we first set up a type x ◂ ys ↝ xys of witnesses that inserting x into ys somewhere yields the list xys.

data _◂_↝_ : A  List A  List A  Set where
  here  : {x : A} {xs : List A}  x  xs  (x  xs)
  there : {x y : A} {ys xys : List A}  x  ys  xys  x  (y  ys)  (y  xys)

We then set up a type xs ≈ ys of witnesses that the two lists xs and ys are permutations of each other, that is, contain exactly the same elements just perhaps in different order.

infix 4 _≈_
data _≈_ : List A  List A  Set where
  empty : []  []
  cons  : {x : A} {xs ys xys : List A}  (x  ys  xys)  xs  ys  (x  xs)  xys

Here is an example for such a permutation witness:

example : (x y z : A)  (x  y  z  [])  (z  x  y  [])
example = {!!}

We can then state and prove the fundamental lemma about the inserting behavior of insert.

lemma' : (x : A) (ys : List A)  x  ys  insert x ys
lemma' = {!!}

The desired result about the sort function is then a quick corollary.

theorem' : (xs : List A)  xs  sort xs
theorem' = {!!}