(* This file is generated by Why3's Coq driver *)
(* Beware! Only edit allowed sections below    *)
Require Import BuiltIn.
Require BuiltIn.
Require HighOrd.
Require int.Int.
Require int.Abs.
Require int.EuclideanDivision.

Axiom set : forall (a:Type), Type.
Parameter set_WhyType : forall (a:Type) {a_WT:WhyType a}, WhyType (set a).
Existing Instance set_WhyType.

Parameter mem: forall {a:Type} {a_WT:WhyType a}, a -> (set a) -> Prop.

Parameter infix_eqeq:
  forall {a:Type} {a_WT:WhyType a}, (set a) -> (set a) -> Prop.

Axiom infix_eqeq_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (s1:set a) (s2:set a),
  (infix_eqeq s1 s2) <-> forall (x:a), (mem x s1) <-> (mem x s2).

Axiom extensionality :
  forall {a:Type} {a_WT:WhyType a},
  forall (s1:set a) (s2:set a), (infix_eqeq s1 s2) -> (s1 = s2).

Parameter subset:
  forall {a:Type} {a_WT:WhyType a}, (set a) -> (set a) -> Prop.

Axiom subset_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (s1:set a) (s2:set a),
  (subset s1 s2) <-> forall (x:a), (mem x s1) -> mem x s2.

Axiom subset_refl :
  forall {a:Type} {a_WT:WhyType a}, forall (s:set a), subset s s.

Axiom subset_trans :
  forall {a:Type} {a_WT:WhyType a},
  forall (s1:set a) (s2:set a) (s3:set a), (subset s1 s2) ->
  (subset s2 s3) -> subset s1 s3.

Parameter is_empty: forall {a:Type} {a_WT:WhyType a}, (set a) -> Prop.

Axiom is_empty_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a), (is_empty s) <-> forall (x:a), ~ (mem x s).

Parameter empty: forall {a:Type} {a_WT:WhyType a}, set a.

Axiom empty_def : forall {a:Type} {a_WT:WhyType a}, is_empty (empty : set a).

Parameter add: forall {a:Type} {a_WT:WhyType a}, a -> (set a) -> set a.

Axiom add_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (x:a) (s:set a), forall (y:a),
  (mem y (add x s)) <-> ((y = x) \/ (mem y s)).

Parameter remove: forall {a:Type} {a_WT:WhyType a}, a -> (set a) -> set a.

Axiom remove_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (x:a) (s:set a), forall (y:a),
  (mem y (remove x s)) <-> (~ (y = x) /\ (mem y s)).

Axiom add_remove :
  forall {a:Type} {a_WT:WhyType a},
  forall (x:a) (s:set a), (mem x s) -> ((add x (remove x s)) = s).

Axiom remove_add :
  forall {a:Type} {a_WT:WhyType a},
  forall (x:a) (s:set a), ((remove x (add x s)) = (remove x s)).

Axiom subset_remove :
  forall {a:Type} {a_WT:WhyType a},
  forall (x:a) (s:set a), subset (remove x s) s.

Parameter union:
  forall {a:Type} {a_WT:WhyType a}, (set a) -> (set a) -> set a.

Axiom union_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (s1:set a) (s2:set a), forall (x:a),
  (mem x (union s1 s2)) <-> ((mem x s1) \/ (mem x s2)).

Parameter inter:
  forall {a:Type} {a_WT:WhyType a}, (set a) -> (set a) -> set a.

Axiom inter_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (s1:set a) (s2:set a), forall (x:a),
  (mem x (inter s1 s2)) <-> ((mem x s1) /\ (mem x s2)).

Parameter diff:
  forall {a:Type} {a_WT:WhyType a}, (set a) -> (set a) -> set a.

Axiom diff_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (s1:set a) (s2:set a), forall (x:a),
  (mem x (diff s1 s2)) <-> ((mem x s1) /\ ~ (mem x s2)).

Axiom subset_diff :
  forall {a:Type} {a_WT:WhyType a},
  forall (s1:set a) (s2:set a), subset (diff s1 s2) s1.

Parameter choose: forall {a:Type} {a_WT:WhyType a}, (set a) -> a.

Axiom choose_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a), ~ (is_empty s) -> mem (choose s) s.

Parameter cardinal: forall {a:Type} {a_WT:WhyType a}, (set a) -> Z.

Axiom cardinal_nonneg :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a), (0%Z <= (cardinal s))%Z.

Axiom cardinal_empty :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a), ((cardinal s) = 0%Z) <-> (is_empty s).

Axiom cardinal_add :
  forall {a:Type} {a_WT:WhyType a},
  forall (x:a), forall (s:set a), ~ (mem x s) ->
  ((cardinal (add x s)) = (1%Z + (cardinal s))%Z).

Axiom cardinal_remove :
  forall {a:Type} {a_WT:WhyType a},
  forall (x:a), forall (s:set a), (mem x s) ->
  ((cardinal s) = (1%Z + (cardinal (remove x s)))%Z).

Axiom cardinal_subset :
  forall {a:Type} {a_WT:WhyType a},
  forall (s1:set a) (s2:set a), (subset s1 s2) ->
  ((cardinal s1) <= (cardinal s2))%Z.

Axiom subset_eq :
  forall {a:Type} {a_WT:WhyType a},
  forall (s1:set a) (s2:set a), (subset s1 s2) ->
  ((cardinal s1) = (cardinal s2)) -> infix_eqeq s1 s2.

Axiom cardinal1 :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a), ((cardinal s) = 1%Z) -> forall (x:a), (mem x s) ->
  (x = (choose s)).

(* Why3 assumption *)
Inductive ref (a:Type) :=
  | mk_ref : a -> ref a.
Axiom ref_WhyType : forall (a:Type) {a_WT:WhyType a}, WhyType (ref a).
Existing Instance ref_WhyType.
Arguments mk_ref {a}.

(* Why3 assumption *)
Definition contents {a:Type} {a_WT:WhyType a} (v:ref a) : a :=
  match v with
  | mk_ref x => x
  end.

Axiom union_exchange :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a), ~ (is_empty s') ->
  ((union (add (choose s') s) (remove (choose s') s')) = (union s s')).

Axiom inter_empty :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a), (is_empty s) -> is_empty (inter s s').

Axiom inter_empty_comm :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a), (is_empty s') -> is_empty (inter s s').

Axiom union_empty :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a), (is_empty s) -> ((union s s') = s').

Axiom union_comm :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a), (is_empty s') -> ((union s s') = s).

Axiom union_empty_comm :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a), (is_empty s') -> ((union s s') = s).

Axiom union_add :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a) (x:a), ~ (mem x s') ->
  ((union s (add x s')) = (add x (union s s'))).

Axiom union_add_comm :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a) (x:a), ~ (mem x s') ->
  ((add x (union s s')) = (union s (add x s'))).

Axiom remove_add1 :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (x:a), ~ (mem x s) -> ((remove x (add x s)) = s).

Axiom add_remove1 :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (x:a), (mem x s) -> ((add x (remove x s)) = s).

(* Why3 assumption *)
Definition injective {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}
    (s:set a) (f:a -> b) : Prop :=
  forall (a1:a) (b1:a), ~ (a1 = b1) -> ~ ((f a1) = (f b1)).

Parameter apply:
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}, (set a) ->
  (a -> b) -> set b.

Axiom apply_def :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (f:a -> b),
  ((is_empty s) -> ((apply s f) = (empty : set b))) /\
  (~ (is_empty s) ->
   ((apply s f) = (add (f (choose s)) (apply (remove (choose s) s) f)))).

