File: quicksort.v

package info (click to toggle)
coq-equations 1.3.1-8.20-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,796 kB
  • sloc: ml: 12,434; makefile: 98; sh: 35
file content (204 lines) | stat: -rw-r--r-- 7,864 bytes parent folder | download
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
From Equations Require Import Equations.

Require Import Vector.
Notation vector := t.
Derive NoConfusion NoConfusionHom for vector.

Set Equations Transparent.

Arguments Vector.nil {A}.
Arguments Vector.cons {A} _ {n}.

Notation " x |:| y " := (@Vector.cons _ x _ y) (at level 20, right associativity) : vect_scope.
Notation " x |: n :| y " := (@Vector.cons _ x n y) (at level 20, right associativity) : vect_scope.
Notation "[]v" := Vector.nil (at level 0) : vect_scope.
Local Open Scope vect_scope.

Equations app {A} {n m} (v : vector A n) (w : vector A m) : vector A (n + m) :=
  app []v w := w ;
  app (cons a v) w := a |:| app v w.

Equations In {A n} (x : A) (v : vector A n) : Prop :=
  In x nil := False;
  In x (cons a v) := (x = a) \/ In x v.

Inductive All {A : Type} (P : A -> Prop) : forall {n}, vector A n -> Prop :=
| All_nil : All P nil
| All_cons {a n} {v : vector A n} : P a -> All P v -> All P (a |:| v).

Lemma All_impl {A : Type} (P Q : A -> Prop) {n} (v : vector A n) : (forall x, P x -> Q x) -> All P v -> All Q v.
Proof. induction 2; constructor; auto. Qed.

Derive Signature for All.
Lemma All_app {A P n m} (v : vector A n) (w : vector A m) :
  @All A P _ v -> All P w -> All P (app v w).
Proof.
  funelim (app v w). auto.
  intros. depelim H0; simp app in *. econstructor; auto.
Qed.

Lemma In_All {A P n} (v : vector A n) : All P v <-> (forall x, In x v -> P x).
Proof.
  split. induction 1. intros. depelim H. auto. intros x; simpl. simp In. intuition. subst; auto.
  induction v; simpl; intros; auto; constructor. apply H; simp In; auto.
  firstorder.
Qed.

