(* This file was originally generated by why.
   It can be modified; only the generated parts will be overwritten. *)

Require Import Why.
Require Export Partition.
Require Import Omega.
Require Import ZArithRing.

Proof.
intuition.
Save.

Proof.
intuition.
Save.

Proof.
intuition.
Save.

Proof.
intuition.
ArraySubst t0.
Save.

Proof.
intuition.
subst; auto with *.
Save.




Admitted.

Admitted.

Proof.
intuition.
Save.

Proof.
intuition.
apply array_le_empty; omega.
apply array_ge_empty; omega.
Save.

Proof.
intuition.
Save.

Proof.
intuition ArrayLength; omega.
Save.

Proof.
intuition; subst.
replace (i0+1-1) with ((i0-1)+1).
apply array_le_right_extension; intuition.
ring (i0-1+1); auto.
omega.
Save.

Proof.
intuition.
Save.

Proof.
intuition.
Save.

Proof.
intuition; subst.
apply array_ge_cons.
 intros j1 Hj1.
 elim (Z_le_gt_dec (j0 + 1) j1); intro.
assert (h: array_ge t0 (j + 1) r (access t l)). assumption.
elim h; intros.
auto with *.
cut (j0 = j1); [ intro | omega ].
subst.
 omega.
Save.

Proof.
intuition.
Save.

Ltac elimh p :=  match goal with
  | h:p |- _ => elim h
end.

Proof.
intuition.
replace (i1 - 1)%Z with (i0 - 1 + 1)%Z.
apply array_le_right_extension.
apply array_le_exchange with (t := t0) (x := i0) (y := j0).
omega.
 omega.
 assumption.
omega.
 apply exchange_sym; assumption.
ring (i0 - 1 + 1)%Z.
 elimh (exchange t1 t0 i0 j0); intros.
 replace (access t1 i0) with (access t0 j0); auto.
omega.
omega.
replace (j1 + 1)%Z with (j0 + 1 - 1)%Z.
apply array_ge_left_extension.
apply array_ge_exchange with (t := t0) (x := i0) (y := j0).
omega.
  SameLength t t0.
 omega.
assumption.
omega.
 apply exchange_sym; assumption.
ring (j0 + 1 - 1)%Z.
 elimh (exchange t1 t0 i0 j0); intros.
 replace (access t1 j0) with (access t0 i0); auto.
