(* This file is generated by Why3's Coq driver *)
(* Beware! Only edit allowed sections below    *)
Require Import BuiltIn.
Require BuiltIn.
Require int.Int.
Require option.Option.
Require list.List.
Require list.Length.
Require list.Mem.
Require map.Map.
Require list.Nth.
Require list.NthLength.
Require list.Append.
Require list.NthLengthAppend.

(* Why3 assumption *)
Definition unit := unit.

(* Why3 assumption *)
Inductive array (a:Type) :=
  | mk_array : Z -> (map.Map.map Z a) -> array a.
Axiom array_WhyType : forall (a:Type) {a_WT:WhyType a}, WhyType (array a).
Existing Instance array_WhyType.
Implicit Arguments mk_array [[a]].

(* Why3 assumption *)
Definition elts {a:Type} {a_WT:WhyType a} (v:(array a)): (map.Map.map Z a) :=
  match v with
  | (mk_array x x1) => x1
  end.

(* Why3 assumption *)
Definition length {a:Type} {a_WT:WhyType a} (v:(array a)): Z :=
  match v with
  | (mk_array x x1) => x
  end.

(* Why3 assumption *)
Definition get {a:Type} {a_WT:WhyType a} (a1:(array a)) (i:Z): a :=
  (map.Map.get (elts a1) i).

(* Why3 assumption *)
Definition set {a:Type} {a_WT:WhyType a} (a1:(array a)) (i:Z) (v:a): (array
  a) := (mk_array (length a1) (map.Map.set (elts a1) i v)).

(* Why3 assumption *)
Inductive buffer
  (a:Type) :=
  | mk_buffer : Z -> Z -> (array a) -> (list a) -> buffer a.
Axiom buffer_WhyType : forall (a:Type) {a_WT:WhyType a}, WhyType (buffer a).
Existing Instance buffer_WhyType.
Implicit Arguments mk_buffer [[a]].

(* Why3 assumption *)
Definition sequence {a:Type} {a_WT:WhyType a} (v:(buffer a)): (list a) :=
  match v with
  | (mk_buffer x x1 x2 x3) => x3
  end.

(* Why3 assumption *)
Definition data {a:Type} {a_WT:WhyType a} (v:(buffer a)): (array a) :=
  match v with
  | (mk_buffer x x1 x2 x3) => x2
  end.

(* Why3 assumption *)
Definition len {a:Type} {a_WT:WhyType a} (v:(buffer a)): Z :=
  match v with
  | (mk_buffer x x1 x2 x3) => x1
  end.

(* Why3 assumption *)
Definition first {a:Type} {a_WT:WhyType a} (v:(buffer a)): Z :=
  match v with
  | (mk_buffer x x1 x2 x3) => x
  end.

(* Why3 assumption *)
Definition size {a:Type} {a_WT:WhyType a} (b:(buffer a)): Z :=
  (length (data b)).

Require Import Why3.
Ltac ae := why3 "Alt-Ergo,0.99.1," timelimit 5; admit.

(* Why3 goal *)
Theorem WP_parameter_pop : forall {a:Type} {a_WT:WhyType a}, forall (b:Z)
  (b1:Z) (b2:Z) (b3:(map.Map.map Z a)) (b4:(list a)), (((((0%Z <= b)%Z /\
  (b < b2)%Z) /\ (((0%Z <= b1)%Z /\ (b1 <= b2)%Z) /\
  ((b1 = (list.Length.length b4)) /\ forall (i:Z), ((0%Z <= i)%Z /\
  (i < b1)%Z) -> ((((b + i)%Z < b2)%Z -> ((list.Nth.nth i
  b4) = (Init.Datatypes.Some (map.Map.get b3 (b + i)%Z)))) /\
  ((0%Z <= ((b + i)%Z - b2)%Z)%Z -> ((list.Nth.nth i
  b4) = (Init.Datatypes.Some (map.Map.get b3 ((b + i)%Z - b2)%Z)))))))) /\
  (0%Z <= b2)%Z) /\ (0%Z < b1)%Z) -> forall (x:a) (x1:(list a)),
  (b4 = (Init.Datatypes.cons x x1)) -> forall (rho:(list a)), (rho = x1) ->
  (((0%Z <= b)%Z /\ (b < b2)%Z) -> forall (rho1:Z), (rho1 = (b1 - 1%Z)%Z) ->
  forall (rho2:Z), (rho2 = (b + 1%Z)%Z) -> ((~ (rho2 = b2)) ->
  ((((0%Z <= rho2)%Z /\ (rho2 < b2)%Z) /\ (((0%Z <= rho1)%Z /\
  (rho1 <= b2)%Z) /\ ((rho1 = (list.Length.length rho)) /\ forall (i:Z),
  ((0%Z <= i)%Z /\ (i < rho1)%Z) -> ((((rho2 + i)%Z < b2)%Z ->
  ((list.Nth.nth i rho) = (Init.Datatypes.Some (map.Map.get b3
  (rho2 + i)%Z)))) /\ ((0%Z <= ((rho2 + i)%Z - b2)%Z)%Z -> ((list.Nth.nth i
  rho) = (Init.Datatypes.Some (map.Map.get b3
  ((rho2 + i)%Z - b2)%Z)))))))) -> forall (x2:a) (x3:(list a)),
  (b4 = (Init.Datatypes.cons x2 x3)) -> ((map.Map.get b3 b) = x2)))).
(* Why3 intros a a_WT b b1 b2 b3 b4 ((((h1,h2),((h3,h4),(h5,h6))),h7),h8) x
        x1 h9 rho h10 (h11,h12) rho1 h13 rho2 h14 h15
        ((h16,h17),((h18,h19),(h20,h21))) x2 x3 h22. *)
intros a a_WT b b1 b2 b3 b4 ((((h1,h2),((h3,h4),(h5,h6))),h7),h8) x x1 h9 rho
h10 (h11,h12) rho1 h13 rho2 h14 h15 ((h16,h17),((h18,h19),(h20,h21))) x2 x3
h22.
generalize (h6 0)%Z.
ae.
Admitted.