Axiom apply_spec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (f:a -> b), (injective s f) -> forall (a1:a),
  (mem a1 s) <-> (mem (f a1) (apply s f)).

Axiom apply_choose :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a), forall (f:a -> b),
  ((choose (apply s f)) = (f (choose s))).

Axiom apply_remove_choose :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (f:a -> b), (injective s f) ->
  ((apply (remove (choose s) s) f) =
   (remove (choose (apply s f)) (apply s f))).

Parameter right_injections:
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}, a -> (set b) ->
  set (a* b)%type.

Axiom right_injections_def :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (a1:a) (s:set b),
  ((is_empty s) -> ((right_injections a1 s) = (empty : set (a* b)%type))) /\
  (~ (is_empty s) ->
   ((right_injections a1 s) =
    (add (a1, choose s) (right_injections a1 (remove (choose s) s))))).

Axiom right_injections_spec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (a1:a) (s:set b),
  ((cardinal (right_injections a1 s)) = (cardinal s)) /\
  ((forall (a':a), forall (b1:b),
    (mem (a', b1) (right_injections a1 s)) <-> ((a' = a1) /\ (mem b1 s))) /\
   ((right_injections a1 s) = (apply s (fun (b1:b) => (a1, b1))))).

Parameter left_injections:
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}, (set a) -> b ->
  set (a* b)%type.

Axiom left_injections_def :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (b1:b),
  ((is_empty s) -> ((left_injections s b1) = (empty : set (a* b)%type))) /\
  (~ (is_empty s) ->
   ((left_injections s b1) =
    (add (choose s, b1) (left_injections (remove (choose s) s) b1)))).

Axiom left_injections_spec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (b1:b),
  (forall (a1:a), forall (b':b),
   (mem (a1, b') (left_injections s b1)) <-> ((mem a1 s) /\ (b' = b1))) /\
  (((cardinal (left_injections s b1)) = (cardinal s)) /\
   ((left_injections s b1) = (apply s (fun (a1:a) => (a1, b1))))).

Axiom right_injections_l :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (a1:a) (s:set b),
  ((cardinal (right_injections a1 s)) = (cardinal s)) /\
  ((forall (a':a), forall (b1:b),
    (mem (a', b1) (right_injections a1 s)) <-> ((a' = a1) /\ (mem b1 s))) /\
   ((right_injections a1 s) = (apply s (fun (b1:b) => (a1, b1))))).

Axiom left_injections_l :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (b1:b),
  (forall (a1:a), forall (b':b),
   (mem (a1, b') (left_injections s b1)) <-> ((mem a1 s) /\ (b' = b1))) /\
  (((cardinal (left_injections s b1)) = (cardinal s)) /\
   ((left_injections s b1) = (apply s (fun (a1:a) => (a1, b1))))).

Axiom disjoint_injections :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (b1:b) (c:b), ~ (b1 = c) ->
  (is_empty (inter (right_injections b1 s) (right_injections c s))) /\
  (is_empty (inter (left_injections s b1) (left_injections s c))).

Axiom induction :
  forall {a:Type} {a_WT:WhyType a},
  forall (p:(set a) -> bool) (t:set a),
  (forall (s:set a), (is_empty s) -> ((p s) = true)) ->
  (forall (s:set a), ((p s) = true) -> forall (t1:a), ~ (mem t1 s) ->
   ((p (add t1 s)) = true)) ->
  ((p t) = true).

Axiom cardinal_sum :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a),
  ((cardinal (union s s')) =
   (((cardinal s) + (cardinal s'))%Z - (cardinal (inter s s')))%Z).

Axiom cardinal_sum_empty_inter :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a), ((inter s s') = (empty : set a)) ->
  ((cardinal (union s s')) = ((cardinal s) + (cardinal s'))%Z).

Parameter cartesian_product:
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}, (set a) ->
  (set b) -> set (a* b)%type.

Axiom cartesian_product_spec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s1:set a) (s2:set b),
  ((cardinal (cartesian_product s1 s2)) = ((cardinal s1) * (cardinal s2))%Z) /\
  ((forall (a1:a), forall (b1:b),
    (mem (a1, b1) (cartesian_product s1 s2)) <-> ((mem a1 s1) /\ (mem b1 s2))) /\
   forall (o:(a* b)%type),
   (mem o (cartesian_product s1 s2)) <->
   match o with
   | (a1, b1) => (mem a1 s1) /\ (mem b1 s2)
   end).

(* Why3 assumption *)
Definition commute {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}
    (o:(a* b)%type) : (b* a)%type :=
  match o with
  | (a1, b1) => (b1, a1)
  end.

Axiom commute_inj :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (a1:a) (a':a) (b1:b) (b':b), ((a1 = a') -> ~ (b1 = b')) ->
  ~ ((commute (a1, b1)) = (commute (a', b'))).

Axiom commute_inj_gen :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s1:set a) (s2:set b),
  injective (cartesian_product s1 s2) (fun (y0:(a* b)%type) => (commute y0)).

(* Why3 assumption *)
Definition commute_product {a:Type} {a_WT:WhyType a}
    {b:Type} {b_WT:WhyType b} (s1:set a) (s2:set b) : set (b* a)%type :=
  apply (cartesian_product s1 s2) (fun (y0:(a* b)%type) => (commute y0)).

Axiom commute_product_spec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s1:set a) (s2:set b),
  ((commute_product s1 s2) = (cartesian_product s2 s1)).

(* Why3 assumption *)
Definition commute_product_el {a:Type} {a_WT:WhyType a}
    {b:Type} {b_WT:WhyType b} (s1:set a) (s2:set b) : set (b* a)%type :=
  apply (cartesian_product s1 s2) (fun (y0:(a* b)%type) => (commute y0)).

Axiom commute_product_el_spec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s1:set a) (s2:set b), forall (o:(a* b)%type),
  match o with
  | (a1, b1) =>
      ((mem o (cartesian_product s1 s2)) <-> ((mem a1 s1) /\ (mem b1 s2))) /\
      (((mem a1 s1) /\ (mem b1 s2)) <->
       (mem (b1, a1) (commute_product_el s1 s2)))
  end.

Axiom cartesian_product_union :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s1:set a) (s2:set b) (s3:set b),
  ((cartesian_product s1 (union s2 s3)) =
   (union (cartesian_product s1 s2) (cartesian_product s1 s3))).

Axiom cartesian_union_product :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s1:set a) (s2:set a) (s3:set b),
  ((cartesian_product (union s1 s2) s3) =
   (union (cartesian_product s1 s3) (cartesian_product s2 s3))).

Axiom cartesian_product_cardone_r :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s1:set a) (s2:set b), ((cardinal s1) = 1%Z) ->
  (infix_eqeq (cartesian_product s1 s2) (right_injections (choose s1) s2)) /\
  (infix_eqeq (cartesian_product s1 s2)
   (apply s2 (fun (e2:b) => (choose s1, e2)))).

Axiom cartesian_product_cardone_l :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s1:set a) (s2:set b), ((cardinal s2) = 1%Z) ->
  (infix_eqeq (cartesian_product s1 s2) (left_injections s1 (choose s2))) /\
  (infix_eqeq (cartesian_product s1 s2)
   (apply s1 (fun (e1:a) => (e1, choose s2)))).

Parameter op: forall {im:Type} {im_WT:WhyType im}, im -> im -> im.

Parameter po: forall {im:Type} {im_WT:WhyType im}, im -> im -> im.

Parameter inver: forall {im:Type} {im_WT:WhyType im}, im -> im.