omega.
omega.
apply sub_permut_trans with (t' := t0).
apply exchange_is_sub_permut with (i := i0) (j := j0);
 [ omega | omega | assumption ].
assumption.
Save.

Proof.
intuition.
Save.

Proof.
intuition.
Save.

Proof.
intuition.
replace (i1 - 1)%Z with (i0 - 1 + 1)%Z.
apply array_le_right_extension.
apply array_le_exchange with (t := t0) (x := i0) (y := j0).
omega.
 omega.
 assumption.
omega.
 apply exchange_sym; assumption.
ring (i0 - 1 + 1)%Z.
  elimh (exchange t1 t0 i0 j0); intros.
  replace (access t1 i0) with (access t0 j0); auto.
omega.
omega.
replace (j1 + 1)%Z with (j0 + 1 - 1)%Z.
apply array_ge_left_extension.
apply array_ge_exchange with (t := t0) (x := i0) (y := j0).
omega.
 SameLength t t0.
 omega.
assumption.
 omega.
 apply exchange_sym; assumption.
ring (j0 + 1 - 1)%Z.
  elimh (exchange t1 t0 i0 j0); intros.
  replace (access t1 j0) with (access t0 i0); auto.
omega.
omega.
apply sub_permut_trans with (t' := t0).
apply exchange_is_sub_permut with (i := i0) (j := j0);
 [ omega | omega | assumption ].
assumption.
Save.

Proof.
intuition.
Save.

Proof.
intuition.
Save.

Proof.
intuition.
SameLength t t0.
omega.
Save.

Proof.
intuition.
apply array_ge_cons.
 intros j' Hj'.
 elim (Z_le_gt_dec (j0 + 1) j'); intro.
 elimh (array_ge t0 (j0 + 1) r result); intros.
  auto with *.
cut (j' = j0); [ intro | omega ].
subst; omega.
Save.

Proof.
intuition.
Save.

Proof.
intros; absurd (i0 < j0); omega.
Save.

Proof.
intuition.
Save.

Proof.
intuition.
Save.

Proof.
intuition.
apply array_le_cons.
intros i' Hi'.
 elim (Z_le_lt_eq_dec l i'); intros.
(* case l < i' *)
elimh (exchange t1 t0 i0 j0); intros h1 h2 h3 h4 h5 h6.
assert (i' < i0 \/ i'=i0). omega. intuition.
rewrite h6; try omega.
elimh (array_le t0 (l + 1) (i0 - 1) result); auto with *.
subst i'; rewrite h4; omega.
(* case l = i' *)
elimh (exchange t1 t0 i0 j0); intros h1 h2 h3 h4 h5 h6.
omega.
omega.
(* array_ge *)
apply array_ge_cons.
intros j' Hj'.
elimh (exchange t1 t0 i0 j0); intros h1 h2 h3 h4 h5 h6.
assert (j0 < j' \/ j'=j0). omega. intuition.
rewrite h6; try omega.
elimh (array_ge t0 (j0 + 1) r result); auto with *.
SameLength t0 t; omega.
subst j'; rewrite h5; omega.
(* (sub_permut l r t1 t) *)
apply sub_permut_trans with (t' := t0); auto.
apply exchange_is_sub_permut with (i := i0) (j := j0).
omega.
omega.
assumption.
elimh (exchange t1 t0 i0 j0); intros h1 h2 h3 h4 h5 h6.
rewrite (h6 l); try omega.
unfold Zwf; intuition.
SameLength t1 t0; omega.
Save.

Proof.
intuition.
Save.

Proof.
intuition.
SameLength t0 t; omega.
Save.

Proof.
intuition.
Save.

Proof.
intuition.
apply piv.
omega.
omega.
(* array_le *)
apply array_le_cons.
intros i' Hi'.
 elim (Z_le_lt_eq_dec l i'); intros.
(* case l < i *)
elimh (exchange t1 t0 l i); intros h1 h2 h3 h4 h5 h6.
rewrite h6.
rewrite h5.
subst.
replace (access t0 l) with (access t l); auto.
elimh (array_le t0 (l + 1) (i - 1) (access t l)); auto with *.
omega.
omega.
omega.
(* case l = i *)
subst.
elimh (exchange t1 t0 i' i); intros h1 h2 h3 h4 h5 h6.
rewrite h4.
rewrite h5.
omega.
omega.
(* array_ge *)
apply array_ge_cons.
intros i' Hi'.
subst.
 ring (i1 - 1 + 1)%Z.
 intro Hj.
 elim Post30; intros.
rewrite H22.
 rewrite (H23 j0).
rewrite H18.
elim H15; intros.
 elim (Z_le_lt_eq_dec i1 j0); intros.
(* case i0 < j *)
rewrite <- Post11.
 apply H24; omega.
(* case i0 = j *)
rewrite <- b.
 omega.
omega.
SameLength t1 t0; SameLength t0 t; omega.
omega.
omega.
(* (sub_permut t1 t l r) *)
apply sub_permut_trans with (t' := t0).
apply exchange_is_sub_permut with (i := l) (j := Zpred i1).
omega.
unfold Zpred; omega.
assumption.
assumption.
Save.

Proof.
intuition.
Save.

Proof.
intuition.
Save.

Proof.
intuition ArrayLength; omega.
Qed.

 Proof.
 intuition.
induction result2; auto.
induction result2; auto.
Qed.

Proof.
intuition.
induction result2; auto || discriminate Post5.
induction result2; auto || discriminate Post5.
Qed.

Proof.
intuition.
Qed.

Proof.
intuition.
rewrite <- H23.
elim Post25; intros.
apply H28; omega.
absurd (i2 < j2)%Z; omega.
replace (j3 + 1)%Z with (j2 + 1 - 1)%Z.
apply array_ge_left_extension.
apply array_ge_exchange with (t := t0) (x := i2) (y := j2).
omega.
 intuition; generalize (sub_permut_length H21); intro; omega.
assumption.
 omega.
 apply exchange_sym; assumption.
ring (j2 + 1 - 1)%Z.
 elim Post25; intros.
 rewrite H28.
omega.
omega.
apply sub_permut_trans with (t' := t0).
apply exchange_is_sub_permut with (i := i2) (j := j2);
 [ omega | omega | assumption ].
assumption.
absurd (i2 < j2)%Z; omega.
Qed.

Proof.
intuition ArrayLength; omega.
Qed.

Proof.
intros.
decompose [and or] Invj; clear Invj.
 intuition unfold Zwf; ArrayLength; try omega.
Qed.

Proof.
intuition unfold Zwf; SameLength t t0; omega.
rewrite <- H23.
elim Post25; intros.
apply H28; omega.
absurd (i2 < j2)%Z; omega.
replace (j3 + 1)%Z with (j2 + 1 - 1)%Z.
apply array_ge_left_extension.
apply array_ge_exchange with (t := t0) (x := i2) (y := j2).
omega.
 intuition; generalize (sub_permut_length H21); intro; omega.
assumption.
 omega.
 apply exchange_sym; assumption.
ring (j2 + 1 - 1)%Z.
 elim Post25; intros.
 rewrite H28.
omega.
omega.
apply sub_permut_trans with (t' := t0).
apply exchange_is_sub_permut with (i := i2) (j := j2);
 [ omega | omega | assumption ].
assumption.
absurd (i2 < j2)%Z; omega.
Qed.

Proof.
intuition.
apply array_le_empty; omega.
apply array_ge_empty; omega.
Qed.

Proof.
intuition SameLength t t0; omega.
Qed.

Proof.
intuition SameLength t t0; auto with *.
Qed.

Proof.
intuition.
apply piv.
omega.
omega.
Qed.

Proof.
intuition SameLength t0 t; omega.
Qed.

Proof.
intuition.
Qed.


Proof.
intuition.
Save.


Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.



(*Why type*) Definition farray: Set ->Set.
Admitted.

(*Why logic*) Definition access : forall (A1:Set), (array A1) -> Z -> A1.
Admitted.
Implicit Arguments access.

(*Why logic*) Definition update :
  forall (A1:Set), (array A1) -> Z -> A1 -> (array A1).
Admitted.
Implicit Arguments update.

(*Why axiom*) Lemma access_update :
  forall (A1:Set),
  (forall (a:(array A1)),
   (forall (i:Z), (forall (v:A1), (access (update a i v) i) = v))).
Admitted.

(*Why axiom*) Lemma access_update_neq :
  forall (A1:Set),
  (forall (a:(array A1)),
   (forall (i:Z),
    (forall (j:Z),
     (forall (v:A1), (i <> j -> (access (update a i v) j) = (access a j)))))).
Admitted.

(*Why logic*) Definition array_length : forall (A1:Set), (array A1) -> Z.
Admitted.
Implicit Arguments array_length.

(*Why predicate*) Definition sorted_array  (t:(array Z)) (i:Z) (j:Z)
  := (forall (k1:Z),
      (forall (k2:Z),
       ((i <= k1 /\ k1 <= k2) /\ k2 <= j -> (access t k1) <= (access t k2)))).

(*Why predicate*) Definition exchange (A112:Set) (a1:(array A112)) (a2:(array A112)) (i:Z) (j:Z)
  := (array_length a1) = (array_length a2) /\
     (access a1 i) = (access a2 j) /\ (access a2 i) = (access a1 j) /\
     (forall (k:Z), (k <> i /\ k <> j -> (access a1 k) = (access a2 k))).
Implicit Arguments exchange.

(*Why logic*) Definition permut :
  forall (A1:Set), (array A1) -> (array A1) -> Z -> Z -> Prop.
Admitted.
Implicit Arguments permut.

(*Why axiom*) Lemma permut_refl :
  forall (A1:Set),
  (forall (t:(array A1)), (forall (l:Z), (forall (u:Z), (permut t t l u)))).
Admitted.

(*Why axiom*) Lemma permut_sym :
  forall (A1:Set),
  (forall (t1:(array A1)),
   (forall (t2:(array A1)),
    (forall (l:Z), (forall (u:Z), ((permut t1 t2 l u) -> (permut t2 t1 l u)))))).
Admitted.

(*Why axiom*) Lemma permut_trans :
  forall (A1:Set),
  (forall (t1:(array A1)),
   (forall (t2:(array A1)),
    (forall (t3:(array A1)),
     (forall (l:Z),
      (forall (u:Z),
       ((permut t1 t2 l u) -> ((permut t2 t3 l u) -> (permut t1 t3 l u)))))))).
Admitted.

(*Why axiom*) Lemma permut_exchange :
  forall (A1:Set),
  (forall (a1:(array A1)),
   (forall (a2:(array A1)),
    (forall (l:Z),
     (forall (u:Z),
      (forall (i:Z),
       (forall (j:Z),
        (l <= i /\ i <= u ->
         (l <= j /\ j <= u -> ((exchange a1 a2 i j) -> (permut a1 a2 l u)))))))))).
Admitted.

(*Why axiom*) Lemma exchange_upd :
  forall (A1:Set),
  (forall (a:(array A1)),
   (forall (i:Z),
    (forall (j:Z),
     (exchange a (update (update a i (access a j)) j (access a i)) i j)))).
Admitted.

(*Why axiom*) Lemma permut_weakening :
  forall (A1:Set),
  (forall (a1:(array A1)),
   (forall (a2:(array A1)),
    (forall (l1:Z),
     (forall (r1:Z),
      (forall (l2:Z),
       (forall (r2:Z),
        ((l1 <= l2 /\ l2 <= r2) /\ r2 <= r1 ->
         ((permut a1 a2 l2 r2) -> (permut a1 a2 l1 r1))))))))).
Admitted.

(*Why axiom*) Lemma permut_eq :
  forall (A1:Set),
  (forall (a1:(array A1)),
   (forall (a2:(array A1)),
    (forall (l:Z),
     (forall (u:Z),
      (l <= u ->
       ((permut a1 a2 l u) ->
        (forall (i:Z), (i < l \/ u < i -> (access a2 i) = (access a1 i))))))))).
Admitted.

(*Why predicate*) Definition permutation (A121:Set) (a1:(array A121)) (a2:(array A121))
  := (permut a1 a2 0 ((array_length a1) - 1)).
Implicit Arguments permutation.

(*Why axiom*) Lemma array_length_update :
  forall (A1:Set),
  (forall (a:(array A1)),
   (forall (i:Z),
    (forall (v:A1), (array_length (update a i v)) = (array_length a)))).
Admitted.

(*Why axiom*) Lemma permut_array_length :
  forall (A1:Set),
  (forall (a1:(array A1)),
   (forall (a2:(array A1)),
    (forall (l:Z),
     (forall (u:Z),
      ((permut a1 a2 l u) -> (array_length a1) = (array_length a2)))))).
Admitted.

(*Why predicate*) Definition array_le  (a:(array Z)) (l:Z) (r:Z) (v:Z)
  := (forall (i:Z), (l <= i /\ i <= r -> (access a i) <= v)).

(*Why predicate*) Definition array_ge  (a:(array Z)) (l:Z) (r:Z) (v:Z)
  := (forall (i:Z), (l <= i /\ i <= r -> v <= (access a i))).

(*Why predicate*) Definition partition_p  (a:(array Z)) (l:Z) (r:Z) (p:Z)
  := (l <= p /\ p <= r) /\ (array_le a l (p - 1) (access a p)) /\
     (array_ge a (p + 1) r (access a p)).

