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

Require Export find_spec.
Require Import find_lemmas.
Require Import find_proofs.

Require Import Why.
Require Import Omega.


Proof.
intros; generalize le_f_N; generalize le_1_f.
intuition; SameLength A0 A; omega.
Qed.

Proof.
intuition SameLength A1 A.
unfold i_invariant in H13; omega.
omega.
Qed.

Proof.
intros.
 subst r.
subst i3.
generalize
 (subgoal_1 m1 n1 i1 j1 i2 A A0 A1 Inv_mn Test14 zero_f_SN Inv_ij Test9
    Inv_i Test4).
intuition.
Qed.

Proof.
intuition.
unfold j_invariant in H8; unfold termination in H12; omega.
Qed.

Proof.
intuition SameLength A1 A.
unfold j_invariant in H8; unfold termination in H12; omega.
unfold j_invariant in H8; unfold termination in H12; omega.
Qed.

Proof.
intros.
 subst r.
subst j3.
generalize
 (subgoal_2 m1 n1 i1 j1 i2 j2 A A0 A1 Inv_mn Test14 zero_f_SN Inv_ij
    Test9 Inv_i Inv_j Test6).
intuition.
Qed.

Proof.
intuition.
unfold m_invariant in H7.
unfold termination in H12.
omega.
Qed.

Proof.
intuition.
Qed.

Proof.
intuition SameLength A1 A.
unfold i_invariant in H16; omega.
unfold i_invariant in H16; omega.
Qed.

Proof.
intuition SameLength A1 A.
unfold termination in H28; unfold j_invariant in H25; omega.
unfold termination in H28; unfold j_invariant in H25; omega.
Qed.

Proof.
intuition WhyArrays.
ArraySubst A2; omega.
Qed.

Proof.
intros.
subst r.
assert (H: exchange A3 A1 i2 j2).
subst A3.
 subst A2.
 subst w.
auto with datatypes.

assert (H0: (access A3 i2 <= access A0 f)).
elim H; intros; rewrite H3; omega.
assert (H1: (access A0 f <= access A3 j2)).
elim H; intros; rewrite H5; omega.
generalize
 (subgoal_3 m1 n1 i1 j1 i2 j2 A A0 A1 A3 Pre27 Inv_mn Test14 zero_f_SN
    Inv_ij Test9 Inv_i Inv_j Pre22 Test8 H H0 H1).
intuition subst; intuition.
Qed.

Proof.
intuition.
 Qed.

Proof.
intros; subst r i j; intuition.
apply Lemma_4_14; auto.
elim H; elim H3; omega.
apply Lemma_5_14'; auto.
elim H; elim H3; omega.
unfold termination; right; elim H; elim H3; intros; split.
omega.
auto.
Qed.

Proof.
intuition elim H13; omega.
Qed.

Proof.
intros; subst n2 r.
assert (array_length A0 = array_length A).
intuition; ProveSameLength A0 A.
rewrite H in Pre25; rewrite Pre27 in Pre25.
generalize
 (subgoal_5 m1 n1 i1 j1 A A0 A1 Inv_mn Test14 Pre25 Inv_ij Pre24 Test13).
intuition.
Qed.

Proof.
intros; subst m2 r.
assert (array_length A0 = array_length A).
intuition; ProveSameLength A0 A.
rewrite H in Pre25; rewrite Pre27 in Pre25.
generalize
 (subgoal_6 m1 n1 i1 j1 A A0 A1 Inv_mn Test14 Pre25 Inv_ij Pre24 Test12
    Test11).
intuition.
Qed.

Proof.
intros; subst n2 m2 r.
assert (array_length A0 = array_length A).
intuition; ProveSameLength A0 A.
rewrite H in Pre25; rewrite Pre27 in Pre25.
generalize
 (subgoal_7 m1 n1 i1 j1 A A0 A1 Inv_mn Test14 Pre25 Inv_ij Pre24 Test12
    Test10).
intuition.
Qed.

Proof.
intuition.
subst m; exact (Lemma_1 A).
subst n; exact (Lemma_2 A).
Qed.

Proof.
intuition.
apply Lemma_3 with (m := m1) (n := n1); auto.
Qed.


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.

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.

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 (A119:Set) (a1:(array A119)) (a2:(array A119)) (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 (A128:Set) (a1:(array A128)) (a2:(array A128))
  := (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 logic*) Definition N : Z.
Admitted.

(*Why logic*) Definition f : Z.
Admitted.

(*Why axiom*) Lemma f_N_range : 1 <= f /\ f <= N.
Admitted.

(*Why predicate*) Definition found  (A:(array Z))
  := (forall (p:Z),
      (forall (q:Z),
       (((1 <= p /\ p <= f) /\ f <= q) /\ q <= N -> (access A p) <=
        (access A f) /\ (access A f) <= (access A q)))).

(*Why predicate*) Definition m_invariant  (m:Z) (A:(array Z))
  := m <= f /\
     (forall (p:Z),
      (forall (q:Z),
       (((1 <= p /\ p < m) /\ m <= q) /\ q <= N -> (access A p) <=
        (access A q)))).

(*Why predicate*) Definition n_invariant  (n:Z) (A:(array Z))
  := f <= n /\
     (forall (p:Z),
      (forall (q:Z),
       (((1 <= p /\ p <= n) /\ n < q) /\ q <= N -> (access A p) <=
        (access A q)))).

(*Why predicate*) Definition i_invariant  (m:Z) (n:Z) (i:Z) (r:Z) (A:(array Z))
  := m <= i /\ (forall (p:Z), (1 <= p /\ p < i -> (access A p) <= r)) /\
     ((i <= n -> (exists p:Z, (i <= p /\ p <= n) /\ r <= (access A p)))).

(*Why predicate*) Definition j_invariant  (m:Z) (n:Z) (j:Z) (r:Z) (A:(array Z))
  := j <= n /\ (forall (q:Z), (j < q /\ q <= N -> r <= (access A q))) /\
     ((m <= j -> (exists q:Z, (m <= q /\ q <= j) /\ (access A q) <= r))).

(*Why predicate*) Definition termination  (i:Z) (j:Z) (i0:Z) (j0:Z) (r:Z) (A:(array Z))
  := i > i0 /\ j < j0 \/ (i <= f /\ f <= j) /\ (access A f) = r.