(* Lemma All_In_All {A P n m} (v : vector A n) (v' : vector A m) : *)
(*   All (fun x => In x v) v' -> All P v -> All P v'. *)
(* Proof. *)
(*   induction 1. simpl. constructor. *)
(*   intros. constructor; auto. *)
(*   eapply In_All; eauto. *)
(* Qed. *)

Inductive Sorted {A : Type} (R : A -> A -> Prop) : forall {n}, vector A n -> Prop :=
| Sorted_nil : Sorted R nil
| Sorted_cons {a n} {v : vector A n} : All (R a) v -> Sorted R v -> Sorted R (a |:| v).
Import Sigma_Notations.
Derive Signature for Sorted.

Lemma Sorted_app {A R n m} (v : vector A n) (w : vector A m) :
  @Sorted A R _ v -> Sorted R w ->
  Sorted R (app v w).
Proof.
Admitted.

Lemma In_app {A n m} (v : vector A n) (w : vector A m) (a : A) : In a v \/ In a w <-> In a (app v w).
Proof.
  funelim (app v w). intuition. depelim H0.
  split; intros; depelim H0; cbn; simp In app in *; intuition eauto with *; simp In in *.
  apply H in H0. intuition.
Qed.
Require Import Sumbool.

Notation dec x := (sumbool_of_bool x).

Section QuickSort.
  Context {A : Type} (leb : A -> A -> bool).
  Context (leb_inverse : forall x y, leb x y = false -> leb y x = true).
  Local Definition sorted {n} (v : vector A n) := Sorted (fun x y => leb x y = true) v.
  Set Program Mode.

  Equations? filter {n} (v : vector A n) (f : A -> bool) :
    Σ (k : nat), { v : vector A k | k <= n /\ All (fun x => f x = true) v } :=
    filter nil        f := (0, nil);
    filter (cons a v') f with dec (f a) :=
           { | left H => (_, cons a (filter v' f).2);
             | right H => (_, (filter v' f).2) }.
  Proof.
    split; auto. constructor.
    destruct filter as [n' [v'' [Hn' Hv']]]. simpl.
    split; auto with arith. constructor; auto.
    destruct filter as [n' [v'' [Hn' Hv']]]. simpl.
    split; auto with arith.
  Defined.

  Equations? pivot {n} (v : vector A n) (f : A -> bool) :
    Σ (k : nat) (l : nat) (v' : vector A k), { w : vector A l
    | (k + l = n)%nat
      /\ forall x, In x v <->
                   (if f x then In x v'
                    else In x w) } :=
                   (*   All (fun x => In x v /\ f x = true) v' *)
                   (* /\ All (fun x => In x v /\ f x = false) w } } } } := *)
    pivot nil        f := (0 , 0 , nil, nil);
    pivot (cons a v') f with dec (f a), pivot v' f :=
           { | left H | (k, l, v, w) => (_ , _, cons a v, w);
             | right H | (k, l, v, w) => (_ , _, v, cons a w) }.
  Proof.
    split; intros; simp In; auto. intuition. destruct (f x); auto. simpl.
    split; auto with arith. intros x. simp In. split; intros Hx.
    intuition; subst; try rewrite H; intuition. specialize (proj1 (i _) H0). destruct (f x); intuition.
    specialize (i x). destruct (f x); intuition.
    split; auto with arith. intros x. constructor; simp In; intuition auto.
    subst. rewrite H. auto. specialize (proj1 (i _) H1). destruct (f x); intuition.
    specialize (i x). destruct (f x); intuition.
  Defined.

  Equations? qs {n} (l : vector A n) : { v : vector A n | sorted v /\ (forall x, In x l <-> In x v) } by wf n lt :=
    qs nil := nil ;
    qs (cons a v) with pivot v (fun x => leb x a) :=
                { | (k, l, lower, higher) =>
                    app (qs lower) (a |:| qs higher) }.
  Proof.
    all:simpl. all:repeat (destruct qs; simpl).
    repeat constructor; trivial. auto with arith. auto with arith.
    simpl. destruct (eq_sym (plus_n_Sm k l)). simpl.
    intuition.
    apply Sorted_app; auto. constructor.
    apply In_All. intros x1 Inx1. apply H2 in Inx1.
    specialize (i x1).
    eapply leb_inverse.

    eapply All_In_All; eauto. eapply All_impl; eauto. simpl. intros x1 [inx1 lebx1].
    apply leb_inverse; assumption. intuition.
    eapply All_app. eapply All_In_All; eauto. eapply All_impl; eauto. simpl.
    intros x1 [inx1 lebx1]. constructor; auto.
    constructor; auto. constructor.
    eapply All_In_All; eauto.
    eapply All_impl; eauto. simpl. intros x1 [Inx1 lebx1]. constructor; auto.
  Defined.

  Definition qs_forget {n} (l : vector A n) : vector A n := qs l.

  (* Proof after the definition. *)

  Lemma All_In {n} (v : vector A n) P : All P v -> (forall x, In x v -> P x).
  Proof. induction 1. intros x Hx. depelim Hx. intros x Hx. depelim Hx. auto. auto. Qed.

  Lemma All_In_self {n} (v : vector A n) : All (fun x => In x v) v.
  Proof.
    induction v. constructor. constructor. constructor. eapply All_impl; eauto. simpl.
    intros. constructor; auto.
  Qed.

  Local Open Scope program_scope.

  Local Open Scope program_scope.
  Lemma qs_all {n} (l : vector A n) : forall x, In x (qs_forget l) -> In x l.
  Proof.
    intros x. unfold qs_forget. destruct (qs l). simpl; eauto. destruct a.
    eapply (All_In _ _ H0).
  Qed.

  Lemma all_qs {n} (l : vector A n) : forall x, In x l -> In x (qs_forget l).
  Proof.
    intros x. unfold qs_forget. funelim (qs l); simpl.
    + trivial.
    + destruct qs_obligation_4. simpl.
      clear H1.
      intros Hx. eapply In_app. destruct Hx.
      destruct pr6. simpl in *. destruct a. destruct a. simpl in *.

      constructor. clear Heq. eapply All_In in a. intuition eauto. auto.
      clear Heq; intuition; destruct pr6; intuition; simpl in *.
      depelim H1. constructor. constructor. simpl in H1. apply H0 in H1.
      intuition. eapply All_In in H5. intuition eauto. auto.
  Qed.
  Lemma qs_all {n} (l : vector A n) : forall x, In x (qs_forget l) -> In x l.
  Proof.
    intros x. unfold qs_forget. funelim (qs l); simpl.
    + trivial.
    + destruct qs_obligation_4. simpl.
      clear H1.
      intros Hx. apply In_app in Hx. destruct Hx. apply H in H1.
      destruct pr6. simpl in *. destruct a. destruct a. simpl in *.
      constructor. clear Heq. eapply All_In in a. intuition eauto. auto.
      clear Heq; intuition; destruct pr6; intuition; simpl in *.
      depelim H1. constructor. constructor. simpl in H1. apply H0 in H1.
      intuition. eapply All_In in H5. intuition eauto. auto.
  Qed.

  Lemma qs_equiv {n} (l : vector A n) : forall x, In x l <-> In x (qs_forget l).
  Proof.
    split; auto using qs_all. intros.
    unfold qs_forget. funelim (destruct qs. simpl. intuition.
    eapply (All_In in H1.
    pose (All_In_self x0). eapply All_In_All in a; eauto.


End QuickSort.

Extraction Inline pivot.
Extraction qs.