From Coq.micromega Require Import Lia.
From Coq.Arith Require Import PeanoNat.
Import Compare_dec.
From Coq.Lists Require Import List.
Import ListNotations.
Fixpoint insert (n : nat) (l : list nat) : list nat :=
match l with
| [] => [n]
| a :: l' => if le_lt_dec n a then n :: l else a :: (insert n l')
end.
Fixpoint insertion_sort (l : list nat) : list nat :=
match l with
| [] => []
| a :: l' => insert a (insertion_sort l')
end.
Fixpoint sorted (l : list nat) : Prop :=
match l with
| nil => True
| cons a l' =>
match l' with
| [] => True
| b :: l'' => a <= b /\ sorted l'
end
end.
From Coq.Arith Require Import PeanoNat.
Import Compare_dec.
From Coq.Lists Require Import List.
Import ListNotations.
Fixpoint insert (n : nat) (l : list nat) : list nat :=
match l with
| [] => [n]
| a :: l' => if le_lt_dec n a then n :: l else a :: (insert n l')
end.
Fixpoint insertion_sort (l : list nat) : list nat :=
match l with
| [] => []
| a :: l' => insert a (insertion_sort l')
end.
Fixpoint sorted (l : list nat) : Prop :=
match l with
| nil => True
| cons a l' =>
match l' with
| [] => True
| b :: l'' => a <= b /\ sorted l'
end
end.
Exercise: finish the following proofs, i.e., replace the Admitted
command with Qed.
Lemma sorted_tail (a : nat) (l : list nat) : sorted (a :: l) -> sorted l.
Proof.
Admitted.
Lemma sorted_first_two (a b : nat) (l : list nat) :
sorted (a :: b :: l) -> a <= b.
Proof.
simpl.
intros Habl.
destruct Habl as [Habl1 Habl2].
trivial.
Qed.
Lemma sorted_less_than_all (a : nat) (l : list nat) :
sorted l /\ (forall b, In b l -> a <= b) <-> sorted (a :: l).
Proof.
Admitted.
Lemma in_insert (n : nat) (l : list nat) :
forall a, In a (insert n l) <-> a = n \/ In a l.
Proof.
Admitted.
Lemma insert_sorted (n : nat) (l : list nat) : sorted l -> sorted (insert n l).
Proof.
revert n.
induction l as [|a l IHl].
- intros n. simpl. trivial.
- intros n Hl. simpl.
destruct le_lt_dec.
+ simpl.
split.
* trivial.
* destruct l as [|b l].
-- trivial.
-- split.
++ eapply sorted_first_two; eauto.
++ eapply sorted_tail; eauto.
+ apply sorted_less_than_all.
split.
* apply IHl. eapply sorted_tail; eauto.
* apply sorted_less_than_all in Hl.
destruct Hl as [Hl1 Hl2].
intros b Hb.
apply in_insert in Hb.
destruct Hb as [Hb1|Hb2].
-- rewrite Hb1. lia.
-- auto.
Qed.
Theorem insertion_sort_sorted (l : list nat) : sorted (insertion_sort l).
Proof.
induction l as [|a l IHl].
- simpl. trivial.
- simpl.
apply insert_sorted; trivial.
Qed.