-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
import Mathlib
variable [LE α] [DecidableLE α] [Std.IsLinearOrder α] (xs : List α)
def ins (a : α)
| [] => [a]
| x :: xs =>
if a ≤ x then a :: x :: xs else x :: ins a xs
def List.insSort : List α → List α
| [] => []
| x :: xs => ins x xs.insSort
def Sorted : List α → Prop
| [] | [_] => True
| x :: x' :: xs => x ≤ x' ∧ Sorted (x' :: xs)
-- This section is AI-generated
noncomputable section AristotleLemmas
/-
Inserting an element `x` into a list `xs` results in a permutation of `x :: xs`.
-/
theorem ins_perm (x : α) (xs : List α) : List.Perm (ins x xs) (x :: xs) := by
-- By definition of `ins`, we know that `ins x [] = [x]`.
have h_base : List.Perm (ins x []) (x :: []) := by
rfl;
induction xs <;> simp_all +decide [ List.Perm ];
-- By definition of `ins`, we know that `ins x (head :: tail)` is either `x :: head :: tail` or `head :: ins x tail`.
have h_cases : ins x (‹α› :: ‹List α›) = if x ≤ ‹α› then x :: ‹α› :: ‹List α› else ‹α› :: ins x ‹List α› := by
exact?;
split_ifs at h_cases <;> simp_all +decide [ List.Perm.swap ];
rename_i k hk ih;
exact List.Perm.trans ( List.Perm.cons _ hk ) ( List.Perm.swap .. )
/-
Inserting an element into a sorted list preserves sortedness.
-/
theorem ins_sorted [LE α] [DecidableLE α] [Std.IsLinearOrder α] (x : α) (xs : List α) (h : Sorted xs) : Sorted (ins x xs) := by
revert x xs;
intro x y;
induction y <;> simp_all +decide [ ins ];
· tauto;
· rename_i k hk ih;
split_ifs with h;
· exact fun h' => ⟨ h, h' ⟩;
· rcases hk with ( _ | ⟨ y, hk ⟩ ) <;> simp_all +decide [ Sorted ];
· constructor;
· exact?;
· trivial;
· -- Since $k \leq y$ and $y \leq x$, we have $k \leq x$.
have h_kx : k ≤ x := by
exact?;
rcases n : ins x ( y :: hk ) with ( _ | ⟨ z, _ | ⟨ w, l ⟩ ⟩ ) <;> simp_all +decide [ Sorted ];
· unfold ins at n; aesop;
· unfold ins at n; aesop;
end AristotleLemmas
theorem insSortCorrect : Sorted xs.insSort ∧ xs.Perm xs.insSort := by
constructor;
· induction xs <;> simp_all +decide [ List.insSort ];
· trivial;
· exact?;
· induction xs;
· rfl;
· -- By definition of `ins`, we have `ins head (tail.insSort) = head :: tail.insSort` if `head ≤ tail.insSort`.
have h_insert : List.Perm (ins ‹α› (‹List α›.insSort)) (‹α› :: ‹List α›.insSort) := by
exact?;
exact List.Perm.trans ( List.Perm.cons _ ‹_› ) h_insert.symm