Skip to main content

14. Reverse, Definition of Sorted

21/11/22

set_option pp.structure_projections false


/-
inductive list(A : Type)
| nil : list
-- | cons : A → list → list
| snoc : list → A → list




open list
local notation (name := cons) a :: b := cons a b

1 :: 2 :: 3 :: nil
[1,2,3]
-/

variables {A B C : Type}

/-
def append : list A → list A → list A
| [] bs := bs
| {a :: as} bs := a :: (append as bs)

[1,2] ++ [3,4] = [1,2,3,4]

local notation (name := append) as ++ bs := append as bs
-/


/-
proof is using induction over lists
(list A, ++, [])
commutative monoid?
[1,2]++[3] ≠ [3]++[1,2]
lists are the free monoid
what is the free commutative monoid

multisets, bags
{1,1} ≠ {1}
{1,2,3} = {3,2,1}

forget multisets, back to lists...#check
rev [1,2,3] = [3,2,1]

-/
--snoc [1,2] 3 = [1,2,3]

def snoc : list A → A → list A
| [] a := [a]
| (b :: bs) a := b :: (snoc bs a)

-- rev [1,2,3] = snoc(rev [2,3])
-- snoc [3,2] 1 = [3,2,1]
def rev : list A → list A
| [] := []
| (a :: as) := snoc (rev as) a

#eval (rev [1,2,3])
#eval rev (rev [1,2,3])

open list

lemma revsnoc : ∀ as : list A, ∀ a : A, rev (snoc as a) = a :: rev as :=
begin
assume as a,
induction as with b as' ih,
dsimp[snoc,rev],
refl,
dsimp[snoc,rev],
rw ih,
dsimp[snoc],
refl,
end

theorem revrev : ∀ as : list A, rev(rev as) = as :=
begin
assume as,
induction as with a as' ih,
dsimp [rev],
refl,
dsimp[rev],
rw revsnoc,
rw ih,
end


---

-- sort : list ℕ → list ℕ
-- sort [5,3,2,2,1] → [1,2,2,3,5]

open nat

def leb : ℕ → ℕ → bool
| 0 n := tt
| (succ n) 0 := ff
| (succ m) (succ n) := leb m n

theorem leb_ok : ∀ m n : ℕ, m ≤ n ↔ leb m n = tt :=
begin
sorry,
end

def ins : ℕ → list ℕ → list ℕ
| n [] := [n]
| n (m :: ms) :=
if (leb n m) then n :: m :: ms
else m :: (ins n ms)


def sort : list ℕ → list ℕ
| [] := []
| (n :: ns) := ins n (sort ns)

#eval (sort [ 5,3,2,4,1])

-- sort sorts
-- Sorted : list ℕ → Prop


inductive Le_list : ℕ → list ℕ → Prop
| le_nil : ∀ n : ℕ, Le_list n []
| le_cons : ∀ m n : ℕ, ∀ ns : list ℕ , m ≤ n → Le_list m ns → Le_list m (n :: ns)

inductive Sorted : list ℕ → Prop
| sorted_nil : Sorted []
| sorted_cons : ∀ ms : list ℕ, ∀ n : ℕ, Le_list n ms → Sorted ms → Sorted (n :: ms)

theorem sort_sorts : ∀ ns : list ℕ , Sorted (sort ns) :=
begin
sorry,
end