(* Why3 assumption *)
Definition op_neutral_left {im:Type} {im_WT:WhyType im} (op1:im -> im -> im)
    (neutral:im) : Prop :=
  forall (e:im), (((op1 neutral) e) = e).

(* Why3 assumption *)
Definition op_neutral_right {im:Type} {im_WT:WhyType im} (op1:im -> im -> im)
    (neutral:im) : Prop :=
  forall (e:im), (((op1 e) neutral) = e).

(* Why3 assumption *)
Definition op_assoc {im:Type} {im_WT:WhyType im} (op1:im -> im -> im) : Prop :=
  forall (a:im) (b:im) (c:im),
  (((op1 ((op1 a) b)) c) = ((op1 a) ((op1 b) c))).

(* Why3 assumption *)
Definition op_neutral_left_comm {im:Type} {im_WT:WhyType im}
    (op1:im -> im -> im) (neutral:im) : Prop :=
  forall (a:im), (forall (b:im), (((op1 a) b) = b)) -> (a = neutral).

(* Why3 assumption *)
Definition op_refl {im:Type} {im_WT:WhyType im} (op1:im -> im -> im) : Prop :=
  forall (a:im) (b:im), (((op1 a) b) = ((op1 b) a)).

(* Why3 assumption *)
Definition assoc {im:Type} {im_WT:WhyType im} (op1:im -> im -> im) : Prop :=
  forall (a:im) (b:im) (c:im),
  (((op1 ((op1 a) b)) c) = ((op1 a) ((op1 b) c))).

(* Why3 assumption *)
Definition opposite_n {im:Type} {im_WT:WhyType im} (op1:im -> im -> im)
    (po1:im -> im -> im) (neutral:im) : Prop :=
  forall (a:im), (((po1 a) a) = neutral).

(* Why3 assumption *)
Definition inverse {im:Type} {im_WT:WhyType im} (op1:im -> im -> im)
    (po1:im -> im -> im) (inver1:im -> im) : Prop :=
  forall (a:im) (b:im), (((po1 a) b) = ((op1 a) (inver1 b))).

(* Why3 assumption *)
Definition opposite {im:Type} {im_WT:WhyType im} (op1:im -> im -> im)
    (po1:im -> im -> im) : Prop :=
  forall (a:im) (b:im), (((op1 ((po1 a) b)) b) = a).

(* Why3 assumption *)
Definition opposite_com {im:Type} {im_WT:WhyType im} (op1:im -> im -> im)
    (po1:im -> im -> im) : Prop :=
  forall (a:im) (b:im), (((po1 ((op1 a) b)) b) = a).

Axiom refl :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (a:im) (b:im), (op_refl op1) ->
  (((op1 a) b) = ((op1 b) a)).

(* Why3 assumption *)
Definition neutral {im:Type} {im_WT:WhyType im} (op1:im -> im -> im)
    (neutral1:im) : Prop :=
  (op_neutral_left op1 neutral1) /\
  ((op_neutral_right op1 neutral1) /\ (op_assoc op1)).

(* Why3 assumption *)
Definition has_neutral {im:Type} {im_WT:WhyType im} (op1:im -> im -> im) :
    Prop :=
  exists e:im, neutral op1 e.

(* Why3 assumption *)
Definition iterates {im:Type} {im_WT:WhyType im} (op1:im -> im -> im)
    (neutral1:im) : Prop :=
  (op_neutral_left op1 neutral1) /\
  ((op_neutral_right op1 neutral1) /\ ((op_assoc op1) /\ (op_refl op1))).

(* Why3 assumption *)
Definition iterable {im:Type} {im_WT:WhyType im} (op1:im -> im -> im) : Prop :=
  exists e:im, iterates op1 e.

Parameter neutral_elt:
  forall {im:Type} {im_WT:WhyType im}, (im -> im -> im) -> im.

Axiom neutral_elt_spec :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im),
  (has_neutral op1) <-> (neutral op1 (neutral_elt op1)).

(* Why3 assumption *)
Definition inverse_tuple {im:Type} {im_WT:WhyType im} (op1:im -> im -> im)
    (po1:im -> im -> im) (neutral1:im) : Prop :=
  (opposite_n op1 po1 neutral1) /\
  ((opposite op1 po1) /\ (opposite_com op1 po1)).

Parameter iterate:
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  (im -> im -> im) -> (set a) -> (a -> im) -> im.

Axiom Iterate_def_empty :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im), forall (s:set a), forall (f:a -> im),
  (is_empty s) -> ((iterate op1 (empty : set a) f) = (neutral_elt op1)).

Axiom Iterate_add :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im), forall (s:set a), forall (f:a -> im),
  forall (x:a), ~ (mem x s) ->
  ((iterate op1 (add x s) f) = ((op1 (f x)) (iterate op1 s f))).

Axiom minus_zero :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (po1:im -> im -> im) (a:im), (iterable op1) ->
  (inverse_tuple op1 po1 (neutral_elt op1)) ->
  (((po1 a) (neutral_elt op1)) = a).

Axiom unic :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (po1:im -> im -> im) (a:im) (b:im) (c:im),
  (iterable op1) -> (((op1 a) b) = ((op1 a) c)) ->
  (inverse_tuple op1 po1 (neutral_elt op1)) -> (b = c).

Axiom substract_comm :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (po1:im -> im -> im) (a:im) (b:im) (c:im),
  (iterable op1) -> (inverse_tuple op1 po1 (neutral_elt op1)) ->
  (((po1 ((op1 a) b)) a) = b) /\
  ((((po1 ((op1 b) a)) a) = b) /\
   ((((po1 a) ((po1 b) c)) = ((op1 ((po1 a) b)) c)) /\
    (((po1 ((op1 a) b)) c) = ((op1 a) ((po1 b) c))))).

Parameter int_iterate:
  forall {im:Type} {im_WT:WhyType im}, (im -> im -> im) -> (Z -> im) ->
  Z -> Z -> im.

Axiom int_iterate_def :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (i:Z) (j:Z),
  ((j <= i)%Z -> ((int_iterate op1 f i j) = (neutral_elt op1))) /\
  (~ (j <= i)%Z ->
   ((int_iterate op1 f i j) =
    ((op1 (f i)) (int_iterate op1 f (i + 1%Z)%Z j)))).

Axiom int_iterate_spec :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (i:Z) (j:Z), (j <= i)%Z ->
  ((int_iterate op1 f i j) = (neutral_elt op1)).

Parameter int_int_iterate:
  forall {im:Type} {im_WT:WhyType im}, (im -> im -> im) -> (Z -> Z -> im) ->
  Z -> Z -> Z -> Z -> im.

Axiom int_int_iterate_def :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> Z -> im) (i:Z) (j:Z) (k:Z) (l:Z),
  ((j <= i)%Z -> ((int_int_iterate op1 f i j k l) = (neutral_elt op1))) /\
  (~ (j <= i)%Z ->
   ((int_int_iterate op1 f i j k l) =
    ((op1 (int_iterate op1 ((fun (y0:Z -> im) (y1:Z) => (y0 y1)) (f i)) k l))
     (int_int_iterate op1 f (i + 1%Z)%Z j k l)))).

Axiom iterate_empty :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t:a -> im), (is_empty s) ->
  ((iterate op1 s t) = (neutral_elt op1)).

Axiom iterate_add :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (f:a -> im) (x:a), ~ (mem x s) ->
  ((iterate op1 (add x s) f) = ((op1 (f x)) (iterate op1 s f))).

Axiom iterate_remove :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (f:a -> im) (x:a), (iterable op1) ->
  (inverse_tuple op1 (fun (y0:im) (y1:im) => (po y0 y1)) (neutral_elt op1)) ->
  (mem x s) -> ((iterate op1 (remove x s) f) = (po (iterate op1 s f) (f x))).

Axiom iterate_def_choose :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (f:a -> im), (iterable op1) ->
  ~ (is_empty s) ->
  ((iterate op1 s f) =
   ((op1 (f (choose s))) (iterate op1 (remove (choose s) s) f))).

Axiom choose_any :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (f:a -> im) (t:a), (iterable op1) ->
  (mem t s) ->
  ((iterate op1 s f) = ((op1 (f t)) (iterate op1 (remove t s) f))).

Axiom iterate_comp_iterate :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s1:set a) (f:a -> im) (g:a -> im),
  (iterable op1) ->
  ((iterate op1 s1 (fun (k:a) => ((op1 (f k)) (g k)))) =
   ((op1 (iterate op1 s1 (fun (k:a) => (f k))))
    (iterate op1 s1 (fun (k:a) => (g k))))).

Axiom iterate_comp_iterate_com :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s1:set a) (f:a -> im) (g:a -> im),
  (iterable op1) ->
  (((op1 (iterate op1 s1 (fun (k:a) => (f k))))
    (iterate op1 s1 (fun (k:a) => (g k))))
   = (iterate op1 s1 (fun (k:a) => ((op1 (f k)) (g k))))).

Axiom iterate_transitivity :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (po1:im -> im -> im) (s1:set a) (s2:set a)
    (f:a -> im),
  (iterable op1) -> (inverse_tuple op1 po1 (neutral_elt op1)) ->
  ((iterate op1 (union s1 s2) f) =
   ((po1 ((op1 (iterate op1 s1 f)) (iterate op1 s2 f)))
    (iterate op1 (inter s1 s2) f))).

Axiom iterate_disjoint_transitivity :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s1:set a) (s2:set a) (t:a -> im),
  (iterable op1) -> ((inter s1 s2) = (empty : set a)) ->
  ((iterate op1 (union s1 s2) t) =
   ((op1 (iterate op1 s1 t)) (iterate op1 s2 t))).

Axiom iterate_eq :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (f:a -> im) (g:a -> im),
  (forall (x:a), (mem x s) -> ((f x) = (g x))) ->
  ((iterate op1 s f) = (iterate op1 s g)).

Axiom iterate_apply :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}
    {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set b) (f:b -> a) (t:a -> im),
  (iterable op1) -> (injective s f) ->
  ((iterate op1 (apply s f) t) = (iterate op1 s (fun (b1:b) => (t (f b1))))).

Parameter filter:
  forall {a:Type} {a_WT:WhyType a}, (a -> bool) -> (set a) -> set a.

Axiom filter_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (p:a -> bool) (u:set a), forall (x:a),
  (mem x (filter p u)) <-> (((p x) = true) /\ (mem x u)).

Axiom filter_cardinal :
  forall {a:Type} {a_WT:WhyType a},
  forall (p:a -> bool) (u:set a), ((cardinal (filter p u)) <= (cardinal u))%Z.

Parameter map:
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}, (a -> b) ->
  (set a) -> set b.

Axiom map_def1 :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (u:set a), forall (y:b),
  (mem y (map f u)) <-> exists x:a, (mem x u) /\ (y = (f x)).

Axiom map_def2 :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (u:set a), forall (x:a), (mem x u) -> mem (f x) (map f u).

Axiom map_cardinal :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (u:set a), ((cardinal (map f u)) <= (cardinal u))%Z.

Parameter to_fset: Z -> Z -> set Z.

Axiom to_fset_spec :
  forall (i:Z) (j:Z),
  ((i < j)%Z -> ((cardinal (to_fset i j)) = (j - i)%Z)) /\
  (((j <= i)%Z -> is_empty (to_fset i j)) /\
   forall (k:Z), (mem k (to_fset i j)) <-> ((i <= k)%Z /\ (k < j)%Z)).

Axiom choose_to_fset :
  forall (i:Z) (j:Z), (i <= j)%Z -> ((choose (to_fset i j)) = i).

Axiom to_fset_unit_ext :
  forall (i:Z) (j:Z), (i < j)%Z ->
  ((to_fset i j) = (add i (to_fset (i + 1%Z)%Z j))).

Axiom to_fset_ext :
  forall (i:Z) (i':Z) (j:Z), ((i <= i')%Z /\ (i' <= j)%Z) ->
  ((to_fset i j) = (union (to_fset i i') (to_fset i' j))).

Axiom int_iterate_def_empty :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (i:Z) (j:Z), (j <= i)%Z ->
  ((int_iterate op1 f i j) = (neutral_elt op1)).

Axiom int_iterate_def_plus_one :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (i:Z) (j:Z), (i < j)%Z ->
  ((int_iterate op1 f i j) = ((op1 (f i)) (int_iterate op1 f (i + 1%Z)%Z j))).

Axiom int_iterate_def_plus_one_com :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (i:Z) (j:Z), (i < j)%Z ->
  (((op1 (f i)) (int_iterate op1 f (i + 1%Z)%Z j)) = (int_iterate op1 f i j)).

Axiom int_iterate_to_iterate :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (i:Z) (j:Z),
  ((int_iterate op1 f i j) = (iterate op1 (to_fset i j) f)).

Axiom int_iterate_right_extension :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (i:Z) (j:Z), (assoc op1) ->
  (i < j)%Z ->
  ((int_iterate op1 f i j) =
   ((op1 (int_iterate op1 f i (j - 1%Z)%Z)) (f (j - 1%Z)%Z))).

Axiom int_iterate_transitivity :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (i:Z) (k:Z) (j:Z), (assoc op1) ->
  (op_neutral_left op1 (neutral_elt op1)) -> ((i <= k)%Z /\ (k <= j)%Z) ->
  ((int_iterate op1 f i j) =
   ((op1 (int_iterate op1 f i k)) (int_iterate op1 f k j))).

Axiom int_iterate_comp_iterate :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (g:Z -> im) (i:Z) (j:Z),
  (assoc op1) -> (op_neutral_right op1 (neutral_elt op1)) -> (op_refl op1) ->
  ((int_iterate op1 (fun (k:Z) => ((op1 (f k)) (g k))) i j) =
   ((op1 (int_iterate op1 f i j)) (int_iterate op1 g i j))).

Axiom int_iterate_attr :
  forall {im1:Type} {im1_WT:WhyType im1} {im2:Type} {im2_WT:WhyType im2},
  forall (op1:im1 -> im1 -> im1) (op2:im2 -> im2 -> im2) (t:Z -> im1)
    (f:im1 -> im2) (i:Z) (j:Z),
  (forall (x:Z), forall (y:im1),
   (((op2 (f (t x))) (f y)) = (f ((op1 (t x)) y)))) ->
  ((f (neutral_elt op1)) = (neutral_elt op2)) -> (assoc op1) ->
  (assoc op2) ->
  ((int_iterate op2 (fun (e:Z) => (f (t e))) i j) =
   (f (int_iterate op1 t i j))).

Axiom int_iterate_eq :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (g:Z -> im) (i:Z) (j:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ((f k) = (g k))) ->
  ((int_iterate op1 f i j) = (int_iterate op1 g i j)).

Axiom neutrals :
  (0%Z = (neutral_elt (fun (y0:Z) (y1:Z) => (y0 + y1)%Z))) /\
  (1%Z = (neutral_elt (fun (y0:Z) (y1:Z) => (y0 * y1)%Z))).

(* Why3 assumption *)
Definition isum {a:Type} {a_WT:WhyType a} (s:set a) (t:a -> Z) : Z :=
  iterate (fun (y0:Z) (y1:Z) => (y0 + y1)%Z) s t.

Axiom isum_iter : iterates (fun (y0:Z) (y1:Z) => (y0 + y1)%Z) 0%Z.

Axiom isum_iter__ : iterable (fun (y0:Z) (y1:Z) => (y0 + y1)%Z).

Axiom isum_iter_ :
  (opposite_n (fun (y0:Z) (y1:Z) => (y0 + y1)%Z)
   (fun (y0:Z) (y1:Z) => (y0 - y1)%Z) 0%Z) /\
  ((opposite (fun (y0:Z) (y1:Z) => (y0 + y1)%Z)
    (fun (y0:Z) (y1:Z) => (y0 - y1)%Z)) /\
   ((opposite_com (fun (y0:Z) (y1:Z) => (y0 + y1)%Z)
     (fun (y0:Z) (y1:Z) => (y0 - y1)%Z)) /\
    (inverse_tuple (fun (y0:Z) (y1:Z) => (y0 + y1)%Z)
     (fun (y0:Z) (y1:Z) => (y0 - y1)%Z) 0%Z))).

Axiom neutral_zero :
  ((neutral_elt (fun (y0:Z) (y1:Z) => (y0 + y1)%Z)) = 0%Z).

(* Why3 assumption *)
Definition ind_isum (f:Z -> Z) (i:Z) (j:Z) : Z :=
  int_iterate (fun (y0:Z) (y1:Z) => (y0 + y1)%Z) f i j.

Axiom ind_isum_right_extension :
  forall (f:Z -> Z) (i:Z) (j:Z), (i < j)%Z ->
  ((ind_isum f i (j + 1%Z)%Z) = ((ind_isum f i j) + (f j))%Z).

(* Why3 assumption *)
Definition ind_iproduct (f:Z -> Z) (i:Z) (j:Z) : Z :=
  int_iterate (fun (y0:Z) (y1:Z) => (y0 * y1)%Z) f i j.

Axiom ind_iproduct_right_extension :
  forall (f:Z -> Z) (i:Z) (j:Z), (i < j)%Z ->
  ((ind_iproduct f i (j + 1%Z)%Z) = ((ind_iproduct f i j) * (f j))%Z).

Axiom positive_iproduct :
  forall (f:Z -> Z) (i:Z) (j:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> (0%Z < (f k))%Z) ->
  (0%Z < (ind_iproduct f i j))%Z.

(* Why3 assumption *)
Definition antisym {a:Type} {a_WT:WhyType a} (rel:a -> a -> bool) : Prop :=
  forall (a1:a) (b:a), (((rel a1) b) = true) -> (((rel b) a1) = true) ->
  (a1 = b).

(* Why3 assumption *)
Definition transitive {a:Type} {a_WT:WhyType a} (rel:a -> a -> bool) : Prop :=
  forall (a1:a) (b:a) (c:a), (((rel a1) b) = true) -> (((rel b) c) = true) ->
  (((rel a1) c) = true).

(* Why3 assumption *)
Definition reflexive {a:Type} {a_WT:WhyType a} (rel:a -> a -> bool) : Prop :=
  forall (a1:a), (((rel a1) a1) = true).

(* Why3 assumption *)
Definition pre_order {a:Type} {a_WT:WhyType a} (rel:a -> a -> bool) : Prop :=
  (transitive rel) /\ (reflexive rel).

(* Why3 assumption *)
Definition partial_order {a:Type} {a_WT:WhyType a} (rel:a -> a -> bool) :
    Prop :=
  (antisym rel) /\ (pre_order rel).

(* Why3 assumption *)
Definition recip {a:Type} {a_WT:WhyType a} (rrel:a -> a -> bool)
    (rel:a -> a -> bool) : Prop :=
  forall (a1:a) (b:a), (((rrel a1) b) = true) <-> (((rel b) a1) = true).

(* Why3 assumption *)
Definition strict {a:Type} {a_WT:WhyType a} (srel:a -> a -> bool)
    (rel:a -> a -> bool) : Prop :=
  forall (a1:a) (b:a),
  (((srel a1) b) = true) <-> ((((rel a1) b) = true) /\ ~ (a1 = b)).

(* Why3 assumption *)
Definition compat_order_mult {a:Type} {a_WT:WhyType a} (rel:a -> a -> bool)
    (mul:a -> a -> a) (tzero:a) : Prop :=
  forall (a1:a) (b:a) (c:a), (((rel a1) b) = true) ->
  (((rel tzero) c) = true) -> (((rel ((mul a1) c)) ((mul b) c)) = true).

Parameter c_iter:
  forall {a:Type} {a_WT:WhyType a}, (a -> a -> a) -> a -> Z -> a.

Axiom c_iter_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (op1:a -> a -> a) (t:a) (i:Z), (0%Z <= i)%Z ->
  ((c_iter op1 t i) = (int_iterate op1 (fun (k:Z) => t) 0%Z i)).

Axiom c_iter_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (op1:a -> a -> a) (t:a) (i:Z), (0%Z <= i)%Z ->
  ((c_iter op1 t i) = (int_iterate op1 (fun (k:Z) => t) 0%Z i)).

Axiom c_iter_transl :
  forall {a:Type} {a_WT:WhyType a},
  forall (op1:a -> a -> a) (t:a) (i:Z) (k:Z), (assoc op1) -> (0%Z <= k)%Z ->
  (0%Z <= i)%Z ->
  ((c_iter op1 t i) = (int_iterate op1 (fun (k1:Z) => t) k (k + i)%Z)).

Axiom c_iter_0 :
  forall {a:Type} {a_WT:WhyType a},
  forall (op1:a -> a -> a) (x:a), (has_neutral op1) ->
  ((c_iter op1 x 0%Z) = (neutral_elt op1)).

Axiom c_iter_1 :
  forall {a:Type} {a_WT:WhyType a},
  forall (op1:a -> a -> a) (x:a), (has_neutral op1) ->
  ((c_iter op1 x 1%Z) = x).

Axiom c_iter_plus_1 :
  forall {a:Type} {a_WT:WhyType a},
  forall (op1:a -> a -> a) (x:a) (i:Z), (0%Z <= i)%Z -> (has_neutral op1) ->
  ((c_iter op1 x (i + 1%Z)%Z) = ((op1 x) (c_iter op1 x i))).

Axiom c_iter_plus_1_right :
  forall {a:Type} {a_WT:WhyType a},
  forall (op1:a -> a -> a) (x:a) (i:Z), (0%Z <= i)%Z -> (assoc op1) ->
  (has_neutral op1) ->
  ((c_iter op1 x (i + 1%Z)%Z) = ((op1 (c_iter op1 x i)) x)).

Axiom c_iter_s :
  forall {a:Type} {a_WT:WhyType a},
  forall (op1:a -> a -> a) (x:a) (n:Z), (has_neutral op1) -> (0%Z <= n)%Z ->
  ((c_iter op1 x (n + 1%Z)%Z) = ((op1 x) (c_iter op1 x n))) /\
  ((c_iter op1 x (n + 1%Z)%Z) = ((op1 (c_iter op1 x n)) x)).

Axiom c_iter_s_alt :
  forall {a:Type} {a_WT:WhyType a},
  forall (op1:a -> a -> a) (x:a) (n:Z), (has_neutral op1) -> (0%Z < n)%Z ->
  ((c_iter op1 x n) = ((op1 (c_iter op1 x (n - 1%Z)%Z)) x)) /\
  ((c_iter op1 x n) = ((op1 x) (c_iter op1 x (n - 1%Z)%Z))).

Axiom c_iter_sum :
  forall {a:Type} {a_WT:WhyType a},
  forall (op1:a -> a -> a) (x:a) (n:Z) (m:Z), (has_neutral op1) ->
  (0%Z <= n)%Z -> (0%Z <= m)%Z ->
  ((c_iter op1 x (n + m)%Z) = ((op1 (c_iter op1 x n)) (c_iter op1 x m))).

Axiom c_iter_mult :
  forall {a:Type} {a_WT:WhyType a},
  forall (op1:a -> a -> a) (x:a) (n:Z) (m:Z), (has_neutral op1) ->
  (0%Z <= n)%Z -> (0%Z <= m)%Z ->
  ((c_iter op1 x (n * m)%Z) = (c_iter op1 (c_iter op1 x n) m)).

Axiom c_iter_op_comm1 :
  forall {a:Type} {a_WT:WhyType a},
  forall (op1:a -> a -> a) (x:a) (y:a) (n:Z), (op_refl op1) ->
  (0%Z <= n)%Z -> (((op1 (c_iter op1 x n)) y) = ((op1 y) (c_iter op1 x n))).

Axiom c_iter_op_comm2 :
  forall {a:Type} {a_WT:WhyType a},
  forall (op1:a -> a -> a) (x:a) (y:a) (n:Z), (iterable op1) ->
  (0%Z <= n)%Z ->
  ((c_iter op1 ((op1 x) y) n) = ((op1 (c_iter op1 x n)) (c_iter op1 y n))).

Axiom positive_diff : forall (n:Z) (m:Z), (n < m)%Z -> (0%Z < (m - n)%Z)%Z.

Axiom init_c_iter :
  forall {a:Type} {a_WT:WhyType a},
  forall (op1:a -> a -> a) (k:a) (tone:a), (neutral op1 tone) ->
  ((c_iter op1 k 0%Z) = tone) /\ ((c_iter op1 k 2%Z) = ((op1 k) k)).

Axiom positive_c_iter :
  forall {a:Type} {a_WT:WhyType a},
  forall (rel:a -> a -> bool) (srel:a -> a -> bool) (op1:a -> a -> a)
    (tone:a) (tzero:a) (k:a) (n:Z),
  (compat_order_mult rel op1 tzero) -> (partial_order rel) ->
  (((rel tone) k) = true) -> (((srel tzero) tone) = true) ->
  (strict srel rel) -> (neutral op1 tone) -> (0%Z <= n)%Z ->
  (((rel tone) (c_iter op1 k n)) = true) /\
  ((((srel tzero) (c_iter op1 k n)) = true) /\
   (((rel (c_iter op1 k n)) (c_iter op1 k (n + 1%Z)%Z)) = true)).

Axiom strict_positive_c_iter :
  forall {a:Type} {a_WT:WhyType a},
  forall (rel:a -> a -> bool) (srel:a -> a -> bool) (op1:a -> a -> a)
    (tone:a) (tzero:a) (k:a) (n:Z),
  (compat_order_mult rel op1 tzero) -> (compat_order_mult srel op1 tzero) ->
  (((srel tzero) tone) = true) -> (partial_order rel) ->
  (neutral op1 tone) -> (((srel tone) k) = true) -> (strict srel rel) ->
  (0%Z < n)%Z ->
  (((srel tone) (c_iter op1 k n)) = true) /\
  ((((srel (c_iter op1 k (n - 1%Z)%Z)) (c_iter op1 k n)) = true) /\
   (((srel (c_iter op1 k n)) (c_iter op1 k (n + 1%Z)%Z)) = true)).

Axiom growing_c_iter :
  forall {a:Type} {a_WT:WhyType a},
  forall (rel:a -> a -> bool) (srel:a -> a -> bool) (op1:a -> a -> a)
    (tone:a) (tzero:a) (k:a) (m:Z) (n:Z),
  (compat_order_mult rel op1 tzero) -> (((srel tzero) tone) = true) ->
  (compat_order_mult srel op1 tzero) -> (partial_order rel) ->
  (neutral op1 tone) -> (((srel tone) k) = true) -> (strict srel rel) ->
  (((rel tone) k) = true) -> ((0%Z <= m)%Z /\ (m <= n)%Z) ->
  (((rel (c_iter op1 k m)) (c_iter op1 k n)) = true).

Axiom strict_growing_c_iter :
  forall {a:Type} {a_WT:WhyType a},
  forall (rel:a -> a -> bool) (srel:a -> a -> bool) (op1:a -> a -> a)
    (tone:a) (tzero:a) (k:a) (m:Z) (n:Z),
  (compat_order_mult rel op1 tzero) -> (compat_order_mult srel op1 tzero) ->
  (((srel tzero) tone) = true) -> (partial_order rel) ->
  (neutral op1 tone) -> (((srel tone) k) = true) -> (strict srel rel) ->
  (((srel tone) k) = true) -> ((0%Z <= m)%Z /\ (m < n)%Z) ->
  (((srel (c_iter op1 k m)) (c_iter op1 k n)) = true).

Axiom unicity_c_iter :
  forall {a:Type} {a_WT:WhyType a},
  forall (rel:a -> a -> bool) (srel:a -> a -> bool) (op1:a -> a -> a)
    (tone:a) (tzero:a) (k:a) (m:Z) (n:Z),
  (compat_order_mult rel op1 tzero) -> (compat_order_mult srel op1 tzero) ->
  (((srel tzero) tone) = true) -> (partial_order rel) ->
  (neutral op1 tone) -> (((srel tone) k) = true) -> (strict srel rel) ->
  (0%Z <= m)%Z -> (0%Z <= n)%Z ->
  ((c_iter op1 k m) = (c_iter op1 k n)) <-> (m = n).

Parameter power: Z -> Z -> Z.

Axiom power_def :
  forall (e:Z) (i:Z), (0%Z <= i)%Z ->
  ((power e i) = (c_iter (fun (y0:Z) (y1:Z) => (y0 * y1)%Z) e i)).

Axiom power_spec :
  forall (e:Z) (i:Z), (0%Z <= i)%Z ->
  ((power e i) =
   (int_iterate (fun (y0:Z) (y1:Z) => (y0 * y1)%Z) (fun (k:Z) => e) 0%Z i)).

Parameter infix_ls_closure: Z -> Z -> bool.

Parameter infix_lseq_closure: Z -> Z -> bool.

Axiom infix_ls_closure_def :
  forall (y:Z) (y1:Z), (((infix_ls_closure y) y1) = true) <-> (y < y1)%Z.

Axiom infix_lseq_closure_def :
  forall (y:Z) (y1:Z), (((infix_lseq_closure y) y1) = true) <-> (y <= y1)%Z.

Axiom pre_cond_int :
  (compat_order_mult infix_ls_closure (fun (y0:Z) (y1:Z) => (y0 * y1)%Z) 0%Z) /\
  ((compat_order_mult infix_lseq_closure (fun (y0:Z) (y1:Z) => (y0 * y1)%Z)
    0%Z) /\
   ((0%Z < 1%Z)%Z /\
    ((partial_order infix_lseq_closure) /\
     ((neutral (fun (y0:Z) (y1:Z) => (y0 * y1)%Z) 1%Z) /\
      ((iterable (fun (y0:Z) (y1:Z) => (y0 * y1)%Z)) /\
       (strict infix_ls_closure infix_lseq_closure)))))).

Axiom power_sum :
  forall (x:Z) (n:Z) (m:Z), (0%Z <= n)%Z -> (0%Z <= m)%Z ->
  ((power x (n + m)%Z) = ((power x n) * (power x m))%Z).

Axiom c_iter_comm1 :
  forall {a:Type} {a_WT:WhyType a},
  forall (op1:a -> a -> a) (x:a) (y:a) (n:Z), (op_refl op1) ->
  (0%Z <= n)%Z -> (((op1 (c_iter op1 x n)) y) = ((op1 y) (c_iter op1 x n))).

Axiom c_iter_op_comm11 :
  forall (x:Z) (y:Z) (n:Z), (0%Z <= n)%Z ->
  (((power x n) * y)%Z = (y * (power x n))%Z).

Axiom c_iter_op_comm21 :
  forall (x:Z) (y:Z) (n:Z), (0%Z <= n)%Z ->
  ((power (x * y)%Z n) = ((power x n) * (power y n))%Z).

Axiom growing_mult :
  forall (n:Z) (m:Z), (0%Z <= n)%Z -> (1%Z <= m)%Z -> (n <= (n * m)%Z)%Z.

Axiom strict_growing_mult :
  forall (n:Z) (m:Z), (1%Z < n)%Z -> (1%Z < m)%Z -> (n < (n * m)%Z)%Z.

Axiom init_exp :
  forall (k:Z),
  ((power k 0%Z) = 1%Z) /\
  (((power k 1%Z) = k) /\ ((power k 2%Z) = (k * k)%Z)).

Axiom positive_int_exp :
  forall (k:Z) (n:Z), (1%Z <= k)%Z -> (0%Z <= n)%Z ->
  (1%Z <= (power k n))%Z /\
  ((0%Z < (power k n))%Z /\ ((power k n) <= (power k (n + 1%Z)%Z))%Z).

Axiom strict_positive_int_exp :
  forall (k:Z) (n:Z), (1%Z < k)%Z -> (0%Z < n)%Z ->
  (1%Z < (power k n))%Z /\
  (((power k (n - 1%Z)%Z) < (power k n))%Z /\
   ((power k n) < (power k (n + 1%Z)%Z))%Z).

Axiom growing_exp :
  forall (k:Z) (m:Z) (n:Z), (1%Z <= k)%Z -> ((0%Z <= m)%Z /\ (m <= n)%Z) ->
  ((power k m) <= (power k n))%Z.

Axiom strict_growing_exp :
  forall (k:Z) (m:Z) (n:Z), (1%Z < k)%Z -> ((0%Z <= m)%Z /\ (m < n)%Z) ->
  ((power k m) < (power k n))%Z.

Axiom unicity_exp :
  forall (k:Z) (m:Z) (n:Z), (1%Z < k)%Z -> (0%Z <= m)%Z -> (0%Z <= n)%Z ->
  ((power k m) = (power k n)) <-> (m = n).

Axiom bounded_sum_exp :
  forall (i:Z) (j:Z) (k:Z) (m:Z) (n:Z), (0%Z < k)%Z -> (0%Z <= m)%Z ->
  (0%Z <= n)%Z -> (i < (power 2%Z m))%Z -> (j < (power 2%Z n))%Z ->
  (((i * (power 2%Z n))%Z + j)%Z < (power 2%Z (m + n)%Z))%Z.

Axiom div_plus_one :
  forall (i:Z) (j:Z), (0%Z <= i)%Z -> (0%Z < j)%Z ->
  (((int.EuclideanDivision.div i j) * j)%Z <= i)%Z /\
  (i < (((int.EuclideanDivision.div i j) + 1%Z)%Z * j)%Z)%Z.

Axiom bound_mod :
  forall (i:Z) (j:Z), (0%Z <= i)%Z -> (0%Z < j)%Z ->
  (0%Z <= (int.EuclideanDivision.mod1 i j))%Z /\
  ((int.EuclideanDivision.mod1 i j) < j)%Z.

Axiom unicity_div_mod :
  forall (i:Z) (j:Z) (q:Z) (r:Z), (0%Z <= i)%Z -> (0%Z <= q)%Z ->
  (0%Z <= r)%Z -> (0%Z < j)%Z -> (i = ((q * j)%Z + r)%Z) ->
  ((0%Z <= r)%Z /\ (r < j)%Z) ->
  (q = (int.EuclideanDivision.div i j)) /\
  (r = (int.EuclideanDivision.mod1 i j)).

Axiom decomp :
  forall (i:Z) (j:Z), (0%Z <= i)%Z -> (0%Z < j)%Z ->
  (i =
   ((j * (int.EuclideanDivision.div i j))%Z +
    (int.EuclideanDivision.mod1 i j))%Z).

Axiom div_plus_quotient :
  forall (i:Z) (j:Z), (0%Z <= i)%Z -> (0%Z < j)%Z ->
  ((int.EuclideanDivision.div (i + j)%Z j) =
   ((int.EuclideanDivision.div i j) + 1%Z)%Z).

Axiom div_plus_fact_gen_div :
  forall (i:Z) (j:Z) (k:Z), (0%Z <= i)%Z -> (0%Z < j)%Z -> (0%Z < k)%Z ->
  ((int.EuclideanDivision.div (i + (k * j)%Z)%Z j) =
   ((int.EuclideanDivision.div i j) + k)%Z).

Axiom mod_plus_fact_gen_mod :
  forall (i:Z) (j:Z) (k:Z), (0%Z <= i)%Z -> (0%Z < j)%Z -> (0%Z <= k)%Z ->
  ((int.EuclideanDivision.mod1 ((k * j)%Z + i)%Z j) =
   (int.EuclideanDivision.mod1 i j)).

Axiom bound_div :
  forall (i:Z) (q:Z) (f:Z), (0%Z <= i)%Z -> (0%Z <= q)%Z -> (0%Z <= f)%Z ->
  (i < (f * q)%Z)%Z ->
  ((0%Z <= ((int.EuclideanDivision.div i q) * q)%Z)%Z /\
   ((((int.EuclideanDivision.div i q) * q)%Z <= i)%Z /\
    (i < (q * ((int.EuclideanDivision.div i q) + 1%Z)%Z)%Z)%Z)) /\
  ((int.EuclideanDivision.div i q) < f)%Z.

Axiom mod_invariant :
  forall (i:Z) (q:Z) (f:Z), (0%Z <= i)%Z -> (0%Z < q)%Z -> (0%Z < f)%Z ->
  ((int.EuclideanDivision.mod1
    ((q * (f * (int.EuclideanDivision.div i (q * f)%Z))%Z)%Z +
     (int.EuclideanDivision.mod1 i (q * f)%Z))%Z
    q)
   = (int.EuclideanDivision.mod1 (int.EuclideanDivision.mod1 i (q * f)%Z) q)).

Axiom mod_mod :
  forall (i:Z) (j:Z) (f:Z), (0%Z <= i)%Z -> (0%Z < j)%Z -> (0%Z < f)%Z ->
  ((int.EuclideanDivision.mod1 (int.EuclideanDivision.mod1 i (j * f)%Z) j) =
   (int.EuclideanDivision.mod1 i j)) /\
  ((int.EuclideanDivision.mod1 (int.EuclideanDivision.mod1 i (f * j)%Z) j) =
   (int.EuclideanDivision.mod1 i j)).

Axiom mod_mod_rev :
  forall (i:Z) (j:Z) (f:Z), (0%Z <= i)%Z -> (0%Z < j)%Z -> (0%Z < f)%Z ->
  ((int.EuclideanDivision.mod1 i j) =
   (int.EuclideanDivision.mod1 (int.EuclideanDivision.mod1 i (j * f)%Z) j)) /\
  ((int.EuclideanDivision.mod1 i j) =
   (int.EuclideanDivision.mod1 (int.EuclideanDivision.mod1 i (f * j)%Z) j)).

Axiom mod_mod_plus :
  forall (i:Z) (j:Z), (0%Z <= i)%Z -> (0%Z < j)%Z ->
  ((int.EuclideanDivision.mod1 i j) =
   (int.EuclideanDivision.mod1 (int.EuclideanDivision.mod1 i (j + j)%Z) j)).

Axiom mult_assoc :
  forall (i:Z) (q:Z) (f:Z), (0%Z <= i)%Z -> (0%Z < q)%Z -> (0%Z < f)%Z ->
  ((q * (f * (int.EuclideanDivision.div i (q * f)%Z))%Z)%Z =
   ((q * f)%Z * (int.EuclideanDivision.div i (q * f)%Z))%Z).

Axiom div_div :
  forall (i:Z) (j:Z) (k:Z), (0%Z <= i)%Z -> (0%Z < j)%Z -> (0%Z < k)%Z ->
  ((int.EuclideanDivision.div (int.EuclideanDivision.div i k) j) =
   (int.EuclideanDivision.div i (k * j)%Z)) /\
  ((int.EuclideanDivision.div (int.EuclideanDivision.div i k) j) =
   (int.EuclideanDivision.div i (j * k)%Z)).

Axiom mod_div :
  forall (i:Z) (j:Z) (k:Z), (0%Z <= i)%Z -> (0%Z < j)%Z -> (0%Z < k)%Z ->
  ((int.EuclideanDivision.div (int.EuclideanDivision.mod1 i (j * k)%Z) j) =
   (int.EuclideanDivision.mod1 (int.EuclideanDivision.div i j) k)).

Axiom inf_mul :
  forall (ia:Z) (ib:Z) (a:Z) (b:Z), ((0%Z <= ia)%Z /\ (ia < a)%Z) ->
  ((0%Z <= ib)%Z /\ (ib < b)%Z) ->
  (((a * ib)%Z + ia)%Z < (a * b)%Z)%Z /\ (((ib * a)%Z + ia)%Z < (b * a)%Z)%Z.

Axiom inf_mul_comm :
  forall (i:Z) (bi:Z) (quot:Z) (rest:Z), ((0%Z <= i)%Z /\ (i < bi)%Z) ->
  (0%Z < rest)%Z -> (0%Z < quot)%Z -> (bi = (quot * rest)%Z) ->
  ((int.EuclideanDivision.div i quot) < rest)%Z /\
  ((int.EuclideanDivision.mod1 i rest) < rest)%Z.

Axiom int_iterate_def_empty1 :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (i:Z) (j:Z), (j <= i)%Z ->
  ((int_iterate op1 f i j) = (neutral_elt op1)).

Axiom int_iterate_def_plus_one1 :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (i:Z) (j:Z), (i < j)%Z ->
  ((int_iterate op1 f i j) = ((op1 (f i)) (int_iterate op1 f (i + 1%Z)%Z j))).

Axiom int_iterate_def_plus_one_com1 :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (i:Z) (j:Z), (i < j)%Z ->
  (((op1 (f i)) (int_iterate op1 f (i + 1%Z)%Z j)) = (int_iterate op1 f i j)).

Axiom int_iterate_to_iterate1 :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (i:Z) (j:Z),
  ((int_iterate op1 f i j) = (iterate op1 (to_fset i j) f)).

Axiom int_iterate_right_extension1 :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (i:Z) (j:Z), (assoc op1) ->
  (i < j)%Z ->
  ((int_iterate op1 f i j) =
   ((op1 (int_iterate op1 f i (j - 1%Z)%Z)) (f (j - 1%Z)%Z))).

Axiom int_iterate_transitivity1 :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (i:Z) (k:Z) (j:Z), (assoc op1) ->
  (op_neutral_left op1 (neutral_elt op1)) -> ((i <= k)%Z /\ (k <= j)%Z) ->
  ((int_iterate op1 f i j) =
   ((op1 (int_iterate op1 f i k)) (int_iterate op1 f k j))).

Axiom int_iterate_comp_iterate1 :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (g:Z -> im) (i:Z) (j:Z),
  (assoc op1) -> (op_neutral_right op1 (neutral_elt op1)) -> (op_refl op1) ->
  ((int_iterate op1 (fun (k:Z) => ((op1 (f k)) (g k))) i j) =
   ((op1 (int_iterate op1 f i j)) (int_iterate op1 g i j))).

Axiom int_iterate_attr1 :
  forall {im1:Type} {im1_WT:WhyType im1} {im2:Type} {im2_WT:WhyType im2},
  forall (op1:im1 -> im1 -> im1) (op2:im2 -> im2 -> im2) (t:Z -> im1)
    (f:im1 -> im2) (i:Z) (j:Z),
  (forall (x:Z), forall (y:im1),
   (((op2 (f (t x))) (f y)) = (f ((op1 (t x)) y)))) ->
  ((f (neutral_elt op1)) = (neutral_elt op2)) -> (assoc op1) ->
  (assoc op2) ->
  ((int_iterate op2 (fun (e:Z) => (f (t e))) i j) =
   (f (int_iterate op1 t i j))).

Axiom int_iterate_eq1 :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (g:Z -> im) (i:Z) (j:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ((f k) = (g k))) ->
  ((int_iterate op1 f i j) = (int_iterate op1 g i j)).

Axiom div_isum_exponents :
  forall (i:Z) (k:Z) (n:Z) (m:Z), (0%Z <= i)%Z -> (0%Z < k)%Z ->
  (0%Z <= n)%Z -> (0%Z <= m)%Z ->
  ((power k (n + m)%Z) = ((power k n) * (power k m))%Z) /\
  (((power k (n + 1%Z)%Z) = ((power k n) * k)%Z) /\
   (((power k 1%Z) = k) /\
    (((int.EuclideanDivision.div (int.EuclideanDivision.div i (power k n))
       (power k m))
      = (int.EuclideanDivision.div i (power k (n + m)%Z))) /\
     ((int.EuclideanDivision.div (int.EuclideanDivision.div i (power k n)) k)
      = (int.EuclideanDivision.div i (power k (n + 1%Z)%Z)))))).

Parameter divp: Z -> Z -> Z.

Axiom divp_def :
  forall (i:Z) (j:Z), (0%Z <= i)%Z -> (0%Z < j)%Z ->
  ((divp i j) = ((int.EuclideanDivision.div i j) * j)%Z).

Axiom divp_spec :
  forall (i:Z) (j:Z), (0%Z <= i)%Z -> (0%Z < j)%Z ->
  (i = ((divp i j) + (int.EuclideanDivision.mod1 i j))%Z) /\
  ((((divp i j) <= i)%Z /\ (i < (((divp i j) + 1%Z)%Z * j)%Z)%Z) /\
   ((j < i)%Z -> (0%Z < (divp i j))%Z)).

Parameter i: Z.

Parameter k: Z.

Parameter f: Z -> Z.

Axiom H : (0%Z <= i)%Z.

Axiom H1 : (0%Z <= k)%Z.

Axiom H2 : forall (k1:Z), (0%Z < (f k1))%Z.

(* Why3 goal *)
Theorem VC_k_th : ~ ((f k) = 0%Z).
Proof.

Qed.