(* 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.MinMax.
Require int.EuclideanDivision.
Require map.Map.

Axiom t : Type.
Parameter t_WhyType : WhyType t.
Existing Instance t_WhyType.

Parameter tzero: t.

Parameter tone: t.

Parameter prefix_mndt: t -> t.

Parameter infix_mndt: t -> t -> t.

Parameter infix_sldt: t -> t -> t.

Parameter infix_pldt: t -> t -> t.

Parameter infix_asdt: t -> t -> t.

Parameter infix_lseqdt: t -> t -> Prop.

Parameter infix_lsdt: t -> t -> Prop.

Parameter infix_gteqdt: t -> t -> Prop.

Parameter infix_gtdt: t -> t -> Prop.

Axiom inf_st :
  forall (x:t) (y:t), (infix_lsdt x y) <-> ((infix_lseqdt x y) /\ ~ (x = y)).

Axiom sup_eq : forall (x:t) (y:t), (infix_gteqdt x y) <-> (infix_lseqdt y x).

Axiom sup_st :
  forall (x:t) (y:t), (infix_gtdt x y) <-> ((infix_gteqdt x y) /\ ~ (x = y)).

Parameter prefix_mnas: R -> R.

Parameter infix_mnas: R -> R -> R.

Parameter infix_slas: R -> R -> R.

Parameter infix_plas: R -> R -> R.

Parameter infix_asas: R -> R -> R.

Parameter infix_lseqas: R -> R -> Prop.

(* Why3 assumption *)
Definition infix_lsas (x:R) (y:R) : Prop := (infix_lseqas x y) /\ ~ (x = y).

Axiom Two : ((infix_plas 1%R 1%R) = 2%R).

Axiom two : ((infix_plas 1%R 1%R) = 2%R).

Axiom Assoc :
  forall (x:R) (y:R) (z:R),
  ((infix_plas (infix_plas x y) z) = (infix_plas x (infix_plas y z))).

Axiom Unit_def_l : forall (x:R), ((infix_plas 0%R x) = x).

Axiom Unit_def_r : forall (x:R), ((infix_plas x 0%R) = x).

Axiom Inv_def_l : forall (x:R), ((infix_plas (prefix_mnas x) x) = 0%R).

Axiom Inv_def_r : forall (x:R), ((infix_plas x (prefix_mnas x)) = 0%R).

Axiom Comm : forall (x:R) (y:R), ((infix_plas x y) = (infix_plas y x)).

Axiom Assoc1 :
  forall (x:R) (y:R) (z:R),
  ((infix_asas (infix_asas x y) z) = (infix_asas x (infix_asas y z))).

Axiom Mul_distr_l :
  forall (x:R) (y:R) (z:R),
  ((infix_asas x (infix_plas y z)) =
   (infix_plas (infix_asas x y) (infix_asas x z))).

Axiom Mul_distr_r :
  forall (x:R) (y:R) (z:R),
  ((infix_asas (infix_plas y z) x) =
   (infix_plas (infix_asas y x) (infix_asas z x))).

Axiom Comm1 : forall (x:R) (y:R), ((infix_asas x y) = (infix_asas y x)).

Axiom Unitary : forall (x:R), ((infix_asas 1%R x) = x).

Axiom NonTrivialRing : ~ (0%R = 1%R).

Parameter inv: R -> R.

Axiom Inverse : forall (x:R), ~ (x = 0%R) -> ((infix_asas x (inv x)) = 1%R).

Axiom sub_def :
  forall (x:R) (y:R), ((infix_mnas x y) = (infix_plas x (prefix_mnas y))).

Axiom div_def :
  forall (x:R) (y:R), ~ (y = 0%R) ->
  ((infix_slas x y) = (infix_asas x (inv y))).

Axiom absorbinf_zero : forall (x:R), ((infix_asas x 0%R) = 0%R).

Axiom add_div :
  forall (x:R) (y:R) (z:R), ~ (z = 0%R) ->
  ((infix_slas (infix_plas x y) z) =
   (infix_plas (infix_slas x z) (infix_slas y z))).

Axiom sub_div :
  forall (x:R) (y:R) (z:R), ~ (z = 0%R) ->
  ((infix_slas (infix_mnas x y) z) =
   (infix_mnas (infix_slas x z) (infix_slas y z))).

Axiom neg_div :
  forall (x:R) (y:R), ~ (y = 0%R) ->
  ((infix_slas (prefix_mnas x) y) = (prefix_mnas (infix_slas x y))).

Axiom assoc_mul_div :
  forall (x:R) (y:R) (z:R), ~ (z = 0%R) ->
  ((infix_slas (infix_asas x y) z) = (infix_asas x (infix_slas y z))).

Axiom assoc_div_mul :
  forall (x:R) (y:R) (z:R), (~ (y = 0%R) /\ ~ (z = 0%R)) ->
  ((infix_slas (infix_slas x y) z) = (infix_slas x (infix_asas y z))).

Axiom assoc_div_div :
  forall (x:R) (y:R) (z:R), (~ (y = 0%R) /\ ~ (z = 0%R)) ->
  ((infix_slas x (infix_slas y z)) = (infix_slas (infix_asas x z) y)).

Axiom Refl : forall (x:R), infix_lseqas x x.

Axiom Trans :
  forall (x:R) (y:R) (z:R), (infix_lseqas x y) -> (infix_lseqas y z) ->
  infix_lseqas x z.

Axiom Antisymm :
  forall (x:R) (y:R), (infix_lseqas x y) -> (infix_lseqas y x) -> (x = y).

Axiom Total : forall (x:R) (y:R), (infix_lseqas x y) \/ (infix_lseqas y x).

Axiom ZeroLessOne : infix_lseqas 0%R 1%R.

Axiom CompatOrderAdd :
  forall (x:R) (y:R) (z:R), (infix_lseqas x y) ->
  infix_lseqas (infix_plas x z) (infix_plas y z).

Axiom CompatOrderMult :
  forall (x:R) (y:R) (z:R), (infix_lseqas x y) -> (infix_lseqas 0%R z) ->
  infix_lseqas (infix_asas x z) (infix_asas y z).

Parameter from_int: Z -> R.

Axiom Zero : ((from_int 0%Z) = 0%R).

Axiom One : ((from_int 1%Z) = 1%R).

Axiom Add :
  forall (x:Z) (y:Z),
  ((from_int (x + y)%Z) = (infix_plas (from_int x) (from_int y))).

Axiom Sub :
  forall (x:Z) (y:Z),
  ((from_int (x - y)%Z) = (infix_mnas (from_int x) (from_int y))).

Axiom Mul :
  forall (x:Z) (y:Z),
  ((from_int (x * y)%Z) = (infix_asas (from_int x) (from_int y))).

Axiom Neg : forall (x:Z), ((from_int (-x)%Z) = (prefix_mnas (from_int x))).

Axiom Injective :
  forall (x:Z) (y:Z), ((from_int x) = (from_int y)) -> (x = y).

Axiom Monotonic :
  forall (x:Z) (y:Z), (x <= y)%Z -> infix_lseqas (from_int x) (from_int y).

Axiom r_zeroLessOne : infix_lseqas 0%R 1%R.

Axiom r_compatOrderAdd :
  forall (x:R) (y:R) (z:R), (infix_lseqas x y) ->
  infix_lseqas (infix_plas x z) (infix_plas y z).

Axiom r_compatOrderMult :
  forall (x:R) (y:R) (z:R), (infix_lseqas x y) -> (infix_lseqas 0%R z) ->
  infix_lseqas (infix_asas x z) (infix_asas y z).

Axiom Assoc2 :
  forall (x:t) (y:t) (z:t),
  ((infix_pldt (infix_pldt x y) z) = (infix_pldt x (infix_pldt y z))).

Axiom Unit_def_l1 : forall (x:t), ((infix_pldt tzero x) = x).

Axiom Unit_def_r1 : forall (x:t), ((infix_pldt x tzero) = x).

Axiom Inv_def_l1 : forall (x:t), ((infix_pldt (prefix_mndt x) x) = tzero).

Axiom Inv_def_r1 : forall (x:t), ((infix_pldt x (prefix_mndt x)) = tzero).

Axiom Comm2 : forall (x:t) (y:t), ((infix_pldt x y) = (infix_pldt y x)).

Axiom Assoc3 :
  forall (x:t) (y:t) (z:t),
  ((infix_asdt (infix_asdt x y) z) = (infix_asdt x (infix_asdt y z))).

Axiom Mul_distr_l1 :
  forall (x:t) (y:t) (z:t),
  ((infix_asdt x (infix_pldt y z)) =
   (infix_pldt (infix_asdt x y) (infix_asdt x z))).

Axiom Mul_distr_r1 :
  forall (x:t) (y:t) (z:t),
  ((infix_asdt (infix_pldt y z) x) =
   (infix_pldt (infix_asdt y x) (infix_asdt z x))).

Axiom Comm3 : forall (x:t) (y:t), ((infix_asdt x y) = (infix_asdt y x)).

Axiom Unitary1 : forall (x:t), ((infix_asdt tone x) = x).

Axiom NonTrivialRing1 : ~ (tzero = tone).

Parameter inv1: t -> t.

Axiom Inverse1 :
  forall (x:t), ~ (x = tzero) -> ((infix_asdt x (inv1 x)) = tone).

Axiom sub_def1 :
  forall (x:t) (y:t), ((infix_mndt x y) = (infix_pldt x (prefix_mndt y))).

Axiom div_def1 :
  forall (x:t) (y:t), ~ (y = tzero) ->
  ((infix_sldt x y) = (infix_asdt x (inv1 y))).

Axiom absorbinf_zero1 : forall (x:t), ((infix_asdt x tzero) = tzero).

Axiom add_div1 :
  forall (x:t) (y:t) (z:t), ~ (z = tzero) ->
  ((infix_sldt (infix_pldt x y) z) =
   (infix_pldt (infix_sldt x z) (infix_sldt y z))).

Axiom sub_div1 :
  forall (x:t) (y:t) (z:t), ~ (z = tzero) ->
  ((infix_sldt (infix_mndt x y) z) =
   (infix_mndt (infix_sldt x z) (infix_sldt y z))).

Axiom neg_div1 :
  forall (x:t) (y:t), ~ (y = tzero) ->
  ((infix_sldt (prefix_mndt x) y) = (prefix_mndt (infix_sldt x y))).

Axiom assoc_mul_div1 :
  forall (x:t) (y:t) (z:t), ~ (z = tzero) ->
  ((infix_sldt (infix_asdt x y) z) = (infix_asdt x (infix_sldt y z))).

Axiom assoc_div_mul1 :
  forall (x:t) (y:t) (z:t), (~ (y = tzero) /\ ~ (z = tzero)) ->
  ((infix_sldt (infix_sldt x y) z) = (infix_sldt x (infix_asdt y z))).

Axiom assoc_div_div1 :
  forall (x:t) (y:t) (z:t), (~ (y = tzero) /\ ~ (z = tzero)) ->
  ((infix_sldt x (infix_sldt y z)) = (infix_sldt (infix_asdt x z) y)).

Axiom Absorbing_zero :
  forall (a:t) (b:t),
  ((infix_asdt a b) = tzero) <-> (~ (a = tzero) -> (b = tzero)).

Axiom absorbing_zero :
  forall (a:t) (b:t), ((infix_asdt a b) = tzero) ->
  (~ (a = tzero) -> (b = tzero)) /\ (~ (b = tzero) -> (a = tzero)).

Axiom mult_num :
  forall (a:t) (b:t) (c:t), ~ (c = tzero) ->
  ((infix_sldt (infix_asdt a b) c) = (infix_asdt a (infix_sldt b c))).

Axiom mult_denom :
  forall (a:t) (b:t) (c:t), ~ (c = tzero) -> ~ (b = tzero) ->
  ((infix_sldt a (infix_asdt b c)) =
   (infix_asdt (infix_sldt a b) (infix_sldt tone c))).

Axiom mult_simpl :
  forall (a:t) (b:t) (c:t), ~ (c = tzero) -> ~ (b = tzero) ->
  ((infix_sldt (infix_asdt a b) (infix_asdt c b)) = (infix_sldt a c)).

Axiom non_zero_prod :
  forall (a:t) (b:t), ~ (a = tzero) -> ~ (b = tzero) ->
  ~ ((infix_asdt a b) = tzero).

Axiom invadd :
  forall (i:t), ((prefix_mndt i) = (infix_asdt (prefix_mndt tone) i)).

Axiom notZeroAdd :
  forall (x:t) (y:t), ~ (x = tzero) -> ~ ((infix_pldt x y) = y).

Parameter im: t.

Axiom im_Def : ((infix_asdt im im) = (prefix_mndt tone)).

Parameter r_to_t: R -> t.

Axiom r_to_t_zero : ((r_to_t 0%R) = tzero).

Axiom r_to_t_one : ((r_to_t 1%R) = tone).

Axiom r_to_t_add :
  forall (i:R) (j:R),
  ((infix_pldt (r_to_t i) (r_to_t j)) = (r_to_t (infix_plas i j))).

Axiom r_to_t_mult :
  forall (i:R) (j:R),
  ((infix_asdt (r_to_t i) (r_to_t j)) = (r_to_t (infix_asas i j))).

Axiom r_to_t_sub :
  forall (i:R) (j:R),
  ((infix_mndt (r_to_t i) (r_to_t j)) = (r_to_t (infix_mnas i j))).

Axiom r_to_t_div :
  forall (i:R) (j:R), ~ (j = 0%R) ->
  ((infix_sldt (r_to_t i) (r_to_t j)) = (r_to_t (infix_slas i j))).

Axiom r_to_t_inf :
  forall (i:R) (j:R),
  (infix_lseqdt (r_to_t i) (r_to_t j)) <-> (infix_lseqas i j).

Parameter real_part: t -> R.

Parameter im_part: t -> R.

Axiom Real_part_add :
  forall (i:t) (j:t),
  ((real_part (infix_pldt i j)) = (infix_plas (real_part i) (real_part j))).

Axiom Im_part_add :
  forall (i:t) (j:t),
  ((im_part (infix_pldt i j)) = (infix_plas (im_part i) (im_part j))).

Axiom real_part_add :
  forall (i:t) (j:t),
  ((real_part (infix_pldt i j)) = (infix_plas (real_part i) (real_part j))).

Axiom im_part_add :
  forall (i:t) (j:t),
  ((im_part (infix_pldt i j)) = (infix_plas (im_part i) (im_part j))).

Axiom Complex_decomp :
  forall (i:t),
  (i =
   (infix_pldt (r_to_t (real_part i)) (infix_asdt im (r_to_t (im_part i))))).

Axiom Unic_decomp :
  forall (i:t), forall (x:R) (y:R),
  (i = (infix_pldt (r_to_t x) (infix_asdt im (r_to_t y)))) ->
  (x = (real_part i)) /\ (y = (im_part i)).

Axiom injective_real_part :
  forall (i:t) (j:t), ~ ((real_part i) = (real_part j)) -> ~ (i = j).

Axiom injective_im_part :
  forall (i:t) (j:t), ~ ((im_part i) = (im_part j)) -> ~ (i = j).

Axiom complex_decomp :
  forall (i:t),
  (i =
   (infix_pldt (r_to_t (real_part i)) (infix_asdt im (r_to_t (im_part i))))).

Axiom unic_decomp :
  forall (i:t) (x:R) (y:R),
  (i = (infix_pldt (r_to_t x) (infix_asdt im (r_to_t y)))) ->
  (x = (real_part i)) /\ (y = (im_part i)).

(* Why3 assumption *)
Definition real_ (x:t) : Prop := ((im_part x) = 0%R).

(* Why3 assumption *)
Definition pure_im_ (x:t) : Prop := ((real_part x) = 0%R).

Parameter pi: t.

Axiom pi_def : real_ pi.

Axiom r_to_t_real : forall (x:t), (real_ x) -> (x = (r_to_t (real_part x))).

Axiom real_r_to_t : forall (x:R), real_ (r_to_t x).

Axiom r_to_t_pure_im :
  forall (x:t), (pure_im_ x) -> (x = (infix_asdt im (r_to_t (im_part x)))).

Axiom simpl_frac :
  forall (x:t) (y:t), ~ (y = tzero) -> ((infix_sldt (infix_asdt x y) y) = x).

Axiom simpl_frac_ :
  forall (x:t) (y:t) (z:t), ~ (y = tzero) -> ~ (z = tzero) ->
  ((infix_sldt (infix_asdt x y) (infix_asdt z y)) = (infix_sldt x z)).

Axiom fact_frac :
  forall (x:t) (y:t) (z:t), ~ (z = tzero) ->
  ((infix_sldt (infix_asdt x y) z) = (infix_asdt x (infix_sldt y z))).

Axiom inv_mult :
  forall (x:t) (y:t), ~ (x = tzero) -> ~ (y = tzero) ->
  ((infix_asdt (infix_sldt tone x) (infix_sldt tone y)) =
   (infix_sldt tone (infix_asdt x y))).

Axiom Inf_eq_def :
  forall (x:t) (y:t),
  (infix_lseqdt x y) <->
  (((real_ x) /\ ((real_ y) /\ (infix_lseqas (real_part x) (real_part y)))) \/
   (x = y)).

Axiom inf_eq_def :
  forall (x:t) (y:t),
  (infix_lseqdt x y) <->
  (((real_ x) /\ ((real_ y) /\ (infix_lseqas (real_part x) (real_part y)))) \/
   (x = y)).

Axiom inf_def :
  forall (x:t) (y:t),
  (infix_lsdt x y) <->
  ((real_ x) /\ ((real_ y) /\ (infix_lsas (real_part x) (real_part y)))).

Axiom sup_eq_def :
  forall (x:t) (y:t),
  (infix_gteqdt x y) <->
  (((real_ x) /\ ((real_ y) /\ (infix_lseqas (real_part y) (real_part x)))) \/
   (x = y)).

Axiom sup_def :
  forall (x:t) (y:t),
  (infix_gtdt x y) <->
  ((real_ x) /\ ((real_ y) /\ (infix_lsas (real_part y) (real_part x)))).

Axiom decomp_mult :
  forall (a:t) (b:t),
  ((infix_asdt a b) =
   (infix_pldt
    (infix_mndt (infix_asdt (r_to_t (real_part a)) (r_to_t (real_part b)))
     (infix_asdt (r_to_t (im_part a)) (r_to_t (im_part b))))
    (infix_asdt im
     (infix_pldt (infix_asdt (r_to_t (real_part a)) (r_to_t (im_part b)))
      (infix_asdt (r_to_t (real_part b)) (r_to_t (im_part a))))))).

Axiom decomp_mult_real_part :
  forall (a:t) (b:t),
  ((real_part (infix_asdt a b)) =
   (infix_mnas (infix_asas (real_part a) (real_part b))
    (infix_asas (im_part a) (im_part b)))).

Axiom decomp_mult_im_part :
  forall (a:t) (b:t),
  ((im_part (infix_asdt a b)) =
   (infix_plas (infix_asas (real_part a) (im_part b))
    (infix_asas (real_part b) (im_part a)))).

(* Why3 assumption *)
Definition t_real_part (x:t) : t := r_to_t (real_part x).

Axiom t_real_part_spec : forall (x:t), real_ (t_real_part x).

(* Why3 assumption *)
Definition t_im_part (x:t) : t := r_to_t (im_part x).

Axiom t_im_part_spec : forall (x:t), real_ (t_im_part x).

Axiom t_complex_decomp :
  forall (i:t),
  (i = (infix_pldt (t_real_part i) (infix_asdt im (t_im_part i)))).

Axiom t_unic_decomp :
  forall (i:t) (a:t) (b:t), (real_ a) -> (real_ b) ->
  (i = (infix_pldt a (infix_asdt im b))) ->
  (a = (t_real_part i)) /\ (b = (t_im_part i)).

Axiom real_sum :
  forall (x:t) (y:t), (real_ x) -> (real_ y) -> real_ (infix_pldt x y).

Axiom real_diff :
  forall (x:t) (y:t), (real_ x) -> (real_ y) -> real_ (infix_mndt x y).

Axiom pure_im_sum :
  forall (x:t) (y:t), (pure_im_ x) -> (pure_im_ y) ->
  pure_im_ (infix_pldt x y).

Axiom pure_im_diff :
  forall (x:t) (y:t), (pure_im_ x) -> (pure_im_ y) ->
  pure_im_ (infix_mndt x y).

Axiom real_mult :
  forall (x:t) (y:t), (real_ x) -> (real_ y) -> real_ (infix_asdt x y).

Axiom real_inv : forall (x:t), (real_ x) -> ~ (x = tzero) -> real_ (inv1 x).

Axiom real_div :
  forall (x:t) (y:t), (real_ x) -> ~ (y = tzero) -> (real_ y) ->
  real_ (infix_sldt x y).

Axiom mult_real_real :
  forall (a:t) (b:t), (real_ a) -> (real_ b) ->
  (((infix_asdt a b) =
    (infix_asdt (r_to_t (real_part a)) (r_to_t (real_part b)))) /\
   ((infix_asdt (r_to_t (real_part a)) (r_to_t (real_part b))) =
    (r_to_t (infix_asas (real_part a) (real_part b))))) /\
  (((real_part (infix_asdt a b)) = (infix_asas (real_part a) (real_part b))) /\
   ((im_part (infix_asdt a b)) = 0%R)).

Axiom mult_im_im :
  forall (a:t) (b:t), (pure_im_ a) -> (pure_im_ b) ->
  ((infix_asdt a b) =
   (infix_asdt (infix_asdt im im)
    (infix_asdt (r_to_t (im_part a)) (r_to_t (im_part b))))) /\
  (((infix_asdt a b) =
    (prefix_mndt (r_to_t (infix_asas (im_part a) (im_part b))))) /\
   (((real_part (infix_asdt a b)) =
     (prefix_mnas (infix_asas (im_part a) (im_part b)))) /\
    ((im_part (infix_asdt a b)) = 0%R))).

Axiom mult_real_im :
  forall (a:t) (b:t), (real_ a) -> (pure_im_ b) ->
  ((infix_asdt a b) =
   (infix_asdt im (infix_asdt (r_to_t (real_part a)) (r_to_t (im_part b))))) /\
  (((infix_asdt a b) =
    (infix_asdt im (r_to_t (infix_asas (real_part a) (im_part b))))) /\
   (((real_part (infix_asdt a b)) = 0%R) /\
    ((im_part (infix_asdt a b)) = (infix_asas (real_part a) (im_part b))))).

Axiom mult_im_real :
  forall (a:t) (b:t), (pure_im_ a) -> (real_ b) ->
  ((infix_asdt a b) =
   (infix_asdt im (infix_asdt (r_to_t (im_part a)) (r_to_t (real_part b))))) /\
  (((infix_asdt a b) =
    (infix_asdt im (r_to_t (infix_asas (im_part a) (real_part b))))) /\
   (((real_part (infix_asdt a b)) = 0%R) /\
    ((im_part (infix_asdt a b)) = (infix_asas (im_part a) (real_part b))))).

Axiom decomp_mult_gen :
  forall (a:t) (b:t),
  ((real_part (infix_asdt a b)) =
   (infix_mnas (infix_asas (real_part a) (real_part b))
    (infix_asas (im_part a) (im_part b)))) /\
  ((im_part (infix_asdt a b)) =
   (infix_plas (infix_asas (real_part a) (im_part b))
    (infix_asas (im_part a) (real_part b)))).

Axiom inv_real :
  forall (a:t), ~ (a = tzero) -> (real_ a) ->
  ((real_part (inv1 a)) = (infix_slas 1%R (real_part a))) /\ (real_ (inv1 a)).

Axiom zeroLessOne : infix_lseqdt tzero tone.

Axiom compatOrderAdd :
  forall (x:t) (y:t) (z:t), (infix_lseqdt x y) -> (real_ x) -> (real_ y) ->
  (real_ z) -> infix_lseqdt (infix_pldt x z) (infix_pldt y z).

Axiom compat_order_mult :
  forall (x:t) (y:t) (z:t), (infix_lseqdt x y) -> (real_ x) -> (real_ y) ->
  (real_ z) -> (infix_lseqdt tzero z) ->
  infix_lseqdt (infix_asdt x z) (infix_asdt y z).

Axiom strict_compat_order_mult :
  forall (x:t) (y:t) (z:t), (infix_lsdt x y) -> (real_ x) -> (real_ y) ->
  (real_ z) -> (infix_lsdt tzero z) ->
  infix_lsdt (infix_asdt x z) (infix_asdt y z).

Axiom inv_eqinf :
  forall (x:t) (y:t), ((infix_lsdt tzero x) /\ (infix_lseqdt x y)) ->
  infix_gteqdt (inv1 x) (inv1 y).

Axiom inv_inf :
  forall (x:t) (y:t), ((infix_lsdt tzero x) /\ (infix_lsdt x y)) ->
  infix_gtdt (inv1 x) (inv1 y).

Axiom inv_eqsup :
  forall (x:t) (y:t), ((infix_gteqdt x y) /\ (infix_gtdt y tzero)) ->
  infix_lseqdt (inv1 x) (inv1 y).

Axiom inv_sup :
  forall (x:t) (y:t), ((infix_gtdt x y) /\ (infix_gtdt y tzero)) ->
  infix_lsdt (inv1 x) (inv1 y).

Axiom inv_pos :
  forall (x:t), (infix_lsdt tzero x) -> infix_gtdt (inv1 x) tzero.

Axiom inv_neg :
  forall (x:t), (infix_gtdt tzero x) -> infix_lsdt (inv1 x) tzero.

Axiom zero_add_t :
  forall (a1:t) (a2:t), (a1 = tzero) -> ((infix_pldt a1 a2) = a2).

Axiom add_zero_t :
  forall (a1:t) (a2:t), (a2 = tzero) -> ((infix_pldt a1 a2) = a1).

Axiom one_mult_t :
  forall (a1:t) (a2:t), (a1 = tone) -> ((infix_asdt a1 a2) = a2).

Axiom one_mult_t_const : forall (a:t), ((infix_asdt tone a) = a).

Axiom mult_one_t :
  forall (a1:t) (a2:t), (a2 = tone) -> ((infix_asdt a1 a2) = a1).

Axiom add_eq_t :
  forall (a1:t) (a2:t) (b1:t) (b2:t), (a1 = a2) -> (b1 = b2) ->
  ((infix_pldt a1 b1) = (infix_pldt a2 b2)).

Axiom add_eq_t_rev :
  forall (a1:t) (a2:t) (b1:t) (b2:t), (a1 = a2) -> (b1 = b2) ->
  ((infix_pldt a1 b1) = (infix_pldt b2 a2)).

Axiom mult_eq_t :
  forall (a1:t) (a2:t) (b1:t) (b2:t), (a1 = a2) -> (b1 = b2) ->
  ((infix_asdt a1 b1) = (infix_asdt a2 b2)).

Axiom mult_eq_t_rev :
  forall (a1:t) (a2:t) (b1:t) (b2:t), (a1 = a2) -> (b1 = b2) ->
  ((infix_asdt a1 b1) = (infix_asdt b2 a2)).

Axiom mult_comm : forall (a:t) (b:t), ((infix_asdt a b) = (infix_asdt b a)).

Axiom mult_assoc :
  forall (a:t) (b:t) (c:t),
  ((infix_asdt (infix_asdt a b) c) = (infix_asdt a (infix_asdt b c))).

Axiom mult_assoc_rev :
  forall (a:t) (b:t) (c:t),
  ((infix_asdt a (infix_asdt b c)) = (infix_asdt (infix_asdt a b) c)).

Axiom div_mult :
  forall (a:t) (b:t) (c:t), ~ (c = tzero) ->
  ((infix_asdt a (infix_sldt b c)) = (infix_sldt (infix_asdt a b) c)).

Axiom div_mult_rev :
  forall (a:t) (b:t) (c:t), ~ (c = tzero) ->
  ((infix_sldt (infix_asdt a b) c) = (infix_asdt a (infix_sldt b c))).

Axiom div_eq :
  forall (a1:t) (a2:t) (b1:t) (b2:t), (a1 = a2) -> (b1 = b2) ->
  ~ (b1 = tzero) -> ((infix_sldt a1 b1) = (infix_sldt a2 b2)).

Axiom add_eq_inv_t :
  forall (a1:t) (a2:t) (b1:t) (b2:t), (a1 = a2) -> (b1 = b2) ->
  ((infix_pldt a1 b1) = (infix_pldt b2 a2)).

Axiom mult_eq_inv_t :
  forall (a1:t) (a2:t) (b1:t) (b2:t), (a1 = a2) -> (b1 = b2) ->
  ((infix_asdt a1 b1) = (infix_asdt b2 a2)).

Axiom sum_frac :
  forall (a1:t) (a2:t) (b:t), ~ (b = tzero) ->
  ((infix_pldt (infix_sldt a1 b) (infix_sldt a2 b)) =
   (infix_sldt (infix_pldt a1 a2) b)).

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)).

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.

Axiom assert_equal : True.

Axiom goal_comm :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:a) (b:a), (a1 = b) -> (b = a1).

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

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

Axiom projections :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (o:(a* b)%type), (o = (fir o, sec o)).

Axiom get_fir :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (a1:a) (b1:b), ((fir (a1, b1)) = a1).

Axiom get_sec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (a1:a) (b1:b), ((sec (a1, b1)) = b1).

(* 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 get_filter :
  forall {a:Type} {a_WT:WhyType a},
  forall (p:a -> bool) (s:set a) (x:a), (mem x (filter p s)) ->
  ((p x) = true) /\ (mem x s).

Axiom set_filter :
  forall {a:Type} {a_WT:WhyType a},
  forall (p:a -> bool) (s:set a) (x:a), ((p x) = true) -> (mem x s) ->
  mem x (filter p 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_alt :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a) (e:a), (mem e (union s s')) -> ~ (mem e s) ->
  mem e 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 set_subset :
  forall {a:Type} {a_WT:WhyType a},
  forall (s':set a) (s:set a), (forall (e:a), (mem e s') -> mem e s) ->
  subset s' s.

Axiom set_empty :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a), (forall (e:a), ~ (mem e s)) ->
  (s = (empty : set a)) /\ (is_empty s).

Axiom set_equal :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a), (forall (e:a), (mem e s) -> mem e s') ->
  (forall (e:a), (mem e s') -> mem e s) -> (s = s').

Axiom get_empty :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a), (s = (empty : set a)) ->
  (forall (e:a), ~ (mem e s)) /\ (is_empty s).

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

Axiom set_non_empty :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a), (exists e:a, mem e s) ->
  ~ (is_empty s) /\ (0%Z < (cardinal s))%Z.

Axiom set_pos_card_elt :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (a1:a), (mem a1 s) -> (0%Z < (cardinal s))%Z.

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_mem :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a) (x:a) (y:a), (mem x (add y (union s s'))) ->
  ~ (mem x s') -> ~ (mem x s) -> (x = y).

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 p_injective {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}
    (f:a -> b) (s:set a) : Prop :=
  forall (e:a) (e':a), (mem e s) -> (mem e' s) -> ~ (e = e') ->
  ~ ((f e) = (f e')).

Axiom set_map_mem :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (b1:b),
  (exists a1:a, (mem a1 s) /\ (b1 = (f a1))) -> mem b1 (map f s).

Axiom map_add :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (x:a), ~ (mem x s) ->
  ((map f (add x s)) = (add (f x) (map f s))).

Axiom map_eq :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (g:a -> b) (s:set a),
  (forall (e:a), (mem e s) -> ((f e) = (g e))) -> ((map f s) = (map g s)).

Axiom injective_map_cardinal :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a), (p_injective f s) ->
  ((cardinal (map f s)) = (cardinal s)).

Axiom set_map_mem_el :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (b1:b) (a1:a), (mem a1 s) -> (b1 = (f a1)) ->
  mem b1 (map f s).

Axiom set_map_mem_el_gen :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (b1:b),
  (exists a1:a, (mem a1 s) /\ (b1 = (f a1))) -> mem b1 (map f s).

Axiom map_antec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (b1:b), (mem b1 (map f s)) ->
  exists a1:a, (mem a1 s) /\ (b1 = (f a1)).

Axiom map_antec_gen :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a), forall (b1:b), (mem b1 (map f s)) ->
  exists a1:a, (mem a1 s) /\ (b1 = (f a1)).

Axiom map_remove_choose :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (f:a -> b), (p_injective f s) ->
  ((map f (remove (choose s) s)) = (remove (f (choose s)) (map f s))).

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

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

Axiom result_def :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (b1:b) (e:a), (((result f b1) e) = true) <-> ((f e) = b1).

Axiom antec_set_def :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (f:a -> b) (b1:b), (mem b1 (map f s)) ->
  ((antec_set s f b1) = (filter (result f b1) s)).

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

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

Axiom result_def1 :
  forall {a:Type} {a_WT:WhyType a},
  forall (s':set a) (e:a), (((result1 s') e) = true) <-> ~ (mem e s').

Axiom remove_s_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a), (subset s' s) ->
  ((remove_s s s') = (filter (result1 s') s)).

Axiom remove_s_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a), (subset s' s) -> forall (e:a),
  (mem e (remove_s s s')) <-> ((mem e s) /\ ~ (mem e s')).

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

Axiom remove_antecs_def :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (f:a -> b) (b1:b), (mem b1 (map f s)) ->
  ((remove_antecs s f b1) = (remove_s s (antec_set s f b1))).

Axiom remove_antecs_spec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (f:a -> b) (b1:b), (mem b1 (map f s)) ->
  (forall (e:a),
   (mem e (remove_antecs s f b1)) <-> ((mem e s) /\ ~ ((f e) = b1))) /\
  ((cardinal (remove_antecs s f b1)) < (cardinal s))%Z.

Axiom map_remove_antec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (f:a -> b) (b1:b), (mem b1 (map f s)) ->
  ((map f (remove_antecs s f b1)) = (remove b1 (map f s))).

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

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

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) = (map (fun (b1:b) => (a1, b1)) s))).

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) = (map (fun (a1:a) => (a1, b1)) s))).

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) = (map (fun (b1:b) => (a1, b1)) s))).

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) = (map (fun (a1:a) => (a1, b1)) s))).

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) (t1:set a),
  (forall (s:set a), (is_empty s) -> ((p s) = true)) ->
  (forall (s:set a), ((p s) = true) -> forall (t2:a), ~ (mem t2 s) ->
   ((p (add t2 s)) = true)) ->
  ((p t1) = 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)) <->
   ((mem (fir o) s1) /\ (mem (sec o) s2))).

(* 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 mem_cartesian_product :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s1:set a) (s2:set b) (a1:a) (b1:b), (mem a1 s1) -> (mem b1 s2) ->
  mem (a1, b1) (cartesian_product s1 s2).

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

(* 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 :=
  map (fun (y0:(a* b)%type) => (commute y0)) (cartesian_product s1 s2).

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 :=
  map (fun (y0:(a* b)%type) => (commute y0)) (cartesian_product s1 s2).

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)
   (map (fun (e2:b) => (choose s1, e2)) s2)).

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)
   (map (fun (e1:a) => (e1, choose s2)) s1)).

Axiom disjoint_cartesian_product_l :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s1:set a) (s2:set a) (s3:set b),
  ((inter s1 s2) = (empty : set a)) ->
  ((inter (cartesian_product s1 s3) (cartesian_product s2 s3)) =
   (empty : set (a* b)%type)).

Axiom disjoint_cartesian_product_r :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s1:set a) (s2:set b) (s3:set b),
  ((inter s2 s3) = (empty : set b)) ->
  ((inter (cartesian_product s1 s2) (cartesian_product s1 s3)) =
   (empty : set (a* b)%type)).

Axiom to_set_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (e:a),
  ((cardinal (add e (empty : set a))) = 1%Z) /\
  forall (b:a), (mem b (add e (empty : set a))) -> (b = e).

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 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 real : forall (x:t), (real_ x) -> (x = (r_to_t (real_part x))).

Axiom pure_im :
  forall (x:t), (pure_im_ x) -> (x = (infix_asdt im (r_to_t (im_part x)))).

Axiom im_dec : ((real_part im) = 0%R) /\ ((im_part im) = 1%R).

Axiom tone_dec : ((real_part tone) = 1%R) /\ ((im_part tone) = 0%R).

Axiom tzero_dec : ((real_part tzero) = 0%R) /\ ((im_part tzero) = 0%R).

Axiom ttwo_dec :
  ((real_part (infix_pldt tone tone)) = 2%R) /\
  ((im_part (infix_pldt tone tone)) = 0%R).

(* Why3 assumption *)
Definition i_to_t (i:Z) : t := r_to_t (from_int i).

Axiom i_to_t_spec : forall (i:Z), real_ (i_to_t i).

Axiom i_to_t_zero : ((i_to_t 0%Z) = tzero).

Axiom i_to_t_eq : forall (i:Z) (j:Z), (i = j) -> ((i_to_t i) = (i_to_t j)).

Axiom i_to_t_nzero : forall (i:Z), ~ (i = 0%Z) -> ~ ((i_to_t i) = tzero).

Axiom i_to_t_one : ((i_to_t 1%Z) = tone).

Axiom i_to_t_add :
  forall (i:Z) (j:Z),
  ((infix_pldt (i_to_t i) (i_to_t j)) = (i_to_t (i + j)%Z)).

Axiom i_to_t_ttwo : ((i_to_t 2%Z) = (infix_pldt tone tone)).

Axiom i_to_t_mult :
  forall (i:Z) (j:Z),
  ((infix_asdt (i_to_t i) (i_to_t j)) = (i_to_t (i * j)%Z)).

Axiom i_to_t_mult_rev :
  forall (i:Z) (j:Z),
  ((i_to_t (i * j)%Z) = (infix_asdt (i_to_t i) (i_to_t j))).

Axiom i_to_t_sub :
  forall (i:Z) (j:Z),
  ((infix_mndt (i_to_t i) (i_to_t j)) = (i_to_t (i - j)%Z)).

Axiom i_to_t_div :
  forall (i:Z) (j:Z), ~ (j = 0%Z) ->
  ((infix_sldt (i_to_t (i * j)%Z) (i_to_t j)) = (i_to_t i)).

(* 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_mult1 {a:Type} {a_WT:WhyType a} (rel:a -> a -> bool)
    (mul:a -> a -> a) (tzero1:a) : Prop :=
  forall (a1:a) (b:a) (c:a), (((rel a1) b) = true) ->
  (((rel tzero1) c) = true) -> (((rel ((mul a1) c)) ((mul b) c)) = true).

Axiom set_antisym :
  forall {a:Type} {a_WT:WhyType a},
  forall (rel:a -> a -> bool),
  (forall (a1:a) (b:a), (((rel a1) b) = true) -> (((rel b) a1) = true) ->
   (a1 = b)) ->
  antisym rel.

Axiom set_transitive :
  forall {a:Type} {a_WT:WhyType a},
  forall (rel:a -> a -> bool),
  (forall (a1:a) (b:a) (c:a), (((rel a1) b) = true) ->
   (((rel b) c) = true) -> (((rel a1) c) = true)) ->
  transitive rel.

Axiom set_reflexive :
  forall {a:Type} {a_WT:WhyType a},
  forall (rel:a -> a -> bool), (forall (a1:a), (((rel a1) a1) = true)) ->
  reflexive rel.

Axiom set_strict :
  forall {a:Type} {a_WT:WhyType a},
  forall (srel:a -> a -> bool) (rel:a -> a -> bool),
  (forall (a1:a) (b:a),
   (((srel a1) b) = true) <-> ((((rel a1) b) = true) /\ ~ (a1 = b))) ->
  strict srel rel.

Axiom set_partial_order :
  forall {a:Type} {a_WT:WhyType a},
  forall (rel:a -> a -> bool),
  (forall (a1:a) (b:a), (((rel a1) b) = true) -> (((rel b) a1) = true) ->
   (a1 = b)) ->
  (forall (a1:a) (b:a) (c:a), (((rel a1) b) = true) ->
   (((rel b) c) = true) -> (((rel a1) c) = true)) ->
  (forall (a1:a), (((rel a1) a1) = true)) -> partial_order rel.

Axiom compat_order_mul :
  forall {a:Type} {a_WT:WhyType a},
  forall (rel:a -> a -> bool) (mul:a -> a -> a) (tzero1:a),
  (compat_order_mult1 rel mul tzero1) -> forall (a1:a) (b:a) (c:a),
  (((rel a1) b) = true) -> (((rel tzero1) c) = true) ->
  (((rel ((mul a1) c)) ((mul b) c)) = true).

Axiom set_compat_order_mul :
  forall {a:Type} {a_WT:WhyType a},
  forall (rel:a -> a -> bool) (mul:a -> a -> a) (tzero1:a),
  (forall (a1:a) (b:a) (c:a), (((rel a1) b) = true) ->
   (((rel tzero1) c) = true) -> (((rel ((mul a1) c)) ((mul b) c)) = true)) ->
  compat_order_mult1 rel mul tzero1.

Parameter op: forall {im1:Type} {im1_WT:WhyType im1}, im1 -> im1 -> im1.

Parameter po: forall {im1:Type} {im1_WT:WhyType im1}, im1 -> im1 -> im1.

Parameter inver: forall {im1:Type} {im1_WT:WhyType im1}, im1 -> im1.

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

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

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

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

(* Why3 assumption *)
Definition commut {im1:Type} {im1_WT:WhyType im1} (op1:im1 -> im1 -> im1) :
    Prop :=
  forall (a:im1) (b:im1), (((op1 a) b) = ((op1 b) a)).

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

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

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

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

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

Axiom refl :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (a:im1) (b:im1), (commut op1) ->
  (((op1 a) b) = ((op1 b) a)).

(* Why3 assumption *)
Definition neutral {im1:Type} {im1_WT:WhyType im1} (op1:im1 -> im1 -> im1)
    (neut:im1) : Prop :=
  (op_neutral_left op1 neut) /\
  ((op_neutral_right op1 neut) /\ (op_assoc op1)).

Axiom set_neutral :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (neut:im1), (op_neutral_left op1 neut) ->
  (op_neutral_right op1 neut) -> (op_assoc op1) -> neutral op1 neut.

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

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

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

Axiom iterates_ :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (neutral1:im1),
  (op_neutral_left op1 neutral1) -> (op_neutral_right op1 neutral1) ->
  (op_assoc op1) -> (iterates op1 neutral1) /\ (iterable op1).

Parameter neutral_elt:
  forall {im1:Type} {im1_WT:WhyType im1}, (im1 -> im1 -> im1) -> im1.

Axiom neutral_elt_spec :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1), forall (e:im1),
  (neutral op1 e) <-> ((neutral_elt op1) = e).

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

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

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

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

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

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

Axiom substract_comm :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (po1:im1 -> im1 -> im1) (a:im1) (b:im1)
    (c:im1),
  (iterable op1) -> (commut 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 {im1:Type} {im1_WT:WhyType im1}, (im1 -> im1 -> im1) ->
  (Z -> im1) -> Z -> Z -> im1.

Axiom int_iterate_def :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> im1) (i:Z) (j:Z), (iterable op1) ->
  ((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 {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> im1) (i:Z) (j:Z), (iterable op1) ->
  (j <= i)%Z -> ((int_iterate op1 f i j) = (neutral_elt op1)).

Parameter int_int_iterate:
  forall {im1:Type} {im1_WT:WhyType im1}, (im1 -> im1 -> im1) ->
  (Z -> Z -> im1) -> Z -> Z -> Z -> Z -> im1.

Axiom int_int_iterate_def :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> Z -> im1) (i:Z) (j:Z) (k:Z) (l:Z),
  (iterable op1) ->
  ((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 (f i) k l))
     (int_int_iterate op1 f (i + 1%Z)%Z j k l)))).

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

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

Axiom cardone :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (a1:a), (forall (b:a), (mem b s) <-> (b = a1)) ->
  (0%Z < (cardinal s))%Z -> ((cardinal s) = 1%Z) /\ ((element s) = a1).

Axiom set_cardone :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a), (0%Z < (cardinal s))%Z ->
  (exists a1:a, forall (b:a), (mem b s) <-> (b = a1)) -> ((cardinal s) = 1%Z).

Axiom get_cardone :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a), ((cardinal s) = 1%Z) ->
  exists a1:a, forall (b:a), (mem b s) <-> (b = a1).

Axiom set_cardone_elt :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (a1:a), (0%Z < (cardinal s))%Z ->
  (forall (b:a), (mem b s) <-> (b = a1)) ->
  ((cardinal s) = 1%Z) /\ ((element s) = a1).

Axiom cardzero :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a), (forall (b:a), ~ (mem b s)) -> ((cardinal s) = 0%Z).

(* Why3 assumption *)
Definition p_injective_in {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}
    (f:a -> b) (s:set a) (s':set b) : Prop :=
  forall (e:a), (mem e s) ->
  (mem (f e) s') /\
  forall (e1:a) (e':a), (mem e1 s) -> (mem e' s) -> ~ (e1 = e') ->
  ~ ((f e1) = (f e')).

(* Why3 assumption *)
Definition equal_func {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}
    (f:a -> b) (g:a -> b) : Prop :=
  forall (e:a), ((f e) = (g e)).

Axiom set_equal_func :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (g:a -> b), (forall (e:a), ((f e) = (g e))) -> (f = g).

Axiom get_equal_func :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (g:a -> b), (equal_func f g) -> forall (e:a),
  ((f e) = (g e)).

Axiom set_injective :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a),
  (forall (e:a) (e':a), (mem e s) -> (mem e' s) -> ~ (e = e') ->
   ~ ((f e) = (f e'))) ->
  p_injective f s.

Axiom image_spec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a), forall (a1:b),
  (mem a1 (map f s)) <->
  exists antec_a:a, (mem antec_a s) /\ (a1 = (f antec_a)).

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

Axiom card_image_injective :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a), (p_injective f s) ->
  ((cardinal (map f s)) = (cardinal s)).

Axiom get_injective :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a), (p_injective f s) -> forall (e:a) (e':a),
  (mem e s) -> (mem e' s) -> ~ (e = e') -> ~ ((f e) = (f e')).

Axiom set_injective_in :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b),
  (forall (e:a), (mem e s) -> mem (f e) s') ->
  (forall (e:a) (e':a), (mem e s) -> (mem e' s) -> ~ (e = e') ->
   ~ ((f e) = (f e'))) ->
  p_injective f s.

Axiom get_injective_in :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b), (p_injective_in f s s') ->
  (forall (e:a), (mem e s) -> mem (f e) s') /\
  forall (e:a) (e':a), (mem e s) -> (mem e' s) -> ~ (e = e') ->
  ~ ((f e) = (f e')).

(* Why3 assumption *)
Definition p_surjective {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}
    (f:a -> b) (s:set a) (s':set b) : Prop :=
  (forall (e:a), (mem e s) -> mem (f e) s') /\
  forall (e':b), (mem e' s') -> exists e:a, (mem e s) /\ ((f e) = e').

Axiom set_surjective :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b),
  (forall (e:a), (mem e s) -> mem (f e) s') ->
  (forall (e':b), (mem e' s') -> exists e:a, (mem e s) /\ ((f e) = e')) ->
  p_surjective f s s'.

Axiom get_surjective :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b), (p_surjective f s s') ->
  (forall (e:a), (mem e s) -> mem (f e) s') /\
  forall (e':b), (mem e' s') -> exists e:a, (mem e s) /\ ((f e) = e').

Axiom image_surjective :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b), (p_surjective f s s') ->
  ((map f s) = s').

(* Why3 assumption *)
Definition p_bijective {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}
    (f:a -> b) (s:set a) (s':set b) : Prop :=
  (p_injective_in f s s') /\ (p_surjective f s s').

Axiom bijective_is_injective :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b), (p_bijective f s s') ->
  p_injective f s.

Axiom bijective_is_surjective :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b), (p_bijective f s s') ->
  p_surjective f s s'.

Axiom set_bijective :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b),
  (forall (e:a), (mem e s) -> mem (f e) s') ->
  (forall (e:a) (e':a), (mem e s) -> (mem e' s) -> ~ (e = e') ->
   ~ ((f e) = (f e'))) ->
  (forall (e':b), (mem e' s') -> exists e:a, (mem e s) /\ ((f e) = e')) ->
  (p_bijective f s s') /\ ((map f s) = s').

Axiom bijectivity_is_transitive :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}
    {c:Type} {c_WT:WhyType c},
  forall (f:a -> b) (g:b -> c) (s:set a) (s':set b) (s'':set c),
  (p_bijective f s s') -> (p_bijective g s' s'') ->
  p_bijective (fun (k:a) => (g (f k))) s s''.

Axiom bijective_image :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> a) (s:set a) (s':set a), (p_bijective f s s') ->
  ((cardinal s) = (cardinal s')) /\ (s' = (map f s)).

Axiom get_bijective :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b), (p_bijective f s s') ->
  (forall (e:a), (mem e s) -> mem (f e) s') /\
  ((forall (e:a) (e':a), (mem e s) -> (mem e' s) -> ~ (e = e') ->
    ~ ((f e) = (f e'))) /\
   ((forall (e':b), (mem e' s') -> exists e:a, (mem e s) /\ ((f e) = e')) /\
    ((cardinal s) = (cardinal s')))).

Axiom bijective_eq :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (g:a -> b) (s:set a) (s':set b), (p_bijective f s s') ->
  (forall (e:a), (mem e s) -> ((f e) = (g e))) -> p_bijective g s s'.

Axiom bijective_eq_gen :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b), (p_bijective f s s') ->
  forall (g:a -> b), (forall (e:a), (mem e s) -> ((f e) = (g e))) ->
  p_bijective g s s'.

Axiom bij_equal_card :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a), ((cardinal s) = (cardinal (map f s))) ->
  p_bijective f s (map f s).

Axiom set_bijective_auto :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> a) (s:set a), (forall (e:a), (mem e s) -> mem (f e) s) ->
  (forall (e':a), (mem e' s) -> exists e:a, (mem e s) /\ ((f e) = e')) ->
  p_bijective f s s.

Axiom iterate_empty :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (t1:a -> im1), (is_empty s) ->
  (commut op1) -> (iterable op1) -> ((iterate op1 s t1) = (neutral_elt op1)).

Axiom iterate_add :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (f:a -> im1) (x:a),
  (commut op1) -> (iterable op1) -> ~ (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} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (f:a -> im1) (x:a),
  (commut op1) -> (iterable op1) ->
  (inverse_tuple op1 (fun (y0:im1) (y1:im1) => (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} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (f:a -> im1), (iterable op1) ->
  (commut 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} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (f:a -> im1) (t1:a),
  (iterable op1) -> (commut op1) -> (mem t1 s) ->
  ((iterate op1 s f) = ((op1 (f t1)) (iterate op1 (remove t1 s) f))).

Axiom iterate_comp_iterate :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s1:set a) (f:a -> im1) (g:a -> im1),
  (iterable op1) -> (commut op1) -> (assoc 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} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s1:set a) (f:a -> im1) (g:a -> im1),
  (iterable op1) -> (commut 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} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (po1:im1 -> im1 -> im1) (s1:set a)
    (s2:set a) (f:a -> im1),
  (iterable op1) -> (commut 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} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s1:set a) (s2:set a) (t1:a -> im1),
  (iterable op1) -> (commut op1) -> ((inter s1 s2) = (empty : set a)) ->
  ((iterate op1 (union s1 s2) t1) =
   ((op1 (iterate op1 s1 t1)) (iterate op1 s2 t1))).

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

Axiom iterate_map :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}
    {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set b) (f:b -> a) (t1:a -> im1),
  (iterable op1) -> (commut op1) -> (p_injective f s) ->
  ((iterate op1 (map f s) t1) = (iterate op1 s (fun (b1:b) => (t1 (f b1))))).

Axiom iterate_cardone :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (t1:a -> im1), (iterable op1) ->
  (commut op1) -> ((cardinal s) = 1%Z) ->
  ((iterate op1 s t1) = (t1 (element s))).

Axiom iterate_cardzero :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (t1:a -> im1), (commut op1) ->
  (iterable op1) -> ((cardinal s) = 0%Z) ->
  ((iterate op1 s t1) = (neutral_elt op1)).

Axiom injec_iterate :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}
    {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (a1:a) (s:set b) (f:a -> b -> im1),
  (iterable op1) -> (commut op1) ->
  ((iterate op1 s (f a1)) =
   (iterate op1 (cartesian_product (add a1 (empty : set a)) s)
    (fun (o:(a* b)%type) => ((f (fir o)) (sec o))))).

Axiom iterate_cartesian_product :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}
    {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s1:set a) (s2:set b) (f:a -> b -> im1),
  (iterable op1) -> (commut op1) ->
  ((iterate op1 s1 (fun (a1:a) => (iterate op1 s2 (f a1)))) =
   (iterate op1 (cartesian_product s1 s2)
    (fun (o:(a* b)%type) => ((f (fir o)) (sec o))))).

Axiom iterate_eq_func :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (f1:a -> im1) (f2:a -> im1),
  (commut op1) -> (iterable op1) -> (p_injective f1 s) ->
  (p_injective f2 s) -> ((map f1 s) = (map f2 s)) ->
  ((iterate op1 s f1) = (iterate op1 s f2)).

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

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

Axiom int_iterate_cardone :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> im1) (i:Z) (j:Z),
  (j = (i + 1%Z)%Z) -> (iterable op1) -> ((int_iterate op1 f i j) = (f i)).

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

Axiom int_iterate_to_iterate :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> im1) (i:Z) (j:Z), (iterable op1) ->
  (commut op1) -> ((int_iterate op1 f i j) = (iterate op1 (to_fset i j) f)).

Axiom int_iterate_right_extension :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> im1) (i:Z) (j:Z), (iterable 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 {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> im1) (i:Z) (k:Z) (j:Z),
  (iterable 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 {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> im1) (g:Z -> im1) (i:Z) (j:Z),
  (iterable op1) -> (op_neutral_right op1 (neutral_elt op1)) ->
  (commut 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_no_f :
  forall {im1:Type} {im1_WT:WhyType im1} {im2:Type} {im2_WT:WhyType im2},
  forall (op1:im1 -> im1 -> im1) (op2:im2 -> im2 -> im2) (t1:Z -> im1)
    (t2:Z -> im2) (f:im1 -> im2) (i:Z) (j:Z),
  (forall (x:Z), forall (y:im1),
   (((op2 (t2 x)) (f y)) = (f ((op1 (t1 x)) y)))) ->
  ((f (neutral_elt op1)) = (neutral_elt op2)) -> (iterable op1) ->
  (iterable op2) -> (forall (i1:Z), ((f (t1 i1)) = (t2 i1))) ->
  ((int_iterate op2 t2 i j) = (f (int_iterate op1 t1 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) (t1:Z -> im1)
    (f:im1 -> im2) (i:Z) (j:Z),
  (forall (x:Z), forall (y:im1),
   (((op2 (f (t1 x))) (f y)) = (f ((op1 (t1 x)) y)))) ->
  ((f (neutral_elt op1)) = (neutral_elt op2)) -> (iterable op1) ->
  (iterable op2) ->
  ((int_iterate op2 (fun (e:Z) => (f (t1 e))) i j) =
   (f (int_iterate op1 t1 i j))).

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

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

Axiom int_iterate_left_right :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> im1) (l:Z) (k:Z) (h:Z),
  (iterable op1) -> (commut op1) -> ((l <= k)%Z /\ (k <= h)%Z) ->
  ((int_iterate op1 f l k) =
   (int_iterate op1 (fun (a:Z) => (f ((h - (a + 1%Z)%Z)%Z + l)%Z))
    ((h - k)%Z + l)%Z h)).

Axiom int_iterate_eq_func :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (i:Z) (j:Z) (f:Z -> im1) (g:Z -> im1),
  (iterable op1) -> (commut op1) -> (p_injective f (to_fset i j)) ->
  (p_injective g (to_fset i j)) ->
  ((map f (to_fset i j)) = (map g (to_fset i j))) ->
  ((int_iterate op1 f i j) = (int_iterate op1 g i j)).

Axiom int_iterate_map :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (i:Z) (j:Z) (k:Z) (l:Z) (f:Z -> Z)
    (t1:Z -> im1),
  (iterable op1) -> (commut op1) ->
  (p_bijective f (to_fset i j) (to_fset k l)) ->
  ((int_iterate op1 t1 k l) =
   (int_iterate op1 (fun (b:Z) => (t1 (f b))) i j)).

Axiom int_iterate_transl :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> im1) (i:Z) (j:Z) (k:Z),
  (iterable op1) ->
  ((int_iterate op1 f i j) =
   (int_iterate op1 (fun (b:Z) => (f (b + k)%Z)) (i - k)%Z (j - k)%Z)).

Axiom int_iterate_map_auto :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (i:Z) (j:Z) (f:Z -> Z) (t1:Z -> im1),
  (iterable op1) -> (commut op1) ->
  (p_bijective f (to_fset i j) (to_fset i j)) ->
  ((int_iterate op1 t1 i j) =
   (int_iterate op1 (fun (b:Z) => (t1 (f b))) 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))) /\
   ((iterable (fun (y0:Z) (y1:Z) => (y0 + y1)%Z)) /\
    (iterable (fun (y0:Z) (y1:Z) => (y0 * y1)%Z)))).

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

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_eq :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> Z) (t':a -> Z),
  (forall (e:a), (mem e s) -> ((t1 e) = (t' e))) ->
  ((isum s t1) = (isum s t')).

Axiom isum_eq_gen :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a) (t1:a -> Z) (t':a -> Z), (s = s') ->
  (forall (e:a), (mem e s) -> ((t1 e) = (t' e))) ->
  ((isum s t1) = (isum s t')).

Axiom mul_assoc :
  forall (a:Z) (b:Z) (c:Z), (((a * b)%Z * c)%Z = (a * (b * c)%Z)%Z).

Axiom mul_assoc_rev :
  forall (a:Z) (b:Z) (c:Z), ((a * (b * c)%Z)%Z = ((a * b)%Z * c)%Z).

Axiom mult_add_distr :
  forall (a:Z) (b:Z) (c:Z) (d:Z),
  (((a + b)%Z * (c + d)%Z)%Z =
   ((((a * c)%Z + (a * d)%Z)%Z + (b * c)%Z)%Z + (b * d)%Z)%Z).

Axiom mult_add_right :
  forall (a:Z) (b:Z) (c:Z), (((a + b)%Z * c)%Z = ((a * c)%Z + (b * c)%Z)%Z).

Axiom mult_add_right_rev :
  forall (a:Z) (b:Z) (c:Z), (((a * c)%Z + (b * c)%Z)%Z = ((a + b)%Z * c)%Z).

Axiom mult_add_left :
  forall (a:Z) (b:Z) (c:Z), ((a * (b + c)%Z)%Z = ((a * b)%Z + (a * c)%Z)%Z).

Axiom mult_add_left_rev :
  forall (a:Z) (b:Z) (c:Z), (((a * b)%Z + (a * c)%Z)%Z = (a * (b + c)%Z)%Z).

Axiom mult_add_distr_rev :
  forall (a:Z) (b:Z) (c:Z) (d:Z),
  (((((a * c)%Z + (a * d)%Z)%Z + (b * c)%Z)%Z + (b * d)%Z)%Z =
   ((a + b)%Z * (c + d)%Z)%Z).

Axiom mul_assoc_comm :
  forall (a:Z) (b:Z) (c:Z), (((a * b)%Z * c)%Z = (b * (a * c)%Z)%Z).

Axiom mul_assoc_rev_comm :
  forall (a:Z) (b:Z) (c:Z), ((a * (b * c)%Z)%Z = ((a * c)%Z * b)%Z).

Axiom add_assoc :
  forall (a:Z) (b:Z) (c:Z), (((a + b)%Z + c)%Z = (a + (b + c)%Z)%Z).

Axiom add_assoc_rev :
  forall (a:Z) (b:Z) (c:Z), ((a + (b + c)%Z)%Z = ((a + b)%Z + c)%Z).

Axiom isum_empty :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> Z), (is_empty s) -> ((isum s f) = 0%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))).

(* 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_empty :
  forall (f:Z -> Z) (i:Z) (j:Z), (j <= i)%Z -> ((ind_isum f i j) = 0%Z).

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

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

Axiom ind_isum_to_isum :
  forall (f:Z -> Z) (i:Z) (j:Z), (i < j)%Z ->
  ((ind_isum f i j) = (isum (to_fset i j) f)).

Axiom ind_isum_const :
  forall (k:Z) (i:Z) (j:Z), (i < j)%Z ->
  ((ind_isum ((fun (y0:Z) (y1:Z) => y0) k) i j) = (k * (j - i)%Z)%Z).

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).

Axiom ind_isum_eq :
  forall (f:Z -> Z) (g:Z -> Z) (i:Z) (j:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ((f k) = (g k))) ->
  ((ind_isum f i j) = (ind_isum g i j)).

Parameter fc: (Z -> Z) -> (Z -> Z) -> (Z -> bool) -> Z -> Z.

Axiom fc_def :
  forall (f:Z -> Z) (g:Z -> Z) (p:Z -> bool) (k:Z),
  (((p k) = true) -> (((fc f g p) k) = (f k))) /\
  (~ ((p k) = true) -> (((fc f g p) k) = (g k))).

Axiom ind_isum_to_guard :
  forall (f:Z -> Z) (g:Z -> Z) (p:Z -> bool) (i:Z) (j:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ((p k) = true)) ->
  ((ind_isum (fc f g p) i j) = (ind_isum f i j)).

Parameter fc1: (Z -> Z) -> (Z -> Z) -> (Z -> bool) -> Z -> Z.

Axiom fc_def1 :
  forall (f:Z -> Z) (g:Z -> Z) (p:Z -> bool) (k:Z),
  (((p k) = true) -> (((fc1 f g p) k) = (g k))) /\
  (~ ((p k) = true) -> (((fc1 f g p) k) = (f k))).

Axiom ind_isum_no_guard :
  forall (f:Z -> Z) (g:Z -> Z) (p:Z -> bool) (i:Z) (j:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ~ ((p k) = true)) ->
  ((ind_isum (fc1 f g p) i j) = (ind_isum f i j)).

Axiom ind_isum_eq_gen :
  forall (f:Z -> Z) (g:Z -> Z) (i:Z) (i1:Z) (j:Z) (j1:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ((f k) = (g k))) -> (i = i1) ->
  (j = j1) -> ((ind_isum f i j) = (ind_isum g i1 j1)).

Axiom ind_isum_func_const :
  forall (k:Z) (f:Z -> Z) (i:Z) (j:Z), (i < j)%Z ->
  (forall (l:Z), ((i <= l)%Z /\ (l < j)%Z) -> ((f l) = k)) ->
  ((ind_isum f i j) = (k * (j - i)%Z)%Z).

Axiom ind_isum_pos :
  forall (f:Z -> Z) (i:Z) (j:Z), (i <= j)%Z ->
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> (0%Z <= (f k))%Z) ->
  (0%Z <= (ind_isum f i 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_eq :
  forall (f:Z -> Z) (g:Z -> Z) (i:Z) (j:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ((f k) = (g k))) ->
  ((ind_iproduct f i j) = (ind_iproduct g i j)).

Axiom ind_iproduct_eq_gen :
  forall (f:Z -> Z) (g:Z -> Z) (i1:Z) (j1:Z) (i2:Z) (j2:Z),
  (forall (k:Z), ((i1 <= k)%Z /\ (k < j1)%Z) -> ((f k) = (g k))) ->
  (i1 = i2) -> (j1 = j2) -> ((ind_iproduct f i1 j1) = (ind_iproduct g i2 j2)).

Axiom iproduct_to_iterate :
  forall (f:Z -> Z) (i:Z) (j:Z),
  ((ind_iproduct f i j) =
   (int_iterate (fun (y0:Z) (y1:Z) => (y0 * y1)%Z) f i j)).

Axiom ind_isum_map_auto :
  forall (i:Z) (j:Z) (f:Z -> Z) (t1:Z -> Z),
  (p_bijective f (to_fset i j) (to_fset i j)) ->
  ((ind_isum t1 i j) = (ind_isum (fun (b:Z) => (t1 (f b))) i j)).

Axiom ind_isum_map :
  forall (i:Z) (j:Z) (k:Z) (l:Z) (f:Z -> Z) (t1:Z -> Z),
  (p_bijective f (to_fset i j) (to_fset k l)) ->
  ((ind_isum t1 k l) = (ind_isum (fun (b:Z) => (t1 (f b))) i j)).

Axiom ind_isum_map_auto_bij :
  forall (i:Z) (j:Z) (f:Z -> Z) (t1:Z -> Z),
  (forall (e:Z), ((i <= e)%Z /\ (e < j)%Z) ->
   (i <= (f e))%Z /\ ((f e) < j)%Z) ->
  (forall (e:Z) (e':Z), ((i <= e)%Z /\ (e < j)%Z) ->
   ((i <= e')%Z /\ (e' < j)%Z) -> ~ (e = e') -> ~ ((f e) = (f e'))) ->
  (forall (e':Z), ((i <= e')%Z /\ (e' < j)%Z) ->
   exists e:Z, ((i <= e)%Z /\ (e < j)%Z) /\ ((f e) = e')) ->
  ((ind_isum t1 i j) = (ind_isum (fun (b:Z) => (t1 (f b))) i j)).

Axiom ind_isum_map_bij :
  forall (i:Z) (j:Z) (k:Z) (l:Z) (f:Z -> Z) (t1:Z -> Z),
  (forall (e:Z), ((i <= e)%Z /\ (e < j)%Z) ->
   (k <= (f e))%Z /\ ((f e) < l)%Z) ->
  (forall (e:Z) (e':Z), ((i <= e)%Z /\ (e < j)%Z) ->
   ((i <= e')%Z /\ (e' < j)%Z) -> ~ (e = e') -> ~ ((f e) = (f e'))) ->
  (forall (e':Z), ((k <= e')%Z /\ (e' < l)%Z) ->
   exists e:Z, ((i <= e)%Z /\ (e < j)%Z) /\ ((f e) = e')) ->
  ((ind_isum t1 k l) = (ind_isum (fun (b:Z) => (t1 (f b))) i j)).

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

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

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

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

Axiom ind_iproduct_one :
  forall (f:Z -> Z) (i:Z) (j:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ((f k) = 1%Z)) ->
  ((ind_iproduct f i j) = 1%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.

Axiom ind_iproduct_left_right :
  forall (f:Z -> Z) (l:Z) (k:Z) (h:Z), ((l <= k)%Z /\ (k <= h)%Z) ->
  ((ind_iproduct f l k) =
   (ind_iproduct (fun (a:Z) => (f ((h - (a + 1%Z)%Z)%Z + l)%Z))
    ((h - k)%Z + l)%Z h)).

Axiom iterable_imult : iterable (fun (y0:Z) (y1:Z) => (y0 * y1)%Z).

Axiom ind_iproduct_map_auto :
  forall (i:Z) (j:Z) (f:Z -> Z) (t1:Z -> Z),
  (p_bijective f (to_fset i j) (to_fset i j)) ->
  ((ind_iproduct t1 i j) = (ind_iproduct (fun (b:Z) => (t1 (f b))) i j)).

Axiom ind_iproduct_map :
  forall (i:Z) (j:Z) (k:Z) (l:Z) (f:Z -> Z) (t1:Z -> Z),
  (p_bijective f (to_fset i j) (to_fset k l)) ->
  ((ind_iproduct t1 k l) = (ind_iproduct (fun (b:Z) => (t1 (f b))) i j)).

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

Axiom ind_isum_transl :
  forall (f:Z -> Z) (i:Z) (j:Z) (k:Z),
  ((ind_isum f i j) =
   (ind_isum (fun (b:Z) => (f (b + k)%Z)) (i - k)%Z (j - k)%Z)).

Axiom ind_isum_transl_plus_one :
  forall (f:Z -> Z) (i:Z) (j:Z),
  ((ind_isum f i j) =
   (ind_isum (fun (b:Z) => (f (b - 1%Z)%Z)) (i + 1%Z)%Z (j + 1%Z)%Z)).

Axiom ind_isum_transl_minus_one :
  forall (f:Z -> Z) (i:Z) (j:Z),
  ((ind_isum f i j) =
   (ind_isum (fun (b:Z) => (f (b + 1%Z)%Z)) (i - 1%Z)%Z (j - 1%Z)%Z)).

Axiom ind_isum_scal :
  forall (f:Z -> Z) (i:Z) (j:Z) (a:Z), (i <= j)%Z ->
  ((ind_isum (fun (i1:Z) => (a * (f i1))%Z) i j) = (a * (ind_isum f i j))%Z).

Axiom ind_isum_scal_rev :
  forall (f:Z -> Z) (i:Z) (j:Z) (a:Z), (i <= j)%Z ->
  ((a * (ind_isum f i j))%Z = (ind_isum (fun (i1:Z) => (a * (f i1))%Z) i j)).

Axiom ind_isum_scal_rev_right :
  forall (f:Z -> Z) (i:Z) (j:Z) (a:Z), (i <= j)%Z ->
  (((ind_isum f i j) * a)%Z = (ind_isum (fun (i1:Z) => ((f i1) * a)%Z) i j)).

Axiom ind_isum_scal_right :
  forall (f:Z -> Z) (i:Z) (j:Z) (a:Z), (i <= j)%Z ->
  ((ind_isum (fun (i1:Z) => ((f i1) * a)%Z) i j) = ((ind_isum f i j) * a)%Z).

Axiom ind_isum_bound :
  forall (f:Z -> Z) (g:Z -> Z) (i:Z) (j:Z), (i < j)%Z ->
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ((f k) < (g k))%Z) ->
  ((ind_isum f i j) < (ind_isum g i j))%Z.

Axiom comp_trans_equal_strict :
  forall (a:Z) (b:Z) (c:Z), (a <= b)%Z -> (b < c)%Z -> (a < c)%Z.

Axiom compeq_trans_sum :
  forall (a:Z) (b:Z) (c:Z), (b <= c)%Z -> ((a + b)%Z <= (a + c)%Z)%Z.

Axiom compeq_trans_sum_zero :
  forall (a:Z) (b:Z), (0%Z <= b)%Z -> (a <= (a + b)%Z)%Z.

Axiom comp_trans_sum :
  forall (a:Z) (b:Z) (c:Z), (b < c)%Z -> ((a + b)%Z < (a + c)%Z)%Z.

Axiom ind_isum_bound_eq :
  forall (f:Z -> Z) (g:Z -> Z) (i:Z) (j:Z), (i <= j)%Z ->
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ((f k) <= (g k))%Z) ->
  ((ind_isum f i j) <= (ind_isum g i j))%Z.

Axiom ind_isum_scal_gen :
  forall (f:Z -> Z) (i:Z) (j:Z), forall (a:Z), ((i <= a)%Z /\ (a < j)%Z) ->
  ((ind_isum (fun (i1:Z) => (a * (f i1))%Z) i j) = (a * (ind_isum f i j))%Z).

Axiom ind_isum_trans :
  forall (f:Z -> Z) (i:Z) (k:Z) (j:Z), ((i <= k)%Z /\ (k <= j)%Z) ->
  ((ind_isum f i j) = ((ind_isum f i k) + (ind_isum f k j))%Z).

Parameter power: Z -> Z -> Z.

Axiom Power_zero : forall (i:Z), ((power i 0%Z) = 1%Z).

Axiom Power_one : forall (i:Z), ((power i 1%Z) = i).

Axiom Power_sum :
  forall (x:Z) (y:Z) (i:Z), (0%Z <= x)%Z -> (0%Z <= y)%Z ->
  ((power i (x + y)%Z) = ((power i x) * (power i y))%Z).

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

Axiom power_plus_one :
  forall (e:Z) (i:Z), (0%Z <= i)%Z ->
  ((power e (i + 1%Z)%Z) = (e * (power e i))%Z).

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

Axiom power_transl :
  forall (e:Z) (k:Z) (i:Z), (0%Z <= i)%Z ->
  ((power e i) = (ind_iproduct ((fun (y0:Z) (y1:Z) => y0) e) k (k + i)%Z)).

Axiom ind_iproduct_to_power :
  forall (e:Z) (i:Z) (j:Z), ((0%Z <= i)%Z /\ (i <= j)%Z) ->
  ((ind_iproduct ((fun (y0:Z) (y1:Z) => y0) e) i j) = (power e (j - i)%Z)).

Axiom ind_iproduct_to_power_gen :
  forall (e:Z), forall (i:Z) (j:Z), ((0%Z <= i)%Z /\ (i <= j)%Z) ->
  ((ind_iproduct ((fun (y0:Z) (y1:Z) => y0) e) i j) = (power e (j - i)%Z)).

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 power_eq :
  forall (x:Z) (n:Z) (m:Z), (n = m) -> ((power x n) = (power x m)).

Axiom power_eq_gen :
  forall (x:Z) (y:Z) (n:Z) (m:Z), (n = m) -> (x = y) ->
  ((power x n) = (power y m)).

Axiom power_decomp :
  forall (i:Z), (1%Z <= i)%Z ->
  ((ind_isum (fun (k:Z) => (power 2%Z (k + 1%Z)%Z)) 0%Z i) <
   (power 2%Z (i + 1%Z)%Z))%Z.

Parameter fc2: Z -> Z -> Z.

Axiom fc_def2 :
  forall (i:Z) (k:Z),
  (((1%Z <= k)%Z /\ (k < (i + 1%Z)%Z)%Z) ->
   (((fc2 i) k) = (power 2%Z (k - 1%Z)%Z))) /\
  (~ ((1%Z <= k)%Z /\ (k < (i + 1%Z)%Z)%Z) -> (((fc2 i) k) = 0%Z)).

Axiom power_decomp_minus_one :
  forall (i:Z), (1%Z <= i)%Z ->
  ((ind_isum (fc2 i) 1%Z i) < (power 2%Z (i - 1%Z)%Z))%Z.

Axiom power_decomp_ :
  forall (i:Z), (1%Z <= i)%Z ->
  ((ind_isum (fun (k:Z) => (power 2%Z k)) 0%Z i) < (power 2%Z i))%Z.

Axiom power_decomp_one :
  forall (i:Z), (1%Z <= i)%Z ->
  ((ind_isum (fun (k:Z) => (power 2%Z (k + 1%Z)%Z)) 1%Z i) <
   (power 2%Z (i + 1%Z)%Z))%Z.

Axiom power_decomp_one_ :
  forall (i:Z), (1%Z <= i)%Z ->
  ((ind_isum (fun (k:Z) => (power 2%Z k)) 1%Z i) < (power 2%Z i))%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) (m:Z) (n:Z), (0%Z <= m)%Z -> (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z m))%Z) ->
  ((0%Z <= j)%Z /\ (j < (power 2%Z n))%Z) ->
  (((i * (power 2%Z n))%Z + j)%Z < (power 2%Z (m + n)%Z))%Z.

Parameter result2:
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  (im1 -> im1 -> im1) -> (a -> im1) -> a -> bool.

Axiom result_def2 :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (t1:a -> im1) (e:a),
  (((result2 op1 t1) e) = true) <-> ~ (neutral op1 (t1 e)).

(* Why3 assumption *)
Definition nonn_part {a:Type} {a_WT:WhyType a}
    {im1:Type} {im1_WT:WhyType im1} (op1:im1 -> im1 -> im1) (s:set a)
    (t1:a -> im1) : set a :=
  filter (result2 op1 t1) s.

Axiom nonn_part_spec :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (t1:a -> im1), forall (e:a),
  (mem e (nonn_part op1 s t1)) <-> ((mem e s) /\ ~ (neutral op1 (t1 e))).

Parameter result3:
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  (im1 -> im1 -> im1) -> (a -> im1) -> a -> bool.

Axiom result_def3 :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (t1:a -> im1) (e:a),
  (((result3 op1 t1) e) = true) <-> (neutral op1 (t1 e)).

(* Why3 assumption *)
Definition n_part {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1}
    (op1:im1 -> im1 -> im1) (s:set a) (t1:a -> im1) : set a :=
  filter (result3 op1 t1) s.

Axiom n_part_spec :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (t1:a -> im1), forall (e:a),
  (mem e (n_part op1 s t1)) <-> ((mem e s) /\ (neutral op1 (t1 e))).

Axiom nullity_partition :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (t1:a -> im1), (commut op1) ->
  (s = (union (nonn_part op1 s t1) (n_part op1 s t1))) /\
  ((inter (nonn_part op1 s t1) (n_part op1 s t1)) = (empty : set a)).

Axiom iterate_neutral :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (t1:a -> im1), (iterable op1) ->
  (commut op1) ->
  (forall (a1:a), (mem a1 s) -> ((t1 a1) = (neutral_elt op1))) ->
  ((iterate op1 s t1) = (neutral_elt op1)).

Axiom iterate_nullity_partition :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (t1:a -> im1), (iterable op1) ->
  (commut op1) ->
  ((iterate op1 s t1) = (iterate op1 (nonn_part op1 s t1) t1)).

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

Axiom null_product :
  forall (a:t) (b:t), ((infix_asdt a b) = tzero) ->
  (a = tzero) \/ (b = tzero).

Axiom neutral_tzero :
  (neutral (fun (y0:t) (y1:t) => (infix_pldt y0 y1)) tzero) /\
  (iterable (fun (y0:t) (y1:t) => (infix_pldt y0 y1))).

(* Why3 assumption *)
Definition sum {a:Type} {a_WT:WhyType a} (s:set a) (t1:a -> t) : t :=
  iterate (fun (y0:t) (y1:t) => (infix_pldt y0 y1)) s t1.

Axiom sum_empty :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> t), (is_empty s) -> ((sum s t1) = tzero).

Axiom sum_add :
  forall {b:Type} {b_WT:WhyType b},
  forall (s:set b) (f:b -> t) (x:b), ~ (mem x s) ->
  ((sum (add x s) f) = (infix_pldt (f x) (sum s f))).

Axiom map_sum_eq :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set b) (f:b -> a) (t1:a -> t), (p_injective f s) ->
  ((sum (map f s) t1) = (sum s (fun (b1:b) => (t1 (f b1))))).

Axiom sum_comp :
  forall {b:Type} {b_WT:WhyType b},
  forall (s:set b) (f:b -> t) (g:b -> t),
  ((sum s (fun (k:b) => (infix_pldt (f k) (g k)))) =
   (infix_pldt (sum s f) (sum s g))).

Axiom sum_iter_ :
  (opposite_n (fun (y0:t) (y1:t) => (infix_pldt y0 y1))
   (fun (y0:t) (y1:t) => (infix_mndt y0 y1)) tzero) /\
  ((opposite (fun (y0:t) (y1:t) => (infix_pldt y0 y1))
    (fun (y0:t) (y1:t) => (infix_mndt y0 y1))) /\
   ((opposite_com (fun (y0:t) (y1:t) => (infix_pldt y0 y1))
     (fun (y0:t) (y1:t) => (infix_mndt y0 y1))) /\
    (inverse_tuple (fun (y0:t) (y1:t) => (infix_pldt y0 y1))
     (fun (y0:t) (y1:t) => (infix_mndt y0 y1)) tzero))).

Axiom neutral_zero :
  ((neutral_elt (fun (y0:t) (y1:t) => (infix_pldt y0 y1))) = tzero).

Axiom sum_eq :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> t) (g:a -> t),
  (forall (x:a), (mem x s) -> ((f x) = (g x))) -> ((sum s f) = (sum s g)).

Axiom sum_eq_gen :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a) (f:a -> t) (g:a -> t), (s = s') ->
  (forall (x:a), (mem x s) -> ((f x) = (g x))) -> ((sum s f) = (sum s' g)).

Axiom sum_disjoint_transitivity :
  forall {a:Type} {a_WT:WhyType a},
  forall (s1:set a) (s2:set a) (t1:a -> t),
  ((inter s1 s2) = (empty : set a)) ->
  ((sum (union s1 s2) t1) = (infix_pldt (sum s1 t1) (sum s2 t1))).

Axiom sum_to_cartesian_product :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s1:set a) (s2:set b) (f:a -> b -> t),
  ((sum s1 (fun (a1:a) => (sum s2 (f a1)))) =
   (sum (cartesian_product s1 s2)
    (fun (o:(a* b)%type) => ((f (fir o)) (sec o))))).

Axiom sum_from_cartesian_product :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s1:set a) (s2:set b) (f:a -> b -> t),
  ((sum (cartesian_product s1 s2)
    (fun (o:(a* b)%type) => ((f (fir o)) (sec o))))
   = (sum s1 (fun (a1:a) => (sum s2 (f a1))))).

(* Why3 assumption *)
Definition ind_sum (f:Z -> t) (i:Z) (j:Z) : t :=
  int_iterate (fun (y0:t) (y1:t) => (infix_pldt y0 y1)) f i j.

Axiom ind_sum_to_int_iterate :
  forall (f:Z -> t) (i:Z) (j:Z),
  ((ind_sum f i j) =
   (int_iterate (fun (y0:t) (y1:t) => (infix_pldt y0 y1)) f i j)).

Axiom ind_sum_cardone :
  forall (f:Z -> t) (i:Z) (j:Z), (j = (i + 1%Z)%Z) ->
  ((ind_sum f i j) = (f i)).

Axiom ind_sum_right_extension :
  forall (f:Z -> t) (i:Z) (j:Z), (i < j)%Z ->
  ((ind_sum f i j) = (infix_pldt (ind_sum f i (j - 1%Z)%Z) (f (j - 1%Z)%Z))).

Axiom ind_sum_plus_one :
  forall (f:Z -> t) (i:Z) (j:Z), (i < j)%Z ->
  ((ind_sum f i j) = (infix_pldt (f i) (ind_sum f (i + 1%Z)%Z j))).

Axiom ind_sum_eq :
  forall (f:Z -> t) (g:Z -> t) (i:Z) (j:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ((f k) = (g k))) ->
  ((ind_sum f i j) = (ind_sum g i j)).

Parameter fc3: (Z -> t) -> t -> Z -> Z -> Z -> t.

Axiom fc_def3 :
  forall (f:Z -> t) (g:t) (i:Z) (j:Z) (k:Z),
  (((i <= k)%Z /\ (k < j)%Z) -> (((fc3 f g i j) k) = (f k))) /\
  (~ ((i <= k)%Z /\ (k < j)%Z) -> (((fc3 f g i j) k) = g)).

Axiom ind_sum_eq_del_bound :
  forall (f:Z -> t) (g:t) (i:Z) (j:Z),
  ((ind_sum (fc3 f g i j) i j) = (ind_sum f i j)).

Parameter fc4: (Z -> t) -> t -> Z -> Z -> Z -> t.

Axiom fc_def4 :
  forall (f:Z -> t) (g:t) (i:Z) (j:Z) (k:Z),
  (((i <= k)%Z /\ (k < j)%Z) -> (((fc4 f g i j) k) = (f k))) /\
  (~ ((i <= k)%Z /\ (k < j)%Z) -> (((fc4 f g i j) k) = g)).

Axiom ind_sum_eq_del_bound_rev :
  forall (f:Z -> t) (g:t) (i:Z) (j:Z),
  ((ind_sum f i j) = (ind_sum (fc4 f g i j) i j)).

Axiom ind_sum_eq_gen :
  forall (f:Z -> t) (g:Z -> t) (i1:Z) (j1:Z) (i2:Z) (j2:Z), (i1 = i2) ->
  (j1 = j2) ->
  (forall (k:Z), ((i1 <= k)%Z /\ (k < j1)%Z) -> ((f k) = (g k))) ->
  ((ind_sum f i1 j1) = (ind_sum g i2 j2)).

Axiom ind_sum_eq_bound :
  forall (f:Z -> t) (g:Z -> t) (i:Z) (j:Z), (i = j) ->
  (forall (k:Z), ((0%Z <= k)%Z /\ (k < j)%Z) -> ((f k) = (g k))) ->
  ((ind_sum f 0%Z i) = (ind_sum g 0%Z j)).

Axiom ind_sum_comp :
  forall (f:Z -> t) (g:Z -> t) (i:Z) (j:Z),
  ((ind_sum (fun (k:Z) => (infix_pldt (f k) (g k))) i j) =
   (infix_pldt (ind_sum f i j) (ind_sum g i j))).

Axiom ind_sum_to_iterate :
  forall (f:Z -> t) (i:Z) (j:Z),
  ((ind_sum f i j) =
   (iterate (fun (y0:t) (y1:t) => (infix_pldt y0 y1)) (to_fset i j) f)).

Axiom ind_sum_to_sum :
  forall (f:Z -> t) (i:Z) (j:Z), ((ind_sum f i j) = (sum (to_fset i j) f)).

Axiom map_ind_sum_eq :
  forall (i:Z) (j:Z) (k:Z) (l:Z) (f:Z -> Z) (t1:Z -> t),
  (p_bijective f (to_fset i j) (to_fset k l)) ->
  ((ind_sum t1 k l) = (ind_sum (fun (b:Z) => (t1 (f b))) i j)).

Axiom sum_scal :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> t) (s:set a) (c:t),
  ((sum s (fun (x:a) => (infix_asdt c (f x)))) = (infix_asdt c (sum s f))).

Axiom ind_sum_scal :
  forall (f:Z -> t) (i:Z) (j:Z) (a:t),
  ((ind_sum (fun (i1:Z) => (infix_asdt a (f i1))) i j) =
   (infix_asdt a (ind_sum f i j))).

Axiom ind_sum_scal_rev :
  forall (f:Z -> t) (i:Z) (j:Z) (a:t),
  ((infix_asdt a (ind_sum f i j)) =
   (ind_sum (fun (i1:Z) => (infix_asdt a (f i1))) i j)).

Axiom sum_scal_gen :
  forall (f:Z -> t) (s:set Z), forall (a:t),
  ((sum s (fun (i:Z) => (infix_asdt a (f i)))) = (infix_asdt a (sum s f))).

Axiom ind_sum_scal_gen :
  forall (f:Z -> t) (i:Z) (j:Z), forall (a:t),
  ((ind_sum (fun (i1:Z) => (infix_asdt a (f i1))) i j) =
   (infix_asdt a (ind_sum f i j))).

Axiom int_int_iterate_def_empty :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> Z -> im1) (i:Z) (j:Z) (k:Z) (l:Z),
  (j <= i)%Z -> (iterable op1) ->
  ((int_int_iterate op1 f i j k l) = (neutral_elt op1)).

Axiom int_int_iterate_def_plus_one :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> Z -> im1) (i:Z) (j:Z) (k:Z) (l:Z),
  (i < j)%Z -> (iterable op1) ->
  ((int_int_iterate op1 f i j k l) =
   ((op1 (int_iterate op1 (fun (n:Z) => ((f i) n)) k l))
    (int_int_iterate op1 f (i + 1%Z)%Z j k l))).

Axiom int_int_iterate_to_int_iterate :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> Z -> im1) (i:Z) (j:Z) (k:Z) (l:Z),
  (i <= j)%Z -> (iterable op1) ->
  ((int_int_iterate op1 f i j k l) =
   (int_iterate op1 (fun (a:Z) => (int_iterate op1 (f a) k l)) i j)).

Axiom int_iterate_to_int_int_iterate :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> Z -> im1) (i:Z) (j:Z) (k:Z) (l:Z),
  (i <= j)%Z -> (iterable op1) ->
  ((int_iterate op1 (fun (a:Z) => (int_iterate op1 (f a) k l)) i j) =
   (int_int_iterate op1 f i j k l)).

Axiom int_int_iterate_to_iterate :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> Z -> im1) (i:Z) (j:Z) (k:Z) (l:Z),
  (i <= j)%Z -> (iterable op1) -> (commut op1) ->
  ((int_int_iterate op1 f i j k l) =
   (iterate op1 (cartesian_product (to_fset i j) (to_fset k l))
    (fun (o:(Z* Z)%type) => ((f (fir o)) (sec o))))).

Axiom iterate_commute :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}
    {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s1:set a) (s2:set b) (f:a -> b -> im1),
  (iterable op1) -> (commut op1) ->
  ((iterate op1 (cartesian_product s1 s2)
    (fun (o:(a* b)%type) => ((f (fir o)) (sec o))))
   =
   (iterate op1 (cartesian_product s2 s1)
    (fun (o:(b* a)%type) => ((f (sec o)) (fir o))))).

Axiom int_int_iterate_commute :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> Z -> im1) (i:Z) (j:Z) (k:Z) (l:Z),
  (iterable op1) -> (commut op1) -> (i <= j)%Z -> (k <= l)%Z ->
  ((int_int_iterate op1 f i j k l) =
   (int_int_iterate op1 (fun (a:Z) (b:Z) => ((f b) a)) k l i j)).

Axiom int_iterate_commute :
  forall {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (f:Z -> Z -> im1) (i:Z) (j:Z) (k:Z) (l:Z),
  (iterable op1) -> (commut op1) -> (i <= j)%Z -> (k <= l)%Z ->
  ((int_iterate op1 (fun (a:Z) => (int_iterate op1 (f a) k l)) i j) =
   (int_iterate op1
    (fun (a:Z) => (int_iterate op1 (fun (b:Z) => ((f b) a)) i j)) k l)).

Axiom ind_sum_commute :
  forall (f:Z -> Z -> t) (i:Z) (j:Z) (k:Z) (l:Z), (i <= j)%Z -> (k <= l)%Z ->
  ((ind_sum (fun (k1:Z) => (ind_sum (f k1) k l)) i j) =
   (ind_sum (fun (k1:Z) => (ind_sum (fun (k2:Z) => ((f k2) k1)) i j)) k l)).

(* Why3 assumption *)
Definition non_tzero {a:Type} {a_WT:WhyType a} (s:set a) (t1:a -> t) : set a :=
  nonn_part (fun (y0:t) (y1:t) => (infix_pldt y0 y1)) s t1.

Axiom non_tzero_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> t), forall (e:a),
  (mem e (non_tzero s t1)) <-> ((mem e s) /\ ~ ((t1 e) = tzero)).

Axiom get_non_tzero_member :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> t) (e:a), (mem e (non_tzero s t1)) ->
  (mem e s) /\ ~ ((t1 e) = tzero).

Axiom set_non_tzero_member :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> t) (e:a), (mem e s) -> ~ ((t1 e) = tzero) ->
  mem e (non_tzero s t1).

Axiom set_non_tzero_member_gen :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> t), forall (e:a),
  ((mem e s) /\ ~ ((t1 e) = tzero)) -> mem e (non_tzero s t1).

Axiom set_non_tzero_member_gen_ :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> t), forall (e:a),
  ((mem e s) /\ ~ ((t1 e) = tzero)) -> mem e (non_tzero s t1).

Axiom sum_nullity_partition :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> t), ((sum s t1) = (sum (non_tzero s t1) t1)).

Axiom non_null_map :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> a) (t1:a -> t),
  ((non_tzero (map f s) t1) =
   (map f (non_tzero s (fun (b:a) => (t1 (f b)))))).

Axiom map_sum_eq_nonnull :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> a) (t1:a -> t),
  (p_bijective f (non_tzero s (fun (b:a) => (t1 (f b))))
   (non_tzero (map f s) t1)) ->
  ((sum (non_tzero (map f s) t1) t1) =
   (sum (non_tzero s (fun (b:a) => (t1 (f b)))) (fun (b:a) => (t1 (f b))))).

Axiom sum_null_but_one :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> t), ((cardinal (non_tzero s t1)) = 1%Z) ->
  ((sum s t1) = (t1 (element (non_tzero s t1)))).

Axiom sum_null :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> t), ((cardinal (non_tzero s t1)) = 0%Z) ->
  ((sum s t1) = tzero).

Axiom ind_sum_null :
  forall (t1:Z -> t) (i:Z) (j:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ((t1 k) = tzero)) ->
  ((ind_sum t1 i j) = tzero).

Axiom sum_null_but_one_elt :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> t) (elt:a),
  ((mem elt s) /\ ~ ((t1 elt) = tzero)) ->
  (forall (a1:a), (mem a1 s) -> ~ (a1 = elt) -> ((t1 a1) = tzero)) ->
  ((sum s t1) = (t1 elt)).

Axiom sum_null_but_maybe_one_elt :
  forall {a:Type} {a_WT:WhyType a},
  forall (t1:a -> t) (s:set a) (elt:a), (mem elt s) ->
  (forall (k:a), (mem k s) -> ~ (k = elt) -> ((t1 k) = tzero)) ->
  ((sum s t1) = (t1 elt)).

Axiom ind_sum_null_but_maybe_one_elt :
  forall (t1:Z -> t) (i:Z) (j:Z) (ind:Z), ((i <= ind)%Z /\ (ind < j)%Z) ->
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ~ (k = ind) ->
   ((t1 k) = tzero)) ->
  ((ind_sum t1 i j) = (t1 ind)).

Axiom neutral_tone :
  (neutral (fun (y0:t) (y1:t) => (infix_asdt y0 y1)) tone) /\
  (iterable (fun (y0:t) (y1:t) => (infix_asdt y0 y1))).

Axiom product_iter :
  (op_neutral_left (fun (y0:t) (y1:t) => (infix_asdt y0 y1)) tone) /\
  (((op_neutral_right (fun (y0:t) (y1:t) => (infix_asdt y0 y1)) tone) /\
    (op_assoc (fun (y0:t) (y1:t) => (infix_asdt y0 y1)))) /\
   ((commut (fun (y0:t) (y1:t) => (infix_asdt y0 y1))) /\
    (iterates (fun (y0:t) (y1:t) => (infix_asdt y0 y1)) tone))).

(* Why3 assumption *)
Definition product {a:Type} {a_WT:WhyType a} (s:set a) (t1:a -> t) : t :=
  iterate (fun (y0:t) (y1:t) => (infix_asdt y0 y1)) s t1.

Axiom product_eq :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> t) (t':a -> t),
  (forall (e:a), (mem e s) -> ((t1 e) = (t' e))) ->
  ((product s t1) = (product s t')).

Axiom product_eq_gen :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a) (t1:a -> t) (t':a -> t), (s = s') ->
  (forall (e:a), (mem e s) -> ((t1 e) = (t' e))) ->
  ((product s t1) = (product s' t')).

Axiom product_empty :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> t), (is_empty s) -> ((product s f) = tone).

Axiom product_iter_ : iterable (fun (y0:t) (y1:t) => (infix_asdt y0 y1)).

Axiom add_product :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> t) (x:a), ~ (mem x s) ->
  ((product (add x s) f) = (infix_asdt (f x) (product s f))).

Axiom product_add :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> t) (x:a), ~ (mem x s) ->
  ((product (add x s) f) = (infix_asdt (product s f) (f x))).

Axiom neutral_one :
  ((neutral_elt (fun (y0:t) (y1:t) => (infix_asdt y0 y1))) = tone).

(* Why3 assumption *)
Definition ind_product (f:Z -> t) (i:Z) (j:Z) : t :=
  int_iterate (fun (y0:t) (y1:t) => (infix_asdt y0 y1)) f i j.

Axiom ind_product_eq :
  forall (f:Z -> t) (g:Z -> t) (i:Z) (j:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ((f k) = (g k))) ->
  ((ind_product f i j) = (ind_product g i j)).

Axiom ind_product_eq_gen :
  forall (f:Z -> t) (g:Z -> t) (i1:Z) (j1:Z) (i2:Z) (j2:Z),
  (forall (k:Z), ((i1 <= k)%Z /\ (k < j1)%Z) -> ((f k) = (g k))) ->
  (i1 = i2) -> (j1 = j2) -> ((ind_product f i1 j1) = (ind_product g i2 j2)).

Axiom ind_product_right_extension :
  forall (f:Z -> t) (i:Z) (j:Z), (i < j)%Z ->
  ((ind_product f i j) =
   (infix_asdt (ind_product f i (j - 1%Z)%Z) (f (j - 1%Z)%Z))).

Axiom ind_product_left_extension :
  forall (f:Z -> t) (i:Z) (j:Z), (i < j)%Z ->
  ((ind_product f i j) = (infix_asdt (f i) (ind_product f (i + 1%Z)%Z j))).

Axiom ind_product_to_product :
  forall (f:Z -> t) (i:Z) (j:Z),
  ((ind_product f i j) = (product (to_fset i j) f)).

Axiom map_product_eq :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set b) (f:b -> a) (t1:a -> t), (p_injective f s) ->
  ((product (map f s) t1) = (product s (fun (b1:b) => (t1 (f b1))))).

Axiom map_ind_product_eq :
  forall (i:Z) (j:Z) (k:Z) (l:Z) (f:Z -> Z) (t1:Z -> t),
  (p_bijective f (to_fset i j) (to_fset k l)) ->
  ((ind_product t1 k l) = (ind_product (fun (b:Z) => (t1 (f b))) i j)).

Axiom ind_product_right_extension_comm :
  forall (f:Z -> t) (i:Z) (j:Z), (i < j)%Z ->
  ((infix_asdt (ind_product f i (j - 1%Z)%Z) (f (j - 1%Z)%Z)) =
   (ind_product f i j)).

Axiom ind_product_eq_func :
  forall (i:Z) (j:Z) (f1:Z -> t) (f2:Z -> t),
  (p_injective f1 (to_fset i j)) -> (p_injective f2 (to_fset i j)) ->
  ((map f1 (to_fset i j)) = (map f2 (to_fset i j))) ->
  ((ind_product f1 i j) = (ind_product f2 i j)).

Axiom ind_product_trans :
  forall (f:Z -> t) (i:Z) (k:Z) (j:Z), ((i <= k)%Z /\ (k <= j)%Z) ->
  ((ind_product f i j) =
   (infix_asdt (ind_product f i k) (ind_product f k j))).

Axiom ind_product_zero_pre :
  forall (f:Z -> t) (i:Z) (t1:Z) (j:Z), ((i <= t1)%Z /\ (t1 < j)%Z) ->
  ((f t1) = tzero) -> ((ind_product f i j) = tzero).

Axiom ind_product_zero :
  forall (f:Z -> t) (i:Z) (j:Z), (i <= j)%Z ->
  (exists t1:Z, ((i <= t1)%Z /\ (t1 < j)%Z) /\ ((f t1) = tzero)) ->
  ((ind_product f i j) = tzero).

Axiom ind_product_zero_elt :
  forall (f:Z -> t) (i:Z) (j:Z) (t1:Z), (i <= j)%Z ->
  ((i <= t1)%Z /\ (t1 < j)%Z) -> ((f t1) = tzero) ->
  ((ind_product f i j) = tzero).

Axiom ind_product_const_tone :
  forall (f:Z -> t) (i:Z) (j:Z), (i <= j)%Z ->
  (forall (t1:Z), ((i <= t1)%Z /\ (t1 < j)%Z) -> ((f t1) = tone)) ->
  ((ind_product f i j) = tone).

Axiom abs_eqinf :
  forall (x:Z) (y:Z), ((x <= y)%Z /\ (y <= 0%Z)%Z) ->
  ((ZArith.BinInt.Z.abs y) <= (ZArith.BinInt.Z.abs x))%Z.

Axiom abs_inf :
  forall (x:Z) (y:Z), ((0%Z < x)%Z /\ ((x < y)%Z /\ (y <= 0%Z)%Z)) ->
  ((ZArith.BinInt.Z.abs y) < (ZArith.BinInt.Z.abs x))%Z.

Axiom abs_eqsup :
  forall (x:Z) (y:Z), ((x <= 0%Z)%Z /\ (y <= x)%Z) ->
  ((ZArith.BinInt.Z.abs x) <= (ZArith.BinInt.Z.abs y))%Z.

Axiom abs_sup :
  forall (x:Z) (y:Z), ((x <= 0%Z)%Z /\ (y < x)%Z) ->
  ((ZArith.BinInt.Z.abs x) < (ZArith.BinInt.Z.abs y))%Z.

Axiom inv_negeq :
  forall (x:Z), (x <= 0%Z)%Z -> (0%Z <= (ZArith.BinInt.Z.abs x))%Z.

Axiom inv_neg1 :
  forall (x:Z), (x < 0%Z)%Z -> (0%Z < (ZArith.BinInt.Z.abs x))%Z.

Parameter infix_lseqdt_closure: t -> t -> bool.

Axiom infix_lseqdt_closure_def :
  forall (y:t) (y1:t),
  (((infix_lseqdt_closure y) y1) = true) <-> (infix_lseqdt y y1).

Axiom antisym_infeq_t :
  (forall (a:t) (b:t), (infix_lseqdt a b) -> (infix_lseqdt b a) -> (a = b)) /\
  (antisym infix_lseqdt_closure).

Axiom transitive_infeq_t :
  (forall (a:t) (b:t) (c:t), (infix_lseqdt a b) -> (infix_lseqdt b c) ->
   infix_lseqdt a c) /\
  (transitive infix_lseqdt_closure).

Parameter infix_lsdt_closure: t -> t -> bool.

Axiom infix_lsdt_closure_def :
  forall (y:t) (y1:t),
  (((infix_lsdt_closure y) y1) = true) <-> (infix_lsdt y y1).

Axiom transitive_inf_t :
  (forall (a:t) (b:t) (c:t), (infix_lsdt a b) -> (infix_lsdt b c) ->
   infix_lsdt a c) /\
  (transitive infix_lsdt_closure).

Axiom reflexive_infeq_t :
  (forall (a:t), infix_lseqdt a a) /\ (reflexive infix_lseqdt_closure).

Parameter cpower: t -> Z -> t.

Axiom Cpower_zero : forall (i:t), ((cpower i 0%Z) = tone).

Axiom Cpower_one : forall (i:t), ((cpower i 1%Z) = i).

Axiom Cpower_sum :
  forall (i:t), forall (n:Z) (m:Z),
  ((cpower i (n + m)%Z) = (infix_asdt (cpower i n) (cpower i m))).

Axiom cpower_sum :
  forall (x:t) (n:Z) (m:Z),
  ((cpower x (n + m)%Z) = (infix_asdt (cpower x n) (cpower x m))).

Axiom cpower_zero : forall (e:t), ((cpower e 0%Z) = tone).

Axiom cpower_inv :
  forall (e:t) (i:Z), ((infix_asdt (cpower e i) (cpower e (-i)%Z)) = tone).

Axiom inv_cpower :
  forall (e:t) (i:Z), ((inv1 (cpower e i)) = (cpower e (-i)%Z)).

Axiom cpower_plus_one :
  forall (e:t) (i:Z), ((cpower e (i + 1%Z)%Z) = (infix_asdt (cpower e i) e)).

Axiom cpower_tone_pos :
  forall (m:Z), (0%Z <= m)%Z -> ((cpower tone m) = tone).

Axiom cpower_iterate :
  forall (e:t) (i:Z), (0%Z <= i)%Z ->
  ((cpower e i) =
   (int_iterate (fun (y0:t) (y1:t) => (infix_asdt y0 y1))
    ((fun (y0:t) (y1:Z) => y0) e) 0%Z i)).

Axiom cpower_mult_pre :
  forall (x:t) (n:Z) (m:Z), (0%Z <= m)%Z ->
  ((cpower x (n * m)%Z) = (cpower (cpower x n) m)).

Axiom cpower_mult :
  forall (x:t) (n:Z) (m:Z), ((cpower x (n * m)%Z) = (cpower (cpower x n) m)).

Axiom non_zero_cpower_pos :
  forall (i:t) (n:Z), ~ (i = tzero) -> (0%Z <= n)%Z ->
  ~ ((cpower i n) = tzero).

Axiom zero_cpower_pos :
  forall (n:Z), (0%Z < n)%Z -> ((cpower tzero n) = tzero).

Axiom zero_cpower : forall (n:Z), ~ (n = 0%Z) -> ((cpower tzero n) = tzero).

Axiom non_zero_cpower :
  forall (i:t) (n:Z), ~ (i = tzero) -> ~ ((cpower i n) = tzero).

Axiom real_cpower_pos :
  forall (elt:t) (i:Z), (real_ elt) -> (0%Z <= i)%Z -> real_ (cpower elt i).

Axiom real_cpower :
  forall (elt:t) (i:Z), (real_ elt) -> real_ (cpower elt i).

Axiom pre_cond_int_ :
  forall (a:t) (b:t) (c:t), (infix_lsdt a b) -> (infix_lsdt tzero c) ->
  infix_lsdt (infix_asdt a c) (infix_asdt b c).

Axiom pre_cond_int :
  (compat_order_mult1 infix_lsdt_closure
   (fun (y0:t) (y1:t) => (infix_asdt y0 y1)) tzero) /\
  ((compat_order_mult1 infix_lseqdt_closure
    (fun (y0:t) (y1:t) => (infix_asdt y0 y1)) tzero) /\
   ((infix_lsdt tzero tone) /\
    ((partial_order infix_lseqdt_closure) /\
     ((neutral (fun (y0:t) (y1:t) => (infix_asdt y0 y1)) tone) /\
      ((iterable (fun (y0:t) (y1:t) => (infix_asdt y0 y1))) /\
       (strict infix_lsdt_closure infix_lseqdt_closure)))))).

Axiom growing_mult1 :
  forall (n:t) (m:t), (infix_lseqdt tzero n) -> (infix_lseqdt tone m) ->
  infix_lseqdt n (infix_asdt n m).

Axiom strict_growing_mult_pos :
  forall (n:t) (m:t), (infix_lsdt tone n) -> (infix_lsdt tone m) ->
  infix_lsdt n (infix_asdt n m).

Axiom init_exp1 :
  forall (k:t),
  ((cpower k 0%Z) = tone) /\
  (((cpower k 1%Z) = k) /\ ((cpower k 2%Z) = (infix_asdt k k))).

Axiom int_exp_pos :
  forall (k:t) (n:Z), (infix_lseqdt tone k) -> (0%Z <= n)%Z ->
  (infix_gteqdt (cpower k n) tone) /\
  ((infix_gtdt (cpower k n) tzero) /\
   (infix_lseqdt (cpower k n) (cpower k (n + 1%Z)%Z))).

Axiom strict_int_exp_pos :
  forall (k:t) (n:Z), (infix_lsdt tone k) -> (0%Z < n)%Z ->
  (infix_gtdt (cpower k n) tone) /\
  ((infix_lsdt (cpower k (n - 1%Z)%Z) (cpower k n)) /\
   (infix_lsdt (cpower k n) (cpower k (n + 1%Z)%Z))).

Axiom strict_int_exp_neg :
  forall (k:t) (n:Z), (infix_lsdt tone k) -> (n < 0%Z)%Z ->
  (infix_lsdt (cpower k n) tone) /\
  ((infix_lsdt (cpower k (n - 1%Z)%Z) (cpower k n)) /\
   (infix_lsdt (cpower k n) (cpower k (n + 1%Z)%Z))).

Axiom int_exp_neg :
  forall (k:t) (n:Z), (infix_lseqdt tone k) -> (n < 0%Z)%Z ->
  (infix_lseqdt (cpower k n) tone) /\
  ((infix_gtdt (cpower k n) tzero) /\
   (infix_lseqdt (cpower k n) (cpower k (n + 1%Z)%Z))).

Axiom growing_exp_pos :
  forall (k:t) (m:Z) (n:Z), (infix_lseqdt tone k) ->
  ((0%Z <= m)%Z /\ (m <= n)%Z) -> infix_lseqdt (cpower k m) (cpower k n).

Axiom growing_exp1 :
  forall (k:t) (m:Z) (n:Z), (infix_lseqdt tone k) -> (m <= n)%Z ->
  infix_lseqdt (cpower k m) (cpower k n).

Axiom strict_growing_exp1 :
  forall (k:t) (m:Z) (n:Z), (infix_lsdt tone k) -> (m < n)%Z ->
  infix_lsdt (cpower k m) (cpower k n).

Axiom positive_exp :
  forall (k:t) (m:Z), (infix_lseqdt tone k) -> infix_lsdt tzero (cpower k m).

Axiom cpower_comm_pos :
  forall (x:t) (y:t) (n:Z), (infix_lseqdt tone x) -> (infix_lseqdt tone y) ->
  (0%Z <= n)%Z ->
  ((cpower (infix_asdt x y) n) = (infix_asdt (cpower x n) (cpower y n))).

Axiom cpower_comm :
  forall (x:t) (y:t) (n:Z), (infix_lseqdt tone x) -> (infix_lseqdt tone y) ->
  ((cpower (infix_asdt x y) n) = (infix_asdt (cpower x n) (cpower y n))).

Axiom unicity_exp1 :
  forall (k:t) (m:Z) (n:Z), (infix_lsdt tone k) ->
  ((cpower k m) = (cpower k n)) <-> (m = n).

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 zero_add : forall (a1:Z) (a2:Z), (a1 = 0%Z) -> ((a1 + a2)%Z = a2).

Axiom add_zero : forall (a1:Z) (a2:Z), (a2 = 0%Z) -> ((a1 + a2)%Z = a1).

Axiom one_mult : forall (a1:Z) (a2:Z), (a1 = 1%Z) -> ((a1 * a2)%Z = a2).

Axiom mult_one : forall (a1:Z) (a2:Z), (a2 = 1%Z) -> ((a1 * a2)%Z = a1).

Axiom add_eq :
  forall (a1:Z) (a2:Z) (b1:Z) (b2:Z), (a1 = a2) -> (b1 = b2) ->
  ((a1 + b1)%Z = (a2 + b2)%Z).

Axiom mult_eq :
  forall (a1:Z) (a2:Z) (b1:Z) (b2:Z), (a1 = a2) -> (b1 = b2) ->
  ((a1 * b1)%Z = (a2 * b2)%Z).

Axiom add_eq_inv :
  forall (a1:Z) (a2:Z) (b1:Z) (b2:Z), (a1 = a2) -> (b1 = b2) ->
  ((a1 + b1)%Z = (b2 + a2)%Z).

Axiom mult_eq_inv :
  forall (a1:Z) (a2:Z) (b1:Z) (b2:Z), (a1 = a2) -> (b1 = b2) ->
  ((a1 * b1)%Z = (b2 * a2)%Z).

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

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 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 mod_eq :
  forall (a:Z) (b:Z) (d:Z), (a = b) ->
  ((int.EuclideanDivision.mod1 a d) = (int.EuclideanDivision.mod1 b d)).

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

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

Axiom mod_zero :
  forall (i:Z) (j:Z), (0%Z <= i)%Z -> (0%Z < j)%Z ->
  ((int.EuclideanDivision.mod1 i j) = 0%Z) ->
  (i = (j * (int.EuclideanDivision.div 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 < j)%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 < j)%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))%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 bound_div_gen :
  forall (q:Z) (f:Z), (0%Z <= q)%Z -> (0%Z <= f)%Z -> forall (i:Z),
  ((0%Z <= i)%Z /\ (i < (q * f)%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_left :
  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 (f * j)%Z) j) =
   (int.EuclideanDivision.mod1 i j)).

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

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

Axiom add_mod :
  forall (a:Z) (b:Z) (c:Z), (0%Z < c)%Z ->
  ((int.EuclideanDivision.mod1
    ((int.EuclideanDivision.mod1 a c) + (int.EuclideanDivision.mod1 b c))%Z
    c)
   = (int.EuclideanDivision.mod1 (a + b)%Z c)).

Axiom mod_mod_right :
  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)).

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_assoc1 :
  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_gen :
  forall (n:Z) (v:Z) (p:Z), ((0%Z <= p)%Z /\ (p < v)%Z) -> forall (k:Z),
  ((0%Z <= k)%Z /\ (k < n)%Z) -> (((k * v)%Z + p)%Z < (n * v)%Z)%Z.

Axiom inf_mul_gen_b :
  forall (n:Z) (v:Z) (p:Z), ((0%Z <= p)%Z /\ (p < n)%Z) -> forall (k:Z),
  ((0%Z <= k)%Z /\ (k < v)%Z) -> (((p * v)%Z + k)%Z < (n * v)%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.mod1 i rest) < rest)%Z.

Parameter result4:
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  (im1 -> im1 -> im1) -> (a -> im1) -> a -> bool.

Axiom result_def4 :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (t1:a -> im1) (e:a),
  (((result4 op1 t1) e) = true) <-> ~ (neutral op1 (t1 e)).

(* Why3 assumption *)
Definition nonn_part1 {a:Type} {a_WT:WhyType a}
    {im1:Type} {im1_WT:WhyType im1} (op1:im1 -> im1 -> im1) (s:set a)
    (t1:a -> im1) : set a :=
  filter (result4 op1 t1) s.

Axiom nonn_part_spec1 :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (t1:a -> im1), forall (e:a),
  (mem e (nonn_part1 op1 s t1)) <-> ((mem e s) /\ ~ (neutral op1 (t1 e))).

Parameter result5:
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  (im1 -> im1 -> im1) -> (a -> im1) -> a -> bool.

Axiom result_def5 :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (t1:a -> im1) (e:a),
  (((result5 op1 t1) e) = true) <-> (neutral op1 (t1 e)).

(* Why3 assumption *)
Definition n_part1 {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1}
    (op1:im1 -> im1 -> im1) (s:set a) (t1:a -> im1) : set a :=
  filter (result5 op1 t1) s.

Axiom n_part_spec1 :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (t1:a -> im1), forall (e:a),
  (mem e (n_part1 op1 s t1)) <-> ((mem e s) /\ (neutral op1 (t1 e))).

Axiom nullity_partition1 :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (t1:a -> im1), (commut op1) ->
  (s = (union (nonn_part1 op1 s t1) (n_part1 op1 s t1))) /\
  ((inter (nonn_part1 op1 s t1) (n_part1 op1 s t1)) = (empty : set a)).

Axiom iterate_neutral1 :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (t1:a -> im1), (iterable op1) ->
  (commut op1) ->
  (forall (a1:a), (mem a1 s) -> ((t1 a1) = (neutral_elt op1))) ->
  ((iterate op1 s t1) = (neutral_elt op1)).

Axiom iterate_nullity_partition1 :
  forall {a:Type} {a_WT:WhyType a} {im1:Type} {im1_WT:WhyType im1},
  forall (op1:im1 -> im1 -> im1) (s:set a) (t1:a -> im1), (iterable op1) ->
  (commut op1) ->
  ((iterate op1 s t1) = (iterate op1 (nonn_part1 op1 s t1) t1)).

Parameter indic: forall {a:Type} {a_WT:WhyType a}, a -> a -> t.

Axiom indic_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:a) (a':a),
  ((a1 = a') -> ((indic a1 a') = tone)) /\
  (~ (a1 = a') -> ((indic a1 a') = tzero)).

Axiom get_indic :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:a) (a':a),
  ((a1 = a') -> ((indic a1 a') = tone)) /\
  (~ (a1 = a') -> ((indic a1 a') = tzero)).

Parameter indic_bool: forall {a:Type} {a_WT:WhyType a}, a -> a -> bool.

Axiom indic_bool_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:a) (a':a),
  ((a1 = a') -> ((indic_bool a1 a') = true)) /\
  (~ (a1 = a') -> ((indic_bool a1 a') = false)).

Axiom indic_comm :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:a) (a':a), ((indic a1 a') = (indic a' a1)).

Axiom indic_transl_r :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:a) (b:a) (c:a), (b = c) -> ((indic a1 b) = (indic a1 c)).

Axiom indic_transl_l :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:a) (b:a) (c:a), (b = c) -> ((indic b a1) = (indic c a1)).

Parameter indic_2:
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}, a -> a -> b ->
  b -> t.

Axiom indic_2_def :
  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')) -> ((indic_2 a1 a' b1 b') = tone)) /\
  (~ ((a1 = a') /\ (b1 = b')) -> ((indic_2 a1 a' b1 b') = tzero)).

Axiom indic_2_spec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (a1:a) (a':a) (b1:b) (b':b),
  ((indic_2 a1 a' b1 b') = (infix_asdt (indic a1 a') (indic b1 b'))) /\
  ((indic_2 a1 a' b1 b') = (indic (a1, b1) (a', b'))).

Axiom indic_2_comm :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (a1:a) (a':a) (b1:b) (b':b),
  ((indic_2 a1 a' b1 b') = (indic_2 a' a1 b1 b')) /\
  (((indic_2 a1 a' b1 b') = (indic_2 a1 a' b' b1)) /\
   ((indic_2 a1 a' b1 b') = (indic_2 a' a1 b' b1))).

(* Why3 assumption *)
Definition sum_indic {a:Type} {a_WT:WhyType a} (s:set a) (t1:a -> t)
    (i:a) : t :=
  sum s (fun (e:a) => (infix_asdt (t1 e) (indic i e))).

Parameter ind_sum_indic: (Z -> t) -> Z -> Z -> Z -> t.

Axiom ind_sum_indic_def :
  forall (t1:Z -> t) (l:Z) (h:Z) (i:Z), (l < h)%Z ->
  ((ind_sum_indic t1 l h i) =
   (ind_sum (fun (e:Z) => (infix_asdt (t1 e) (indic i e))) l h)).

Axiom ind_sum_indic_spec :
  forall (t1:Z -> t) (l:Z) (h:Z) (i:Z), (l < h)%Z ->
  ((ind_sum_indic t1 l h i) = (sum_indic (to_fset l h) t1 i)).

Axiom sum_indic_t :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> t) (i:a), (mem i s) ->
  ((sum_indic s t1 i) = (t1 i)).

Axiom sum_indic_ts :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> t) (i:a), (mem i s) ->
  ((sum s (fun (e:a) => (infix_asdt (t1 e) (indic i e)))) = (t1 i)).

Axiom ind_sum_indic_t :
  forall (t1:Z -> t) (l:Z) (h:Z) (i:Z), ((l <= i)%Z /\ (i < h)%Z) ->
  ((ind_sum_indic t1 l h i) = (t1 i)) /\
  ((ind_sum (fun (e:Z) => (infix_asdt (t1 e) (indic i e))) l h) = (t1 i)).

Axiom ind_sum_indic_t_quant :
  forall (t1:Z -> t) (l:Z) (h:Z), forall (i:Z), ((l <= i)%Z /\ (i < h)%Z) ->
  ((ind_sum (fun (e:Z) => (infix_asdt (t1 e) (indic i e))) l h) = (t1 i)).

Axiom indic_div_mod :
  forall (i:Z) (j:Z) (q:Z), (0%Z <= i)%Z -> (0%Z <= j)%Z -> (0%Z < q)%Z ->
  ((indic i j) =
   (infix_asdt
    (indic (int.EuclideanDivision.mod1 i q) (int.EuclideanDivision.mod1 j q))
    (indic (int.EuclideanDivision.div i q) (int.EuclideanDivision.div j q)))).

Axiom indic_div_mod_gen :
  forall (q:Z), (0%Z < q)%Z -> forall (i:Z) (j:Z),
  ((0%Z <= i)%Z /\ (0%Z <= j)%Z) ->
  ((indic i j) =
   (infix_asdt
    (indic (int.EuclideanDivision.mod1 i q) (int.EuclideanDivision.mod1 j q))
    (indic (int.EuclideanDivision.div i q) (int.EuclideanDivision.div j q)))).

Axiom set_inf : True.

Axiom set_infeq : True.

Parameter exp: t -> t.

Axiom Exp_one : real_ (exp tone).

Axiom Exp_zero : ((exp tzero) = tone).

Axiom Exp_sum :
  forall (x:t) (y:t), ((exp (infix_pldt x y)) = (infix_asdt (exp x) (exp y))).

Axiom exp_one : real_ (exp tone).

Axiom exp_sum :
  forall (x:t) (y:t), ((exp (infix_pldt x y)) = (infix_asdt (exp x) (exp y))).

Axiom exp_eq : forall (t1:t) (t2:t), (t1 = t2) -> ((exp t1) = (exp t2)).

Axiom exp_sum_rev :
  forall (x:t) (y:t), ((infix_asdt (exp x) (exp y)) = (exp (infix_pldt x y))).

Axiom exp_inv :
  forall (i:t), ~ ((exp i) = tzero) ->
  ((exp (prefix_mndt i)) = (infix_sldt tone (exp i))).

Axiom exp_mult :
  forall (x:t) (y:Z), ((exp (infix_asdt x (i_to_t y))) = (cpower (exp x) y)).

Axiom cpower_to_exp :
  forall (x:t) (y:Z), ((cpower (exp x) y) = (exp (infix_asdt x (i_to_t y)))).

Axiom Exp_h_pi :
  ((exp (infix_sldt (infix_asdt im pi) (infix_pldt tone tone))) = im).

Axiom exp_pi : ((exp (infix_asdt im pi)) = (prefix_mndt tone)).

Axiom exp_two_pi :
  ((exp (infix_asdt (infix_asdt im pi) (infix_pldt tone tone))) = tone).

Axiom exp_two_pi_mul :
  forall (k:Z), (0%Z <= k)%Z ->
  ((exp
    (infix_asdt (i_to_t k)
     (infix_asdt (infix_asdt im pi) (infix_pldt tone tone))))
   = tone).

Axiom exp_two_pi_mul_den :
  forall (k:Z) (l:Z), ~ (k = 0%Z) ->
  ((exp
    (infix_sldt
     (infix_asdt (i_to_t (k * l)%Z)
      (infix_asdt (infix_asdt im pi) (infix_pldt tone tone)))
     (i_to_t k)))
   = tone).

Axiom exp_two_pi_mul_den_add :
  forall (k:Z) (l:Z) (m:Z), (0%Z <= (k * m)%Z)%Z ->
  ((exp
    (infix_asdt (i_to_t ((k * m)%Z + l)%Z)
     (infix_asdt (infix_asdt im pi) (infix_pldt tone tone))))
   =
   (exp
    (infix_asdt (i_to_t l)
     (infix_asdt (infix_asdt im pi) (infix_pldt tone tone))))).

Axiom comp_exp_cpower :
  forall (i:Z) (j:Z), (0%Z <= i)%Z -> (0%Z <= j)%Z ->
  ((cpower (exp (i_to_t i)) j) = (cpower (exp tone) (i * j)%Z)) /\
  ((cpower (exp (i_to_t i)) j) = (exp (i_to_t (i * j)%Z))).

Parameter unity_rt: Z -> t.

Axiom unity_rt_def :
  forall (n:Z), (0%Z < n)%Z ->
  ((unity_rt n) =
   (exp
    (infix_sldt (infix_asdt (infix_asdt im pi) (infix_pldt tone tone))
     (i_to_t n)))).

Axiom unity_rt_spec :
  forall (n:Z), (0%Z < n)%Z ->
  ((cpower (unity_rt n) n) = tone) /\ ~ ((unity_rt n) = tzero).

Axiom exp_mod :
  forall (k:Z) (n:Z), (0%Z < n)%Z ->
  ((exp
    (infix_sldt
     (infix_asdt (i_to_t k)
      (infix_asdt (infix_asdt im pi) (infix_pldt tone tone)))
     (i_to_t n)))
   =
   (exp
    (infix_sldt
     (infix_asdt (i_to_t (int.EuclideanDivision.mod1 k n))
      (infix_asdt (infix_asdt im pi) (infix_pldt tone tone)))
     (i_to_t n)))).

Parameter p_unity: Z -> Z -> t.

Axiom p_unity_def :
  forall (n:Z) (k:Z), (0%Z < n)%Z ->
  ((p_unity n k) = (cpower (unity_rt n) k)).

Axiom p_unity_mod :
  forall (n:Z) (k:Z), (0%Z < n)%Z ->
  ((p_unity n k) = (p_unity n (int.EuclideanDivision.mod1 k n))).

Axiom cpower_mod :
  forall (n:Z) (k:Z), (0%Z < n)%Z ->
  ((cpower (unity_rt n) k) =
   (cpower (unity_rt n) (int.EuclideanDivision.mod1 k n))).

Axiom p_unity_sum :
  forall (n:Z) (k:Z) (k':Z), (0%Z < n)%Z ->
  ((p_unity n (k + k')%Z) = (infix_asdt (p_unity n k) (p_unity n k'))).

Axiom exp_p_unity :
  forall (n:Z) (k:Z), (0%Z < n)%Z ->
  ((p_unity n k) =
   (exp
    (infix_sldt
     (infix_asdt (i_to_t (int.EuclideanDivision.mod1 k n))
      (infix_asdt (infix_asdt im pi) (infix_pldt tone tone)))
     (i_to_t n)))).

Axiom unity_rt_trans :
  forall (n:Z) (k:Z), (0%Z < n)%Z -> (0%Z < k)%Z ->
  ((unity_rt n) = (cpower (unity_rt (n * k)%Z) k)).

Axiom unity_rt_two : ((unity_rt 2%Z) = (prefix_mndt tone)).

Axiom p_unity_neut :
  forall (n:Z) (k:Z), (0%Z < n)%Z -> (0%Z <= k)%Z ->
  ((p_unity n (n * k)%Z) = tone).

Parameter omega: Z -> t.

Axiom omega_def :
  forall (n:Z), (0%Z <= n)%Z -> ((omega n) = (unity_rt (power 2%Z n))).

Parameter p_omega: Z -> Z -> t.

Axiom p_omega_def :
  forall (n:Z) (k:Z), (0%Z <= n)%Z -> ((p_omega n k) = (cpower (omega n) k)).

Axiom p_omega_spec :
  forall (n:Z) (k:Z), (0%Z <= n)%Z ->
  ((p_omega n k) = (p_unity (power 2%Z n) k)).

Axiom p_omega_to_omega :
  forall (n:Z) (k:Z), (0%Z <= n)%Z ->
  ((p_omega n k) =
   (cpower (omega n) (int.EuclideanDivision.mod1 k (power 2%Z n)))).

Axiom p_omega_eq :
  forall (n:Z) (k:Z) (k':Z), (0%Z <= n)%Z -> (k = k') ->
  ((p_omega n k) = (p_omega n k')).

Axiom p_omega_eq_gen :
  forall (n:Z) (n':Z) (k:Z) (k':Z), (0%Z <= n)%Z -> (k = k') -> (n = n') ->
  ((p_omega n k) = (p_omega n' k')).

Axiom p_omega_unity :
  forall (n:Z) (k:Z), (0%Z <= n)%Z ->
  ((p_omega n k) = (p_unity (power 2%Z n) k)).

Axiom p_unity_omega :
  forall (n:Z) (k:Z), (0%Z <= n)%Z ->
  ((p_unity (power 2%Z n) k) = (p_omega n k)).

Axiom exp_omega :
  forall (n:Z), (0%Z <= n)%Z ->
  ((omega n) =
   (exp
    (infix_sldt (infix_asdt (infix_asdt im pi) (infix_pldt tone tone))
     (i_to_t (power 2%Z n))))).

Axiom exp_p_omega :
  forall (n:Z) (k:Z), (0%Z <= n)%Z ->
  ((p_omega n k) =
   (exp
    (infix_sldt
     (infix_asdt (i_to_t k)
      (infix_asdt (infix_asdt im pi) (infix_pldt tone tone)))
     (i_to_t (power 2%Z n))))).

Axiom p_omega_sum :
  forall (n:Z) (k:Z) (k':Z), (0%Z <= n)%Z ->
  ((p_omega n (k + k')%Z) = (infix_asdt (p_omega n k) (p_omega n k'))).

Axiom p_omega_sum_rev :
  forall (n:Z) (k:Z) (k':Z), (0%Z <= n)%Z ->
  ((infix_asdt (p_omega n k) (p_omega n k')) = (p_omega n (k + k')%Z)).

Axiom p_omega_sum_gen :
  forall (n:Z) (n':Z) (k:Z) (k':Z), (0%Z <= n)%Z -> (n = n') ->
  ((p_omega n (k + k')%Z) = (infix_asdt (p_omega n k) (p_omega n' k'))).

Axiom p_omega_sum_rev_gen :
  forall (n:Z) (n':Z) (k:Z) (k':Z), (0%Z <= n)%Z -> (n = n') ->
  ((infix_asdt (p_omega n k) (p_omega n' k')) = (p_omega n (k + k')%Z)).

Axiom p_omega_neut :
  forall (n:Z) (k:Z), (0%Z <= n)%Z -> (0%Z <= k)%Z ->
  ((p_omega n ((power 2%Z n) * k)%Z) = tone).

Axiom p_omega_mod :
  forall (n:Z) (k:Z), (0%Z <= n)%Z ->
  ((p_omega n k) = (p_omega n (int.EuclideanDivision.mod1 k (power 2%Z n)))).

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

Axiom omega_transl :
  forall (n:Z) (n':Z), (0%Z <= n)%Z -> (0%Z <= n')%Z -> (n <= n')%Z ->
  ((omega n) = (p_omega n' (power 2%Z (n' - n)%Z))).

Axiom p_omega_transl :
  forall (n:Z) (n':Z) (k:Z), (0%Z <= n)%Z -> (0%Z <= n')%Z -> (n <= n')%Z ->
  ((p_omega n k) = (p_omega n' (k * (power 2%Z (n' - n)%Z))%Z)).

Axiom p_omega_plus_one :
  forall (n:Z) (k:Z), (0%Z <= n)%Z ->
  ((p_omega n k) = (p_omega (n + 1%Z)%Z (k * 2%Z)%Z)).

Axiom p_omega_minus_one :
  forall (n:Z) (k:Z), (0%Z < n)%Z ->
  ((p_omega n k) = (p_omega (n + 1%Z)%Z (k * 2%Z)%Z)).

Axiom p_omega_rt_two :
  forall (n:Z), (0%Z < n)%Z ->
  ((p_omega n (power 2%Z (n - 1%Z)%Z)) = (prefix_mndt tone)).

Axiom p_omega_sum_units :
  forall (n:Z) (n':Z), (0%Z <= n)%Z -> (0%Z <= n')%Z -> (n <= n')%Z ->
  ((infix_asdt (omega n) (omega n')) =
   (p_omega n' (1%Z + (power 2%Z (n' - n)%Z))%Z)).

Axiom p_omega_add_ord :
  forall (n:Z) (k:Z) (n':Z) (k':Z), ((n <= n')%Z /\ (0%Z <= n)%Z) ->
  ((infix_asdt (p_omega n k) (p_omega n' k')) =
   (p_omega n' (k' + (k * (power 2%Z (n' - n)%Z))%Z)%Z)).

Axiom p_omega_add :
  forall (n:Z) (k:Z) (n':Z) (k':Z), (0%Z <= n)%Z -> (0%Z <= n')%Z ->
  ((n' <= n)%Z ->
   ((infix_asdt (p_omega n k) (p_omega n' k')) =
    (p_omega n (k + (k' * (power 2%Z (n - n')%Z))%Z)%Z))) /\
  (~ (n' <= n)%Z ->
   ((infix_asdt (p_omega n k) (p_omega n' k')) =
    (p_omega n' (k' + (k * (power 2%Z (n' - n)%Z))%Z)%Z))).

Axiom p_omega_equiv :
  forall (n:Z) (k:Z) (a:Z), (0%Z <= n)%Z ->
  ((p_omega n k) = (p_omega n (k + (a * (power 2%Z n))%Z)%Z)).

Axiom p_omega_equiv_rev :
  forall (n:Z) (k:Z) (a:Z), (0%Z <= n)%Z ->
  ((p_omega n (k + ((power 2%Z n) * a)%Z)%Z) = (p_omega n k)).

Axiom omega_sum_to_prod :
  forall {a:Type} {a_WT:WhyType a},
  forall (n:Z) (f:a -> Z) (s:set a), (0%Z <= n)%Z ->
  ((p_omega n (isum s f)) = (product s (fun (k:a) => (p_omega n (f k))))).

Parameter fc5: Z -> (Z -> Z) -> Z -> Z -> Z -> t.

Axiom fc_def5 :
  forall (n:Z) (f:Z -> Z) (i:Z) (j:Z) (k:Z),
  (((i <= k)%Z /\ (k < j)%Z) -> (((fc5 n f i j) k) = (p_omega n (f k)))) /\
  (~ ((i <= k)%Z /\ (k < j)%Z) -> (((fc5 n f i j) k) = tone)).

Axiom omega_ind_sum_to_prod :
  forall (n:Z) (f:Z -> Z) (i:Z) (j:Z), (0%Z <= n)%Z -> (0%Z <= n)%Z ->
  ((p_omega n (ind_isum f i j)) = (ind_product (fc5 n f i j) i j)).

Parameter cos: t -> t.

Axiom cos_spec :
  forall (x:t), (real_ x) ->
  (real_ (cos x)) /\
  ((infix_lseqdt (prefix_mndt tone) (cos x)) /\ (infix_lseqdt (cos x) tone)).

Axiom cos_zero : ((cos tzero) = tone).

Axiom cos_half_pi : ((cos (infix_sldt pi (infix_pldt tone tone))) = tzero).

Axiom cos_pi : ((cos pi) = (prefix_mndt tone)).

Parameter sin: t -> t.

Axiom sin_def :
  forall (x:t), (real_ x) ->
  ((sin x) = (cos (infix_mndt x (infix_sldt pi (infix_pldt tone tone))))).

Axiom sin_spec :
  forall (x:t), (real_ x) ->
  (real_ (sin x)) /\
  ((infix_lseqdt (prefix_mndt tone) (sin x)) /\ (infix_lseqdt (sin x) tone)).

Axiom euler_real_r :
  forall (x:t), (real_ x) ->
  ((cos x) = (r_to_t (real_part (exp (infix_asdt im x))))).

Axiom euler_im_r :
  forall (x:t), (real_ x) ->
  ((sin x) = (r_to_t (im_part (exp (infix_asdt im x))))).

Axiom euler_real :
  forall (x:t), (real_ x) ->
  ((cos x) = (t_real_part (exp (infix_asdt im x)))).

Axiom euler_im :
  forall (x:t), (real_ x) -> ((sin x) = (t_im_part (exp (infix_asdt im x)))).

Axiom power_minus_one :
  forall (i:Z), (0%Z <= i)%Z ->
  (((int.EuclideanDivision.mod1 i 2%Z) = 0%Z) -> ((power (-1%Z)%Z i) = 1%Z)) /\
  (((int.EuclideanDivision.mod1 i 2%Z) = 1%Z) ->
   ((power (-1%Z)%Z i) = (-1%Z)%Z)).

Parameter kth_right: Z -> Z -> Z -> (Z -> Z) -> Z.

Axiom kth_right_def :
  forall (i:Z) (k:Z) (h:Z) (f:Z -> Z), (0%Z <= i)%Z -> (1%Z <= k)%Z ->
  (forall (l:Z), (((h - k)%Z <= l)%Z /\ (l < h)%Z) -> (0%Z < (f l))%Z) ->
  ((kth_right i k h f) =
   (int.EuclideanDivision.mod1
    (int.EuclideanDivision.div i (ind_iproduct f ((h - k)%Z + 1%Z)%Z h))
    (f (h - k)%Z))).

Axiom kth_right_spec :
  forall (i:Z) (k:Z) (h:Z) (f:Z -> Z), (0%Z <= i)%Z -> (1%Z <= k)%Z ->
  (forall (l:Z), (((h - k)%Z <= l)%Z /\ (l < h)%Z) -> (0%Z < (f l))%Z) ->
  (0%Z <= (kth_right i k h f))%Z /\ ((kth_right i k h f) < (f (h - k)%Z))%Z.

Axiom kth_right_eq :
  forall (i:Z) (k:Z) (h:Z) (f:Z -> Z) (g:Z -> Z), (0%Z <= i)%Z ->
  (1%Z <= k)%Z ->
  (forall (l:Z), (((h - k)%Z <= l)%Z /\ (l <= h)%Z) -> (0%Z < (f l))%Z) ->
  (forall (l:Z), (((h - k)%Z <= l)%Z /\ (l <= h)%Z) -> ((f l) = (g l))) ->
  ((kth_right i k h f) = (kth_right i k h g)).

Axiom kth_right_trans :
  forall (i:Z) (k:Z) (h:Z) (t1:Z) (f:Z -> Z), (0%Z <= i)%Z -> (1%Z <= k)%Z ->
  (forall (l:Z), (0%Z < (f l))%Z) -> (0%Z <= h)%Z -> (0%Z <= t1)%Z ->
  ((kth_right (int.EuclideanDivision.div i (ind_iproduct f h (h + t1)%Z)) k h
    f)
   = (kth_right i (k + t1)%Z (h + t1)%Z f)).

Parameter kth_left: Z -> Z -> Z -> Z -> (Z -> Z) -> Z.

Axiom kth_left_def :
  forall (i:Z) (k:Z) (l:Z) (h:Z) (f:Z -> Z), (0%Z <= i)%Z -> (0%Z <= l)%Z ->
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  (forall (ind:Z), ((l <= ind)%Z /\ (ind < h)%Z) -> (0%Z < (f ind))%Z) ->
  ((kth_left i k l h f) = (kth_right i (((h - l)%Z - k)%Z + 1%Z)%Z h f)).

Axiom kth_left_spec :
  forall (i:Z) (k:Z) (l:Z) (h:Z) (f:Z -> Z), (0%Z <= i)%Z -> (0%Z <= l)%Z ->
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  (forall (ind:Z), ((l <= ind)%Z /\ (ind < h)%Z) -> (0%Z < (f ind))%Z) ->
  ((kth_left i k l h f) =
   (int.EuclideanDivision.mod1
    (int.EuclideanDivision.div i (ind_iproduct f (l + k)%Z h))
    (f ((l + k)%Z - 1%Z)%Z))) /\
  ((0%Z <= (kth_left i k l h f))%Z /\
   ((kth_left i k l h f) < (f ((l + k)%Z - 1%Z)%Z))%Z).

Axiom kth_left_eq :
  forall (i:Z) (k:Z) (l:Z) (h:Z) (f:Z -> Z) (g:Z -> Z), (0%Z <= i)%Z ->
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) -> (0%Z <= l)%Z ->
  (forall (ind:Z), ((l <= ind)%Z /\ (ind < h)%Z) ->
   ((f ind) = (g ind)) /\ (0%Z < (g ind))%Z) ->
  ((kth_left i k l h f) = (kth_left i k l h g)).

Axiom kth_left_to_mod_div :
  forall (i:Z) (k:Z) (l:Z) (h:Z) (f:Z -> Z), (0%Z <= i)%Z -> (0%Z <= l)%Z ->
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  (forall (ind:Z), ((l <= ind)%Z /\ (ind <= h)%Z) -> (0%Z < (f ind))%Z) ->
  ((kth_left i k l h f) =
   (int.EuclideanDivision.mod1
    (int.EuclideanDivision.div i (ind_iproduct f (l + k)%Z h))
    (f ((l + k)%Z - 1%Z)%Z))).

Axiom kth_left_trans :
  forall (i:Z) (k:Z) (l:Z) (h:Z) (f:Z -> Z), (0%Z <= i)%Z -> (0%Z <= l)%Z ->
  ((1%Z <= k)%Z /\ (k < (h - l)%Z)%Z) ->
  (forall (ind:Z), ((l <= ind)%Z /\ (ind <= h)%Z) -> (0%Z < (f ind))%Z) ->
  ((kth_left i k l h f) =
   (kth_left (int.EuclideanDivision.div i (f (h - 1%Z)%Z)) k l (h - 1%Z)%Z f)).

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)).

Axiom kth_right_div_mod :
  forall (i:Z) (k:Z) (h:Z) (f:Z -> Z), (0%Z <= i)%Z -> (1%Z <= k)%Z ->
  (forall (k1:Z), (0%Z < (f k1))%Z) ->
  ((kth_right i k h f) =
   (int.EuclideanDivision.div
    (int.EuclideanDivision.mod1 i (ind_iproduct f (h - k)%Z h))
    (ind_iproduct f ((h - k)%Z + 1%Z)%Z h))).

Axiom kth_head :
  forall (i:Z) (h:Z) (f:Z -> Z), (0%Z <= i)%Z -> (1%Z <= h)%Z ->
  (forall (k:Z), (0%Z < (f k))%Z) ->
  ((kth_right i 1%Z h f) = (int.EuclideanDivision.mod1 i (f (h - 1%Z)%Z))).

Parameter weighted_kth_right: Z -> Z -> Z -> (Z -> Z) -> Z.

Axiom weighted_kth_right_def :
  forall (i:Z) (k:Z) (h:Z) (f:Z -> Z), (0%Z <= i)%Z ->
  (forall (k1:Z), (0%Z < (f k1))%Z) -> (1%Z <= k)%Z ->
  ((weighted_kth_right i k h f) =
   ((kth_right i k h f) * (ind_iproduct f ((h - k)%Z + 1%Z)%Z h))%Z).

Axiom weighted_kth_right_ :
  forall (i:Z) (k:Z) (h:Z) (f:Z -> Z), (1%Z <= k)%Z -> (0%Z <= i)%Z ->
  (forall (k1:Z), (0%Z < (f k1))%Z) ->
  ((int.EuclideanDivision.mod1 i (ind_iproduct f (h - k)%Z h)) =
   ((weighted_kth_right i k h f) +
    (int.EuclideanDivision.mod1 i (ind_iproduct f ((h - k)%Z + 1%Z)%Z h)))%Z).

Axiom kth_right_decomposition :
  forall (i:Z) (k:Z) (h:Z) (f:Z -> Z), (0%Z <= i)%Z -> (1%Z <= k)%Z ->
  (forall (k1:Z), (0%Z < (f k1))%Z) ->
  ((int.EuclideanDivision.mod1 i (ind_iproduct f (h - k)%Z h)) =
   (ind_isum (fun (a:Z) => (weighted_kth_right i a h f)) 1%Z (k + 1%Z)%Z)).

Axiom kth_left_div_mod :
  forall (i:Z) (k:Z) (l:Z) (h:Z) (f:Z -> Z), (0%Z <= i)%Z ->
  ((0%Z <= l)%Z /\ (l <= h)%Z) -> ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  (forall (k1:Z), (0%Z < (f k1))%Z) ->
  ((kth_left i k l h f) =
   (int.EuclideanDivision.div
    (int.EuclideanDivision.mod1 i (ind_iproduct f ((l + k)%Z - 1%Z)%Z h))
    (ind_iproduct f (l + k)%Z h))).

Parameter weighted_kth_left: Z -> Z -> Z -> Z -> (Z -> Z) -> Z.

Axiom weighted_kth_left_def :
  forall (i:Z) (k:Z) (l:Z) (h:Z) (f:Z -> Z), (0%Z <= i)%Z -> (l <= h)%Z ->
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  (forall (k1:Z), (0%Z < (f k1))%Z) ->
  ((weighted_kth_left i k l h f) =
   (weighted_kth_right i (((h - l)%Z - k)%Z + 1%Z)%Z h f)).

Axiom weighted_kth_left_ :
  forall (i:Z) (k:Z) (l:Z) (h:Z) (f:Z -> Z), (0%Z <= i)%Z -> (l <= h)%Z ->
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  (forall (k1:Z), (0%Z < (f k1))%Z) ->
  ((int.EuclideanDivision.mod1 i (ind_iproduct f ((l + k)%Z - 1%Z)%Z h)) =
   ((weighted_kth_left i k l h f) +
    (int.EuclideanDivision.mod1 i (ind_iproduct f (l + k)%Z h)))%Z).

Axiom bounded_kth_left_decomposition :
  forall (i:Z) (k:Z) (l:Z) (h:Z) (f:Z -> Z), (0%Z <= i)%Z -> (l <= h)%Z ->
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  (forall (k1:Z), (0%Z < (f k1))%Z) ->
  ((int.EuclideanDivision.mod1 i (ind_iproduct f ((l + k)%Z - 1%Z)%Z h)) =
   (ind_isum (fun (a:Z) => (weighted_kth_left i a l h f)) k
    ((h - l)%Z + 1%Z)%Z)).

Axiom kth_left_decomposition :
  forall (i:Z) (l:Z) (h:Z) (f:Z -> Z),
  ((0%Z <= i)%Z /\ (i < (ind_iproduct f l h))%Z) -> (l < h)%Z ->
  (forall (k:Z), (0%Z < (f k))%Z) ->
  (i =
   (ind_isum (fun (a:Z) => (weighted_kth_left i a l h f)) 1%Z
    ((h - l)%Z + 1%Z)%Z)).

Axiom d_frac : Type.
Parameter d_frac_WhyType : WhyType d_frac.
Existing Instance d_frac_WhyType.

Parameter to_values: d_frac -> (Z* Z)%type.

Parameter num: d_frac -> Z.

Parameter den: d_frac -> Z.

Axiom d_frac'invariant :
  forall (self:d_frac),
  ((to_values self) = (num self, den self)) /\ (0%Z <= (den self))%Z.

Axiom equal_dyadic :
  forall (d1:d_frac) (d2:d_frac),
  (d1 = d2) <-> (((num d1) = (num d2)) /\ ((den d1) = (den d2))).

Axiom set_equal_d :
  forall (d1:d_frac) (d2:d_frac), ((num d1) = (num d2)) ->
  ((den d1) = (den d2)) -> (d1 = d2).

Axiom get_equal_d :
  forall (d1:d_frac) (d2:d_frac), (d1 = d2) ->
  ((num d1) = (num d2)) /\
  (((den d1) = (den d2)) /\ ((to_values d1) = (to_values d2))).

Parameter dyadic: Z -> Z -> d_frac.

Axiom dyadic_spec :
  forall (k:Z) (n:Z),
  ((num (dyadic k n)) = k) /\
  (((den (dyadic k n)) = n) /\ ((to_values (dyadic k n)) = (k, n))).

Axiom d_num : forall (k:Z) (n:Z), ((num (dyadic k n)) = k).

Axiom d_den : forall (k:Z) (n:Z), ((den (dyadic k n)) = n).

(* Why3 assumption *)
Definition d_inv (o:d_frac) : d_frac := dyadic (-(num o))%Z (den o).

(* Why3 assumption *)
Definition d_to_t (o:d_frac) : t :=
  infix_sldt (i_to_t (num o)) (i_to_t (power 2%Z (den o))).

Axiom d_to_t_spec : forall (o:d_frac), real_ (d_to_t o).

(* Why3 assumption *)
Definition d_cos (o:d_frac) : t :=
  cos (infix_asdt (infix_asdt (infix_pldt tone tone) pi) (d_to_t o)).

Axiom d_cos_spec : forall (o:d_frac), real_ (d_cos o).

(* Why3 assumption *)
Definition d_sin (o:d_frac) : t :=
  sin (infix_asdt (infix_asdt (infix_pldt tone tone) pi) (d_to_t o)).

Axiom d_sin_spec : forall (o:d_frac), real_ (d_sin o).

(* Why3 assumption *)
Definition d_omega (o:d_frac) : t := p_omega (den o) (num o).

Axiom d_omega_spec :
  forall (o:d_frac),
  ((d_omega o) = (p_unity (power 2%Z (den o)) (num o))) /\
  ((d_omega o) =
   (exp
    (infix_asdt (infix_asdt (infix_asdt im pi) (infix_pldt tone tone))
     (d_to_t o)))).

(* Why3 assumption *)
Definition d_omega_int (n:Z) (k:Z) : t := d_omega (dyadic k n).

Axiom d_omega_int_spec :
  forall (n:Z) (k:Z),
  ((d_omega_int n k) = (p_unity (power 2%Z n) k)) /\
  ((d_omega_int n k) =
   (exp
    (infix_asdt (infix_asdt (infix_asdt im pi) (infix_pldt tone tone))
     (d_to_t (dyadic k n))))).

Axiom d_omega_mod :
  forall (k:Z) (k':Z) (n:Z), (0%Z <= n)%Z ->
  ((int.EuclideanDivision.mod1 k (power 2%Z n)) =
   (int.EuclideanDivision.mod1 k' (power 2%Z n))) ->
  ((d_omega (dyadic k n)) = (d_omega (dyadic k' n))).

Axiom d_omega_to_exp :
  forall (o:d_frac),
  ((d_omega o) =
   (exp
    (infix_asdt (infix_asdt (infix_asdt im pi) (infix_pldt tone tone))
     (d_to_t o)))).

(* Why3 assumption *)
Definition d_mult_int (i:Z) (o:d_frac) : d_frac :=
  dyadic (i * (num o))%Z (den o).

Axiom d_mult_int_spec :
  forall (i:Z) (o:d_frac),
  ((d_to_t (d_mult_int i o)) = (infix_asdt (i_to_t i) (d_to_t o))).

Axiom mult_two_spec :
  forall (o:d_frac),
  ((d_to_t (d_mult_int 2%Z o)) =
   (infix_asdt (infix_pldt tone tone) (d_to_t o))).

Parameter d_div_power_two: d_frac -> Z -> d_frac.

Axiom d_div_power_two_def :
  forall (o:d_frac) (i:Z), (0%Z <= i)%Z ->
  ((d_div_power_two o i) = (dyadic (num o) ((den o) + i)%Z)).

Axiom d_div_power_two_spec :
  forall (o:d_frac) (i:Z), (0%Z <= i)%Z ->
  ((infix_asdt (d_to_t (d_div_power_two o i)) (i_to_t (power 2%Z i))) =
   (d_to_t o)).

(* Why3 assumption *)
Definition div_two (o:d_frac) : d_frac := dyadic (num o) ((den o) + 1%Z)%Z.

Axiom div_two_spec :
  forall (o:d_frac), ((cpower (d_omega (div_two o)) 2%Z) = (d_omega o)).

Axiom div_two_i :
  forall (k:Z) (n:Z), ((div_two (dyadic k n)) = (dyadic k (n + 1%Z)%Z)).

Axiom real_omega :
  forall (o:d_frac), ((t_real_part (d_omega o)) = (d_cos o)).

Axiom im_omega : forall (o:d_frac), ((t_im_part (d_omega o)) = (d_sin o)).

Axiom omega_decomp :
  forall (o:d_frac),
  ((d_omega o) = (infix_pldt (d_cos o) (infix_asdt im (d_sin o)))).

Axiom d_cos_eq :
  forall (d1:d_frac) (d2:d_frac), ((d_omega d1) = (d_omega d2)) ->
  ((d_cos d1) = (d_cos d2)).

Axiom d_sin_eq :
  forall (d1:d_frac) (d2:d_frac), ((d_omega d1) = (d_omega d2)) ->
  ((d_sin d1) = (d_sin d2)).

(* Why3 assumption *)
Definition phase_inv (o:d_frac) : d_frac := dyadic (-(num o))%Z (den o).

Axiom phase_inv_spec :
  forall (o:d_frac),
  ((num (phase_inv o)) = (-(num o))%Z) /\ ((den (phase_inv o)) = (den o)).

Axiom phase_inv_i :
  forall (k:Z) (n:Z), ((phase_inv (dyadic k n)) = (dyadic (-k)%Z n)).

(* Why3 assumption *)
Definition phase_inv_ (i:Z) (o:d_frac) : d_frac :=
  dyadic ((power (-1%Z)%Z (ZArith.BinInt.Z.abs i)) * (num o))%Z (den o).

Axiom phase_inv__spec :
  forall (i:Z) (o:d_frac),
  ((num (phase_inv_ i o)) =
   ((power (-1%Z)%Z (ZArith.BinInt.Z.abs i)) * (num o))%Z) /\
  ((den (phase_inv_ i o)) = (den o)).

Axiom phase_inv__i :
  forall (i:Z) (k:Z) (n:Z),
  ((phase_inv_ i (dyadic k n)) =
   (dyadic ((power (-1%Z)%Z (ZArith.BinInt.Z.abs i)) * k)%Z n)).

Axiom d_omega_inv :
  forall (o:d_frac),
  ((d_omega (phase_inv o)) =
   (d_omega (dyadic ((power 2%Z (den o)) - (num o))%Z (den o)))).

Axiom even_phase_inv :
  forall (i:Z) (o:d_frac), ((int.EuclideanDivision.mod1 i 2%Z) = 0%Z) ->
  ((phase_inv_ i o) = o).

Axiom even_phase_inv_i :
  forall (i:Z) (k:Z) (n:Z), ((int.EuclideanDivision.mod1 i 2%Z) = 0%Z) ->
  ((phase_inv_ i (dyadic k n)) = (dyadic k n)).

Axiom odd_phase_inv :
  forall (i:Z) (o:d_frac), ((int.EuclideanDivision.mod1 i 2%Z) = 1%Z) ->
  ((phase_inv_ i o) = (phase_inv o)) /\
  ((phase_inv_ i o) = (dyadic (-(num o))%Z (den o))).

Axiom odd_phase_inv_i :
  forall (i:Z) (k:Z) (n:Z), ((int.EuclideanDivision.mod1 i 2%Z) = 1%Z) ->
  ((phase_inv_ i (dyadic k n)) = (dyadic (-k)%Z n)).

(* Why3 assumption *)
Inductive quantum_circuit_pre :=
  | Phase : d_frac -> quantum_circuit_pre
  | Rx : d_frac -> quantum_circuit_pre
  | Ry : d_frac -> quantum_circuit_pre
  | Rz : d_frac -> quantum_circuit_pre
  | Cnot : quantum_circuit_pre
  | Sequence : quantum_circuit_pre -> quantum_circuit_pre ->
      quantum_circuit_pre
  | Parallel : quantum_circuit_pre -> quantum_circuit_pre ->
      quantum_circuit_pre.
Axiom quantum_circuit_pre_WhyType : WhyType quantum_circuit_pre.
Existing Instance quantum_circuit_pre_WhyType.

(* Why3 assumption *)
Fixpoint depth_pre (c:quantum_circuit_pre) {struct c}: Z :=
  match c with
  | Cnot => 2%Z
  | Sequence d _ => depth_pre d
  | Parallel d e => ((depth_pre d) + (depth_pre e))%Z
  | _ => 1%Z
  end.

Axiom depth_pre_spec :
  forall (c:quantum_circuit_pre), (1%Z <= (depth_pre c))%Z.

(* Why3 assumption *)
Fixpoint build_correct (c:quantum_circuit_pre) {struct c}: Prop :=
  match c with
  | Sequence d e =>
      ((depth_pre d) = (depth_pre e)) /\
      ((build_correct d) /\ (build_correct e))
  | Parallel d e => (build_correct d) /\ (build_correct e)
  | _ => True
  end.

Axiom quantum_circuit : Type.
Parameter quantum_circuit_WhyType : WhyType quantum_circuit.
Existing Instance quantum_circuit_WhyType.

Parameter to_pre: quantum_circuit -> quantum_circuit_pre.

Parameter depth: quantum_circuit -> Z.

Axiom quantum_circuit'invariant :
  forall (self:quantum_circuit),
  (build_correct (to_pre self)) /\ ((depth self) = (depth_pre (to_pre self))).

Axiom injective_to_pre :
  forall (c:quantum_circuit) (c':quantum_circuit), ~ (c = c') ->
  ~ ((to_pre c) = (to_pre c')).

Parameter sequence: quantum_circuit -> quantum_circuit -> quantum_circuit.

Axiom sequence_spec :
  forall (d:quantum_circuit) (e:quantum_circuit),
  ((to_pre (sequence d e)) = (Sequence (to_pre d) (to_pre e))).

Parameter parallel: quantum_circuit -> quantum_circuit -> quantum_circuit.

Axiom parallel_spec :
  forall (d:quantum_circuit) (e:quantum_circuit),
  ((to_pre (parallel d e)) = (Parallel (to_pre d) (to_pre e))).

Parameter phase: d_frac -> quantum_circuit.

Axiom phase_spec : forall (o:d_frac), ((to_pre (phase o)) = (Phase o)).

Parameter rx: d_frac -> quantum_circuit.

Axiom rx_spec : forall (o:d_frac), ((to_pre (rx o)) = (Rx o)).

Parameter ry: d_frac -> quantum_circuit.

Axiom ry_spec : forall (o:d_frac), ((to_pre (ry o)) = (Ry o)).

Parameter rz: d_frac -> quantum_circuit.

Axiom rz_spec : forall (o:d_frac), ((to_pre (rz o)) = (Rz o)).

Parameter cnot: quantum_circuit.

Axiom cnot_def : ((to_pre cnot) = Cnot).

Parameter to_qc: quantum_circuit_pre -> quantum_circuit.

Axiom to_qc_def :
  forall (c:quantum_circuit_pre), (build_correct c) ->
  match c with
  | Rx o => ((to_qc c) = (rx o))
  | Ry o => ((to_qc c) = (ry o))
  | Rz o => ((to_qc c) = (rz o))
  | Phase o => ((to_qc c) = (phase o))
  | Cnot => ((to_qc c) = cnot)
  | Sequence d e => ((to_qc c) = (sequence (to_qc d) (to_qc e)))
  | Parallel d e => ((to_qc c) = (parallel (to_qc d) (to_qc e)))
  end.

Axiom to_qc_spec :
  forall (c:quantum_circuit_pre), (build_correct c) ->
  ((to_pre (to_qc c)) = c).

Axiom to_qc_to_pre : forall (c:quantum_circuit), ((to_qc (to_pre c)) = c).

Parameter repeat: quantum_circuit -> Z -> quantum_circuit.

Axiom repeat_def :
  forall (c:quantum_circuit) (k:Z), (1%Z <= k)%Z ->
  ((k = 1%Z) -> ((repeat c k) = c)) /\
  (~ (k = 1%Z) -> ((repeat c k) = (parallel c (repeat c (k - 1%Z)%Z)))).

Axiom repeat_spec :
  forall (c:quantum_circuit) (k:Z), (1%Z <= k)%Z ->
  ((depth (repeat c k)) = ((depth c) * k)%Z).

(* Why3 assumption *)
Definition reverse_pre (c:quantum_circuit_pre) : quantum_circuit_pre :=
  match c with
  | Ry r => Ry (d_inv r)
  | Rx r => Rx (d_inv r)
  | Rz ind => Rz (d_inv ind)
  | Cnot => Cnot
  | Sequence d e => Sequence e d
  | Parallel d e => Parallel d e
  | _ => c
  end.

Axiom reverse_pre_spec :
  forall (c:quantum_circuit_pre), (build_correct c) ->
  build_correct (reverse_pre c).

(* Why3 assumption *)
Definition reverse (c:quantum_circuit) : quantum_circuit :=
  to_qc (reverse_pre (to_pre c)).

Parameter identity: Z -> quantum_circuit.

Axiom identity_def :
  forall (k:Z), (1%Z <= k)%Z ->
  ((identity k) = (repeat (phase (dyadic 0%Z 1%Z)) k)).

Axiom identity_spec :
  forall (k:Z), (1%Z <= k)%Z -> ((depth (identity k)) = k).

Parameter cont: quantum_circuit -> Z -> Z -> Z -> quantum_circuit.

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

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

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

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

Axiom matrix'invariant :
  forall {a:Type} {a_WT:WhyType a},
  forall (self:matrix a), (0%Z < (rows self))%Z /\ (0%Z < (columns self))%Z.

(* Why3 assumption *)
Definition valid_index {a:Type} {a_WT:WhyType a} (a1:matrix a) (r:Z)
    (c:Z) : Prop :=
  ((0%Z <= r)%Z /\ (r < (rows a1))%Z) /\
  ((0%Z <= c)%Z /\ (c < (columns a1))%Z).

(* Why3 assumption *)
Definition equal_size {a:Type} {a_WT:WhyType a} (a1:matrix a) (b:matrix a) :
    Prop :=
  ((rows a1) = (rows b)) /\ ((columns a1) = (columns b)).

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

Axiom get_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:matrix a) (r:Z) (c:Z), ((get a1 r c) = (((elts a1) r) c)).

Parameter make: forall {a:Type} {a_WT:WhyType a}, Z -> Z -> a -> matrix a.

Axiom make_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (r:Z) (c:Z) (v:a), ((0%Z < r)%Z /\ (0%Z < c)%Z) ->
  ((rows (make r c v)) = r) /\
  (((columns (make r c v)) = c) /\
   forall (i:Z) (j:Z),
   (((0%Z <= i)%Z /\ (i < r)%Z) /\ ((0%Z <= j)%Z /\ (j < c)%Z)) ->
   ((get (make r c v) i j) = v)).

Axiom make_value :
  forall {a:Type} {a_WT:WhyType a},
  forall (r:Z) (c:Z) (i:Z) (j:Z) (v:a), ((0%Z < r)%Z /\ (0%Z < c)%Z) ->
  ((0%Z <= i)%Z /\ (i < r)%Z) -> ((0%Z <= j)%Z /\ (j < c)%Z) ->
  ((get (make r c v) i j) = v).

(* Why3 assumption *)
Definition mat_indices {a:Type} {a_WT:WhyType a} (m:matrix a) :
    set (Z* Z)%type :=
  cartesian_product (to_fset 0%Z (rows m)) (to_fset 0%Z (columns m)).

Axiom mat_indices_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:matrix a), forall (i:Z) (j:Z),
  (valid_index m i j) <-> (mem (i, j) (mat_indices m)).

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

Axiom set_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:matrix a) (r:Z) (c:Z) (v:a), (valid_index a1 r c) ->
  ((rows (set1 a1 r c v)) = (rows a1)) /\
  (((columns (set1 a1 r c v)) = (columns a1)) /\
   ((forall (i:Z) (j:Z), (valid_index a1 i j) ->
     (((i = r) /\ (j = c)) -> ((get (set1 a1 r c v) i j) = v)) /\
     (~ ((i = r) /\ (j = c)) -> ((get (set1 a1 r c v) i j) = (get a1 i j)))) /\
    (((get (set1 a1 r c v) r c) = v) /\
     ((forall (i:Z) (j:Z), (valid_index (set1 a1 r c v) i j) -> ~ (i = r) ->
       ((get (set1 a1 r c v) i j) = (get a1 i j))) /\
      forall (i:Z) (j:Z), (valid_index (set1 a1 r c v) i j) -> ~ (j = c) ->
      ((get (set1 a1 r c v) i j) = (get a1 i j)))))).

Axiom set_valid_index :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:matrix a) (i:Z) (j:Z), ((0%Z <= i)%Z /\ (i < (rows a1))%Z) ->
  ((0%Z <= j)%Z /\ (j < (columns a1))%Z) -> valid_index a1 i j.

Axiom get_valid_index :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:matrix a) (r:Z) (c:Z), ((rows a1) = r) -> ((columns a1) = c) ->
  (forall (i:Z) (j:Z), (valid_index a1 i j) -> (0%Z <= i)%Z /\ (i < r)%Z) /\
  forall (i:Z) (j:Z), (valid_index a1 i j) -> (0%Z <= j)%Z /\ (j < c)%Z.

Axiom set_values :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:matrix a) (r:Z) (c:Z) (v:a), (valid_index a1 r c) ->
  forall (i:Z) (j:Z), (valid_index a1 i j) ->
  (((i = r) /\ (j = c)) -> ((get (set1 a1 r c v) i j) = v)) /\
  (~ ((i = r) /\ (j = c)) -> ((get (set1 a1 r c v) i j) = (get a1 i j))).

Axiom set_rows :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:matrix a) (r:Z) (c:Z) (v:a), (valid_index a1 r c) ->
  ((rows (set1 a1 r c v)) = (rows a1)).

Axiom set_columns :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:matrix a) (r:Z) (c:Z) (v:a), (valid_index a1 r c) ->
  ((columns (set1 a1 r c v)) = (columns a1)).

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

Axiom make_f_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (r:Z) (c:Z) (f:Z -> Z -> a), (0%Z < r)%Z -> (0%Z < c)%Z ->
  ((rows (make_f r c f)) = r) /\
  (((columns (make_f r c f)) = c) /\
   forall (i:Z) (j:Z), ((get (make_f r c f) i j) = ((f i) j))).

Axiom assert_make :
  forall {a:Type} {a_WT:WhyType a},
  forall (r:Z) (c:Z) (f:Z -> Z -> a) (i:Z) (j:Z),
  ((0%Z <= i)%Z /\ (i < r)%Z) -> ((0%Z <= j)%Z /\ (j < c)%Z) ->
  ((get (make_f r c f) i j) = ((f i) j)).

Axiom assert_make_r :
  forall {a:Type} {a_WT:WhyType a},
  forall (r:Z) (c:Z) (f:Z -> Z -> a), (0%Z < r)%Z -> (0%Z < c)%Z ->
  ((rows (make_f r c f)) = r).

Axiom assert_make_c :
  forall {a:Type} {a_WT:WhyType a},
  forall (r:Z) (c:Z) (f:Z -> Z -> a), (0%Z < r)%Z -> (0%Z < c)%Z ->
  ((columns (make_f r c f)) = c).

(* Why3 assumption *)
Definition to_indexes {a:Type} {a_WT:WhyType a} (m:matrix a) :
    set (Z* Z)%type :=
  cartesian_product (to_fset 0%Z (rows m)) (to_fset 0%Z (columns m)).

Axiom to_indexes_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:matrix a),
  ((cardinal (to_indexes m)) = ((rows m) * (columns m))%Z).

Axiom set_to_indexes_mem :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:matrix a) (i:Z) (j:Z), ((0%Z <= i)%Z /\ (i < (rows m))%Z) ->
  ((0%Z <= j)%Z /\ (j < (columns m))%Z) -> mem (i, j) (to_indexes m).

Axiom get_to_indexes_mem :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:matrix a) (o:(Z* Z)%type), (mem o (to_indexes m)) ->
  ((0%Z <= (fir o))%Z /\ ((fir o) < (rows m))%Z) /\
  ((0%Z <= (sec o))%Z /\ ((sec o) < (columns m))%Z).

Parameter kth_nit_r: Z -> Z -> Z -> Z.

Axiom kth_nit_r_def :
  forall (i:Z) (k:Z) (n:Z), (0%Z <= i)%Z -> (1%Z <= k)%Z -> (0%Z < n)%Z ->
  ((kth_nit_r i k n) =
   (kth_right i k (k - 1%Z)%Z ((fun (y0:Z) (y1:Z) => y0) n))).

Axiom kth_nit_r_spec :
  forall (i:Z) (k:Z) (n:Z), (0%Z <= i)%Z -> (1%Z <= k)%Z -> (0%Z < n)%Z ->
  ((kth_nit_r i k n) =
   (int.EuclideanDivision.mod1
    (int.EuclideanDivision.div i (power n (k - 1%Z)%Z)) n)) /\
  forall (h:Z), (k < h)%Z ->
  ((kth_nit_r i k n) = (kth_right i k h ((fun (y0:Z) (y1:Z) => y0) n))).

Parameter kth_nit_l: Z -> Z -> Z -> Z -> Z.

Axiom kth_nit_l_def :
  forall (i:Z) (k:Z) (n:Z) (h:Z), (0%Z <= i)%Z -> (0%Z < n)%Z ->
  ((1%Z <= k)%Z /\ (k <= h)%Z) ->
  ((kth_nit_l i k n h) =
   (int.EuclideanDivision.mod1
    (int.EuclideanDivision.div i (power n (h - k)%Z)) n)).

Axiom kth_nit_l_spec :
  forall (i:Z) (k:Z) (n:Z) (h:Z), (0%Z <= i)%Z -> (0%Z < n)%Z ->
  ((1%Z <= k)%Z /\ (k <= h)%Z) ->
  ((kth_nit_l i k n h) = (kth_nit_r i ((h - k)%Z + 1%Z)%Z n)) /\
  ((kth_nit_l i k n h) =
   (kth_right i ((h - k)%Z + 1%Z)%Z (h - k)%Z ((fun (y0:Z) (y1:Z) => y0) n))).

Axiom kth_nit_l_val :
  forall (i:Z) (k:Z) (n:Z) (h:Z) (l:Z), (0%Z <= i)%Z -> (0%Z < n)%Z ->
  (0%Z <= l)%Z -> ((1%Z <= k)%Z /\ (k <= h)%Z) ->
  ((kth_nit_l i k n h) =
   (kth_left i k l (h + l)%Z ((fun (y0:Z) (y1:Z) => y0) n))).

Axiom kth_nit_div_mod :
  forall (i:Z) (k:Z) (n:Z), (0%Z <= i)%Z -> (1%Z <= k)%Z -> (0%Z < n)%Z ->
  ((kth_nit_r i k n) =
   (int.EuclideanDivision.div (int.EuclideanDivision.mod1 i (power n k))
    (power n (k - 1%Z)%Z))).

Parameter weighted_kth_nit_r: Z -> Z -> Z -> Z.

Axiom weighted_kth_nit_r_def :
  forall (i:Z) (k:Z) (n:Z), (0%Z <= i)%Z -> (0%Z < n)%Z -> (0%Z < k)%Z ->
  ((weighted_kth_nit_r i k n) =
   ((kth_nit_r i k n) * (power n (k - 1%Z)%Z))%Z).

Axiom weighted_kth_nit_r_spec :
  forall (i:Z) (k:Z) (n:Z), (0%Z <= i)%Z -> (0%Z < n)%Z -> (0%Z < k)%Z ->
  (((power n (k - 1%Z)%Z) < i)%Z ->
   (0%Z <= (weighted_kth_nit_r i k n))%Z /\
   ((weighted_kth_nit_r i k n) <= i)%Z) /\
  forall (h:Z), (k < h)%Z ->
  ((weighted_kth_nit_r i k n) =
   (weighted_kth_right i k h ((fun (y0:Z) (y1:Z) => y0) n))).

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

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

Axiom decreasing_div_n :
  forall (i:Z) (k:Z) (n:Z), (0%Z <= i)%Z -> (0%Z < k)%Z -> (1%Z < n)%Z ->
  ((power n k) < i)%Z -> ((int.EuclideanDivision.div i (power n k)) <= i)%Z.

Parameter nary_length: Z -> Z -> Z.

Axiom nary_length_spec :
  forall (i:Z) (n:Z), (1%Z < n)%Z -> (0%Z <= i)%Z ->
  ((0%Z < i)%Z ->
   ((power n ((nary_length i n) - 1%Z)%Z) <= i)%Z /\
   (i < (power n (nary_length i n)))%Z) /\
  (((i < n)%Z -> ((nary_length i n) = 1%Z)) /\
   ((1%Z <= (nary_length i n))%Z /\
    (i = (int.EuclideanDivision.mod1 i (power n (nary_length i n)))))).

Parameter weighted_kth_nit_l: Z -> Z -> Z -> Z -> Z.

Axiom weighted_kth_nit_l_def :
  forall (i:Z) (k:Z) (n:Z) (h:Z), (0%Z <= i)%Z ->
  ((0%Z < k)%Z /\ (k <= h)%Z) -> (0%Z < n)%Z -> ((nary_length i n) <= h)%Z ->
  ((weighted_kth_nit_l i k n h) =
   ((kth_nit_l i k n h) * (power n (h - k)%Z))%Z).

Axiom weighted_kth_nit_l_spec :
  forall (i:Z) (k:Z) (n:Z) (h:Z), (0%Z <= i)%Z ->
  ((0%Z < k)%Z /\ (k <= h)%Z) -> (0%Z < n)%Z -> ((nary_length i n) <= h)%Z ->
  ((weighted_kth_nit_l i k n h) =
   (weighted_kth_nit_r i ((h - k)%Z + 1%Z)%Z n)) /\
  (((1%Z < k)%Z ->
    ((weighted_kth_nit_l i k n h) =
     (weighted_kth_right i ((h - k)%Z + 1%Z)%Z h
      ((fun (y0:Z) (y1:Z) => y0) n)))) /\
   (((power n (n - k)%Z) < i)%Z ->
    (0%Z <= (weighted_kth_nit_l i k n h))%Z /\
    ((weighted_kth_nit_l i k n h) <= i)%Z)).

Parameter weighted_kth_left1: Z -> Z -> Z -> Z -> (Z -> Z) -> Z.

Axiom weighted_kth_left_def1 :
  forall (i:Z) (k:Z) (l:Z) (h:Z) (f:Z -> Z), (0%Z <= i)%Z -> (l <= h)%Z ->
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  (forall (k1:Z), (0%Z < (f k1))%Z) ->
  ((weighted_kth_left1 i k l h f) =
   (weighted_kth_right i (((h - l)%Z - k)%Z + 1%Z)%Z h f)).

Axiom no_rest_length :
  forall (i:Z) (l:Z) (n:Z), (0%Z < i)%Z -> (1%Z < n)%Z -> (0%Z <= l)%Z ->
  (i = (power n l)) -> ((nary_length i n) = (l + 1%Z)%Z).

Axiom mod_nary :
  forall (i:Z) (l:Z) (k:Z) (n:Z), (0%Z <= i)%Z -> (1%Z < n)%Z ->
  ((1%Z <= k)%Z /\ (k <= l)%Z) ->
  ((kth_nit_r (int.EuclideanDivision.mod1 i (power n l)) k n) =
   (kth_nit_r i k n)).

Axiom mod_nary_comm :
  forall (i:Z) (l:Z) (k:Z) (n:Z), (0%Z <= i)%Z -> (0%Z <= l)%Z ->
  (1%Z < n)%Z -> ((1%Z <= k)%Z /\ (k <= l)%Z) ->
  ((kth_nit_r i k n) =
   (kth_nit_r (int.EuclideanDivision.mod1 i (power n l)) k n)).

Parameter fc6: Z -> Z -> Z -> Z.

Axiom fc_def6 :
  forall (i:Z) (n:Z) (l:Z),
  ((1%Z <= l)%Z ->
   (((fc6 i n) l) = ((kth_nit_r i l n) * (power n (l - 1%Z)%Z))%Z)) /\
  (~ (1%Z <= l)%Z -> (((fc6 i n) l) = 0%Z)).

Axiom nary_decomposition_pre :
  forall (i:Z) (k:Z) (n:Z), (0%Z <= i)%Z -> (0%Z < n)%Z -> (1%Z <= k)%Z ->
  ((int.EuclideanDivision.mod1 i (power n k)) =
   (ind_isum (fc6 i n) 1%Z (k + 1%Z)%Z)) /\
  ((int.EuclideanDivision.mod1 i (power n k)) =
   (ind_isum (fun (l:Z) => ((kth_nit_r i l n) * (power n (l - 1%Z)%Z))%Z) 1%Z
    (k + 1%Z)%Z)).

Axiom nary_decomposition :
  forall (i:Z) (n:Z) (h:Z), (0%Z <= i)%Z -> (1%Z < n)%Z ->
  ((nary_length i n) <= h)%Z ->
  (i =
   (ind_isum (fun (l:Z) => ((kth_nit_r i l n) * (power n (l - 1%Z)%Z))%Z) 1%Z
    (h + 1%Z)%Z)) /\
  (i = (ind_isum (fun (l:Z) => (weighted_kth_nit_r i l n)) 1%Z (h + 1%Z)%Z)).

Axiom nary_decomposition_l :
  forall (i:Z) (n:Z) (h:Z), (0%Z <= i)%Z -> (1%Z < n)%Z ->
  ((nary_length i n) <= h)%Z ->
  (i =
   (ind_isum (fun (l:Z) => (weighted_kth_nit_l i l n h)) 1%Z (h + 1%Z)%Z)) /\
  (i =
   (ind_isum (fun (l:Z) => ((kth_nit_l i l n h) * (power n (h - l)%Z))%Z) 1%Z
    (h + 1%Z)%Z)).

(* Why3 assumption *)
Definition is_nary (t1:Z -> Z) (i:Z) (j:Z) (n:Z) : Prop :=
  forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) ->
  (0%Z <= (t1 k))%Z /\ ((t1 k) < n)%Z.

Axiom is_nary_kth_nit_r :
  forall (i:Z) (k:Z) (n:Z), (0%Z <= i)%Z -> (0%Z < n)%Z ->
  is_nary (fun (j:Z) => (kth_nit_r i j n)) 1%Z (k + 1%Z)%Z n.

Axiom subset_closure_naries :
  forall (i:Z) (j:Z) (k:Z) (m:Z) (n:Z) (t1:Z -> Z),
  ((i <= k)%Z /\ ((k < m)%Z /\ (m < j)%Z)) -> (0%Z < n)%Z ->
  (is_nary t1 i j n) -> is_nary t1 k m n.

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

Axiom equal_mat :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:matrix a) (n:matrix a),
  (equal m n) <->
  ((((rows m) = (rows n)) /\ ((columns m) = (columns n))) /\
   forall (i:Z) (j:Z), (valid_index m i j) -> ((get m i j) = (get n i j))).

Axiom equality :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:matrix a) (n:matrix a), (equal m n) <-> (m = n).

Axiom mat_equality :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:matrix a) (n:matrix a), ((rows m) = (rows n)) ->
  ((columns m) = (columns n)) ->
  (forall (i:Z) (j:Z), (valid_index m i j) -> ((get m i j) = (get n i j))) ->
  equal m n.

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

Axiom square_mat :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:matrix a), (square m) <-> ((rows m) = (columns m)).

Axiom equal_sym :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:matrix a) (n:matrix a), (equal m n) <-> (equal n m).

Axiom equal_rex :
  forall {a:Type} {a_WT:WhyType a}, forall (m:matrix a), equal m m.

Axiom equal_trans :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:matrix a) (n:matrix a) (o:matrix a), (equal m n) ->
  (equal n o) -> equal m o.

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

Axiom equal_mat_funct :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> matrix a) (g:Z -> matrix a), forall (i:Z) (j:Z),
  ((0%Z <= i)%Z /\ (i < j)%Z) ->
  (equal_funct f g) <->
  forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> equal (f k) (g k).

Axiom set_equal_mat :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:matrix a) (n:matrix a), ((rows m) = (rows n)) ->
  ((columns m) = (columns n)) ->
  (forall (i:Z) (j:Z), (valid_index m i j) -> ((get m i j) = (get n i j))) ->
  (m = n).

Axiom set_equal_mat_make :
  forall {a:Type} {a_WT:WhyType a},
  forall (r:Z) (c:Z) (f:Z -> Z -> a) (g:Z -> Z -> a), (0%Z < r)%Z ->
  (0%Z < c)%Z ->
  (forall (i:Z) (j:Z), ((0%Z <= i)%Z /\ (i < r)%Z) ->
   ((0%Z <= j)%Z /\ (j < c)%Z) -> (((f i) j) = ((g i) j))) ->
  ((make_f r c f) = (make_f r c g)).

Axiom set_equal_mat_make_t :
  forall {a:Type} {a_WT:WhyType a},
  forall (r:Z) (r':Z) (c:Z) (c':Z) (f:Z -> Z -> a) (g:Z -> Z -> a),
  (0%Z < r)%Z -> (0%Z < c)%Z -> (r = r') -> (c = c') ->
  (forall (i:Z) (j:Z), ((0%Z <= i)%Z /\ (i < r)%Z) ->
   ((0%Z <= j)%Z /\ (j < c)%Z) -> (((f i) j) = ((g i) j))) ->
  ((make_f r c f) = (make_f r' c' g)).

Axiom get_equal_mat :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:matrix a) (n:matrix a), (equal m n) ->
  ((rows m) = (rows n)) /\
  (((columns m) = (columns n)) /\
   forall (i:Z) (j:Z), (valid_index m i j) -> ((get m i j) = (get n i j))).

Axiom equal_functions :
  forall {a:Type} {a_WT:WhyType a},
  forall (r:Z) (c:Z) (f:Z -> Z -> a) (g:Z -> Z -> a), (0%Z < r)%Z ->
  (0%Z < c)%Z ->
  (forall (i:Z) (j:Z),
   (((0%Z <= i)%Z /\ (i < r)%Z) /\ ((0%Z <= j)%Z /\ (j < c)%Z)) ->
   (((f i) j) = ((g i) j))) ->
  ((make_f r c f) = (make_f r c g)).

Axiom equal_functions_mat :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> Z -> a) (m:matrix a),
  (forall (i:Z) (j:Z),
   (((0%Z <= i)%Z /\ (i < (rows m))%Z) /\
    ((0%Z <= j)%Z /\ (j < (columns m))%Z)) ->
   (((f i) j) = (get m i j))) ->
  (m = (make_f (rows m) (columns m) f)).

(* Why3 assumption *)
Definition null_mat (a:matrix t) : Prop :=
  forall (i:Z) (j:Z), (valid_index a i j) -> ((get a i j) = tzero).

Axiom set_null_mat :
  forall (a:matrix t),
  (forall (i:Z) (j:Z), (valid_index a i j) -> ((get a i j) = tzero)) ->
  null_mat a.

Axiom get_null_mat :
  forall (a:matrix t), (null_mat a) -> forall (i:Z) (j:Z),
  (valid_index a i j) -> ((get a i j) = tzero).

Parameter kronecker_neutral: matrix t.

Axiom kronecker_neutral1 : (kronecker_neutral = (make 1%Z 1%Z tone)).

(* Why3 assumption *)
Definition kronecker (m:matrix t) (n:matrix t) : matrix t :=
  make_f ((rows m) * (rows n))%Z ((columns m) * (columns n))%Z
  (fun (i:Z) (j:Z) =>
   (infix_asdt
    (get m (int.EuclideanDivision.div i (rows n))
     (int.EuclideanDivision.div j (columns n)))
    (get n (int.EuclideanDivision.mod1 i (rows n))
     (int.EuclideanDivision.mod1 j (columns n))))).

Axiom kronecker_spec :
  forall (m:matrix t) (n:matrix t),
  ((rows (kronecker m n)) = ((rows m) * (rows n))%Z) /\
  (((columns (kronecker m n)) = ((columns m) * (columns n))%Z) /\
   forall (i:Z) (j:Z), (valid_index (kronecker m n) i j) ->
   ((get (kronecker m n) i j) =
    (infix_asdt
     (get m (int.EuclideanDivision.div i (rows n))
      (int.EuclideanDivision.div j (columns n)))
     (get n (int.EuclideanDivision.mod1 i (rows n))
      (int.EuclideanDivision.mod1 j (columns n)))))).

Axiom kronecker_eq :
  forall (m1:matrix t) (n1:matrix t) (m2:matrix t) (n2:matrix t),
  (m1 = m2) -> (n1 = n2) -> ((kronecker m1 n1) = (kronecker m2 n2)).

Axiom get_kronecker :
  forall (m:matrix t) (n:matrix t),
  ((kronecker m n) =
   (make_f ((rows m) * (rows n))%Z ((columns m) * (columns n))%Z
    (fun (i:Z) (j:Z) =>
     (infix_asdt
      (get m (int.EuclideanDivision.div i (rows n))
       (int.EuclideanDivision.div j (columns n)))
      (get n (int.EuclideanDivision.mod1 i (rows n))
       (int.EuclideanDivision.mod1 j (columns n))))))).

Axiom kronecker_values :
  forall (m:matrix t) (n:matrix t) (i:Z) (j:Z),
  (valid_index (kronecker m n) i j) ->
  ((get (kronecker m n) i j) =
   (infix_asdt
    (get m (int.EuclideanDivision.div i (rows n))
     (int.EuclideanDivision.div j (columns n)))
    (get n (int.EuclideanDivision.mod1 i (rows n))
     (int.EuclideanDivision.mod1 j (columns n))))).

Axiom kronecker_values_gen :
  forall (m:matrix t) (n:matrix t), forall (i:Z) (j:Z),
  (valid_index (kronecker m n) i j) ->
  ((get (kronecker m n) i j) =
   (infix_asdt
    (get m (int.EuclideanDivision.div i (rows n))
     (int.EuclideanDivision.div j (columns n)))
    (get n (int.EuclideanDivision.mod1 i (rows n))
     (int.EuclideanDivision.mod1 j (columns n))))).

Axiom kronecker_mod_values :
  forall (m:matrix t) (n:matrix t) (i:Z) (j:Z),
  (valid_index (kronecker m n) i j) ->
  ((get (kronecker m n) i j) =
   (infix_asdt
    (get m
     (int.EuclideanDivision.div
      (int.EuclideanDivision.mod1 i (rows (kronecker m n))) (rows n))
     (int.EuclideanDivision.div
      (int.EuclideanDivision.mod1 j (columns (kronecker m n))) (columns n)))
    (get n
     (int.EuclideanDivision.mod1
      (int.EuclideanDivision.mod1 i (rows (kronecker m n))) (rows n))
     (int.EuclideanDivision.mod1
      (int.EuclideanDivision.mod1 j (columns (kronecker m n))) (columns n))))).

Axiom kronecker_indexes :
  forall (m:matrix t) (n:matrix t) (i:Z) (j:Z) (k:Z) (l:Z),
  (valid_index m i j) -> (valid_index n k l) ->
  valid_index (kronecker m n) ((i * (rows n))%Z + k)%Z
  ((j * (columns n))%Z + l)%Z.

Axiom kronecker_indexes_com :
  forall (m:matrix t) (n:matrix t) (i:Z) (j:Z),
  (valid_index (kronecker m n) i j) ->
  (valid_index m (int.EuclideanDivision.div i (rows n))
   (int.EuclideanDivision.div j (columns n))) /\
  (valid_index n (int.EuclideanDivision.mod1 i (rows n))
   (int.EuclideanDivision.mod1 j (columns n))).

Axiom kronecker_assoc_pre :
  forall (m:matrix t) (n:matrix t) (o:matrix t) (i:Z) (j:Z),
  ((0%Z <= i)%Z /\ (i < (((rows m) * (rows n))%Z * (rows o))%Z)%Z) ->
  ((0%Z <= j)%Z /\ (j < (((columns m) * (columns n))%Z * (columns o))%Z)%Z) ->
  ((get (kronecker (kronecker m n) o) i j) =
   (get (kronecker m (kronecker n o)) i j)).

Axiom kronecker_assoc :
  op_assoc (fun (y0:matrix t) (y1:matrix t) => (kronecker y0 y1)).

Axiom neutral_ :
  forall (m:matrix t),
  ((kronecker m kronecker_neutral) = m) /\
  ((kronecker kronecker_neutral m) = m).

Axiom neutral1 :
  (kronecker_neutral =
   (neutral_elt (fun (y0:matrix t) (y1:matrix t) => (kronecker y0 y1)))) /\
  ((has_neutral (fun (y0:matrix t) (y1:matrix t) => (kronecker y0 y1))) /\
   (iterable (fun (y0:matrix t) (y1:matrix t) => (kronecker y0 y1)))).

Axiom kronecker_equal :
  forall (m:matrix t) (ml:matrix t) (n:matrix t) (nl:matrix t),
  (equal m ml) -> (equal n nl) -> equal (kronecker m n) (kronecker ml nl).

(* Why3 assumption *)
Definition frows (f:Z -> matrix t) (k:Z) : Z := rows (f k).

Axiom frows_spec : forall (f:Z -> matrix t) (k:Z), (0%Z < (frows f k))%Z.

(* Why3 assumption *)
Definition fcolumns (f:Z -> matrix t) (k:Z) : Z := columns (f k).

Axiom fcolumns_spec :
  forall (f:Z -> matrix t) (k:Z), (0%Z < (fcolumns f k))%Z.

Axiom const_fcol :
  forall (m:matrix t) (k:Z),
  ((fcolumns ((fun (y0:matrix t) (y1:Z) => y0) m) k) = (columns m)).

Axiom const_frows :
  forall (m:matrix t) (k:Z),
  ((frows ((fun (y0:matrix t) (y1:Z) => y0) m) k) = (rows m)).

(* Why3 assumption *)
Definition k_iter (f:Z -> matrix t) (i:Z) (j:Z) : matrix t :=
  int_iterate (fun (y0:matrix t) (y1:matrix t) => (kronecker y0 y1)) f i j.

Axiom k_iter_spec :
  forall (f:Z -> matrix t) (i:Z) (j:Z),
  ((rows (k_iter f i j)) =
   (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (frows y0 y1)) f) i j)) /\
  ((columns (k_iter f i j)) =
   (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (fcolumns y0 y1)) f) i j)).

Axiom iterable_kronecker :
  iterable (fun (y0:matrix t) (y1:matrix t) => (kronecker y0 y1)).

Axiom k_iter_cardone :
  forall (f:Z -> matrix t) (i:Z) (j:Z), (j = (i + 1%Z)%Z) ->
  ((k_iter f i j) = (f i)).

Axiom k_iter_cardzero :
  forall (f:Z -> matrix t) (i:Z) (j:Z), (j <= i)%Z ->
  ((k_iter f i j) = kronecker_neutral).

Axiom k_iter_right_extension :
  forall (f:Z -> matrix t) (i:Z) (j:Z), (i < j)%Z ->
  ((k_iter f i j) = (kronecker (k_iter f i (j - 1%Z)%Z) (f (j - 1%Z)%Z))).

Axiom k_iter_left_extension :
  forall (f:Z -> matrix t) (i:Z) (j:Z), (i < j)%Z ->
  ((k_iter f i j) = (kronecker (f i) (k_iter f (i + 1%Z)%Z j))).

Parameter kproj: (Z -> matrix t) -> Z -> Z -> Z -> Z -> Z -> t.

Axiom kproj_def :
  forall (f:Z -> matrix t) (i:Z) (j:Z) (k:Z) (l:Z) (h:Z), (0%Z <= l)%Z ->
  (0%Z <= i)%Z -> (0%Z <= j)%Z -> (l < h)%Z ->
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  ((kproj f i j k l h) =
   (get (f ((l + k)%Z - 1%Z)%Z)
    (kth_left i k l h ((fun (y0:Z -> matrix t) (y1:Z) => (frows y0 y1)) f))
    (kth_left j k l h
     ((fun (y0:Z -> matrix t) (y1:Z) => (fcolumns y0 y1)) f)))).

Axiom kproj_const :
  forall (c:matrix t) (i:Z) (j:Z) (k:Z) (l:Z) (h:Z), (0%Z <= i)%Z ->
  (0%Z <= j)%Z -> (0%Z <= l)%Z -> ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  ((kproj ((fun (y0:matrix t) (y1:Z) => y0) c) i j k l h) =
   (get c (kth_nit_l i k (rows c) (h - l)%Z)
    (kth_nit_l j k (columns c) (h - l)%Z))).

Axiom kproj_const_prod :
  forall (c:matrix t) (i:Z) (j:Z) (l:Z) (h:Z), (1%Z <= l)%Z ->
  (0%Z <= i)%Z -> (0%Z <= j)%Z -> (1%Z <= (h - l)%Z)%Z ->
  ((ind_product
    (fun (k:Z) => (kproj ((fun (y0:matrix t) (y1:Z) => y0) c) i j k l h)) 1%Z
    ((h - l)%Z + 1%Z)%Z)
   =
   (ind_product
    (fun (k:Z) =>
     (get c (kth_nit_l i k (rows c) (h - l)%Z)
      (kth_nit_l j k (columns c) (h - l)%Z)))
    1%Z ((h - l)%Z + 1%Z)%Z)).

Parameter kproj_kth_right: (Z -> matrix t) -> Z -> Z -> Z -> Z -> Z -> unit.

Axiom kproj_kth_right_def :
  forall (f:Z -> matrix t) (i:Z) (j:Z) (k:Z) (l:Z) (h:Z), (0%Z <= i)%Z ->
  ((0%Z <= l)%Z /\ (l < h)%Z) -> (0%Z <= j)%Z ->
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  ((kproj_kth_right f i j k l h) = tt).

Axiom kproj_kth_right_spec :
  forall (f:Z -> matrix t) (i:Z) (j:Z) (k:Z) (l:Z) (h:Z), (0%Z <= i)%Z ->
  ((0%Z <= l)%Z /\ (l < h)%Z) -> (0%Z <= j)%Z ->
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  ((kproj f i j k l h) =
   (get (f ((l + k)%Z - 1%Z)%Z)
    (kth_right i (((h - l)%Z - k)%Z + 1%Z)%Z h
     ((fun (y0:Z -> matrix t) (y1:Z) => (frows y0 y1)) f))
    (kth_right j (((h - l)%Z - k)%Z + 1%Z)%Z h
     ((fun (y0:Z -> matrix t) (y1:Z) => (fcolumns y0 y1)) f)))).

Axiom kproj_div_mod :
  forall (f:Z -> matrix t) (i:Z) (j:Z) (k:Z) (l:Z) (h:Z), (0%Z <= i)%Z ->
  ((0%Z <= l)%Z /\ (l < h)%Z) -> (0%Z <= j)%Z ->
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  ((kproj f i j k l h) =
   (get (f ((l + k)%Z - 1%Z)%Z)
    (int.EuclideanDivision.div
     (int.EuclideanDivision.mod1 i
      (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (frows y0 y1)) f)
       ((l + k)%Z - 1%Z)%Z h))
     (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (frows y0 y1)) f)
      (l + k)%Z h))
    (int.EuclideanDivision.div
     (int.EuclideanDivision.mod1 j
      (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (fcolumns y0 y1)) f)
       ((l + k)%Z - 1%Z)%Z h))
     (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (fcolumns y0 y1)) f)
      (l + k)%Z h)))).

Axiom kproj_const_div_mod :
  forall (c:matrix t) (i:Z) (j:Z) (k:Z) (l:Z) (h:Z), (0%Z <= i)%Z ->
  ((0%Z <= l)%Z /\ (l < h)%Z) -> (0%Z <= j)%Z ->
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  ((kproj ((fun (y0:matrix t) (y1:Z) => y0) c) i j k l h) =
   (get c
    (int.EuclideanDivision.div
     (int.EuclideanDivision.mod1 i
      (power (rows c) (((h - l)%Z - k)%Z + 1%Z)%Z))
     (power (rows c) ((h - l)%Z - k)%Z))
    (int.EuclideanDivision.div
     (int.EuclideanDivision.mod1 j
      (power (columns c) (((h - l)%Z - k)%Z + 1%Z)%Z))
     (power (columns c) ((h - l)%Z - k)%Z)))).

Axiom kproj_const_transl :
  forall (c:matrix t) (i:Z) (j:Z) (k:Z) (t1:Z) (l:Z) (h:Z), (1%Z <= l)%Z ->
  (0%Z <= i)%Z -> (0%Z <= j)%Z -> (0%Z <= t1)%Z ->
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  ((kproj ((fun (y0:matrix t) (y1:Z) => y0) c) i j k l h) =
   (kproj ((fun (y0:matrix t) (y1:Z) => y0) c) i j k (l + t1)%Z (h + t1)%Z)).

Axiom kproj_const_transl_gen :
  forall (c:matrix t) (i:Z) (j:Z) (t1:Z) (l:Z) (h:Z), (1%Z <= l)%Z ->
  (0%Z <= i)%Z -> (0%Z <= j)%Z -> (0%Z <= t1)%Z -> forall (k:Z),
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  ((kproj ((fun (y0:matrix t) (y1:Z) => y0) c) i j k l h) =
   (kproj ((fun (y0:matrix t) (y1:Z) => y0) c) i j k (l + t1)%Z (h + t1)%Z)).

Axiom kproj_div_mod_genk :
  forall (f:Z -> matrix t) (i:Z) (j:Z) (l:Z) (h:Z), (0%Z <= i)%Z ->
  ((0%Z <= l)%Z /\ (l < h)%Z) -> (0%Z <= j)%Z -> forall (k:Z),
  ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  ((kproj f i j k l h) =
   (get (f ((l + k)%Z - 1%Z)%Z)
    (int.EuclideanDivision.div
     (int.EuclideanDivision.mod1 i
      (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (frows y0 y1)) f)
       ((l + k)%Z - 1%Z)%Z h))
     (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (frows y0 y1)) f)
      (l + k)%Z h))
    (int.EuclideanDivision.div
     (int.EuclideanDivision.mod1 j
      (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (fcolumns y0 y1)) f)
       ((l + k)%Z - 1%Z)%Z h))
     (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (fcolumns y0 y1)) f)
      (l + k)%Z h)))).

Axiom kproj_trans :
  forall (f:Z -> matrix t) (i:Z) (j:Z) (k:Z) (l:Z) (h:Z) (t1:Z),
  (0%Z <= i)%Z -> ((0%Z <= l)%Z /\ (l < h)%Z) -> (0%Z <= j)%Z ->
  ((0%Z <= t1)%Z /\ (t1 < k)%Z) -> ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  ((kproj f
    (int.EuclideanDivision.div i
     (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (frows y0 y1)) f) h
      (h + t1)%Z))
    (int.EuclideanDivision.div j
     (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (fcolumns y0 y1)) f) h
      (h + t1)%Z))
    k l h)
   = (kproj f i j (k - t1)%Z (l + t1)%Z (h + t1)%Z)).

Axiom kproj_transl_minus_one :
  forall (f:Z -> matrix t) (i:Z) (j:Z) (k:Z) (l:Z) (h:Z), (0%Z <= i)%Z ->
  ((1%Z <= l)%Z /\ (l < h)%Z) -> (0%Z <= j)%Z ->
  ((1%Z <= k)%Z /\ (k < (h - l)%Z)%Z) ->
  ((kproj f (int.EuclideanDivision.div i (frows f (h - 1%Z)%Z))
    (int.EuclideanDivision.div j (fcolumns f (h - 1%Z)%Z)) (k + 1%Z)%Z
    (l - 1%Z)%Z (h - 1%Z)%Z)
   = (kproj f i j k l h)) /\
  ((kproj f (int.EuclideanDivision.div i (frows f (h - 1%Z)%Z))
    (int.EuclideanDivision.div j (fcolumns f (h - 1%Z)%Z)) k l (h - 1%Z)%Z)
   = (kproj f i j k l h)).

Axiom k_iter_values_pre :
  forall (f:Z -> matrix t) (i:Z) (j:Z) (l:Z) (h:Z),
  ((0%Z <= i)%Z /\
   (i <
    (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (frows y0 y1)) f) l h))%Z) ->
  ((0%Z <= j)%Z /\
   (j <
    (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (fcolumns y0 y1)) f) l
     h))%Z) ->
  ((0%Z <= l)%Z /\ (l < h)%Z) -> (1%Z <= h)%Z ->
  ((get (k_iter f l h) i j) =
   (infix_asdt
    (get (k_iter f l (h - 1%Z)%Z)
     (int.EuclideanDivision.div i (frows f (h - 1%Z)%Z))
     (int.EuclideanDivision.div j (fcolumns f (h - 1%Z)%Z)))
    (get (f (h - 1%Z)%Z)
     (kth_right i 1%Z h ((fun (y0:Z -> matrix t) (y1:Z) => (frows y0 y1)) f))
     (kth_right j 1%Z h
      ((fun (y0:Z -> matrix t) (y1:Z) => (fcolumns y0 y1)) f))))) /\
  ((get (k_iter f l h) i j) =
   (infix_asdt
    (get (k_iter f l (h - 1%Z)%Z)
     (int.EuclideanDivision.div i (frows f (h - 1%Z)%Z))
     (int.EuclideanDivision.div j (fcolumns f (h - 1%Z)%Z)))
    (get (f (h - 1%Z)%Z)
     (kth_left i (h - l)%Z l h
      ((fun (y0:Z -> matrix t) (y1:Z) => (frows y0 y1)) f))
     (kth_left j (h - l)%Z l h
      ((fun (y0:Z -> matrix t) (y1:Z) => (fcolumns y0 y1)) f))))).

Axiom k_iter_values_pre_proj :
  forall (f:Z -> matrix t) (i:Z) (j:Z) (l:Z) (h:Z),
  ((0%Z <= i)%Z /\
   (i <
    (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (frows y0 y1)) f) l h))%Z) ->
  ((0%Z <= j)%Z /\
   (j <
    (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (fcolumns y0 y1)) f) l
     h))%Z) ->
  ((0%Z <= l)%Z /\ (l < h)%Z) -> (1%Z <= h)%Z ->
  ((get (k_iter f l h) i j) =
   (infix_asdt
    (get (k_iter f l (h - 1%Z)%Z)
     (int.EuclideanDivision.div i (frows f (h - 1%Z)%Z))
     (int.EuclideanDivision.div j (fcolumns f (h - 1%Z)%Z)))
    (kproj f i j (h - l)%Z l h))).

Axiom k_iter_values_guarded :
  forall (f:Z -> matrix t) (i:Z) (j:Z) (l:Z) (h:Z),
  ((0%Z <= i)%Z /\
   (i <
    (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (frows y0 y1)) f) l h))%Z) ->
  ((0%Z <= j)%Z /\
   (j <
    (ind_iproduct ((fun (y0:Z -> matrix t) (y1:Z) => (fcolumns y0 y1)) f) l
     h))%Z) ->
  ((0%Z <= l)%Z /\ (l < h)%Z) ->
  ((get (k_iter f l h) i j) =
   (ind_product (fun (k:Z) => (kproj f i j k l h)) 1%Z ((h - l)%Z + 1%Z)%Z)).

Axiom k_iter_values :
  forall (f:Z -> matrix t) (i:Z) (j:Z) (l:Z) (h:Z),
  (valid_index (k_iter f l h) i j) -> ((0%Z <= l)%Z /\ (l < h)%Z) ->
  ((get (k_iter f l h) i j) =
   (ind_product (fun (k:Z) => (kproj f i j k l h)) 1%Z ((h - l)%Z + 1%Z)%Z)).

Axiom k_iter_values_gen :
  forall (f:Z -> matrix t) (l:Z) (h:Z), ((0%Z <= l)%Z /\ (l < h)%Z) ->
  forall (i:Z) (j:Z), (valid_index (k_iter f l h) i j) ->
  ((get (k_iter f l h) i j) =
   (ind_product (fun (k:Z) => (kproj f i j k l h)) 1%Z ((h - l)%Z + 1%Z)%Z)).

Parameter kth_bit_r: Z -> Z -> Z.

Axiom kth_bit_r_def :
  forall (i:Z) (k:Z), (0%Z <= i)%Z -> (1%Z <= k)%Z ->
  ((kth_bit_r i k) = (kth_nit_r i k 2%Z)).

Axiom kth_bit_r_spec :
  forall (i:Z) (k:Z), (0%Z <= i)%Z -> (1%Z <= k)%Z ->
  ((kth_bit_r i k) =
   (int.EuclideanDivision.mod1
    (int.EuclideanDivision.div i (power 2%Z (k - 1%Z)%Z)) 2%Z)).

Parameter kth_bit_l: Z -> Z -> Z -> Z.

Axiom kth_bit_l_def :
  forall (i:Z) (h:Z) (k:Z), (0%Z <= i)%Z -> ((1%Z <= k)%Z /\ (k <= h)%Z) ->
  ((kth_bit_l i h k) = (kth_nit_l i k 2%Z h)).

Axiom kth_bit_l_spec :
  forall (i:Z) (h:Z) (k:Z), (0%Z <= i)%Z -> ((1%Z <= k)%Z /\ (k <= h)%Z) ->
  ((kth_bit_l i h k) =
   (int.EuclideanDivision.mod1
    (int.EuclideanDivision.div i (power 2%Z (h - k)%Z)) 2%Z)) /\
  (((0%Z <= (kth_bit_l i h k))%Z /\ ((kth_bit_l i h k) <= 1%Z)%Z) /\
   (((kth_bit_l i h k) = (kth_bit_r i ((h - k)%Z + 1%Z)%Z)) /\
    ((kth_bit_l i h k) =
     (kth_right i ((h - k)%Z + 1%Z)%Z (h - k)%Z
      ((fun (y0:Z) (y1:Z) => y0) 2%Z))))).

Axiom kth_bit_div_mod :
  forall (i:Z) (k:Z), (0%Z <= i)%Z -> (1%Z <= k)%Z ->
  ((kth_bit_r i k) =
   (int.EuclideanDivision.div (int.EuclideanDivision.mod1 i (power 2%Z k))
    (power 2%Z (k - 1%Z)%Z))).

Axiom kth_bit_l_mod_div :
  forall (i:Z) (h:Z) (k:Z), (0%Z <= i)%Z -> ((1%Z <= k)%Z /\ (k <= h)%Z) ->
  ((kth_bit_l i h k) =
   (int.EuclideanDivision.mod1
    (int.EuclideanDivision.div i (power 2%Z (h - k)%Z)) 2%Z)).

Axiom kth_bit_l_div_mod :
  forall (i:Z) (h:Z) (k:Z), (0%Z <= i)%Z -> ((1%Z <= k)%Z /\ (k <= h)%Z) ->
  ((kth_bit_l i h k) =
   (int.EuclideanDivision.div
    (int.EuclideanDivision.mod1 i (power 2%Z ((h - k)%Z + 1%Z)%Z))
    (power 2%Z (h - k)%Z))).

Axiom kth_bit_l_transl :
  forall (i:Z) (l:Z) (k:Z) (n:Z), (0%Z <= i)%Z ->
  ((1%Z <= k)%Z /\ ((k < l)%Z /\ (l <= n)%Z)) ->
  ((kth_bit_l i n l) =
   (kth_bit_l (int.EuclideanDivision.mod1 i (power 2%Z (n - k)%Z)) (n - k)%Z
    (l - k)%Z)).

Axiom kth_bit_l_transl_gen :
  forall (i:Z) (k:Z) (n:Z), (0%Z <= i)%Z -> ((1%Z <= k)%Z /\ (k < n)%Z) ->
  forall (l:Z), ((k < l)%Z /\ (l <= n)%Z) ->
  ((kth_bit_l i n l) =
   (kth_bit_l (int.EuclideanDivision.mod1 i (power 2%Z (n - k)%Z)) (n - k)%Z
    (l - k)%Z)).

Parameter head_bit: Z -> Z -> Z.

Axiom head_bit_def :
  forall (i:Z) (k:Z), (0%Z < k)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z k))%Z) ->
  ((head_bit i k) = (int.EuclideanDivision.div i (power 2%Z (k - 1%Z)%Z))).

Axiom head_bit_spec :
  forall (i:Z) (k:Z), (0%Z < k)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z k))%Z) ->
  ((0%Z <= (head_bit i k))%Z /\ ((head_bit i k) <= 1%Z)%Z) /\
  ((head_bit i k) = (kth_bit_l i k 1%Z)).

Parameter tail_bits: Z -> Z -> Z.

Axiom tail_bits_def :
  forall (i:Z) (k:Z), (0%Z < k)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z k))%Z) ->
  ((tail_bits i k) = (int.EuclideanDivision.mod1 i (power 2%Z (k - 1%Z)%Z))).

Axiom tail_bits_spec :
  forall (i:Z) (k:Z), (0%Z < k)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z k))%Z) ->
  (0%Z <= (tail_bits i k))%Z /\
  ((tail_bits i k) <= (power 2%Z (k - 1%Z)%Z))%Z.

Parameter ht_to_int: Z -> Z -> Z -> Z.

Axiom ht_to_int_def :
  forall (hi:Z) (ti:Z) (k:Z), (0%Z < k)%Z ->
  ((0%Z <= hi)%Z /\ (hi < 2%Z)%Z) ->
  ((0%Z <= ti)%Z /\ (ti < (power 2%Z (k - 1%Z)%Z))%Z) ->
  ((ht_to_int hi ti k) = ((hi * (power 2%Z (k - 1%Z)%Z))%Z + ti)%Z).

Axiom head_tail_inv :
  forall (i:Z) (k:Z), (0%Z < k)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z k))%Z) ->
  ((ht_to_int (head_bit i k) (tail_bits i k) k) = i).

Axiom ht_to_int_head :
  forall (i:Z) (ti:Z) (k:Z), (0%Z < k)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z k))%Z) ->
  ((0%Z <= ti)%Z /\ (ti < (power 2%Z (k - 1%Z)%Z))%Z) ->
  ((head_bit (ht_to_int (head_bit i k) ti k) k) = (head_bit i k)).

Axiom ht_to_int_tail :
  forall (hi:Z) (i:Z) (k:Z), (0%Z < k)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z k))%Z) ->
  ((0%Z <= hi)%Z /\ (hi < 2%Z)%Z) ->
  ((tail_bits (ht_to_int hi (tail_bits i k) k) k) = (tail_bits i k)).

Parameter kth_weigh: Z -> Z -> Z.

Axiom kth_weigh_def :
  forall (i:Z) (k:Z), (0%Z <= i)%Z -> (0%Z < k)%Z ->
  ((kth_weigh i k) = (weighted_kth_nit_r i k 2%Z)).

Axiom kth_weigh_spec :
  forall (i:Z) (k:Z), (0%Z <= i)%Z -> (0%Z < k)%Z ->
  ((power 2%Z (k - 1%Z)%Z) < i)%Z ->
  (0%Z <= (kth_weigh i k))%Z /\ ((kth_weigh i k) <= i)%Z.

Parameter binary_length: Z -> Z.

Axiom binary_length_def :
  forall (i:Z), (0%Z <= i)%Z -> ((binary_length i) = (nary_length i 2%Z)).

Axiom binary_length_spec :
  forall (i:Z), (0%Z <= i)%Z ->
  ((0%Z < i)%Z ->
   ((power 2%Z ((binary_length i) - 1%Z)%Z) <= i)%Z /\
   (i < (power 2%Z (binary_length i)))%Z) /\
  (((i < 2%Z)%Z -> ((binary_length i) = 1%Z)) /\
   ((1%Z <= (binary_length i))%Z /\
    (i = (int.EuclideanDivision.mod1 i (power 2%Z (binary_length i)))))).

Axiom set_binary_length :
  forall (i:Z) (k:Z), (0%Z <= i)%Z -> (0%Z <= k)%Z ->
  ((0%Z < i)%Z -> ((power 2%Z (k - 1%Z)%Z) <= i)%Z /\ (i < (power 2%Z k))%Z) ->
  ((i < 2%Z)%Z -> (k = 1%Z)) -> (k = (binary_length i)).

Axiom set_binary_length_b :
  forall (i:Z) (k:Z), (0%Z <= i)%Z -> (0%Z < k)%Z -> (i < (power 2%Z k))%Z ->
  ((binary_length i) <= k)%Z.

Axiom no_rest_bin_length :
  forall (i:Z) (l:Z), (0%Z < i)%Z -> (0%Z <= l)%Z -> (i = (power 2%Z l)) ->
  ((binary_length i) = (l + 1%Z)%Z).

Axiom mod_binary :
  forall (i:Z) (l:Z) (k:Z), (0%Z <= i)%Z -> ((1%Z <= k)%Z /\ (k <= l)%Z) ->
  ((kth_bit_r (int.EuclideanDivision.mod1 i (power 2%Z l)) k) =
   (kth_bit_r i k)).

Axiom mod_binary_comm :
  forall (i:Z) (l:Z) (k:Z), (0%Z <= i)%Z -> (0%Z <= l)%Z ->
  ((1%Z <= k)%Z /\ (k <= l)%Z) -> ((0%Z <= k)%Z /\ (k < l)%Z) ->
  ((kth_bit_r i k) =
   (kth_bit_r (int.EuclideanDivision.mod1 i (power 2%Z l)) k)).

Axiom binary_decomposition :
  forall (i:Z), (0%Z <= i)%Z ->
  (i =
   (ind_isum (fun (l:Z) => ((kth_bit_r i l) * (power 2%Z (l - 1%Z)%Z))%Z) 1%Z
    ((binary_length i) + 1%Z)%Z)).

Axiom binary_decomposition_l :
  forall (i:Z) (n:Z), (0%Z <= i)%Z -> ((binary_length i) <= n)%Z ->
  (i =
   (ind_isum (fun (l:Z) => ((kth_bit_l i n l) * (power 2%Z (n - l)%Z))%Z) 1%Z
    (n + 1%Z)%Z)).

Axiom binary_dec_inv :
  forall (i:Z) (k:Z) (n:Z), (0%Z <= i)%Z -> ((0%Z <= k)%Z /\ (k < n)%Z) ->
  ((binary_length i) <= n)%Z ->
  ((ind_isum (fun (l:Z) => ((kth_bit_l i n l) * (power 2%Z (n - l)%Z))%Z)
    (n - k)%Z n)
   =
   (ind_isum (fun (l:Z) => ((kth_bit_l i n (n - l)%Z) * (power 2%Z l))%Z) 1%Z
    (k + 1%Z)%Z)).

Axiom binary_decomposition_inv :
  forall (i:Z) (k:Z) (n:Z), (0%Z <= i)%Z -> ((0%Z <= k)%Z /\ (k <= n)%Z) ->
  ((binary_length i) <= n)%Z ->
  ((ind_isum (fun (l:Z) => ((kth_bit_l i n l) * (power 2%Z (n - l)%Z))%Z) 1%Z
    ((n - k)%Z + 1%Z)%Z)
   =
   (ind_isum (fun (l:Z) => ((kth_bit_l i n (n - l)%Z) * (power 2%Z l))%Z) k
    n)).

Axiom binary_decomposition_l_mod :
  forall (i:Z) (k:Z) (n:Z), ((1%Z <= k)%Z /\ (k < n)%Z) -> (0%Z <= i)%Z ->
  ((0%Z <= k)%Z /\ (k < n)%Z) ->
  ((int.EuclideanDivision.mod1 i (power 2%Z (n - k)%Z)) =
   (ind_isum (fun (l:Z) => ((kth_bit_l i n l) * (power 2%Z (n - l)%Z))%Z)
    (k + 1%Z)%Z (n + 1%Z)%Z)).

Axiom binary_decomposition_l_mod_gen :
  forall (k:Z) (n:Z), ((1%Z <= k)%Z /\ (k < n)%Z) ->
  ((0%Z <= k)%Z /\ (k < n)%Z) -> forall (i:Z),
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((int.EuclideanDivision.mod1 i (power 2%Z (n - k)%Z)) =
   (ind_isum (fun (l:Z) => ((kth_bit_l i n l) * (power 2%Z (n - l)%Z))%Z)
    (k + 1%Z)%Z (n + 1%Z)%Z)).

Axiom tail_bits_mod :
  forall (i:Z) (n:Z), (1%Z < n)%Z -> (0%Z <= i)%Z ->
  ((binary_length i) <= n)%Z ->
  ((tail_bits i n) =
   (ind_isum (fun (l:Z) => ((kth_bit_l i n l) * (power 2%Z (n - l)%Z))%Z) 2%Z
    (n + 1%Z)%Z)).

(* Why3 assumption *)
Definition is_binary (t1:Z -> Z) (i:Z) (j:Z) : Prop :=
  forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) ->
  (0%Z <= (t1 k))%Z /\ ((t1 k) < 2%Z)%Z.

(* Why3 assumption *)
Definition binary (t1:Z -> Z) : Prop :=
  forall (k:Z), (0%Z <= (t1 k))%Z /\ ((t1 k) < 2%Z)%Z.

(* Why3 assumption *)
Definition shift {a:Type} {a_WT:WhyType a} (f:Z -> a) (i:Z) (k:Z) : a :=
  f (k - i)%Z.

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

Axiom concat_fun_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> a) (g:Z -> a) (i:Z) (k:Z),
  ((k <= i)%Z -> ((concat_fun f g i k) = (f k))) /\
  (~ (k <= i)%Z -> ((concat_fun f g i k) = (g (k - i)%Z))).

Axiom concat_fun_bin_i :
  forall (f:Z -> Z) (g:Z -> Z) (i:Z) (k:Z), (binary f) -> (binary g) ->
  (0%Z <= (concat_fun f g i k))%Z /\ ((concat_fun f g i k) < 2%Z)%Z.

Axiom shift_bin_i :
  forall (f:Z -> Z) (i:Z) (k:Z), (binary f) ->
  (0%Z <= (shift f i k))%Z /\ ((shift f i k) < 2%Z)%Z.

Axiom concat_fun_bin :
  forall (f:Z -> Z) (g:Z -> Z) (i:Z), (binary f) -> (binary g) ->
  binary
  ((((fun (y0:Z -> Z) (y1:Z -> Z) (y2:Z) (y3:Z) => (concat_fun y0 y1 y2 y3))
     f)
    g)
   i).

Axiom shift_bin :
  forall (f:Z -> Z) (i:Z), (binary f) ->
  binary (((fun (y0:Z -> Z) (y1:Z) (y2:Z) => (shift y0 y1 y2)) f) i).

Axiom set_is_all_binary :
  forall (t1:Z -> Z),
  (forall (k:Z), (0%Z <= (t1 k))%Z /\ ((t1 k) < 2%Z)%Z) -> binary t1.

Axiom set_is_binary :
  forall (t1:Z -> Z) (i:Z) (j:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) ->
   (0%Z <= (t1 k))%Z /\ ((t1 k) < 2%Z)%Z) ->
  is_binary t1 i j.

Axiom get_is_binary :
  forall (t1:Z -> Z) (i:Z) (j:Z), (is_binary t1 i j) -> forall (k:Z),
  ((i <= k)%Z /\ (k < j)%Z) -> (0%Z <= (t1 k))%Z /\ ((t1 k) < 2%Z)%Z.

Axiom binary_to_nary :
  forall (t1:Z -> Z) (i:Z) (j:Z), (is_binary t1 i j) -> is_nary t1 i j 2%Z.

Axiom nary_to_binary :
  forall (t1:Z -> Z) (i:Z) (j:Z), (is_nary t1 i j 2%Z) -> is_binary t1 i j.

Axiom lambda_int_seq :
  forall (t1:Z -> Z) (i:Z), (((fun (k:Z) => (t1 k)) i) = (t1 i)).

Axiom lambda_int_seq_comm :
  forall (t1:Z -> Z) (i:Z), ((t1 i) = ((fun (k:Z) => (t1 k)) i)).

Axiom is_binary_kth_bit_r :
  forall (i:Z) (k:Z), (0%Z <= i)%Z ->
  is_binary (fun (j:Z) => (kth_bit_r i j)) 1%Z (k + 1%Z)%Z.

Axiom subset_closure_binaries :
  forall (i:Z) (j:Z) (k:Z) (m:Z) (t1:Z -> Z),
  ((i <= k)%Z /\ ((k < m)%Z /\ (m < j)%Z)) -> (is_binary t1 i j) ->
  is_binary t1 k m.

Parameter is_a_q_bra: (matrix t) -> Prop.

Axiom is_a_q_bra1 :
  forall (m:matrix t),
  (is_a_q_bra m) <->
  (((rows m) = 1%Z) /\
   exists s:Z, (0%Z <= s)%Z /\ ((columns m) = (power 2%Z s))).

Parameter is_a_ket: (matrix t) -> Prop.

Axiom is_a_ket1 :
  forall (m:matrix t),
  (is_a_ket m) <->
  (((columns m) = 1%Z) /\
   exists s:Z, (0%Z <= s)%Z /\ ((rows m) = (power 2%Z s))).

Parameter bra_to_ket: (matrix t) -> matrix t.

Axiom bra_to_ket_spec :
  forall (m:matrix t), (is_a_q_bra m) ->
  (is_a_ket (bra_to_ket m)) /\
  ((forall (i:Z) (j:Z),
    (valid_index m i j) <-> (valid_index (bra_to_ket m) j i)) /\
   (((rows (bra_to_ket m)) = (columns m)) /\
    (((columns (bra_to_ket m)) = (rows m)) /\
     forall (i:Z) (j:Z), (valid_index m i j) ->
     ((get m i j) = (get (bra_to_ket m) j i))))).

Parameter ket_to_bra: (matrix t) -> matrix t.

Axiom ket_to_bra_spec :
  forall (m:matrix t), (is_a_ket m) ->
  ((columns (ket_to_bra m)) = (rows m)) /\
  (((rows (ket_to_bra m)) = (columns m)) /\
   ((is_a_q_bra (ket_to_bra m)) /\
    ((forall (i:Z) (j:Z),
      (valid_index m i j) <-> (valid_index (ket_to_bra m) j i)) /\
     forall (i:Z) (j:Z), (valid_index m i j) ->
     ((get m i j) = (get (ket_to_bra m) j i))))).

Axiom ket_to_bra_to_ket :
  forall (m:matrix t), (is_a_ket m) -> equal (bra_to_ket (ket_to_bra m)) m.

Axiom bra_to_ket_to_bra :
  forall (m:matrix t), (is_a_q_bra m) -> equal m (ket_to_bra (bra_to_ket m)).

Parameter bra_length: (matrix t) -> Z.

Axiom bra_length_def :
  forall (m:matrix t), (is_a_q_bra m) ->
  ((bra_length m) = ((binary_length (columns m)) - 1%Z)%Z).

Axiom bra_length_spec :
  forall (m:matrix t), (is_a_q_bra m) ->
  (0%Z <= (bra_length m))%Z /\ ((columns m) = (power 2%Z (bra_length m))).

Parameter ket_length: (matrix t) -> Z.

Axiom ket_length_def :
  forall (m:matrix t), (is_a_ket m) ->
  ((ket_length m) = (bra_length (ket_to_bra m))).

Axiom ket_length_spec :
  forall (m:matrix t), (is_a_ket m) ->
  (0%Z <= (ket_length m))%Z /\ ((rows m) = (power 2%Z (ket_length m))).

Axiom get_ket_length :
  forall (m:matrix t) (n:Z), (0%Z <= n)%Z -> (is_a_ket m) ->
  ((rows m) = (power 2%Z n)) -> ((ket_length m) = n).

Axiom set_ket_length :
  forall (m:matrix t) (n:Z), (0%Z <= n)%Z -> (is_a_ket m) ->
  ((ket_length m) = n) -> ((rows m) = (power 2%Z n)).

Axiom set_ket_length_gen :
  forall (m:matrix t) (n:Z), (0%Z <= n)%Z -> (is_a_ket m) ->
  ((power 2%Z (ket_length m)) = n) -> ((rows m) = n).

Axiom set_is_a_ket :
  forall (m:matrix t), ((columns m) = 1%Z) ->
  (exists s:Z, (0%Z <= s)%Z /\ ((rows m) = (power 2%Z s))) -> is_a_ket m.

Axiom get_is_a_ket :
  forall (m:matrix t), (is_a_ket m) ->
  ((columns m) = 1%Z) /\ ((rows m) = (power 2%Z (ket_length m))).

Axiom get_ket_columns :
  forall (m:matrix t), (is_a_ket m) -> ((columns m) = 1%Z).

Axiom get_ket_rows :
  forall (m:matrix t), (is_a_ket m) ->
  ((rows m) = (power 2%Z (ket_length m))).

Axiom get_ket_rows_gen :
  forall (m:matrix t) (i:Z), (is_a_ket m) ->
  (i = (power 2%Z (ket_length m))) -> ((rows m) = i).

Axiom get_ket_rows_length :
  forall (m:matrix t) (l:Z), (is_a_ket m) -> ((ket_length m) = l) ->
  ((rows m) = (power 2%Z l)).

(* Why3 assumption *)
Definition is_a_q_bra_qbit (m:matrix t) : Prop :=
  (is_a_q_bra m) /\ ((columns m) = 2%Z).

(* Why3 assumption *)
Definition is_a_ket_qbit (m:matrix t) : Prop :=
  (is_a_ket m) /\ ((rows m) = 2%Z).

Axiom q_ket_qbit_kronecker :
  forall (m:matrix t) (n:matrix t), (is_a_ket m) -> (is_a_ket n) ->
  (is_a_ket (kronecker m n)) /\
  ((ket_length (kronecker m n)) = ((ket_length m) + (ket_length n))%Z).

(* Why3 assumption *)
Definition comp_func {a:Type} {a_WT:WhyType a} (f:a -> a) (g:a -> a) : a -> a :=
  fun (a1:a) => (f (g a1)).

Axiom comp_func_apply :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> a) (g:a -> a),
  ((comp_func f g) = (fun (a1:a) => (f (g a1)))).

Axiom comp_func_eq :
  forall {a:Type} {a_WT:WhyType a},
  forall (f1:a -> a) (f2:a -> a) (g1:a -> a) (g2:a -> a), (f1 = f2) ->
  (g1 = g2) -> ((comp_func f1 g1) = (comp_func f2 g2)).

Axiom comp_func_apply_eq :
  forall {a:Type} {a_WT:WhyType a},
  forall (f1:a -> a) (f2:a -> a) (g1:a -> a) (g2:a -> a) (i:a) (j:a),
  (f1 = f2) -> (g1 = g2) -> (i = j) -> ((f1 (g1 i)) = (f2 (g2 j))).

Axiom neutral_id :
  forall {a:Type} {a_WT:WhyType a},
  (neutral (fun (y0:a -> a) (y1:a -> a) => (comp_func y0 y1))
   (fun (y0:a) => y0)) /\
  (iterable (fun (y0:a -> a) (y1:a -> a) => (comp_func y0 y1))).

(* Why3 assumption *)
Definition iter_comp {a:Type} {a_WT:WhyType a} (t1:Z -> a -> a) (i:Z)
    (j:Z) : a -> a :=
  int_iterate (fun (y0:a -> a) (y1:a -> a) => (comp_func y0 y1)) t1 i j.

Axiom comp_func_neutral_left :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> a), ((comp_func (fun (y0:a) => y0) f) = f).

Axiom comp_func_neutral_right :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> a), ((comp_func f (fun (y0:a) => y0)) = f).

Axiom iter_comp_empty :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> a -> a) (i:Z) (j:Z), (j <= i)%Z ->
  ((iter_comp f i j) = (fun (y0:a) => y0)).

Axiom iter_comp_plus_one :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> a -> a) (i:Z) (j:Z), (i < j)%Z ->
  ((iter_comp f i j) = (comp_func (f i) (iter_comp f (i + 1%Z)%Z j))).

Axiom iter_comp_plus_one_value :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> a -> a) (i:Z) (j:Z) (e:a), (i < j)%Z ->
  (((iter_comp f i j) e) = ((f i) ((iter_comp f (i + 1%Z)%Z j) e))).

Axiom iter_comp_cardone :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> a -> a) (i:Z) (j:Z), (j = (i + 1%Z)%Z) ->
  ((iter_comp f i j) = (f i)).

Axiom iter_comp_def_plus_one_com :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> a -> a) (i:Z) (j:Z), (i < j)%Z ->
  ((comp_func (f i) (iter_comp f (i + 1%Z)%Z j)) = (iter_comp f i j)).

Axiom iter_comp_right_extension :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> a -> a) (i:Z) (j:Z), (i < j)%Z ->
  ((iter_comp f i j) =
   (comp_func (iter_comp f i (j - 1%Z)%Z) (f (j - 1%Z)%Z))).

Axiom iter_comp_right_extension_value :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> a -> a) (i:Z) (j:Z) (e:a), (i < j)%Z ->
  (((iter_comp f i j) e) = ((iter_comp f i (j - 1%Z)%Z) ((f (j - 1%Z)%Z) e))).

Axiom iter_comp_transitivity :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> a -> a) (i:Z) (k:Z) (j:Z), ((i <= k)%Z /\ (k <= j)%Z) ->
  ((iter_comp f i j) = (comp_func (iter_comp f i k) (iter_comp f k j))).

Axiom iter_comp_eq :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> a -> a) (g:Z -> a -> a) (i:Z) (j:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ((f k) = (g k))) ->
  ((iter_comp f i j) = (iter_comp g i j)).

Axiom iter_comp_eq_gen :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> a -> a) (g:Z -> a -> a) (i:Z) (i1:Z) (j:Z) (j1:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> ((f k) = (g k))) -> (i = i1) ->
  (j = j1) -> ((iter_comp f i j) = (iter_comp g i1 j1)).

Axiom iter_comp_transl :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> a -> a) (i:Z) (j:Z) (k:Z),
  ((iter_comp f i j) =
   (iter_comp (fun (b:Z) => (f (b + k)%Z)) (i - k)%Z (j - k)%Z)).

Axiom iter_comp_transl_plus_one :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> a -> a) (i:Z) (j:Z),
  ((iter_comp f i j) =
   (iter_comp (fun (b:Z) => (f (b - 1%Z)%Z)) (i + 1%Z)%Z (j + 1%Z)%Z)).

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

Axiom inv_func_def :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b) (e':b), (p_bijective f s s') ->
  (mem e' s') ->
  ((inv_func f s s' e') =
   (element (filter (fun (e:a) => (indic_bool (f e) e')) s))).

Axiom inv_func_spec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b) (e':b), (p_bijective f s s') ->
  (mem e' s') ->
  (mem (inv_func f s s' e') s) /\ ((f (inv_func f s s' e')) = e').

Axiom inv_rec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b) (e:a), (p_bijective f s s') ->
  (mem e s) -> ((inv_func f s s' (f e)) = e).

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

Axiom inv__def :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b) (e:b), (p_bijective f s s') ->
  (mem e s') -> ((inv_ f s s' e) = (inv_func f s s' e)).

Axiom inv__spec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b) (e:b), (p_bijective f s s') ->
  (mem e s') -> (mem (inv_ f s s' e) s) /\ ((f (inv_ f s s' e)) = e).

Axiom inv_bijective :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b), (p_bijective f s s') ->
  p_bijective
  ((((fun (y0:a -> b) (y1:set a) (y2:set b) (y3:b) => (inv_ y0 y1 y2 y3)) f)
    s)
   s')
  s' s.

Axiom set_bijective_inv :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (g:b -> a) (s:set a) (b1:b), (mem b1 (map f s)) ->
  (forall (e:a) (e':a), (mem e s) -> (mem e' s) -> ~ (e = e') ->
   ~ ((f e) = (f e'))) ->
  (forall (e':b), (mem e' (map f s)) -> (mem (g e') s) /\ ((f (g e')) = e')) ->
  (p_bijective f s (map f s)) /\ ((inv_func f s (map f s) b1) = (g b1)).

Axiom set_bij_inv :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (g:b -> a) (s:set a),
  (forall (e:a) (e':a), (mem e s) -> (mem e' s) -> ~ (e = e') ->
   ~ ((f e) = (f e'))) ->
  (forall (e':b), (mem e' (map f s)) -> (mem (g e') s) /\ ((f (g e')) = e')) ->
  (p_bijective f s (map f s)) /\
  ((p_bijective g (map f s) s) /\
   forall (b1:b), (mem b1 (map f s)) ->
   ((inv_func f s (map f s) b1) = (g b1))).

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

Axiom inv_f_spec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:a -> b) (s:set a) (s':set b), (p_bijective f s s') ->
  (forall (e:b), (mem e s') -> mem ((inv_f f s s') e) s) /\
  ((forall (e:b), (mem e s') -> ((f ((inv_f f s s') e)) = e)) /\
   (p_bijective (inv_f f s s') s' s)).

Parameter swap_plus_one: Z -> Z -> Z.

Axiom swap_plus_one_def :
  forall (i:Z) (k:Z),
  ((k = i) -> ((swap_plus_one i k) = (k + 1%Z)%Z)) /\
  (~ (k = i) ->
   ((k = (i + 1%Z)%Z) -> ((swap_plus_one i k) = (k - 1%Z)%Z)) /\
   (~ (k = (i + 1%Z)%Z) -> ((swap_plus_one i k) = k))).

Axiom get_swap_plus_one :
  forall (i:Z) (k:Z),
  ((k = i) -> ((swap_plus_one i k) = (k + 1%Z)%Z)) /\
  (~ (k = i) ->
   ((k = (i + 1%Z)%Z) -> ((swap_plus_one i k) = (k - 1%Z)%Z)) /\
   (~ (k = (i + 1%Z)%Z) -> ((swap_plus_one i k) = k))).

Axiom get_swap_plus_one_valt :
  forall (i:Z) (k:Z), (i = k) -> ((swap_plus_one i k) = (k + 1%Z)%Z).

Axiom get_swap_plus_one_valtp :
  forall (i:Z) (k:Z), (k = (i + 1%Z)%Z) ->
  ((swap_plus_one i k) = (k - 1%Z)%Z).

Axiom get_swap_plus_one_valtn :
  forall (i:Z) (k:Z), ~ (k = (i + 1%Z)%Z) -> ~ (k = i) ->
  ((swap_plus_one i k) = k).

Axiom swap_plus_one_apply :
  forall (i:Z),
  let fc7 := (fun (y0:Z) (y1:Z) => (swap_plus_one y0 y1)) i in
  forall (k:Z),
  ((k = i) -> ((fc7 k) = (k + 1%Z)%Z)) /\
  (~ (k = i) ->
   ((k = (i + 1%Z)%Z) -> ((fc7 k) = (k - 1%Z)%Z)) /\
   (~ (k = (i + 1%Z)%Z) -> ((fc7 k) = k))).

Parameter set_exchange_growing: Z -> Z -> Z -> Z.

Axiom set_exchange_growing_spec :
  forall (i:Z) (j:Z), (i <= j)%Z ->
  (let fc7 := set_exchange_growing i j in
   forall (k:Z),
   ((k = i) -> ((fc7 k) = j)) /\
   (~ (k = i) ->
    (((i < k)%Z /\ (k <= j)%Z) -> ((fc7 k) = (k - 1%Z)%Z)) /\
    (~ ((i < k)%Z /\ (k <= j)%Z) -> ((fc7 k) = k)))) /\
  ((set_exchange_growing i j) =
   (iter_comp
    (fun (l:Z) => ((fun (y0:Z) (y1:Z) => (swap_plus_one y0 y1)) (j - l)%Z))
    1%Z ((j - i)%Z + 1%Z)%Z)).

Parameter set_exchange_decreasing: Z -> Z -> Z -> Z.

Axiom set_exchange_decreasing_spec :
  forall (i:Z) (j:Z), (i <= j)%Z ->
  (let fc7 := set_exchange_decreasing i j in
   forall (k:Z),
   ((k = j) -> ((fc7 k) = i)) /\
   (~ (k = j) ->
    (((i <= k)%Z /\ (k < j)%Z) -> ((fc7 k) = (k + 1%Z)%Z)) /\
    (~ ((i <= k)%Z /\ (k < j)%Z) -> ((fc7 k) = k)))) /\
  ((set_exchange_decreasing i j) =
   (iter_comp (fun (l:Z) => ((fun (y0:Z) (y1:Z) => (swap_plus_one y0 y1)) l))
    i j)).

(* Why3 assumption *)
Definition is_a_permutation (s:set Z) (f:Z -> Z) : Prop := p_bijective f s s.

Axiom permut_in :
  forall (s:set Z) (f:Z -> Z) (i:Z), (is_a_permutation s f) -> (mem i s) ->
  mem (f i) s.

Axiom set_permutation :
  forall (s:set Z) (f:Z -> Z), (forall (e:Z), (mem e s) -> mem (f e) s) ->
  (forall (e:Z), (mem e s) -> exists e':Z, (mem e' s) /\ (e = (f e'))) ->
  is_a_permutation s f.

Axiom get_permutation_bij :
  forall (s:set Z) (f:Z -> Z), (is_a_permutation s f) -> p_bijective f s s.

Axiom get_permutation :
  forall (s:set Z) (f:Z -> Z), (is_a_permutation s f) ->
  (p_bijective f s s) /\
  ((forall (e:Z), (mem e s) -> mem (f e) s) /\
   ((forall (e:Z) (e':Z), (mem e s) -> (mem e' s) -> ~ (e = e') ->
     ~ ((f e) = (f e'))) /\
    ((forall (e:Z) (e':Z), (mem e s) -> (mem e' s) -> ((f e) = (f e')) ->
      (e = e')) /\
     forall (e:Z), (mem e s) -> exists e':Z, (mem e' s) /\ (e = (f e'))))).

Parameter permut_changed: (set Z) -> (Z -> Z) -> set Z.

Parameter result6: (Z -> Z) -> Z -> bool.

Axiom result_def6 :
  forall (f:Z -> Z) (e:Z), (((result6 f) e) = true) <-> ~ ((f e) = e).

Axiom permut_changed_def :
  forall (s:set Z) (f:Z -> Z), (is_a_permutation s f) ->
  ((permut_changed s f) = (filter (result6 f) s)).

Axiom permut_changed_spec :
  forall (s:set Z) (f:Z -> Z), (is_a_permutation s f) ->
  (forall (e:Z), (mem e s) -> (mem e (permut_changed s f)) <-> ~ ((f e) = e)) /\
  (is_a_permutation (permut_changed s f) f).

Parameter permut_unchanged: (set Z) -> (Z -> Z) -> set Z.

Axiom permut_unchanged_spec :
  forall (s:set Z) (f:Z -> Z), (is_a_permutation s f) -> forall (e:Z),
  (mem e s) -> (mem e (permut_unchanged s f)) <-> ((f e) = e).

Parameter disjoint_permut: (set Z) -> (Z -> Z) -> (Z -> Z) -> Prop.

Axiom disjoint_permut_ :
  forall (s:set Z), forall (f:Z -> Z) (g:Z -> Z),
  (disjoint_permut s f g) <->
  ((is_a_permutation s f) /\
   ((is_a_permutation s g) /\
    ((inter (permut_changed s f) (permut_changed s g)) = (empty : set Z)))).

Axiom get_disjoint_permut :
  forall (s:set Z) (f:Z -> Z) (g:Z -> Z), (is_a_permutation s f) ->
  (is_a_permutation s g) -> (disjoint_permut s f g) ->
  ((inter (permut_changed s f) (permut_changed s g)) = (empty : set Z)) /\
  ((forall (i:Z), (mem i (permut_changed s f)) ->
    (((comp_func f g) i) = (f i))) /\
   ((forall (i:Z), (mem i (permut_changed s g)) ->
     (((comp_func f g) i) = (g i))) /\
    ((forall (i:Z), (mem i (permut_changed s f)) ->
      (((comp_func g f) i) = (f i))) /\
     ((forall (i:Z), (mem i (permut_changed s g)) ->
       (((comp_func g f) i) = (g i))) /\
      ((forall (i:Z), (mem i s) -> ~ (((comp_func g f) i) = (g i)) ->
        (((comp_func g f) i) = (f i))) /\
       forall (i:Z), (mem i s) -> ~ (((comp_func f g) i) = (g i)) ->
       (((comp_func g f) i) = (f i))))))).

Axiom set_disjoint_permut :
  forall (s:set Z) (f:Z -> Z) (g:Z -> Z), (is_a_permutation s f) ->
  (is_a_permutation s g) ->
  ((inter (permut_changed s f) (permut_changed s g)) = (empty : set Z)) ->
  (disjoint_permut s f g) /\
  ((forall (i:Z), (mem i (permut_changed s f)) ->
    (((comp_func f g) i) = (f i))) /\
   ((forall (i:Z), (mem i (permut_changed s g)) ->
     (((comp_func f g) i) = (g i))) /\
    ((forall (i:Z), (mem i (permut_changed s f)) ->
      (((comp_func g f) i) = (f i))) /\
     ((forall (i:Z), (mem i (permut_changed s g)) ->
       (((comp_func g f) i) = (g i))) /\
      ((forall (i:Z), (mem i s) -> ~ (((comp_func g f) i) = (g i)) ->
        (((comp_func g f) i) = (f i))) /\
       forall (i:Z), (mem i s) -> ~ (((comp_func f g) i) = (g i)) ->
       (((comp_func g f) i) = (f i))))))).

Axiom permut_transitive :
  forall (s:set Z) (f:Z -> Z) (g:Z -> Z), (is_a_permutation s f) ->
  (is_a_permutation s g) -> is_a_permutation s (comp_func f g).

Axiom permut_iter_comp :
  forall (s:set Z) (f:Z -> Z -> Z) (i:Z) (j:Z),
  (forall (k:Z), ((i <= k)%Z /\ (k < j)%Z) -> is_a_permutation s (f k)) ->
  (i <= j)%Z -> is_a_permutation s (iter_comp f i j).

Parameter exchange_growing: Z -> Z -> Z -> Z.

Axiom exchange_growing_def :
  forall (i:Z) (j:Z), (i < j)%Z ->
  ((exchange_growing i j) =
   (comp_func (set_exchange_decreasing i (j - 1%Z)%Z)
    (set_exchange_growing i j))).

Axiom exchange_growing_spec :
  forall (i:Z) (j:Z), (i < j)%Z ->
  let fc7 := exchange_growing i j in
  forall (k:Z),
  ((k = i) -> ((fc7 k) = j)) /\
  (~ (k = i) -> ((k = j) -> ((fc7 k) = i)) /\ (~ (k = j) -> ((fc7 k) = k))).

Parameter exchange: Z -> Z -> Z -> Z.

Axiom exchange_def :
  forall (i:Z) (j:Z),
  ((i = j) -> ((exchange i j) = (fun (y0:Z) => y0))) /\
  (~ (i = j) ->
   ((i < j)%Z -> ((exchange i j) = (exchange_growing i j))) /\
   (~ (i < j)%Z -> ((exchange i j) = (exchange_growing j i)))).

Axiom exchange_spec :
  forall (i:Z) (j:Z),
  (let fc7 := exchange i j in
   forall (k:Z),
   ((k = i) -> ((fc7 k) = j)) /\
   (~ (k = i) -> ((k = j) -> ((fc7 k) = i)) /\ (~ (k = j) -> ((fc7 k) = k)))) /\
  forall (s:set Z), (mem i s) -> (mem j s) ->
  is_a_permutation s (exchange i j).

Axiom exchange_changed :
  forall (i:Z) (j:Z) (s:set Z), (mem i s) -> (mem j s) -> forall (e:Z),
  (mem e (permut_changed s (exchange i j))) ->
  (mem e s) /\ (~ (e = i) -> (e = j)).

Axiom exchange_unchanged :
  forall (i:Z) (j:Z) (s:set Z), (mem i s) -> (mem j s) -> forall (e:Z),
  ((mem e s) /\ (~ (e = i) /\ ~ (e = j))) ->
  mem e (permut_unchanged s (exchange i j)).

Axiom exchange_decomp_growing :
  forall (i:Z) (j:Z), (i < j)%Z ->
  ((exchange i j) =
   (comp_func
    (iter_comp
     (fun (l:Z) => ((fun (y0:Z) (y1:Z) => (swap_plus_one y0 y1)) l)) i
     (j - 1%Z)%Z)
    (iter_comp
     (fun (l:Z) => ((fun (y0:Z) (y1:Z) => (swap_plus_one y0 y1)) (j - l)%Z))
     1%Z ((j - i)%Z + 1%Z)%Z))).

Axiom exchange_decomp_decreasing :
  forall (i:Z) (j:Z), (j < i)%Z ->
  ((exchange i j) =
   (comp_func
    (iter_comp
     (fun (l:Z) => ((fun (y0:Z) (y1:Z) => (swap_plus_one y0 y1)) l)) j
     (i - 1%Z)%Z)
    (iter_comp
     (fun (l:Z) => ((fun (y0:Z) (y1:Z) => (swap_plus_one y0 y1)) (i - l)%Z))
     1%Z ((i - j)%Z + 1%Z)%Z))).

Axiom exchange_id :
  forall (i:Z) (j:Z) (k:Z), ~ (i = k) -> ~ (j = k) ->
  (((exchange i j) k) = k).

Axiom exchange_input :
  forall (i:Z) (j:Z) (k:Z), (i = k) -> (((exchange i j) k) = j).

Axiom exchange_output :
  forall (i:Z) (j:Z) (k:Z), (j = k) -> (((exchange i j) k) = i).

Axiom set_last_val_permut :
  forall (s:set Z) (f:Z -> Z) (i:Z) (j:Z), (is_a_permutation s f) ->
  (mem i s) -> (mem j s) ->
  (forall (i1:Z), (mem i1 s) -> ~ (i1 = i) -> ~ ((f i1) = j)) -> ((f i) = j).

Axiom permut_comp :
  forall (s:set Z) (f1:Z -> Z) (f2:Z -> Z), (is_a_permutation s f1) ->
  (is_a_permutation s f2) -> is_a_permutation s (comp_func f1 f2).

Axiom is_a_permut_exchange :
  forall (i:Z) (j:Z) (s:set Z), (mem i s) -> (mem j s) ->
  is_a_permutation s (exchange i j).

Axiom associative_permutation :
  forall (f:Z -> Z) (g:Z -> Z) (h:Z -> Z) (e:Z),
  (((comp_func f (comp_func g h)) e) = ((comp_func (comp_func f g) h) e)).

Axiom assoc_permut :
  forall (f:Z -> Z) (g:Z -> Z) (h:Z -> Z),
  ((comp_func f (comp_func g h)) = (comp_func (comp_func f g) h)).

Axiom assoc_permut_comm :
  forall (f:Z -> Z) (g:Z -> Z) (h:Z -> Z),
  ((comp_func (comp_func f g) h) = (comp_func f (comp_func g h))).

Parameter reverse1: (set Z) -> (Z -> Z) -> Z -> Z.

Axiom reverse_def :
  forall (s:set Z) (f:Z -> Z), (is_a_permutation s f) ->
  ((reverse1 s f) = (inv_f f s s)).

Axiom reverse_spec :
  forall (s:set Z) (f:Z -> Z), (is_a_permutation s f) ->
  (is_a_permutation s (reverse1 s f)) /\
  ((forall (e:Z), (mem e s) -> (((reverse1 s f) (f e)) = e)) /\
   forall (e:Z), (mem e s) -> ((f ((reverse1 s f) e)) = e)).

Parameter permut_equal: (set Z) -> (Z -> Z) -> (Z -> Z) -> Prop.

Axiom Permut_equal :
  forall (s:set Z), forall (f:Z -> Z) (g:Z -> Z),
  (permut_equal s f g) <->
  ((is_a_permutation s f) /\ forall (e:Z), (mem e s) -> ((f e) = (g e))).

Parameter permut_reverse: (set Z) -> (Z -> Z) -> (Z -> Z) -> Prop.

Axiom Permut_reverse :
  forall (s:set Z), forall (f:Z -> Z) (g:Z -> Z),
  (permut_reverse s f g) <->
  ((is_a_permutation s f) /\
   ((is_a_permutation s g) /\ forall (e:Z), (mem e s) -> ((f (g e)) = e))).

Axiom apply_f_reverse :
  forall (s:set Z) (f:Z -> Z) (i:Z), (is_a_permutation s f) -> (mem i s) ->
  ((f ((reverse1 s f) i)) = i).

Axiom apply_reverse_f :
  forall (s:set Z) (f:Z -> Z) (i:Z), (is_a_permutation s f) -> (mem i s) ->
  (((reverse1 s f) (f i)) = i).

Axiom apply_f_reverse_gen :
  forall (s:set Z) (f:Z -> Z), (is_a_permutation s f) -> forall (i:Z),
  (mem i s) -> ((f ((reverse1 s f) i)) = i).

Axiom apply_reverse_f_gen :
  forall (s:set Z) (f:Z -> Z), (is_a_permutation s f) -> forall (i:Z),
  (mem i s) -> (((reverse1 s f) (f i)) = i).

Parameter invol_permut: (set Z) -> (Z -> Z) -> Prop.

Axiom invol_permut_spec :
  forall (s:set Z) (f:Z -> Z), (is_a_permutation s f) ->
  ((invol_permut s f) <-> (permut_reverse s f f)) /\
  ((invol_permut s f) <-> ((reverse1 s f) = f)).

Axiom set_invol_permut :
  forall (s:set Z) (f:Z -> Z), (is_a_permutation s f) ->
  (forall (e:Z), (mem e s) -> ((f (f e)) = e)) -> invol_permut s f.

Axiom get_invol_permut :
  forall (s:set Z) (f:Z -> Z), (is_a_permutation s f) ->
  (invol_permut s f) ->
  (forall (e:Z), (mem e s) -> ((f (f e)) = e)) /\ ((reverse1 s f) = f).

Axiom invol_exchange :
  forall (i:Z) (j:Z) (n:Z), ((1%Z <= i)%Z /\ (i <= n)%Z) ->
  ((1%Z <= j)%Z /\ (j <= n)%Z) ->
  invol_permut (to_fset 1%Z (n + 1%Z)%Z) (exchange i j).

Axiom invol_disjoint_permut :
  forall (s:set Z) (f:Z -> Z) (g:Z -> Z), (disjoint_permut s f g) ->
  (invol_permut s f) -> (invol_permut s g) -> invol_permut s (comp_func f g).

Axiom invol_comp_exchange :
  forall (i1:Z) (j1:Z) (i2:Z) (j2:Z) (n:Z), ((1%Z <= i1)%Z /\ (i1 <= n)%Z) ->
  ((1%Z <= j1)%Z /\ (j1 <= n)%Z) -> ((1%Z <= i2)%Z /\ (i2 <= n)%Z) ->
  ((1%Z <= j2)%Z /\ (j2 <= n)%Z) -> ~ (i1 = i2) -> ~ (i1 = j2) ->
  ~ (j1 = j2) -> ~ (j1 = i2) ->
  invol_permut (to_fset 1%Z (n + 1%Z)%Z)
  (comp_func (exchange i1 j1) (exchange i2 j2)).

Axiom permut_reverse_sym :
  forall (s:set Z) (f:Z -> Z) (g:Z -> Z), (permut_reverse s f g) ->
  permut_reverse s g f.

Axiom set_permut_equal :
  forall (s:set Z) (f:Z -> Z) (g:Z -> Z), (is_a_permutation s f) ->
  (forall (e:Z), (mem e s) -> ((f e) = (g e))) ->
  (permut_equal s f g) /\ (is_a_permutation s g).

Axiom get_permut_equal :
  forall (s:set Z) (f:Z -> Z) (g:Z -> Z), (permut_equal s f g) ->
  (is_a_permutation s f) /\
  ((is_a_permutation s g) /\
   ((forall (e:Z), (mem e s) -> ((f e) = (g e))) /\
    forall (e:Z), (mem e s) -> ((g e) = (f e)))).

Axiom set_permut_reverse :
  forall (s:set Z) (f:Z -> Z) (g:Z -> Z), (is_a_permutation s f) ->
  (is_a_permutation s g) -> (forall (e:Z), (mem e s) -> ((f (g e)) = e)) ->
  permut_reverse s f g.

Axiom get_permut_reverse :
  forall (s:set Z) (f:Z -> Z) (g:Z -> Z), (permut_reverse s f g) ->
  (is_a_permutation s f) /\
  ((is_a_permutation s g) /\
   ((forall (e:Z), (mem e s) -> ((f (g e)) = e)) /\
    forall (e:Z), (mem e s) -> ((g (f e)) = e))).

Axiom permut_equal_reverse :
  forall (s:set Z) (f:Z -> Z) (g:Z -> Z) (h:Z -> Z), (permut_equal s f g) ->
  (permut_reverse s g h) -> permut_reverse s f h.

Axiom permut_reverse_equal :
  forall (s:set Z) (f:Z -> Z) (g:Z -> Z) (h:Z -> Z),
  (permut_reverse s f g) -> (permut_equal s g h) -> permut_reverse s f h.

Axiom permut_reverse_inv :
  forall (s:set Z) (f:Z -> Z) (g:Z -> Z) (h:Z -> Z),
  (permut_reverse s f g) -> (permut_reverse s g h) -> permut_equal s f h.

Parameter permut_reverse_step: Z -> (Z -> Z) -> Z -> Z -> Z.

Parameter result7: Z -> (Z -> Z) -> Z -> Z -> Z -> Z.

Axiom result_def7 :
  forall (n:Z) (f:Z -> Z) (i:Z) (k:Z),
  (((1%Z <= k)%Z /\ (k < i)%Z) ->
   (((result7 n f i) k) = (permut_reverse_step n f (i - k)%Z))) /\
  (~ ((1%Z <= k)%Z /\ (k < i)%Z) ->
   (((result7 n f i) k) = (fun (y0:Z) => y0))).

Axiom permut_reverse_step_def :
  forall (n:Z) (f:Z -> Z) (i:Z), (mem i (to_fset 1%Z n)) ->
  (is_a_permutation (to_fset 1%Z n) f) ->
  ((i = 1%Z) -> ((permut_reverse_step n f i) = (exchange 1%Z (f 1%Z)))) /\
  (~ (i = 1%Z) ->
   ((permut_reverse_step n f i) =
    (exchange i ((comp_func (iter_comp (result7 n f i) 1%Z i) f) i)))).

Axiom permut_reverse_step_spec :
  forall (n:Z) (f:Z -> Z) (i:Z), (mem i (to_fset 1%Z n)) ->
  (is_a_permutation (to_fset 1%Z n) f) ->
  is_a_permutation (to_fset 1%Z n) (permut_reverse_step n f i).

Parameter permut_reverse_iter: Z -> (Z -> Z) -> Z -> Z -> Z.

Axiom permut_reverse_iter_def :
  forall (n:Z) (f:Z -> Z) (i:Z),
  (is_a_permutation (to_fset 1%Z (n + 1%Z)%Z) f) ->
  ((1%Z <= i)%Z /\ (i <= n)%Z) ->
  ((i = 1%Z) -> ((permut_reverse_iter n f i) = (fun (y0:Z) => y0))) /\
  (~ (i = 1%Z) ->
   ((permut_reverse_iter n f i) =
    (comp_func (permut_reverse_step (n + 1%Z)%Z f (i - 1%Z)%Z)
     (permut_reverse_iter n f (i - 1%Z)%Z)))).

Parameter fc7: Z -> (Z -> Z) -> Z -> Z -> Z -> Z.

Axiom fc_def7 :
  forall (n:Z) (f:Z -> Z) (i:Z) (k:Z),
  (((1%Z <= k)%Z /\ (k < i)%Z) ->
   (((fc7 n f i) k) = (permut_reverse_step (n + 1%Z)%Z f (i - k)%Z))) /\
  (~ ((1%Z <= k)%Z /\ (k < i)%Z) -> (((fc7 n f i) k) = (fun (y0:Z) => y0))).

Axiom permut_reverse_iter_spec :
  forall (n:Z) (f:Z -> Z) (i:Z),
  (is_a_permutation (to_fset 1%Z (n + 1%Z)%Z) f) ->
  ((1%Z <= i)%Z /\ (i <= n)%Z) ->
  (is_a_permutation (to_fset 1%Z (n + 1%Z)%Z) (permut_reverse_iter n f i)) /\
  ((is_a_permutation (to_fset 1%Z (n + 1%Z)%Z)
    (comp_func (permut_reverse_iter n f i) f)) /\
   (((permut_reverse_iter n f i) =
     (iter_comp (fun (k:Z) => (permut_reverse_step (n + 1%Z)%Z f (i - k)%Z))
      1%Z i)) /\
    (((permut_reverse_iter n f i) = (iter_comp (fc7 n f i) 1%Z i)) /\
     (((permut_reverse_step (n + 1%Z)%Z f i) =
       (exchange i ((permut_reverse_iter n f i) (f i)))) /\
      ((forall (k:Z), ((1%Z <= k)%Z /\ (k <= n)%Z) -> ~ (k = i) ->
        ~ (k = ((comp_func (permut_reverse_iter n f i) f) i)) ->
        (((permut_reverse_step (n + 1%Z)%Z f i) k) = k)) /\
       ((((permut_reverse_step (n + 1%Z)%Z f i) i) =
         ((permut_reverse_iter n f i) (f i))) /\
        ((((permut_reverse_step (n + 1%Z)%Z f i)
           ((permut_reverse_iter n f i) (f i)))
          = i) /\
         (is_a_permutation (to_fset 1%Z (n + 1%Z)%Z)
          (permut_reverse_iter n f i))))))))).

Parameter exchange_double: Z -> Z -> Z -> Z -> Z -> Z -> Z.

Axiom exchange_double_spec :
  forall (a1:Z) (a2:Z) (b1:Z) (b2:Z) (n:Z), ~ (a1 = a2) -> ~ (b1 = b2) ->
  (mem a1 (to_fset 1%Z (n + 1%Z)%Z)) -> (mem a2 (to_fset 1%Z (n + 1%Z)%Z)) ->
  (mem b1 (to_fset 1%Z (n + 1%Z)%Z)) -> (mem b2 (to_fset 1%Z (n + 1%Z)%Z)) ->
  (((exchange_double a1 a2 b1 b2 n) a1) = b1) /\
  ((((exchange_double a1 a2 b1 b2 n) a2) = b2) /\
   ((((exchange_double a1 a2 b1 b2 n) b1) = a1) /\
    ((((exchange_double a1 a2 b1 b2 n) b2) = a2) /\
     (is_a_permutation (to_fset 1%Z (n + 1%Z)%Z)
      (exchange_double a1 a2 b1 b2 n))))).

Axiom permut_reverse_iter_assoc :
  forall (n:Z) (f:Z -> Z) (i:Z), ((1%Z <= i)%Z /\ (i <= n)%Z) ->
  (is_a_permutation (to_fset 1%Z (n + 1%Z)%Z) f) ->
  ((1%Z < i)%Z ->
   ((comp_func (permut_reverse_iter n f i) f) =
    (comp_func (permut_reverse_step (n + 1%Z)%Z f (i - 1%Z)%Z)
     (comp_func (permut_reverse_iter n f (i - 1%Z)%Z) f)))) /\
  ((forall (k:Z), ((1%Z <= k)%Z /\ (k < i)%Z) ->
    (((comp_func (permut_reverse_iter n f i) f) k) = k)) /\
   forall (k:Z), ((i <= k)%Z /\ (k < n)%Z) ->
   (i <= ((comp_func (permut_reverse_iter n f i) f) k))%Z).

Axiom permut_decomp_rev :
  forall (n:Z) (f:Z -> Z), (1%Z < n)%Z ->
  (is_a_permutation (to_fset 1%Z (n + 1%Z)%Z) f) ->
  permut_reverse (to_fset 1%Z (n + 1%Z)%Z) (permut_reverse_iter n f n) f.

Axiom permut_decomp :
  forall (n:Z) (f:Z -> Z), (1%Z < n)%Z ->
  (is_a_permutation (to_fset 1%Z (n + 1%Z)%Z) f) ->
  permut_equal (to_fset 1%Z (n + 1%Z)%Z)
  (permut_reverse_iter n (reverse1 (to_fset 1%Z (n + 1%Z)%Z) f) n) f.

Axiom permut_decomp_inv :
  forall (n:Z) (f:Z -> Z), (1%Z < n)%Z ->
  (is_a_permutation (to_fset 1%Z (n + 1%Z)%Z) f) ->
  permut_equal (to_fset 1%Z (n + 1%Z)%Z) f
  (permut_reverse_iter n (reverse1 (to_fset 1%Z (n + 1%Z)%Z) f) n).

(* Why3 assumption *)
Definition swap : matrix t :=
  make_f 4%Z 4%Z (fun (i:Z) (j:Z) => (indic i ((exchange 1%Z 2%Z) j))).

Axiom swap_values :
  forall (i:Z) (j:Z), (valid_index swap i j) ->
  ((get swap i j) = (indic i ((exchange 1%Z 2%Z) j))).

Parameter odd: Z -> bool.

Axiom odd_def :
  forall (n:Z),
  (((int.EuclideanDivision.mod1 n 2%Z) = 1%Z) -> ((odd n) = true)) /\
  (~ ((int.EuclideanDivision.mod1 n 2%Z) = 1%Z) -> ((odd n) = false)).

Axiom odd_spec :
  forall (n:Z),
  (((odd n) = true) ->
   (n = ((2%Z * (int.EuclideanDivision.div n 2%Z))%Z + 1%Z)%Z)) /\
  (((odd n) = false) -> (n = (2%Z * (int.EuclideanDivision.div n 2%Z))%Z)).

Parameter even: Z -> bool.

Axiom even_def :
  forall (n:Z),
  (((int.EuclideanDivision.mod1 n 2%Z) = 0%Z) -> ((even n) = true)) /\
  (~ ((int.EuclideanDivision.mod1 n 2%Z) = 0%Z) -> ((even n) = false)).

Axiom even_spec : forall (n:Z), ((even n) = true) <-> ~ ((odd n) = true).

Axiom even_or_odd : forall (n:Z), ((even n) = true) \/ ((odd n) = true).

Parameter squarert_two: t.

Axiom squarertTwo : ((cpower squarert_two 2%Z) = (infix_pldt tone tone)).

Axiom not_null_powers_squarert_two :
  forall (i:Z), (0%Z <= i)%Z -> ~ ((cpower squarert_two i) = tzero).

Axiom coeffs :
  ((infix_sldt (prefix_mndt tone) squarert_two) =
   (prefix_mndt (infix_sldt tone squarert_two))).

Parameter mop: Z -> t.

Axiom mop_def :
  forall (i:Z), (0%Z <= i)%Z -> ((mop i) = (cpower (prefix_mndt tone) i)).

Axiom minus_one_power_values :
  forall (i:Z), (0%Z <= i)%Z ->
  (((even i) = true) -> ((mop i) = tone)) /\
  (((odd i) = true) -> ((mop i) = (prefix_mndt tone))).

Axiom factors_mop :
  forall (i:Z) (j:Z), (0%Z <= i)%Z -> (0%Z <= j)%Z ->
  ((mop (i + j)%Z) = (infix_asdt (mop i) (mop j))).

Axiom factors_mop_rev :
  forall (i:Z) (j:Z), (0%Z <= i)%Z -> (0%Z <= j)%Z ->
  ((infix_asdt (mop i) (mop j)) = (mop (i + j)%Z)).

Parameter pow_inv_sqrt_2: Z -> t.

Axiom pow_inv_sqrt_2_def :
  forall (i:Z), (0%Z <= i)%Z ->
  ((pow_inv_sqrt_2 i) = (cpower (infix_sldt tone squarert_two) i)).

Parameter neg_pow_inv_sqrt_2: Z -> t.

Axiom neg_pow_inv_sqrt_2_def :
  forall (i:Z), (0%Z <= i)%Z ->
  ((neg_pow_inv_sqrt_2 i) =
   (cpower (infix_sldt (prefix_mndt tone) squarert_two) i)).

Axiom pow_inv_sqrt_2_values :
  forall (i:Z), (0%Z <= i)%Z ->
  ((pow_inv_sqrt_2 i) = (infix_sldt tone (cpower squarert_two i))).

Axiom neg_pow_inv_sqrt_2_values :
  forall (i:Z), (0%Z <= i)%Z ->
  ((neg_pow_inv_sqrt_2 i) =
   (infix_asdt (mop i) (infix_sldt tone (cpower squarert_two i)))).

Axiom ppos_neg_coeff_values :
  forall (i:Z), (0%Z <= i)%Z ->
  (((even i) = true) -> ((pow_inv_sqrt_2 i) = (neg_pow_inv_sqrt_2 i))) /\
  ((((odd i) = true) ->
    ((pow_inv_sqrt_2 i) = (prefix_mndt (neg_pow_inv_sqrt_2 i)))) /\
   ((neg_pow_inv_sqrt_2 i) = (infix_asdt (mop i) (pow_inv_sqrt_2 i)))).

Parameter pow_inv_sqrt_2_neg: Z -> t.

Axiom pow_inv_sqrt_2_neg_def :
  forall (i:Z), (0%Z <= i)%Z ->
  ((pow_inv_sqrt_2_neg i) = (prefix_mndt (pow_inv_sqrt_2 i))).

Parameter mat_mult_no_bound: (matrix t) -> (matrix t) -> matrix t.

Axiom mat_mult_no_bound_def :
  forall (m:matrix t) (n:matrix t),
  (((columns m) = (rows n)) ->
   ((mat_mult_no_bound m n) =
    (make_f (rows m) (columns n)
     (fun (i:Z) (j:Z) =>
      (ind_sum (fun (k:Z) => (infix_asdt (get m i k) (get n k j))) 0%Z
       (columns m)))))) /\
  (~ ((columns m) = (rows n)) ->
   ((mat_mult_no_bound m n) = (make_f 1%Z 1%Z (fun (i:Z) (j:Z) => tzero)))).

Axiom mat_mult_no_bound_spec :
  forall (m:matrix t) (n:matrix t),
  (((columns m) = (rows n)) -> ((rows (mat_mult_no_bound m n)) = (rows m))) /\
  ((((columns m) = (rows n)) ->
    ((columns (mat_mult_no_bound m n)) = (columns n))) /\
   (((columns m) = (rows n)) -> forall (i:Z) (j:Z),
    (valid_index (mat_mult_no_bound m n) i j) ->
    ((get (mat_mult_no_bound m n) i j) =
     (ind_sum (fun (k:Z) => (infix_asdt (get m i k) (get n k j))) 0%Z
      (columns m))))).

Parameter mat_mult: (matrix t) -> (matrix t) -> matrix t.

Axiom mat_mult_def :
  forall (m:matrix t) (n:matrix t), ((columns m) = (rows n)) ->
  ((mat_mult m n) = (mat_mult_no_bound m n)).

Axiom mat_mult_spec :
  forall (m:matrix t) (n:matrix t), ((columns m) = (rows n)) ->
  ((rows (mat_mult m n)) = (rows m)) /\
  (((columns (mat_mult m n)) = (columns n)) /\
   forall (i:Z) (j:Z), (valid_index (mat_mult m n) i j) ->
   ((get (mat_mult m n) i j) =
    (ind_sum (fun (k:Z) => (infix_asdt (get m i k) (get n k j))) 0%Z
     (columns m)))).

Axiom mat_mult_values :
  forall (m:matrix t) (n:matrix t) (i:Z) (j:Z), ((columns m) = (rows n)) ->
  (valid_index (mat_mult m n) i j) ->
  ((get (mat_mult m n) i j) =
   (ind_sum (fun (k:Z) => (infix_asdt (get m i k) (get n k j))) 0%Z
    (columns m))).

Axiom mat_mult_columns :
  forall (m:matrix t) (n:matrix t), ((columns m) = (rows n)) ->
  ((columns (mat_mult m n)) = (columns n)).

Axiom mat_mult_rows :
  forall (m:matrix t) (n:matrix t), ((columns m) = (rows n)) ->
  ((rows (mat_mult m n)) = (rows m)).

Axiom mat_mult_values_quant :
  forall (m:matrix t) (n:matrix t), ((columns m) = (rows n)) ->
  forall (i:Z) (j:Z), (valid_index (mat_mult m n) i j) ->
  ((get (mat_mult m n) i j) =
   (ind_sum (fun (k:Z) => (infix_asdt (get m i k) (get n k j))) 0%Z
    (columns m))).

Parameter int_mat_prod: (Z -> matrix t) -> Z -> Z -> matrix t.

Axiom int_mat_prod_def :
  forall (f:Z -> matrix t) (i:Z) (j:Z), (i <= j)%Z ->
  (forall (k:Z) (k':Z),
   (((i <= k)%Z /\ (k <= j)%Z) /\ ((i <= k')%Z /\ (k' <= j)%Z)) ->
   ((rows (f k)) = (rows (f k'))) /\ ((rows (f k')) = (columns (f k')))) ->
  (((j - i)%Z = 0%Z) -> ((int_mat_prod f i j) = (f i))) /\
  (~ ((j - i)%Z = 0%Z) ->
   ((int_mat_prod f i j) =
    (mat_mult_no_bound (int_mat_prod f i (j - 1%Z)%Z) (f j)))).

Axiom int_mat_prod_spec :
  forall (f:Z -> matrix t) (i:Z) (j:Z), (i <= j)%Z ->
  (forall (k:Z) (k':Z),
   (((i <= k)%Z /\ (k <= j)%Z) /\ ((i <= k')%Z /\ (k' <= j)%Z)) ->
   ((rows (f k)) = (rows (f k'))) /\ ((rows (f k')) = (columns (f k')))) ->
  ((rows (int_mat_prod f i j)) = (rows (f i))) /\
  (((columns (int_mat_prod f i j)) = (columns (f i))) /\
   ((columns (int_mat_prod f i j)) = (rows (f i)))).

Axiom int_mat_prod_zero :
  forall (f:Z -> matrix t) (i:Z) (j:Z), ((rows (f i)) = (columns (f i))) ->
  (i = j) -> ((int_mat_prod f i j) = (f i)).

Parameter int_mat_prod_plus_one: (Z -> matrix t) -> Z -> Z -> unit.

Axiom int_mat_prod_plus_one_def :
  forall (f:Z -> matrix t) (i:Z) (j:Z), (i < j)%Z ->
  (forall (k:Z) (k':Z),
   (((i <= k)%Z /\ (k <= j)%Z) /\ ((i <= k')%Z /\ (k' <= j)%Z)) ->
   ((rows (f k)) = (rows (f k'))) /\ ((rows (f k')) = (columns (f k')))) ->
  ((int_mat_prod_plus_one f i j) = tt).

Axiom int_mat_prod_plus_one_spec :
  forall (f:Z -> matrix t) (i:Z) (j:Z), (i < j)%Z ->
  (forall (k:Z) (k':Z),
   (((i <= k)%Z /\ (k <= j)%Z) /\ ((i <= k')%Z /\ (k' <= j)%Z)) ->
   ((rows (f k)) = (rows (f k'))) /\ ((rows (f k')) = (columns (f k')))) ->
  ((int_mat_prod f i j) = (mat_mult (int_mat_prod f i (j - 1%Z)%Z) (f j))).

Axiom int_mat_prod_eq :
  forall (f:Z -> matrix t) (g:Z -> matrix t) (i:Z) (j:Z), (i <= j)%Z ->
  (forall (k:Z) (k':Z), ((i <= k)%Z /\ (k <= j)%Z) ->
   ((i <= k')%Z /\ (k' <= j)%Z) ->
   ((rows (f k)) = (rows (f k'))) /\ ((rows (f k')) = (columns (f k')))) ->
  (forall (k:Z), ((i <= k)%Z /\ (k <= j)%Z) -> ((f k) = (g k))) ->
  ((int_mat_prod f i j) = (int_mat_prod g i j)).

Parameter add_mat: (matrix t) -> (matrix t) -> matrix t.

Axiom add_mat_def :
  forall (m:matrix t) (n:matrix t), ((rows m) = (rows n)) ->
  ((columns m) = (columns n)) ->
  ((add_mat m n) =
   (make_f (rows m) (columns m)
    (fun (i:Z) (j:Z) => (infix_pldt (get m i j) (get n i j))))).

Axiom add_mat_spec :
  forall (m:matrix t) (n:matrix t), ((rows m) = (rows n)) ->
  ((columns m) = (columns n)) ->
  (((columns (add_mat m n)) = (columns m)) /\ ((columns m) = (columns n))) /\
  ((((rows (add_mat m n)) = (rows m)) /\ ((rows m) = (rows n))) /\
   forall (i:Z) (j:Z),
   ((get (add_mat m n) i j) = (infix_pldt (get m i j) (get n i j)))).

Axiom add_mat_equal :
  forall (m:matrix t) (n:matrix t) (m':matrix t) (n':matrix t),
  ((rows m) = (rows n)) -> ((columns m) = (columns n)) -> (m = m') ->
  (n = n') -> ((add_mat m n) = (add_mat m' n')).

Axiom add_value :
  forall (m:matrix t) (n:matrix t), ((columns m) = (columns n)) ->
  ((rows m) = (rows n)) -> ((columns m) = (columns n)) -> forall (i:Z) (j:Z),
  ((0%Z <= i)%Z /\ (i < (rows m))%Z) ->
  ((0%Z <= j)%Z /\ (j < (columns m))%Z) ->
  ((get (add_mat m n) i j) = (infix_pldt (get m i j) (get n i j))).

Axiom add_values :
  forall (m:matrix t) (n:matrix t) (i:Z) (j:Z),
  ((columns m) = (columns n)) -> ((rows m) = (rows n)) ->
  ((get (add_mat m n) i j) = (infix_pldt (get m i j) (get n i j))).

Axiom add_mat_null_left :
  forall (m:matrix t) (n:matrix t), ((columns m) = (columns n)) ->
  ((rows m) = (rows n)) -> (null_mat m) -> ((add_mat m n) = n).

Axiom add_mat_null_right :
  forall (m:matrix t) (n:matrix t), ((columns m) = (columns n)) ->
  ((rows m) = (rows n)) -> (null_mat n) -> ((add_mat m n) = m).

Axiom set_equal_columns_elt :
  forall (m:matrix t) (n:matrix t) (i:Z),
  (((columns m) = (columns n)) /\ ((columns n) = i)) ->
  ((columns m) = (columns n)).

Axiom set_equal_rows_elt :
  forall (m:matrix t) (n:matrix t) (i:Z),
  (((rows m) = (rows n)) /\ ((rows n) = i)) -> ((rows m) = (rows n)).

Axiom add_columns :
  forall (m:matrix t) (n:matrix t), ((columns m) = (columns n)) ->
  ((rows m) = (rows n)) -> ((columns (add_mat m n)) = (columns m)).

Axiom add_rows :
  forall (m:matrix t) (n:matrix t), ((columns m) = (columns n)) ->
  ((rows m) = (rows n)) -> ((rows (add_mat m n)) = (rows m)).

Axiom set_equal_dim_elt :
  forall (m:matrix t) (n:matrix t) (i:Z) (j:Z),
  (((rows m) = (rows n)) /\ ((rows n) = i)) ->
  (((columns m) = (columns n)) /\ ((columns n) = j)) ->
  ((columns m) = (columns n)) /\ ((rows m) = (rows n)).

Axiom set_dim_add :
  forall (m:matrix t) (n:matrix t) (i:Z) (j:Z),
  (((rows m) = (rows n)) /\ ((rows n) = i)) ->
  (((columns m) = (columns n)) /\ ((columns n) = j)) ->
  ((rows (add_mat m n)) = i) /\ ((columns (add_mat m n)) = j).

Axiom add_mat_eq :
  forall (m:matrix t) (m1:matrix t) (n:matrix t) (n1:matrix t),
  ((rows m) = (rows n)) -> ((columns m) = (columns n)) -> (m = m1) ->
  (n = n1) -> ((add_mat m n) = (add_mat m1 n1)).

Axiom add_mat_comm :
  forall (m:matrix t) (n:matrix t), ((rows m) = (rows n)) ->
  ((columns m) = (columns n)) -> ((add_mat m n) = (add_mat n m)).

Parameter add_neutral: unit -> matrix t.

Axiom add_neutral_spec :
  forall (us:unit),
  (forall (i:Z) (j:Z), (valid_index (add_neutral us) i j) ->
   ((get (add_neutral us) i j) = tzero)) /\
  ((0%Z < (rows (add_neutral us)))%Z /\ (0%Z < (columns (add_neutral us)))%Z).

Axiom distr_1_pre :
  forall (m:matrix t) (n:matrix t) (o:matrix t) (i:Z) (j:Z),
  ((rows m) = (rows n)) -> ((columns m) = (columns n)) ->
  ((columns m) = (rows o)) -> ((0%Z <= i)%Z /\ (i < (rows m))%Z) ->
  ((0%Z <= j)%Z /\ (j < (columns o))%Z) ->
  ((get (mat_mult (add_mat m n) o) i j) =
   (get (add_mat (mat_mult m o) (mat_mult n o)) i j)).

Axiom distr_l :
  forall (m:matrix t) (n:matrix t) (o:matrix t), ((rows m) = (rows n)) ->
  ((columns m) = (columns n)) -> ((columns m) = (rows o)) ->
  ((mat_mult (add_mat m n) o) = (add_mat (mat_mult m o) (mat_mult n o))).

Axiom distr_2_pre :
  forall (m:matrix t) (n:matrix t) (o:matrix t) (i:Z) (j:Z),
  ((rows n) = (rows o)) -> ((columns n) = (columns o)) ->
  ((columns m) = (rows n)) -> ((0%Z <= i)%Z /\ (i < (rows m))%Z) ->
  ((0%Z <= j)%Z /\ (j < (columns n))%Z) ->
  (valid_index (mat_mult m (add_mat n o)) i j) /\
  ((get (mat_mult m (add_mat n o)) i j) =
   (get (add_mat (mat_mult m n) (mat_mult m o)) i j)).

Axiom distr_r :
  forall (m:matrix t) (n:matrix t) (o:matrix t), ((rows n) = (rows o)) ->
  ((columns n) = (columns o)) -> ((columns m) = (rows n)) ->
  ((mat_mult m (add_mat n o)) = (add_mat (mat_mult m n) (mat_mult m o))).

(* Why3 assumption *)
Definition infix_asdtdt (s:t) (m:matrix t) : matrix t :=
  make_f (rows m) (columns m) (fun (i:Z) (j:Z) => (infix_asdt s (get m i j))).

Axiom infix_asdtdt_spec :
  forall (s:t) (m:matrix t),
  ((columns (infix_asdtdt s m)) = (columns m)) /\
  (((rows (infix_asdtdt s m)) = (rows m)) /\
   ((forall (i:Z) (j:Z), (valid_index (infix_asdtdt s m) i j) ->
     ((get (infix_asdtdt s m) i j) = (infix_asdt s (get m i j)))) /\
    forall (i:Z) (j:Z),
    (valid_index (infix_asdtdt s m) i j) <-> (valid_index m i j))).

Axiom scalar_columns :
  forall (m:matrix t) (a:t), ((columns (infix_asdtdt a m)) = (columns m)).

Axiom scalar_values :
  forall (m:matrix t) (a:t) (i:Z) (j:Z),
  ((get (infix_asdtdt a m) i j) = (infix_asdt a (get m i j))).

Axiom scalar_rows :
  forall (m:matrix t) (a:t), ((rows (infix_asdtdt a m)) = (rows m)).

Axiom scalar_null : forall (m:matrix t), null_mat (infix_asdtdt tzero m).

Axiom scalar_tone : forall (m:matrix t), ((infix_asdtdt tone m) = m).

Axiom scalar_tone_gen :
  forall (m:matrix t) (a:t), (a = tone) -> ((infix_asdtdt a m) = m).

Axiom scalar_null_gen :
  forall (m:matrix t) (a:t), (a = tzero) -> null_mat (infix_asdtdt a m).

Axiom scalar_plus :
  forall (m:matrix t) (a:t) (b:t),
  ((infix_asdtdt (infix_pldt a b) m) =
   (add_mat (infix_asdtdt a m) (infix_asdtdt b m))).

Axiom scalar_plus_rev :
  forall (m:matrix t) (a:t) (b:t),
  ((add_mat (infix_asdtdt a m) (infix_asdtdt b m)) =
   (infix_asdtdt (infix_pldt a b) m)).

Axiom add_scal :
  forall (m:matrix t) (n:matrix t) (a:t), ((rows m) = (rows n)) ->
  ((columns m) = (columns n)) ->
  ((infix_asdtdt a (add_mat m n)) =
   (add_mat (infix_asdtdt a m) (infix_asdtdt a n))).

Axiom mat_mult_scal_values_l :
  forall (m:matrix t) (n:matrix t) (a:t) (i:Z) (j:Z),
  ((rows n) = (columns m)) -> ((0%Z <= i)%Z /\ (i < (rows m))%Z) ->
  ((0%Z <= j)%Z /\ (j < (columns n))%Z) ->
  ((infix_asdt a (get (mat_mult m n) i j)) =
   (ind_sum
    (fun (k:Z) => (infix_asdt (infix_asdt a (get m i k)) (get n k j))) 0%Z
    (columns m))).

Axiom mat_mult_scal_values_r :
  forall (m:matrix t) (n:matrix t) (a:t) (i:Z) (j:Z),
  ((rows n) = (columns m)) -> ((rows m) = (columns n)) ->
  ((columns m) = (columns n)) -> ((0%Z <= i)%Z /\ (i < (rows m))%Z) ->
  ((0%Z <= j)%Z /\ (j < (columns n))%Z) ->
  ((infix_asdt (get (mat_mult m n) i j) a) =
   (ind_sum
    (fun (k:Z) => (infix_asdt (infix_asdt a (get m i k)) (get n k j))) 0%Z
    (columns m))).

Axiom mat_mut_scal :
  forall (m:matrix t) (n:matrix t) (a:t), ((rows n) = (columns m)) ->
  ((mat_mult m (infix_asdtdt a n)) = (infix_asdtdt a (mat_mult m n))).

Axiom scal_mat_mut :
  forall (m:matrix t) (n:matrix t) (a:t), ((rows n) = (columns m)) ->
  ((mat_mult (infix_asdtdt a m) n) = (infix_asdtdt a (mat_mult m n))).

Axiom ind_sum_commute_scal_r :
  forall (f:Z -> Z -> t) (g:Z -> t) (i:Z) (j:Z) (k:Z) (l:Z), (i <= j)%Z ->
  (k <= l)%Z ->
  ((ind_sum (fun (k1:Z) => (infix_asdt (ind_sum (f k1) k l) (g k1))) i j) =
   (ind_sum
    (fun (k1:Z) =>
     (ind_sum (fun (k2:Z) => (infix_asdt ((f k2) k1) (g k2))) i j))
    k l)).

Axiom mat_mult_assoc_pre :
  forall (m:matrix t) (n:matrix t) (o:matrix t) (i:Z) (j:Z),
  ((columns m) = (rows n)) -> ((columns n) = (rows o)) ->
  ((0%Z <= i)%Z /\ (i < (rows m))%Z) ->
  ((0%Z <= j)%Z /\ (j < (columns o))%Z) ->
  ((get (mat_mult (mat_mult m n) o) i j) =
   (get (mat_mult m (mat_mult n o)) i j)).

Axiom mat_mult_assoc :
  forall (m:matrix t) (n:matrix t) (o:matrix t), ((columns m) = (rows n)) ->
  ((columns n) = (rows o)) ->
  ((mat_mult (mat_mult m n) o) = (mat_mult m (mat_mult n o))).

Axiom mat_mult_assoc_quant :
  forall (m:matrix t) (n:matrix t), ((columns m) = (rows n)) ->
  forall (o:matrix t), ((columns n) = (rows o)) ->
  ((mat_mult (mat_mult m n) o) = (mat_mult m (mat_mult n o))).

Axiom mat_mult_assoc_comm :
  forall (m:matrix t) (n:matrix t) (o:matrix t), ((columns m) = (rows n)) ->
  ((columns n) = (rows o)) ->
  ((mat_mult m (mat_mult n o)) = (mat_mult (mat_mult m n) o)).

Axiom scalar_eq :
  forall (m:matrix t) (n:matrix t) (a:t), (m = n) ->
  ((infix_asdtdt a m) = (infix_asdtdt a n)).

Axiom scalar_eq_gen :
  forall (m:matrix t) (n:matrix t) (a:t) (b:t), (m = n) -> (a = b) ->
  ((infix_asdtdt a m) = (infix_asdtdt b n)).

Axiom scalar_add :
  forall (m:matrix t) (a:t) (b:t),
  ((infix_asdtdt (infix_pldt a b) m) =
   (add_mat (infix_asdtdt a m) (infix_asdtdt b m))).

Axiom scalar_assoc :
  forall (m:matrix t) (a:t) (b:t),
  ((infix_asdtdt a (infix_asdtdt b m)) = (infix_asdtdt (infix_asdt a b) m)).

(* Why3 assumption *)
Definition constant_size {a:Type} {a_WT:WhyType a} (s:set a)
    (f:a -> matrix t) : Prop :=
  forall (e:a), (mem e s) ->
  ((rows (f e)) = (rows (f (choose s)))) /\
  ((columns (f e)) = (columns (f (choose s)))).

Axiom set_constant_size :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t),
  (forall (e:a) (e':a), (mem e s) -> (mem e' s) ->
   ((rows (f e)) = (rows (f e')))) ->
  (forall (e:a) (e':a), (mem e s) -> (mem e' s) ->
   ((columns (f e)) = (columns (f e')))) ->
  constant_size s f.

Axiom set_constant_size_t :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (r:Z) (c:Z),
  (forall (e:a), (mem e s) -> ((rows (f e)) = r)) ->
  (forall (e:a), (mem e s) -> ((columns (f e)) = c)) -> constant_size s f.

Parameter fc8:
  forall {a:Type} {a_WT:WhyType a}, (a -> matrix t) -> (a -> bool) ->
  (matrix t) -> a -> matrix t.

Axiom fc_def8 :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> matrix t) (p:a -> bool) (m:matrix t) (j:a),
  (((p j) = true) -> (((fc8 f p m) j) = (f j))) /\
  (~ ((p j) = true) -> (((fc8 f p m) j) = m)).

Axiom guarded_set_constant_size :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (p:a -> bool) (m:matrix t),
  (constant_size s f) -> (forall (e:a), (mem e s) -> ((p e) = true)) ->
  constant_size s (fc8 f p m).

Axiom set_constant_size_set :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> t) (m:matrix t) (i:Z) (j:Z),
  (valid_index m i j) -> constant_size s (fun (e:a) => (set1 m i j (f e))).

Axiom get_constant_size :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t), (constant_size s f) ->
  (forall (e:a) (e':a), (mem e s) -> (mem e' s) ->
   ((rows (f e)) = (rows (f e')))) /\
  forall (e:a) (e':a), (mem e s) -> (mem e' s) ->
  ((columns (f e)) = (columns (f e'))).

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

Axiom s_rows_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t), (constant_size s f) ->
  ((s_rows s f) = (rows (f (choose s)))).

Axiom s_rows_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t), (constant_size s f) ->
  (0%Z < (s_rows s f))%Z /\
  ((forall (e:a), (mem e s) -> ((rows (f e)) = (s_rows s f))) /\
   forall (e:a) (e':a), (mem e s) -> (mem e' s) ->
   ((rows (f e)) = (rows (f e')))).

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

Axiom s_columns_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t), (constant_size s f) ->
  ((s_columns s f) = (columns (f (choose s)))).

Axiom s_columns_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t), (constant_size s f) ->
  (0%Z < (s_columns s f))%Z /\
  ((forall (e:a), (mem e s) -> ((columns (f e)) = (s_columns s f))) /\
   forall (e:a) (e':a), (mem e s) -> (mem e' s) ->
   ((columns (f e)) = (columns (f e')))).

Axiom set_s_rows :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (r:Z), (constant_size s f) ->
  ((rows (f (choose s))) = r) -> ((s_rows s f) = r).

Axiom set_s_rows_elt :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (elt:a), (constant_size s f) ->
  (mem elt s) -> ((s_rows s f) = (rows (f elt))).

Axiom set_s_columns :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (r:Z), (constant_size s f) ->
  ((columns (f (choose s))) = r) -> ((s_columns s f) = r).

Axiom set_s_columns_elt :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (elt:a), (constant_size s f) ->
  (mem elt s) -> ((s_columns s f) = (columns (f elt))).

Axiom s_rows_eq :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (g:a -> matrix t),
  (constant_size s f) -> (0%Z < (cardinal s))%Z ->
  (forall (e:a), (mem e s) -> ((f e) = (g e))) ->
  ((s_rows s f) = (s_rows s g)).

Axiom s_columns_eq :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (g:a -> matrix t),
  (constant_size s f) -> (0%Z < (cardinal s))%Z ->
  (forall (e:a), (mem e s) -> ((f e) = (g e))) ->
  ((s_columns s f) = (s_columns s g)).

Axiom subset_constant_size :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a) (f:a -> matrix t), (constant_size s f) ->
  ~ (is_empty s') -> (subset s' s) ->
  (constant_size s' f) /\
  (((s_rows s' f) = (s_rows s f)) /\ ((s_columns s' f) = (s_columns s f))).

Axiom set_s_rows_rem :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t), (1%Z < (cardinal s))%Z ->
  (constant_size s f) ->
  (constant_size (remove (choose s) s) f) /\
  ((s_rows (remove (choose s) s) f) = (rows (f (choose s)))).

Axiom set_s_columns_rem :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t), (1%Z < (cardinal s))%Z ->
  (constant_size s f) ->
  (constant_size (remove (choose s) s) f) /\
  ((s_columns (remove (choose s) s) f) = (columns (f (choose s)))).

Axiom set_s_rows_add :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (x:a), (0%Z < (cardinal s))%Z ->
  (constant_size s f) -> ((columns (f x)) = (s_columns s f)) ->
  ((rows (f x)) = (s_rows s f)) -> ((s_rows (add x s) f) = (s_rows s f)).

Axiom set_s_columns_add :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (x:a), (0%Z < (cardinal s))%Z ->
  (constant_size s f) -> ((columns (f x)) = (s_columns s f)) ->
  ((rows (f x)) = (s_rows s f)) ->
  ((s_columns (add x s) f) = (s_columns s f)).

Axiom set_s_rows_columns_add :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (x:a), (0%Z < (cardinal s))%Z ->
  (constant_size s f) -> ((columns (f x)) = (s_columns s f)) ->
  ((rows (f x)) = (s_rows s f)) ->
  ((s_columns (add x s) f) = (s_columns s f)) /\
  ((s_rows (add x s) f) = (s_rows s f)).

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

Axiom mat_sum_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t), (constant_size s f) ->
  (0%Z < (cardinal s))%Z ->
  (((cardinal s) = 1%Z) -> ((mat_sum s f) = (f (element s)))) /\
  (~ ((cardinal s) = 1%Z) ->
   ((mat_sum s f) =
    (add_mat (f (choose s)) (mat_sum (remove (choose s) s) f)))).

Axiom mat_sum_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t), (constant_size s f) ->
  (0%Z < (cardinal s))%Z ->
  ((rows (mat_sum s f)) = (s_rows s f)) /\
  (((columns (mat_sum s f)) = (s_columns s f)) /\
   ((forall (e:a), (mem e s) -> ((rows (f e)) = (s_rows s f))) /\
    forall (e:a), (mem e s) -> ((columns (f e)) = (s_columns s f)))).

Axiom columns_mat_sum :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (n:Z), ~ ((cardinal s) = 0%Z) ->
  (constant_size s f) ->
  (forall (e:a), (mem e s) -> ((columns (f e)) = n)) ->
  ((columns (mat_sum s f)) = n).

Axiom rows_mat_sum :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (n:Z), ~ ((cardinal s) = 0%Z) ->
  (constant_size s f) -> (forall (e:a), (mem e s) -> ((rows (f e)) = n)) ->
  ((rows (mat_sum s f)) = n).

Axiom mat_sum_cardone :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t), ((cardinal s) = 1%Z) ->
  ((mat_sum s f) = (f (element s))).

Axiom mat_sum_to_sum_pre :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (i:Z) (j:Z), (constant_size s f) ->
  (0%Z < (cardinal s))%Z -> ((0%Z <= i)%Z /\ (i < (s_rows s f))%Z) ->
  ((0%Z <= j)%Z /\ (j < (s_columns s f))%Z) ->
  ((get (mat_sum s f) i j) = (sum s (fun (e:a) => (get (f e) i j)))).

Axiom mat_sum_to_sum :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t), (constant_size s f) ->
  (0%Z < (cardinal s))%Z ->
  ((mat_sum s f) =
   (make_f (s_rows s f) (s_columns s f)
    (fun (i:Z) (j:Z) => (sum s (fun (e:a) => (get (f e) i j)))))).

Axiom mat_sum_add :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (x:a), (0%Z < (cardinal s))%Z ->
  (constant_size s f) -> ((rows (f x)) = (s_rows s f)) ->
  ((columns (f x)) = (s_columns s f)) -> ~ (mem x s) ->
  ((mat_sum (add x s) f) = (add_mat (f x) (mat_sum s f))).

Axiom mat_sum_comp_pre :
  forall {b:Type} {b_WT:WhyType b},
  forall (s:set b) (f:b -> matrix t) (g:b -> matrix t) (i:Z) (j:Z),
  (constant_size s f) -> (constant_size s g) ->
  ((0%Z <= i)%Z /\ (i < (s_rows s f))%Z) ->
  ((0%Z <= j)%Z /\ (j < (s_columns s f))%Z) ->
  ((s_rows s f) = (s_rows s g)) -> ((s_columns s f) = (s_columns s g)) ->
  (0%Z < (cardinal s))%Z ->
  ((get (mat_sum s (fun (k:b) => (add_mat (f k) (g k)))) i j) =
   (get (add_mat (mat_sum s f) (mat_sum s g)) i j)).

Axiom mat_sum_comp :
  forall {b:Type} {b_WT:WhyType b},
  forall (s:set b) (f:b -> matrix t) (g:b -> matrix t),
  (constant_size s f) -> (constant_size s g) ->
  ((s_rows s f) = (s_rows s g)) -> ((s_columns s f) = (s_columns s g)) ->
  (0%Z < (cardinal s))%Z ->
  ((mat_sum s (fun (k:b) => (add_mat (f k) (g k)))) =
   (add_mat (mat_sum s f) (mat_sum s g))).

Axiom mat_sum_comp_rec :
  forall {b:Type} {b_WT:WhyType b},
  forall (s:set b) (f:b -> matrix t) (g:b -> matrix t),
  (constant_size s f) -> (constant_size s g) ->
  ((s_rows s f) = (s_rows s g)) -> ((s_columns s f) = (s_columns s g)) ->
  (0%Z < (cardinal s))%Z ->
  ((add_mat (mat_sum s f) (mat_sum s g)) =
   (mat_sum s (fun (k:b) => (add_mat (f k) (g k))))).

Axiom mat_sum_to_sum_fun :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (s':set b) (f:a -> b -> matrix t) (r:Z) (c:Z) (i:Z) (j:Z),
  (0%Z < (cardinal s))%Z -> (0%Z < (cardinal s'))%Z ->
  (forall (e:a), forall (e1:b), (mem e s) -> (mem e1 s') ->
   ((rows ((f e) e1)) = r)) ->
  (forall (e:a), forall (e1:b), (mem e s) -> (mem e1 s') ->
   ((columns ((f e) e1)) = c)) ->
  ((0%Z <= i)%Z /\ (i < r)%Z) -> ((0%Z <= j)%Z /\ (j < c)%Z) ->
  ((sum s (fun (e:a) => (get (mat_sum s' (f e)) i j))) =
   (sum s (fun (e:a) => (sum s' (fun (e1:b) => (get ((f e) e1) i j)))))).

Axiom mat_sum_to_sum_double_pre :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (s':set b) (f:a -> b -> matrix t) (r:Z) (c:Z) (i:Z) (j:Z),
  (forall (e:a) (e':b), (mem e s) -> (mem e' s') -> ((rows ((f e) e')) = r)) ->
  (forall (e:a) (e':b), (mem e s) -> (mem e' s') ->
   ((columns ((f e) e')) = c)) ->
  ((0%Z <= i)%Z /\ (i < r)%Z) -> ((0%Z <= j)%Z /\ (j < c)%Z) ->
  (0%Z < (cardinal s))%Z -> (0%Z < (cardinal s'))%Z ->
  ((get (mat_sum s (fun (e:a) => (mat_sum s' (f e)))) i j) =
   (sum s (fun (e:a) => (sum s' (fun (e':b) => (get ((f e) e') i j)))))).

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

Axiom mat_sum_dim_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (r:Z) (c:Z), (0%Z < r)%Z ->
  (0%Z < c)%Z -> (forall (e:a), (mem e s) -> ((rows (f e)) = r)) ->
  (forall (e:a), (mem e s) -> ((columns (f e)) = c)) ->
  (((cardinal s) = 0%Z) -> ((mat_sum_dim s f r c) = (make r c tzero))) /\
  (~ ((cardinal s) = 0%Z) -> ((mat_sum_dim s f r c) = (mat_sum s f))).

Axiom mat_sum_dim_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (r:Z) (c:Z), (0%Z < r)%Z ->
  (0%Z < c)%Z -> (forall (e:a), (mem e s) -> ((rows (f e)) = r)) ->
  (forall (e:a), (mem e s) -> ((columns (f e)) = c)) ->
  ((0%Z < (cardinal s))%Z -> ((mat_sum_dim s f r c) = (mat_sum s f))) /\
  ((((cardinal s) = 0%Z) -> ((mat_sum_dim s f r c) = (make r c tzero))) /\
   (((rows (mat_sum_dim s f r c)) = r) /\
    ((columns (mat_sum_dim s f r c)) = c))).

Axiom mat_sum_dim_to_mat_sum :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (r:Z) (c:Z), (0%Z < (cardinal s))%Z ->
  (0%Z < r)%Z -> (0%Z < c)%Z ->
  (forall (e:a), (mem e s) -> ((rows (f e)) = r)) ->
  (forall (e:a), (mem e s) -> ((columns (f e)) = c)) ->
  ((mat_sum_dim s f r c) = (mat_sum s f)).

Axiom mat_sum_dim_to_make_zero :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (r:Z) (c:Z), ((cardinal s) = 0%Z) ->
  (forall (e:a), (mem e s) -> ((rows (f e)) = r)) ->
  (forall (e:a), (mem e s) -> ((columns (f e)) = c)) -> (0%Z < r)%Z ->
  (0%Z < c)%Z -> ((mat_sum_dim s f r c) = (make r c tzero)).

Axiom mat_sum_dim_add :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (x:a) (r:Z) (c:Z),
  (0%Z <= (cardinal s))%Z -> ~ (mem x s) ->
  (forall (e:a), (mem e (add x s)) -> ((rows (f e)) = r)) ->
  (forall (e:a), (mem e (add x s)) -> ((columns (f e)) = c)) ->
  (0%Z < r)%Z -> (0%Z < c)%Z ->
  ((mat_sum_dim (add x s) f r c) = (add_mat (f x) (mat_sum_dim s f r c))).

Axiom mat_sum_scalar :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (a1:t), (constant_size s f) ->
  (0%Z < (cardinal s))%Z ->
  ((mat_sum s (fun (k:a) => (infix_asdtdt a1 (f k)))) =
   (infix_asdtdt a1 (mat_sum s f))).

Axiom mat_sum_scalar_rev :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (a1:t), (constant_size s f) ->
  (0%Z < (cardinal s))%Z ->
  ((infix_asdtdt a1 (mat_sum s f)) =
   (mat_sum s (fun (k:a) => (infix_asdtdt a1 (f k))))).

Axiom mat_sum_scalar_right :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (m:matrix t) (i:Z) (j:Z),
  (constant_size s f) -> (0%Z < (cardinal s))%Z ->
  ((0%Z <= i)%Z /\ (i < (s_rows s f))%Z) ->
  ((0%Z <= j)%Z /\ (j < (s_columns s f))%Z) ->
  ((infix_asdtdt (get (mat_sum s f) i j) m) =
   (mat_sum s (fun (k:a) => (infix_asdtdt (get (f k) i j) m)))).

Axiom mat_sum_eq :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (g:a -> matrix t),
  (0%Z < (cardinal s))%Z -> (constant_size s f) ->
  (forall (a1:a), (mem a1 s) -> ((f a1) = (g a1))) ->
  ((mat_sum s f) = (mat_sum s g)).

Axiom mat_sum_eq_gen :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s':set a) (f:a -> matrix t) (g:a -> matrix t),
  (0%Z < (cardinal s))%Z -> (s = s') -> (constant_size s f) ->
  (forall (a1:a), (mem a1 s) -> ((f a1) = (g a1))) ->
  ((mat_sum s f) = (mat_sum s g)).

Axiom mat_sum_eq_gen_int :
  forall (i1:Z) (i2:Z) (o1:Z) (o2:Z) (f:Z -> matrix t) (g:Z -> matrix t),
  (i1 < o1)%Z -> (i1 = o1) -> (i2 = o2) ->
  (constant_size (to_fset i1 o1) f) ->
  (forall (a:Z), (mem a (to_fset i1 o1)) -> ((f a) = (g a))) ->
  ((mat_sum (to_fset i1 o1) f) = (mat_sum (to_fset i2 o2) g)).

Axiom mat_sum_comp_eq :
  forall {b:Type} {b_WT:WhyType b},
  forall (s:set b) (f:b -> matrix t) (g:b -> matrix t) (h:b -> matrix t),
  (constant_size s f) -> (constant_size s g) -> (constant_size s h) ->
  (((s_rows s f) = (s_rows s g)) /\ ((s_rows s g) = (s_rows s h))) ->
  (((s_columns s f) = (s_columns s g)) /\
   ((s_columns s g) = (s_columns s h))) ->
  (0%Z < (cardinal s))%Z ->
  (forall (e:b), forall (i:Z) (j:Z), (mem e s) ->
   ((0%Z <= i)%Z /\ (i < (s_rows s f))%Z) ->
   ((0%Z <= j)%Z /\ (j < (s_columns s f))%Z) ->
   ((infix_pldt (get (f e) i j) (get (g e) i j)) = (get (h e) i j))) ->
  ((add_mat (mat_sum s f) (mat_sum s g)) = (mat_sum s h)).

Axiom mat_sum_dim_eq :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (f:a -> matrix t) (g:a -> matrix t) (r:Z) (c:Z),
  (0%Z < r)%Z -> (0%Z < c)%Z ->
  (forall (e:a), (mem e s) -> ((rows (f e)) = r)) ->
  (forall (e:a), (mem e s) -> ((columns (f e)) = c)) ->
  (forall (e:a), (mem e s) -> ((f e) = (g e))) ->
  ((mat_sum_dim s f r c) = (mat_sum_dim s g r c)).

Axiom constant_size_map :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:b -> matrix t) (s:set a) (t1:a -> b),
  (constant_size s (fun (a1:a) => (f (t1 a1)))) -> constant_size (map t1 s) f.

Axiom map_mat_sum :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:b -> matrix t) (s:set a) (t1:a -> b), (0%Z < (cardinal s))%Z ->
  (constant_size s (fun (a1:a) => (f (t1 a1)))) -> (p_injective t1 s) ->
  ((mat_sum (map t1 s) f) = (mat_sum s (fun (a1:a) => (f (t1 a1))))).

Axiom map_mat_sum_rec :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (f:b -> matrix t) (s:set a) (t1:a -> b), (0%Z < (cardinal s))%Z ->
  (constant_size s (fun (a1:a) => (f (t1 a1)))) -> (p_injective t1 s) ->
  ((mat_sum s (fun (a1:a) => (f (t1 a1)))) = (mat_sum (map t1 s) f)).

Axiom mat_sum_id :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> matrix t) (s:set a), (0%Z < (cardinal s))%Z ->
  (constant_size s f) ->
  (constant_size (map f s) (fun (y0:matrix t) => y0)) -> (p_injective f s) ->
  ((mat_sum (map f s) (fun (y0:matrix t) => y0)) = (mat_sum s f)).

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

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

Axiom result_def8 :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> matrix t) (s:set a) (e:a),
  (((result8 f s) e) = true) <->
  ~ (equal (f e) (make (s_rows s f) (s_columns s f) tzero)).

Axiom nonn_mat_subset_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> matrix t) (s:set a), (constant_size s f) ->
  ((nonn_mat_subset f s) = (filter (result8 f s) s)).

Axiom nonn_mat_subset_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> matrix t) (s:set a), (constant_size s f) ->
  (subset (nonn_mat_subset f s) s) /\
  ((forall (e:a), (mem e (nonn_mat_subset f s)) -> mem e s) /\
   ((constant_size (nonn_mat_subset f s) f) /\
    ((~ ((nonn_mat_subset f s) = (empty : set a)) ->
      ((s_rows (nonn_mat_subset f s) f) = (s_rows s f))) /\
     (~ ((nonn_mat_subset f s) = (empty : set a)) ->
      ((s_columns (nonn_mat_subset f s) f) = (s_columns s f)))))).

Axiom mat_subset_elt :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> matrix t) (s:set a), (constant_size s f) -> forall (e:a),
  (mem e (nonn_mat_subset f s)) -> mem e s.

Axiom mat_subset_nonn_elt :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> matrix t) (s:set a), (constant_size s f) -> forall (e:a),
  (mem e (nonn_mat_subset f s)) ->
  ~ ((f e) = (make (s_rows s f) (s_columns s f) tzero)).

Axiom nonn_mat_sum_cardzero :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> matrix t) (s:set a) (r:Z) (c:Z), ((cardinal s) = 0%Z) ->
  (0%Z < r)%Z -> (0%Z < c)%Z ->
  ((mat_sum_dim s f r c) = (mat_sum_dim (nonn_mat_subset f s) f r c)).

Axiom nonn_mat_sum_cardone :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> matrix t) (s:set a) (r:Z) (c:Z), ((cardinal s) = 1%Z) ->
  (0%Z < r)%Z -> (0%Z < c)%Z -> ((rows (f (choose s))) = r) ->
  ((columns (f (choose s))) = c) ->
  ((mat_sum_dim s f r c) = (mat_sum_dim (nonn_mat_subset f s) f r c)).

Axiom mat_sum_null_but_maybe_one_elt :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> matrix t) (s:set a) (e:a), (1%Z < (cardinal s))%Z ->
  (constant_size s f) -> (mem e s) ->
  (forall (e':a), (mem e' s) -> ~ (e = e') -> null_mat (f e')) ->
  ((mat_sum s f) = (f e)).

Axiom nonn_mat_sum_plus_one :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> matrix t) (s:set a) (r:Z) (c:Z), (1%Z < (cardinal s))%Z ->
  (0%Z < r)%Z -> (0%Z < c)%Z ->
  (forall (e:a), (mem e s) -> ((rows (f e)) = r)) ->
  (forall (e:a), (mem e s) -> ((columns (f e)) = c)) ->
  ((mat_sum_dim (remove (choose s) s) f r c) =
   (mat_sum_dim (nonn_mat_subset f (remove (choose s) s)) f r c)) ->
  ((mat_sum_dim s f r c) = (mat_sum_dim (nonn_mat_subset f s) f r c)).

Axiom nonn_mat_sum :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:a -> matrix t) (s:set a) (r:Z) (c:Z), (0%Z < r)%Z ->
  (0%Z < c)%Z -> (forall (e:a), (mem e s) -> ((rows (f e)) = r)) ->
  (forall (e:a), (mem e s) -> ((columns (f e)) = c)) ->
  ((mat_sum_dim s f r c) = (mat_sum_dim (nonn_mat_subset f s) f r c)).

Axiom mat_sum_map_map :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}
    {c:Type} {c_WT:WhyType c},
  forall (s1:set a) (s2:set b) (t1:a -> c) (t2:b -> c) (f:c -> matrix t),
  (0%Z < (cardinal s1))%Z -> (p_injective t1 s1) ->
  (constant_size s1 (fun (a1:a) => (f (t1 a1)))) ->
  (0%Z < (cardinal s2))%Z -> (p_injective t2 s2) ->
  (constant_size s2 (fun (a1:b) => (f (t2 a1)))) ->
  ((map t1 s1) = (map t2 s2)) ->
  ((mat_sum (map t1 s1) f) = (mat_sum (map t2 s2) f)).

Axiom mat_sum_disjoint_transitivity :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s1:set a) (s2:set a) (f:a -> matrix t),
  (constant_size s f) -> ((inter s1 s2) = (empty : set a)) ->
  ((union s1 s2) = s) -> (0%Z < (cardinal s1))%Z ->
  (0%Z < (cardinal s2))%Z ->
  ((add_mat (mat_sum s1 f) (mat_sum s2 f)) = (mat_sum s f)).

Axiom map_add_mat_sum_t :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (s':set b) (f:b -> matrix t) (injz:a -> b) (injo:a -> b),
  (constant_size s' f) -> (0%Z < (cardinal s))%Z ->
  ((inter (map injz s) (map injo s)) = (empty : set b)) ->
  ((union (map injz s) (map injo s)) = s') -> (p_injective injo s) ->
  (p_injective injz s) ->
  ((mat_sum s (fun (e:a) => (add_mat (f (injz e)) (f (injo e))))) =
   (mat_sum s' f)).

Axiom map_add_mat_sum :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (s1:set a) (s2:set a) (s':set a) (f:a -> matrix t)
    (g:a -> matrix t) (h:a -> matrix t),
  (constant_size s' h) -> (constant_size s f) -> (constant_size s g) ->
  (((s_rows s' h) = (s_rows s f)) /\ ((s_rows s f) = (s_rows s g))) ->
  (((s_columns s' h) = (s_columns s f)) /\
   ((s_columns s f) = (s_columns s g))) ->
  (0%Z < (cardinal s))%Z -> (p_injective f s) -> (p_injective g s) ->
  (p_injective h s') -> ((map f s) = (map h s1)) ->
  ((map g s) = (map h s2)) -> ((inter s1 s2) = (empty : set a)) ->
  ((union s1 s2) = s') ->
  ((mat_sum s (fun (e:a) => (add_mat (f e) (g e)))) =
   (mat_sum s' (fun (e:a) => (h e)))).

Axiom bitvec : Type.
Parameter bitvec_WhyType : WhyType bitvec.
Existing Instance bitvec_WhyType.

Parameter value: bitvec -> Z -> Z.

Parameter length: bitvec -> Z.

Axiom bitvec'invariant :
  forall (self:bitvec),
  (0%Z <= (length self))%Z /\
  ((forall (i:Z), ((1%Z <= i)%Z /\ (i <= (length self))%Z) ->
    (0%Z <= ((value self) i))%Z /\ (((value self) i) < 2%Z)%Z) /\
   forall (i:Z), ~ ((1%Z <= i)%Z /\ (i <= (length self))%Z) ->
   (((value self) i) = 0%Z)).

(* Why3 assumption *)
Definition bvlength (f:Z -> Z) (i:Z) : Prop := is_binary f 1%Z (i + 1%Z)%Z.

Axiom binary_mult :
  forall (a:Z) (b:Z),
  ((int.EuclideanDivision.mod1 (a * b)%Z 2%Z) =
   ((int.EuclideanDivision.mod1 a 2%Z) *
    (int.EuclideanDivision.mod1 b 2%Z))%Z).

Parameter getbv: bitvec -> Z -> Z.

Axiom getbv_spec :
  forall (a:bitvec) (i:Z),
  (((1%Z <= i)%Z /\ (i <= (length a))%Z) ->
   (0%Z <= (getbv a i))%Z /\ ((getbv a i) < 2%Z)%Z) /\
  ((getbv a i) = ((value a) i)).

Axiom getbv_bound :
  forall (bv:bitvec) (i:Z), (0%Z <= (getbv bv i))%Z /\ ((getbv bv i) < 2%Z)%Z.

Axiom getbv_eq :
  forall (bvx:bitvec) (bvy:bitvec) (i:Z), (bvx = bvy) ->
  ((getbv bvx i) = (getbv bvy i)).

Axiom getbv_eq_gen :
  forall (bvx:bitvec) (bvy:bitvec) (i:Z) (j:Z), (bvx = bvy) -> (i = j) ->
  ((getbv bvx i) = (getbv bvy j)).

Parameter setbv: (Z -> Z) -> Z -> Z -> Z -> Z.

Axiom setbv_def :
  forall (bv:Z -> Z) (i:Z) (j:Z) (k:Z),
  ((k = i) -> (((setbv bv i j) k) = j)) /\
  (~ (k = i) -> (((setbv bv i j) k) = (bv k))).

Axiom setbv_spec :
  forall (bv:Z -> Z) (i:Z) (j:Z),
  (forall (k:Z), ~ (k = i) -> (((setbv bv i j) k) = (bv k))) /\
  (((setbv bv i j) i) = j).

Parameter setbv_int: (Z -> Z) -> (Z -> Z) -> Z -> Z -> Z -> Z.

Axiom setbv_int_def :
  forall (bv1:Z -> Z) (bv2:Z -> Z) (i:Z) (j:Z) (k:Z),
  (((i < k)%Z /\ (k <= j)%Z) ->
   (((setbv_int bv1 bv2 i j) k) = (bv2 (k - i)%Z))) /\
  (~ ((i < k)%Z /\ (k <= j)%Z) -> (((setbv_int bv1 bv2 i j) k) = (bv1 k))).

Axiom setbv_int_spec :
  forall (bv1:Z -> Z) (bv2:Z -> Z) (i:Z) (j:Z),
  (forall (k:Z), ((i < k)%Z /\ (k <= j)%Z) ->
   (((setbv_int bv1 bv2 i j) k) = (bv2 (k - i)%Z))) /\
  ((forall (k:Z), (k <= i)%Z -> (((setbv_int bv1 bv2 i j) k) = (bv1 k))) /\
   forall (k:Z), (j < k)%Z -> (((setbv_int bv1 bv2 i j) k) = (bv1 k))).

Axiom set_bvlength :
  forall (bv:bitvec) (i:Z),
  (forall (k:Z), ((1%Z <= k)%Z /\ (k <= i)%Z) ->
   (0%Z <= (getbv bv k))%Z /\ ((getbv bv k) < 2%Z)%Z) ->
  bvlength ((fun (y0:bitvec) (y1:Z) => (getbv y0 y1)) bv) i.

Axiom set_flength :
  forall (f:Z -> Z) (i:Z),
  (forall (k:Z), ((1%Z <= k)%Z /\ (k <= i)%Z) ->
   (0%Z <= (f k))%Z /\ ((f k) < 2%Z)%Z) ->
  bvlength f i.

Axiom get_bvlength :
  forall (f:Z -> Z) (i:Z), (bvlength f i) -> forall (k:Z),
  ((1%Z <= k)%Z /\ (k <= i)%Z) -> (0%Z <= (f k))%Z /\ ((f k) < 2%Z)%Z.

Axiom set_bv_to :
  forall (f:Z -> Z) (i:Z), (0%Z < i)%Z ->
  (forall (j:Z), ((1%Z <= j)%Z /\ (j <= i)%Z) ->
   (0%Z <= (f j))%Z /\ ((f j) <= 1%Z)%Z) ->
  bvlength f i.

Axiom set_in_range_val :
  forall (bv:bitvec) (i:Z), ((1%Z <= i)%Z /\ (i <= (length bv))%Z) ->
  (0%Z <= (getbv bv i))%Z /\ ((getbv bv i) < 2%Z)%Z.

Axiom bvlengthm :
  forall (bv:bitvec) (i:Z), ((0%Z <= i)%Z /\ (i <= (length bv))%Z) ->
  bvlength ((fun (y0:bitvec) (y1:Z) => (getbv y0 y1)) bv) i.

(* Why3 assumption *)
Definition in_range (bv:bitvec) (r:Z) : Prop :=
  (1%Z <= r)%Z /\ (r <= (length bv))%Z.

Axiom binary_bv :
  forall (bv:bitvec) (i:Z), (in_range bv i) ->
  (0%Z <= (getbv bv i))%Z /\ ((getbv bv i) <= 1%Z)%Z.

Axiom equal_bv :
  forall (m:bitvec) (n:bitvec),
  (m = n) <->
  (((length m) = (length n)) /\
   forall (i:Z), (in_range m i) -> ((getbv m i) = (getbv n i))).

Axiom set_equal_bv :
  forall (bv:bitvec) (bv':bitvec), ((length bv) = (length bv')) ->
  (forall (i:Z), ((1%Z <= i)%Z /\ (i <= (length bv))%Z) ->
   ((getbv bv i) = (getbv bv' i))) ->
  (bv = bv').

Axiom get_equal_bv :
  forall (bv:bitvec) (bv':bitvec), (bv = bv') ->
  ((length bv) = (length bv')) /\
  forall (i:Z), ((1%Z <= i)%Z /\ (i <= (length bv))%Z) ->
  ((getbv bv i) = (getbv bv' i)).

Parameter make_bv: (Z -> Z) -> Z -> bitvec.

Axiom make_bv_spec :
  forall (f:Z -> Z) (s:Z),
  (forall (i:Z), ((1%Z <= i)%Z /\ (i <= s)%Z) ->
   (0%Z <= (f i))%Z /\ ((f i) < 2%Z)%Z) ->
  (0%Z <= s)%Z ->
  ((length (make_bv f s)) = s) /\
  ((forall (i:Z), ((1%Z <= i)%Z /\ (i <= s)%Z) ->
    ((getbv (make_bv f s) i) = (f i))) /\
   forall (i:Z), ~ ((1%Z <= i)%Z /\ (i <= s)%Z) ->
   ((getbv (make_bv f s) i) = 0%Z)).

Parameter make_bv_m: (Z -> Z) -> Z -> bitvec.

Axiom make_bv_m_def :
  forall (f:Z -> Z) (s:Z), (0%Z <= s)%Z ->
  ((make_bv_m f s) =
   (make_bv (fun (k:Z) => (int.EuclideanDivision.mod1 (f k) 2%Z)) s)).

Axiom make_bv_m_spec :
  forall (f:Z -> Z) (s:Z), (0%Z <= s)%Z ->
  ((length (make_bv_m f s)) = s) /\
  ((forall (i:Z),
    bvlength ((fun (y0:bitvec) (y1:Z) => (getbv y0 y1)) (make_bv_m f s)) i) /\
   ((forall (k:Z), ((1%Z <= k)%Z /\ (k <= s)%Z) ->
     ((getbv (make_bv_m f s) k) = (int.EuclideanDivision.mod1 (f k) 2%Z))) /\
    forall (k:Z), ~ ((1%Z <= k)%Z /\ (k <= s)%Z) ->
    ((getbv (make_bv_m f s) k) = 0%Z))).

Axiom assert_make_bv_no_bound :
  forall (f:Z -> Z) (s:Z) (i:Z),
  (forall (i1:Z), ((1%Z <= i1)%Z /\ (i1 <= s)%Z) ->
   (0%Z <= (f i1))%Z /\ ((f i1) < 2%Z)%Z) ->
  ((1%Z <= i)%Z /\ (i <= s)%Z) -> ((getbv (make_bv f 0%Z) i) = 0%Z).

Axiom make_bv_length :
  forall (f:Z -> Z) (s:Z),
  (forall (i:Z), ((1%Z <= i)%Z /\ (i <= s)%Z) ->
   (0%Z <= (f i))%Z /\ ((f i) < 2%Z)%Z) ->
  (0%Z <= s)%Z -> ((length (make_bv f s)) = s).

Axiom assert_make_bv :
  forall (f:Z -> Z) (s:Z) (i:Z),
  (forall (i1:Z), ((1%Z <= i1)%Z /\ (i1 <= s)%Z) ->
   (0%Z <= (f i1))%Z /\ ((f i1) < 2%Z)%Z) ->
  (0%Z <= s)%Z ->
  (((1%Z <= i)%Z /\ (i <= s)%Z) -> ((getbv (make_bv f s) i) = (f i))) /\
  (~ ((1%Z <= i)%Z /\ (i <= s)%Z) -> ((getbv (make_bv f s) i) = 0%Z)).

Axiom assert_make_m :
  forall (f:Z -> Z) (s:Z) (i:Z), (0%Z <= s)%Z ->
  (((1%Z <= i)%Z /\ (i <= s)%Z) ->
   ((getbv (make_bv_m f s) i) = (int.EuclideanDivision.mod1 (f i) 2%Z))) /\
  (~ ((1%Z <= i)%Z /\ (i <= s)%Z) -> ((getbv (make_bv_m f s) i) = 0%Z)).

Axiom assert_make_bv_b :
  forall (f:Z -> Z) (s:Z) (i:Z),
  (forall (i1:Z), ((1%Z <= i1)%Z /\ (i1 <= s)%Z) ->
   (0%Z <= (f i1))%Z /\ ((f i1) < 2%Z)%Z) ->
  ((1%Z <= i)%Z /\ (i <= s)%Z) -> ((getbv (make_bv f s) i) = (f i)).

Axiom assert_make_m_b :
  forall (f:Z -> Z) (s:Z) (i:Z), ((1%Z <= i)%Z /\ (i <= s)%Z) ->
  (0%Z <= s)%Z ->
  ((getbv (make_bv_m f s) i) = (int.EuclideanDivision.mod1 (f i) 2%Z)).

Axiom make_m_bv_length :
  forall (f:Z -> Z) (s:Z) (i:Z), (0%Z <= s)%Z ->
  bvlength ((fun (y0:bitvec) (y1:Z) => (getbv y0 y1)) (make_bv_m f s)) i.

Axiom make_m_length :
  forall (f:Z -> Z) (s:Z), (0%Z <= s)%Z -> ((length (make_bv_m f s)) = s).

Axiom set_equal_bv_make :
  forall (f:Z -> Z) (g:Z -> Z) (s:Z),
  (forall (i:Z), (0%Z <= (f i))%Z /\ ((f i) < 2%Z)%Z) -> (0%Z <= s)%Z ->
  (forall (i:Z), ((f i) = (g i))) -> ((make_bv f s) = (make_bv g s)).

Axiom set_equal_bv_m_make :
  forall (f:Z -> Z) (g:Z -> Z) (s:Z), (0%Z <= s)%Z ->
  (forall (i:Z),
   ((int.EuclideanDivision.mod1 (f i) 2%Z) =
    (int.EuclideanDivision.mod1 (g i) 2%Z))) ->
  ((make_bv_m f s) = (make_bv_m g s)).

Parameter head: bitvec -> Z.

Axiom head_def :
  forall (bv:bitvec), (1%Z <= (length bv))%Z -> ((head bv) = (getbv bv 1%Z)).

Axiom head_spec :
  forall (bv:bitvec), (1%Z <= (length bv))%Z ->
  (0%Z <= (head bv))%Z /\ ((head bv) <= 1%Z)%Z.

Parameter tail: bitvec -> bitvec.

Axiom tail_def :
  forall (bv:bitvec), (1%Z <= (length bv))%Z ->
  ((tail bv) =
   (make_bv (fun (i:Z) => (getbv bv (i + 1%Z)%Z)) ((length bv) - 1%Z)%Z)).

Axiom tail_spec :
  forall (bv:bitvec), (1%Z <= (length bv))%Z ->
  ((length (tail bv)) = ((length bv) - 1%Z)%Z) /\
  forall (i:Z), (in_range (tail bv) i) ->
  ((getbv (tail bv) i) = (getbv bv (i + 1%Z)%Z)).

Parameter concat_l: bitvec -> Z -> bitvec.

Parameter result9: bitvec -> Z -> Z -> Z.

Axiom result_def9 :
  forall (bv:bitvec) (i:Z) (k:Z),
  ((k = 1%Z) -> (((result9 bv i) k) = i)) /\
  (~ (k = 1%Z) -> (((result9 bv i) k) = (getbv bv (k - 1%Z)%Z))).

Axiom concat_l_def :
  forall (bv:bitvec) (i:Z), ((0%Z <= i)%Z /\ (i <= 1%Z)%Z) ->
  ((concat_l bv i) = (make_bv (result9 bv i) ((length bv) + 1%Z)%Z)).

Axiom concat_l_spec :
  forall (bv:bitvec) (i:Z), ((0%Z <= i)%Z /\ (i <= 1%Z)%Z) ->
  ((length (concat_l bv i)) = ((length bv) + 1%Z)%Z) /\
  (((getbv (concat_l bv i) 1%Z) = i) /\
   forall (j:Z), (in_range bv j) ->
   ((getbv (concat_l bv i) (j + 1%Z)%Z) = (getbv bv j))).

Axiom concat_l_value :
  forall (bv:bitvec) (i:Z) (k:Z), ((0%Z <= i)%Z /\ (i < 2%Z)%Z) ->
  ((k = 1%Z) -> ((getbv (concat_l bv i) k) = i)) /\
  (~ (k = 1%Z) ->
   (((1%Z < k)%Z /\ (k <= ((length bv) + 1%Z)%Z)%Z) ->
    ((getbv (concat_l bv i) k) = (getbv bv (k - 1%Z)%Z))) /\
   (~ ((1%Z < k)%Z /\ (k <= ((length bv) + 1%Z)%Z)%Z) ->
    ((getbv (concat_l bv i) k) = 0%Z))).

Axiom concat_l_value_b :
  forall (bv:bitvec) (i:Z) (k:Z),
  ((1%Z <= k)%Z /\ (k <= ((length bv) + 1%Z)%Z)%Z) ->
  ((0%Z <= i)%Z /\ (i < 2%Z)%Z) ->
  ((k = 1%Z) -> ((getbv (concat_l bv i) k) = i)) /\
  (~ (k = 1%Z) -> ((getbv (concat_l bv i) k) = (getbv bv (k - 1%Z)%Z))).

Axiom concat_ht :
  forall (bv:bitvec), (1%Z <= (length bv))%Z ->
  (bv = (concat_l (tail bv) (head bv))).

Axiom concat_ht_union :
  forall (bv:bitvec), (2%Z <= (length bv))%Z ->
  ~ (bv = (concat_l (tail bv) 0%Z)) -> (bv = (concat_l (tail bv) 1%Z)).

Parameter result10: bitvec -> Z -> Z.

Axiom result_def10 :
  forall (bv:bitvec) (k:Z),
  ((in_range bv k) ->
   (((result10 bv) k) = ((getbv bv k) * (power 2%Z ((length bv) - k)%Z))%Z)) /\
  (~ (in_range bv k) -> (((result10 bv) k) = 1%Z)).

(* Why3 assumption *)
Definition bv_to_int (bv:bitvec) : Z :=
  ind_isum (result10 bv) 1%Z ((length bv) + 1%Z)%Z.

Axiom bv_to_int_spec :
  forall (bv:bitvec),
  ((bv_to_int bv) =
   (ind_isum
    (fun (k:Z) => ((getbv bv k) * (power 2%Z ((length bv) - k)%Z))%Z) 1%Z
    ((length bv) + 1%Z)%Z)) /\
  (0%Z <= (bv_to_int bv))%Z.

Axiom bv_to_int_sum :
  forall (bv:bitvec),
  ((bv_to_int bv) =
   (ind_isum
    (fun (k:Z) => ((getbv bv k) * (power 2%Z ((length bv) - k)%Z))%Z) 1%Z
    ((length bv) + 1%Z)%Z)).

Axiom bv_to_int_onebit :
  forall (bv:bitvec), ((length bv) = 1%Z) ->
  ((bv_to_int bv) = (getbv bv 1%Z)).

Axiom ind_isum_bv_rev :
  forall (bv:bitvec) (i:Z), ((0%Z <= i)%Z /\ (i <= (length bv))%Z) ->
  ((ind_isum
    (fun (l:Z) => ((getbv bv l) * (power 2%Z ((length bv) - l)%Z))%Z)
    (i + 1%Z)%Z ((length bv) + 1%Z)%Z)
   =
   (ind_isum
    (fun (l:Z) => ((getbv bv ((length bv) - l)%Z) * (power 2%Z l))%Z) 0%Z
    ((length bv) - i)%Z)).

Axiom bv_to_int_sum_rev :
  forall (bv:bitvec),
  ((ind_isum
    (fun (k:Z) => ((getbv bv ((length bv) - k)%Z) * (power 2%Z k))%Z) 0%Z
    (length bv))
   = (bv_to_int bv)).

Axiom ind_isum_bv_bound_growing :
  forall (bv:bitvec) (i:Z), ((1%Z < i)%Z /\ (i <= (length bv))%Z) ->
  ((ind_isum (fun (l:Z) => ((getbv bv l) * (power 2%Z (l - 1%Z)%Z))%Z) 1%Z i)
   < (power 2%Z (i - 1%Z)%Z))%Z.

Axiom ind_isum_bv_bound :
  forall (bv:bitvec) (i:Z), ((0%Z <= i)%Z /\ (i < (length bv))%Z) ->
  ((ind_isum
    (fun (l:Z) => ((getbv bv l) * (power 2%Z ((length bv) - l)%Z))%Z)
    (i + 1%Z)%Z ((length bv) + 1%Z)%Z)
   < (power 2%Z ((length bv) - i)%Z))%Z.

Axiom bv_to_int_bound :
  forall (bv:bitvec), (1%Z <= (length bv))%Z ->
  ((bv_to_int bv) < (power 2%Z (length bv)))%Z.

Axiom ind_isum_mod_div :
  forall (bv:bitvec) (i:Z), ((1%Z <= i)%Z /\ (i < (length bv))%Z) ->
  ((int.EuclideanDivision.mod1
    (ind_isum
     (fun (k:Z) => ((getbv bv k) * (power 2%Z ((length bv) - k)%Z))%Z) 1%Z
     ((length bv) + 1%Z)%Z)
    (power 2%Z ((length bv) - i)%Z))
   =
   (ind_isum
    (fun (k:Z) => ((getbv bv k) * (power 2%Z ((length bv) - k)%Z))%Z)
    (i + 1%Z)%Z ((length bv) + 1%Z)%Z)) /\
  ((int.EuclideanDivision.div
    (ind_isum
     (fun (k:Z) => ((getbv bv k) * (power 2%Z ((length bv) - k)%Z))%Z) 1%Z
     ((length bv) + 1%Z)%Z)
    (power 2%Z ((length bv) - i)%Z))
   =
   (ind_isum (fun (k:Z) => ((getbv bv k) * (power 2%Z (i - k)%Z))%Z) 1%Z
    (i + 1%Z)%Z)).

Axiom bv_to_int_kth_pre :
  forall (bv:bitvec) (n:Z), ((1%Z <= n)%Z /\ (n <= (length bv))%Z) ->
  ((int.EuclideanDivision.div
    (ind_isum (fun (l:Z) => ((getbv bv l) * (power 2%Z (l - 1%Z)%Z))%Z) 1%Z
     (n + 1%Z)%Z)
    (power 2%Z (n - 1%Z)%Z))
   = (getbv bv n)).

Axiom bv_to_int_kth :
  forall (bv:bitvec) (k:Z), ((1%Z < k)%Z /\ (k <= (length bv))%Z) ->
  ((getbv bv k) = (kth_bit_l (bv_to_int bv) (length bv) k)).

Axiom kth_bv_to_int :
  forall (bv:bitvec) (k:Z), ((1%Z < k)%Z /\ (k <= (length bv))%Z) ->
  ((kth_bit_l (bv_to_int bv) (length bv) k) = (getbv bv k)).

Axiom bv_to_int_kth_gen :
  forall (bv:bitvec) (k:Z), ((1%Z <= k)%Z /\ (k <= (length bv))%Z) ->
  ((getbv bv k) = (kth_bit_l (bv_to_int bv) (length bv) k)).

Axiom kth_bv_to_int_gen :
  forall (bv:bitvec) (k:Z) (l:Z), ((1%Z <= k)%Z /\ (k <= (length bv))%Z) ->
  (l = (length bv)) -> ((kth_bit_l (bv_to_int bv) l k) = (getbv bv k)).

Parameter int_to_bv: Z -> Z -> bitvec.

Parameter result11: Z -> Z -> Z -> Z.

Axiom result_def11 :
  forall (i:Z) (n:Z) (k:Z),
  (((1%Z <= k)%Z /\ (k <= n)%Z) -> (((result11 i n) k) = (kth_bit_l i n k))) /\
  (~ ((1%Z <= k)%Z /\ (k <= n)%Z) -> (((result11 i n) k) = 0%Z)).

Axiom int_to_bv_def :
  forall (i:Z) (n:Z), (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((int_to_bv i n) = (make_bv (result11 i n) n)).

Axiom int_to_bv_spec :
  forall (i:Z) (n:Z), (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  (i =
   (ind_isum
    (fun (k:Z) => ((getbv (int_to_bv i n) k) * (power 2%Z (n - k)%Z))%Z) 1%Z
    (n + 1%Z)%Z)) /\
  ((length (int_to_bv i n)) = n).

Axiom int_to_bv_value :
  forall (i:Z) (n:Z) (k:Z), (0%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) -> ((1%Z <= k)%Z /\ (k <= n)%Z) ->
  ((getbv (int_to_bv i n) k) = (kth_bit_l i n k)).

Axiom int_to_bv_zero :
  forall (n:Z), forall (k:Z), ((1%Z <= k)%Z /\ (k <= n)%Z) ->
  ((getbv (int_to_bv 0%Z n) k) = 0%Z).

Parameter int_to_sum: Z -> Z -> unit.

Axiom int_to_sum_def :
  forall (i:Z) (n:Z), (0%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) -> ((int_to_sum i n) = tt).

Axiom int_to_sum_spec :
  forall (i:Z) (n:Z), (0%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  (i =
   (ind_isum
    (fun (k:Z) => ((getbv (int_to_bv i n) k) * (power 2%Z (n - k)%Z))%Z) 1%Z
    (n + 1%Z)%Z)).

Axiom int_to_bv_transl :
  forall (i:Z) (k:Z) (n:Z) (t1:Z), ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((1%Z <= t1)%Z /\ ((t1 < k)%Z /\ (k <= n)%Z)) ->
  ((getbv
    (int_to_bv (int.EuclideanDivision.mod1 i (power 2%Z (n - t1)%Z))
     (n - t1)%Z)
    (k - t1)%Z)
   = (getbv (int_to_bv i n) k)).

Axiom int_to_bv_tail :
  forall (i:Z) (n:Z), (1%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((int_to_bv (tail_bits i n) (n - 1%Z)%Z) = (tail (int_to_bv i n))).

Axiom bound_sum_dec :
  forall (bv:bitvec) (i:Z), ((1%Z <= i)%Z /\ (i <= (length bv))%Z) ->
  ((ind_isum
    (fun (l:Z) => ((getbv bv l) * (power 2%Z ((length bv) - l)%Z))%Z) i
    ((length bv) + 1%Z)%Z)
   < (power 2%Z (((length bv) - i)%Z + 1%Z)%Z))%Z.

Axiom bv_to_int_to_bv :
  forall (i:Z) (n:Z), (0%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((bv_to_int (int_to_bv i n)) = i).

Axiom tail_bits_sum :
  forall (i:Z) (n:Z), (1%Z < n)%Z -> (0%Z <= i)%Z ->
  ((binary_length i) <= n)%Z ->
  ((tail_bits i n) =
   (ind_isum
    (fun (l:Z) => ((getbv (int_to_bv i n) l) * (power 2%Z (n - l)%Z))%Z) 2%Z
    (n + 1%Z)%Z)).

Axiom int_to_bv_to_int :
  forall (bv:bitvec), (1%Z <= (length bv))%Z ->
  ((int_to_bv (bv_to_int bv) (length bv)) = bv).

Axiom concat_to_int :
  forall (bv:bitvec) (i:Z), ((0%Z <= i)%Z /\ (i <= 1%Z)%Z) ->
  ((bv_to_int (concat_l bv i)) =
   ((bv_to_int bv) + (i * (power 2%Z (length bv)))%Z)%Z).

Axiom bounded_to_int :
  forall (bv:bitvec), ((bv_to_int bv) < (power 2%Z (length bv)))%Z.

Axiom int_to_bv_to_int_value :
  forall (bv:bitvec) (i:Z), (1%Z <= (length bv))%Z ->
  (((1%Z <= i)%Z /\ (i <= (length bv))%Z) ->
   ((getbv (int_to_bv (bv_to_int bv) (length bv)) i) = (getbv bv i))) /\
  (~ ((1%Z <= i)%Z /\ (i <= (length bv))%Z) ->
   ((getbv (int_to_bv (bv_to_int bv) (length bv)) i) = 0%Z)).

Axiom int_to_bv_to_int_gen :
  forall (bv:bitvec) (n:Z), (1%Z <= (length bv))%Z -> (n = (length bv)) ->
  ((int_to_bv (bv_to_int bv) n) = bv).

Axiom bv_to_int_mod :
  forall (bv:bitvec) (k:Z), ((0%Z <= k)%Z /\ (k < (length bv))%Z) ->
  ((int.EuclideanDivision.mod1 (bv_to_int bv)
    (power 2%Z ((length bv) - k)%Z))
   =
   (ind_isum
    (fun (l:Z) => ((getbv bv l) * (power 2%Z ((length bv) - l)%Z))%Z)
    (k + 1%Z)%Z ((length bv) + 1%Z)%Z)).

Axiom bv_to_int_mod_rev :
  forall (bv:bitvec) (k:Z), ((0%Z <= k)%Z /\ (k < (length bv))%Z) ->
  ((ind_isum
    (fun (l:Z) => ((getbv bv l) * (power 2%Z ((length bv) - l)%Z))%Z)
    (k + 1%Z)%Z ((length bv) + 1%Z)%Z)
   =
   (int.EuclideanDivision.mod1 (bv_to_int bv)
    (power 2%Z ((length bv) - k)%Z))).

Axiom bv_to_int_mod_gen :
  forall (k:Z) (n:Z), ((0%Z <= k)%Z /\ (k < n)%Z) -> forall (bv:bitvec),
  ((length bv) = n) ->
  ((int.EuclideanDivision.mod1 (bv_to_int bv)
    (power 2%Z ((length bv) - k)%Z))
   =
   (ind_isum
    (fun (l:Z) => ((getbv bv l) * (power 2%Z ((length bv) - l)%Z))%Z)
    (k + 1%Z)%Z ((length bv) + 1%Z)%Z)).

Axiom to_int_head_tail :
  forall (bv:bitvec), (1%Z <= (length bv))%Z ->
  ((bv_to_int bv) =
   ((bv_to_int (tail bv)) +
    ((head bv) * (power 2%Z ((length bv) - 1%Z)%Z))%Z)%Z) /\
  ((bv_to_int (tail bv)) =
   (int.EuclideanDivision.mod1 (bv_to_int bv)
    (power 2%Z ((length bv) - 1%Z)%Z))).

Axiom not_disj :
  forall (a:bool) (b:bool), ~ (a = true) -> ~ (b = true) ->
  ~ ((a = true) \/ (b = true)).

Parameter n_bvs: Z -> set bitvec.

Axiom n_bvs_def :
  forall (n:Z), (0%Z <= n)%Z ->
  ((n = 0%Z) ->
   ((n_bvs n) = (add (make_bv (fun (i:Z) => 0%Z) 0%Z) (empty : set bitvec)))) /\
  (~ (n = 0%Z) ->
   ((n_bvs n) =
    (union (map (fun (bv:bitvec) => (concat_l bv 0%Z)) (n_bvs (n - 1%Z)%Z))
     (map (fun (bv:bitvec) => (concat_l bv 1%Z)) (n_bvs (n - 1%Z)%Z))))).

Axiom n_bvs_spec :
  forall (n:Z), (0%Z <= n)%Z ->
  (forall (f:bitvec), (mem f (n_bvs n)) -> ((length f) = n)) /\
  ((forall (f:bitvec), (mem f (n_bvs n)) <-> ((length f) = n)) /\
   (0%Z < (cardinal (n_bvs n)))%Z).

Axiom n_bvs_node :
  forall (n:Z), (0%Z < n)%Z ->
  ((inter (map (fun (bv:bitvec) => (concat_l bv 0%Z)) (n_bvs (n - 1%Z)%Z))
    (map (fun (bv:bitvec) => (concat_l bv 1%Z)) (n_bvs (n - 1%Z)%Z)))
   = (empty : set bitvec)) /\
  ((union (map (fun (bv:bitvec) => (concat_l bv 0%Z)) (n_bvs (n - 1%Z)%Z))
    (map (fun (bv:bitvec) => (concat_l bv 1%Z)) (n_bvs (n - 1%Z)%Z)))
   = (n_bvs n)).

Axiom injective_node :
  forall (n:Z), (0%Z <= n)%Z ->
  (p_injective (fun (bv:bitvec) => (concat_l bv 0%Z)) (n_bvs n)) /\
  (p_injective (fun (bv:bitvec) => (concat_l bv 1%Z)) (n_bvs n)).

Axiom mat_sum_n_bvs_pos :
  forall (n:Z) (f:bitvec -> matrix t), (0%Z < n)%Z ->
  (constant_size (n_bvs n) f) ->
  ((mat_sum (n_bvs n) f) =
   (add_mat
    (mat_sum (n_bvs (n - 1%Z)%Z) (fun (bv:bitvec) => (f (concat_l bv 0%Z))))
    (mat_sum (n_bvs (n - 1%Z)%Z) (fun (bv:bitvec) => (f (concat_l bv 1%Z)))))).

Axiom mat_sum_n_bvs_null :
  forall (f:bitvec -> matrix t),
  ((mat_sum (n_bvs 0%Z) f) =
   (f (make_bv ((fun (y0:Z) (y1:Z) => y0) 0%Z) 0%Z))).

Axiom mat_sum_n_bvs_null_eq :
  forall (f:bitvec -> matrix t) (x:matrix t),
  (x = (f (make_bv ((fun (y0:Z) (y1:Z) => y0) 0%Z) 0%Z))) ->
  ((mat_sum (n_bvs 0%Z) f) = x).

Axiom get_n_bvs : forall (bv:bitvec), mem bv (n_bvs (length bv)).

Axiom get_n_bvs_gen :
  forall (bv:bitvec) (l:Z), (l = (length bv)) -> mem bv (n_bvs l).

Axiom set_n_bvs :
  forall (bv:bitvec), (mem bv (n_bvs (length bv))) -> forall (i:Z),
  ~ ((1%Z <= i)%Z /\ (i <= (length bv))%Z) -> ((getbv bv i) = 0%Z).

Axiom int_to_bv_n_bvs :
  forall (i:Z) (n:Z), (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) -> mem (int_to_bv i n) (n_bvs n).

Axiom n_bvs_def_pos :
  forall (n:Z), (0%Z < n)%Z ->
  ((n_bvs n) =
   (union (map (fun (bv:bitvec) => (concat_l bv 0%Z)) (n_bvs (n - 1%Z)%Z))
    (map (fun (bv:bitvec) => (concat_l bv 1%Z)) (n_bvs (n - 1%Z)%Z)))).

Axiom map_n_bvs :
  forall (n:Z), (0%Z < n)%Z ->
  ((to_fset 0%Z (power 2%Z n)) =
   (map (fun (y0:bitvec) => (bv_to_int y0)) (n_bvs n))).

Parameter first_div: bitvec -> bitvec -> Z.

Axiom first_div_spec :
  forall (bv1:bitvec) (bv2:bitvec), ((length bv1) = (length bv2)) ->
  ~ (bv1 = bv2) ->
  (forall (j:Z), ((1%Z <= j)%Z /\ (j < (first_div bv1 bv2))%Z) ->
   ((getbv bv1 j) = (getbv bv2 j))) /\
  ((((first_div bv1 bv2) <= (length bv1))%Z ->
    ~ ((getbv bv1 (first_div bv1 bv2)) = (getbv bv2 (first_div bv1 bv2)))) /\
   (((1%Z <= (first_div bv1 bv2))%Z /\
     ((first_div bv1 bv2) <= ((length bv1) + 1%Z)%Z)%Z) /\
    (((first_div bv1 bv2) = ((length bv1) + 1%Z)%Z) -> (bv1 = bv2)))).

Axiom injective_concat :
  forall (i:Z) (n:Z), (0%Z <= n)%Z -> ((0%Z <= i)%Z /\ (i <= 1%Z)%Z) ->
  p_injective (fun (bv:bitvec) => (concat_l bv i)) (n_bvs n).

Axiom inf_first_div :
  forall (bv1:bitvec) (bv2:bitvec), ((length bv1) = (length bv2)) ->
  ~ (bv1 = bv2) -> forall (j:Z), (1%Z <= j)%Z ->
  ~ ((getbv bv1 j) = (getbv bv2 j)) -> ((first_div bv1 bv2) <= j)%Z.

Axiom first_div_diff :
  forall (bv1:bitvec) (bv2:bitvec), ((length bv1) = (length bv2)) ->
  ~ (bv1 = bv2) ->
  ~ ((getbv bv1 (first_div bv1 bv2)) = (getbv bv2 (first_div bv1 bv2))).

Axiom exists_first_div :
  forall (bv1:bitvec) (bv2:bitvec), ((length bv1) = (length bv2)) ->
  ~ (bv1 = bv2) ->
  exists i:Z,
  ((1%Z <= i)%Z /\ (i <= (length bv1))%Z) /\ (i = (first_div bv1 bv2)).

Axiom set_diff_length :
  forall (bv1:bitvec) (bv2:bitvec), ~ ((length bv1) = (length bv2)) ->
  ~ (bv1 = bv2).

Axiom set_diff_val :
  forall (bv1:bitvec) (bv2:bitvec) (i:Z), ((length bv1) = (length bv2)) ->
  ((1%Z <= i)%Z /\ (i <= (length bv1))%Z) ->
  ~ ((getbv bv1 i) = (getbv bv2 i)) -> ~ (bv1 = bv2).

Parameter fc9: bitvec -> Z -> Z.

Parameter fc10: bitvec -> Z -> Z.

Axiom fc_def9 :
  forall (bv:bitvec) (l:Z),
  ((l <= (length bv))%Z ->
   (((fc9 bv) l) = ((getbv bv l) * (power 2%Z ((length bv) - l)%Z))%Z)) /\
  (~ (l <= (length bv))%Z -> (((fc9 bv) l) = 0%Z)).

Axiom fc_def10 :
  forall (bv:bitvec) (l:Z),
  ((l <= (length bv))%Z ->
   (((fc10 bv) l) = ((getbv bv l) * (power 2%Z ((length bv) - l)%Z))%Z)) /\
  (~ (l <= (length bv))%Z -> (((fc10 bv) l) = 0%Z)).

Axiom kth_decomp :
  forall (bv:bitvec) (k:Z), ((1%Z <= k)%Z /\ (k <= (length bv))%Z) ->
  ((bv_to_int bv) =
   (((ind_isum (fc9 bv) 1%Z k) +
     ((getbv bv k) * (power 2%Z ((length bv) - k)%Z))%Z)%Z
    + (ind_isum (fc10 bv) (k + 1%Z)%Z ((length bv) + 1%Z)%Z))%Z).

Axiom int_to_bv_prod :
  forall (i:Z) (j:Z) (n:Z), (0%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((0%Z <= j)%Z /\ (j < (power 2%Z n))%Z) ->
  ((ind_product
    (fun (k:Z) =>
     (indic (getbv (int_to_bv i n) k) (getbv (int_to_bv j n) k)))
    1%Z (n + 1%Z)%Z)
   = (indic i j)).

Axiom int_to_bv_prod_gen :
  forall (i:Z) (n:Z), (0%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) -> forall (j:Z),
  ((0%Z <= j)%Z /\ (j < (power 2%Z n))%Z) ->
  ((ind_product
    (fun (k:Z) =>
     (indic (getbv (int_to_bv i n) k) (getbv (int_to_bv j n) k)))
    1%Z (n + 1%Z)%Z)
   = (indic i j)).

Parameter fc11: bitvec -> Z -> Z.

Parameter fc12: bitvec -> Z -> Z.

Axiom fc_def11 :
  forall (bv:bitvec) (l:Z),
  ((l <= (length bv))%Z ->
   (((fc11 bv) l) = ((getbv bv l) * (power 2%Z ((length bv) - l)%Z))%Z)) /\
  (~ (l <= (length bv))%Z -> (((fc11 bv) l) = 0%Z)).

Axiom fc_def12 :
  forall (bv:bitvec) (l:Z),
  ((l <= (length bv))%Z ->
   (((fc12 bv) l) = ((getbv bv l) * (power 2%Z ((length bv) - l)%Z))%Z)) /\
  (~ (l <= (length bv))%Z -> (((fc12 bv) l) = 0%Z)).

Axiom kth_decomp_bound_zero :
  forall (bv:bitvec) (k:Z), ((1%Z <= k)%Z /\ (k <= (length bv))%Z) ->
  ((getbv bv k) = 0%Z) ->
  ((ind_isum (fc11 bv) 1%Z k) <= (bv_to_int bv))%Z /\
  ((bv_to_int bv) <
   ((ind_isum (fc12 bv) 1%Z k) + (power 2%Z ((length bv) - k)%Z))%Z)%Z.

Parameter fc13: bitvec -> Z -> Z.

Parameter fc14: bitvec -> Z -> Z.

Axiom fc_def13 :
  forall (bv:bitvec) (l:Z),
  ((l <= (length bv))%Z ->
   (((fc13 bv) l) = ((getbv bv l) * (power 2%Z ((length bv) - l)%Z))%Z)) /\
  (~ (l <= (length bv))%Z -> (((fc13 bv) l) = 0%Z)).

Axiom fc_def14 :
  forall (bv:bitvec) (l:Z),
  ((l <= (length bv))%Z ->
   (((fc14 bv) l) = ((getbv bv l) * (power 2%Z ((length bv) - l)%Z))%Z)) /\
  (~ (l <= (length bv))%Z -> (((fc14 bv) l) = 0%Z)).

Axiom kth_decomp_bound_one :
  forall (bv:bitvec) (k:Z), ((1%Z <= k)%Z /\ (k <= (length bv))%Z) ->
  ((getbv bv k) = 1%Z) ->
  (((ind_isum (fc13 bv) 1%Z k) + (power 2%Z ((length bv) - k)%Z))%Z <=
   (bv_to_int bv))%Z /\
  ((bv_to_int bv) <
   ((ind_isum (fc14 bv) 1%Z k) + (power 2%Z (((length bv) - k)%Z + 1%Z)%Z))%Z)%Z.

Parameter result12: bitvec -> bitvec -> Z -> Z.

Axiom result_def12 :
  forall (bv1:bitvec) (bv2:bitvec) (i:Z),
  ((((length bv1) < i)%Z /\ (i <= ((length bv1) + (length bv2))%Z)%Z) ->
   (((result12 bv1 bv2) i) = (getbv bv2 (i - (length bv1))%Z))) /\
  (~ (((length bv1) < i)%Z /\ (i <= ((length bv1) + (length bv2))%Z)%Z) ->
   (((result12 bv1 bv2) i) = (getbv bv1 i))).

(* Why3 assumption *)
Definition concat (bv1:bitvec) (bv2:bitvec) : bitvec :=
  make_bv (result12 bv1 bv2) ((length bv1) + (length bv2))%Z.

Axiom concat_spec :
  forall (bv1:bitvec) (bv2:bitvec),
  ((length (concat bv1 bv2)) = ((length bv1) + (length bv2))%Z) /\
  ((forall (i:Z), ((1%Z <= i)%Z /\ (i <= (length bv1))%Z) ->
    ((getbv (concat bv1 bv2) i) = (getbv bv1 i))) /\
   ((forall (i:Z), ((length (concat bv1 bv2)) < i)%Z ->
     ((getbv (concat bv1 bv2) i) = (getbv bv1 i))) /\
    forall (i:Z),
    (((length bv1) < i)%Z /\ (i <= (length (concat bv1 bv2)))%Z) ->
    ((getbv (concat bv1 bv2) i) = (getbv bv2 (i - (length bv1))%Z)))).

Parameter hpart: bitvec -> Z -> bitvec.

Axiom hpart_def :
  forall (bv:bitvec) (m:Z), (0%Z <= m)%Z ->
  ((hpart bv m) = (make_bv ((fun (y0:bitvec) (y1:Z) => (getbv y0 y1)) bv) m)).

Axiom hpart_spec :
  forall (bv:bitvec) (m:Z), (0%Z <= m)%Z ->
  ((length (hpart bv m)) = m) /\
  ((forall (k:Z), ((1%Z <= k)%Z /\ (k <= m)%Z) ->
    ((getbv (hpart bv m) k) = (getbv bv k))) /\
   forall (k:Z), ~ ((1%Z <= k)%Z /\ (k <= m)%Z) ->
   ((getbv (hpart bv m) k) = 0%Z)).

Axiom hpart_value :
  forall (bv:bitvec) (m:Z) (i:Z), (0%Z <= m)%Z ->
  (((1%Z <= i)%Z /\ (i <= m)%Z) -> ((getbv (hpart bv m) i) = (getbv bv i))) /\
  (~ ((1%Z <= i)%Z /\ (i <= m)%Z) -> ((getbv (hpart bv m) i) = 0%Z)).

Parameter tpart: bitvec -> Z -> bitvec.

Axiom tpart_def :
  forall (bv:bitvec) (m:Z), (0%Z <= m)%Z ->
  ((m <= (length bv))%Z ->
   ((tpart bv m) =
    (make_bv (fun (k:Z) => (getbv bv (k + m)%Z)) ((length bv) - m)%Z))) /\
  (~ (m <= (length bv))%Z ->
   ((tpart bv m) = (make_bv (fun (k:Z) => (getbv bv (k + m)%Z)) 0%Z))).

Axiom tpart_spec :
  forall (bv:bitvec) (m:Z), (0%Z <= m)%Z ->
  ((m <= (length bv))%Z -> ((length (tpart bv m)) = ((length bv) - m)%Z)) /\
  ((((length bv) < m)%Z -> ((length (tpart bv m)) = 0%Z)) /\
   forall (k:Z), ((1%Z <= k)%Z /\ (k <= (length (tpart bv m)))%Z) ->
   ((getbv (tpart bv m) k) = (getbv bv (k + m)%Z))).

Axiom tpart_value :
  forall (bv:bitvec) (m:Z) (i:Z), (0%Z <= m)%Z ->
  (((1%Z <= i)%Z /\ (i <= ((length bv) - m)%Z)%Z) ->
   ((getbv (tpart bv m) i) = (getbv bv (i + m)%Z))) /\
  (~ ((1%Z <= i)%Z /\ (i <= ((length bv) - m)%Z)%Z) ->
   ((getbv (tpart bv m) i) = 0%Z)).

Axiom tpart_length :
  forall (bv:bitvec) (m:Z), ((0%Z <= m)%Z /\ (m <= (length bv))%Z) ->
  ((length (tpart bv m)) = ((length bv) - m)%Z).

Axiom tpart_length_gen :
  forall (bv:bitvec) (m:Z) (l:Z), ((0%Z <= m)%Z /\ (m <= (length bv))%Z) ->
  (l = ((length bv) - m)%Z) -> ((length (tpart bv m)) = l).

Axiom concat_value_left :
  forall (bv1:bitvec) (bv2:bitvec) (i:Z),
  ((1%Z <= i)%Z /\ (i <= (length bv1))%Z) ->
  ((getbv (concat bv1 bv2) i) = (getbv bv1 i)).

Axiom concat_value :
  forall (bv1:bitvec) (bv2:bitvec) (i:Z),
  ((((length bv1) < i)%Z /\ (i <= ((length bv1) + (length bv2))%Z)%Z) ->
   ((getbv (concat bv1 bv2) i) = (getbv bv2 (i - (length bv1))%Z))) /\
  (~ (((length bv1) < i)%Z /\ (i <= ((length bv1) + (length bv2))%Z)%Z) ->
   (((1%Z <= i)%Z /\ (i <= (length bv1))%Z) ->
    ((getbv (concat bv1 bv2) i) = (getbv bv1 i))) /\
   (~ ((1%Z <= i)%Z /\ (i <= (length bv1))%Z) ->
    ((getbv (concat bv1 bv2) i) = 0%Z))).

Axiom concat_value_right :
  forall (bv1:bitvec) (bv2:bitvec) (i:Z),
  (((length bv1) < i)%Z /\ (i <= ((length bv1) + (length bv2))%Z)%Z) ->
  ((getbv (concat bv1 bv2) i) = (getbv bv2 (i - (length bv1))%Z)).

Axiom concat_value_out :
  forall (bv1:bitvec) (bv2:bitvec) (i:Z),
  (((length bv1) + (length bv2))%Z < i)%Z ->
  ((getbv (concat bv1 bv2) i) = (getbv bv1 i)).

Axiom concat_value_tpart :
  forall (bv1:bitvec) (bv2:bitvec) (i:Z),
  (((length bv1) < i)%Z /\ (i <= (length bv2))%Z) ->
  ((getbv (concat bv1 (tpart bv2 (length bv1))) i) = (getbv bv2 i)).

Axiom concat_value_ht :
  forall (bv1:bitvec) (bv2:bitvec) (bv3:bitvec) (bv4:bitvec) (i:Z),
  ((1%Z <= i)%Z /\ (i <= (length bv3))%Z) ->
  (((1%Z <= i)%Z /\ (i <= (length bv1))%Z) ->
   ((getbv bv1 i) = (getbv bv4 i))) ->
  (((length bv1) < i)%Z -> ((getbv bv3 i) = (getbv bv4 i))) ->
  (bv2 = (tpart bv3 (length bv1))) ->
  ((getbv (concat bv1 bv2) i) = (getbv bv4 i)).

Axiom concat_ht1 :
  forall (bv1:bitvec) (bv2:bitvec) (bv3:bitvec) (bv4:bitvec),
  (forall (i:Z), ((1%Z <= i)%Z /\ (i <= (length bv1))%Z) ->
   ((getbv bv1 i) = (getbv bv4 i))) ->
  (forall (i:Z), ((length bv1) < i)%Z -> ((getbv bv3 i) = (getbv bv4 i))) ->
  ((length bv4) = ((length bv1) + (length bv2))%Z) ->
  (((length bv1) + (length bv2))%Z <= (length bv3))%Z ->
  (bv2 = (tpart bv3 (length bv1))) -> ((concat bv1 bv2) = bv4).

Axiom set_concat :
  forall (bv1:bitvec) (bv2:bitvec) (bv4:bitvec),
  (forall (i:Z), ((1%Z <= i)%Z /\ (i <= (length bv1))%Z) ->
   ((getbv bv1 i) = (getbv bv4 i))) ->
  (forall (i:Z), ((length bv1) < i)%Z ->
   ((getbv bv2 (i - (length bv1))%Z) = (getbv bv4 i))) ->
  ((length bv4) = ((length bv1) + (length bv2))%Z) ->
  ((concat bv1 bv2) = bv4).

Axiom concat_m :
  forall (bv1:bitvec) (bv2:bitvec) (i1:Z) (i2:Z), (0%Z < i1)%Z ->
  (0%Z < i2)%Z -> ((length bv1) = i1) -> ((length bv2) = i2) ->
  ((concat (make_bv_m ((fun (y0:bitvec) (y1:Z) => (getbv y0 y1)) bv1) i1)
    (make_bv_m ((fun (y0:bitvec) (y1:Z) => (getbv y0 y1)) bv2) i2))
   =
   (make_bv_m ((fun (y0:bitvec) (y1:Z) => (getbv y0 y1)) (concat bv1 bv2))
    (i1 + i2)%Z)).

Axiom concat_comm :
  forall (bv1:bitvec) (bv2:bitvec),
  ((hpart (concat bv1 bv2) (length bv1)) = bv1) /\
  ((tpart (concat bv1 bv2) (length bv1)) = bv2).

Axiom concat_and_rec :
  forall (bv:bitvec) (i:Z), ((0%Z <= i)%Z /\ (i <= (length bv))%Z) ->
  ((concat (hpart bv i) (tpart bv i)) = bv).

Parameter concat_int_bv: bitvec -> Z -> Z -> bitvec.

Axiom concat_int_bv_def :
  forall (bv:bitvec) (i:Z) (n:Z), (0%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((concat_int_bv bv i n) = (concat bv (int_to_bv i n))).

Axiom concat_int_to_bv_value :
  forall (bv:bitvec) (i:Z) (n:Z) (j:Z), (0%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((1%Z <= j)%Z /\ (j < (length (concat_int_bv bv i n)))%Z) ->
  ((j <= (length bv))%Z -> ((getbv (concat_int_bv bv i n) j) = (getbv bv j))) /\
  ((((length bv) < j)%Z /\ (j <= (length (concat_int_bv bv i n)))%Z) ->
   ((getbv (concat_int_bv bv i n) j) = (kth_bit_l i n (j - (length bv))%Z))).

Axiom bv_to_int_concat :
  forall (bvx:bitvec) (bvy:bitvec),
  ((bv_to_int (concat bvx bvy)) =
   (((power 2%Z (length bvy)) * (bv_to_int bvx))%Z + (bv_to_int bvy))%Z).

Axiom bijective_concat :
  forall (i:Z) (j:Z), (0%Z <= i)%Z -> (0%Z <= j)%Z ->
  (p_bijective (fun (o:(bitvec* bitvec)%type) => (concat (fir o) (sec o)))
   (cartesian_product (n_bvs i) (n_bvs j)) (n_bvs (i + j)%Z)) /\
  (p_bijective (fun (x:bitvec) => (hpart x i, tpart x i)) (n_bvs (i + j)%Z)
   (cartesian_product (n_bvs i) (n_bvs j))).

Axiom kproj_const_size :
  forall (f:Z -> matrix t) (i:Z) (j:Z) (k:Z) (l:Z) (h:Z),
  (constant_size (to_fset l h) f) -> (0%Z <= i)%Z -> (0%Z <= j)%Z ->
  (1%Z <= l)%Z -> ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  ((kproj f i j k l h) =
   (get (f ((l + k)%Z - 1%Z)%Z)
    (kth_nit_l i k (s_rows (to_fset l h) f) (h - l)%Z)
    (kth_nit_l j k (s_columns (to_fset l h) f) (h - l)%Z))).

Axiom kproj_const_size_gen :
  forall (f:Z -> matrix t) (i:Z) (j:Z) (l:Z) (h:Z),
  (constant_size (to_fset l h) f) -> (0%Z <= i)%Z -> (0%Z <= j)%Z ->
  (1%Z <= l)%Z -> forall (k:Z), ((1%Z <= k)%Z /\ (k <= (h - l)%Z)%Z) ->
  ((kproj f i j k l h) =
   (get (f ((l + k)%Z - 1%Z)%Z)
    (kth_nit_l i k (s_rows (to_fset l h) f) (h - l)%Z)
    (kth_nit_l j k (s_columns (to_fset l h) f) (h - l)%Z))).

Axiom k_iter_values_const_size :
  forall (f:Z -> matrix t) (i:Z) (j:Z) (l:Z) (h:Z),
  (constant_size (to_fset l h) f) -> (valid_index (k_iter f l h) i j) ->
  ((1%Z <= l)%Z /\ (l < h)%Z) ->
  ((get (k_iter f l h) i j) =
   (ind_product
    (fun (k:Z) =>
     (get (f ((l + k)%Z - 1%Z)%Z)
      (kth_nit_l i k (s_rows (to_fset l h) f) (h - l)%Z)
      (kth_nit_l j k (s_columns (to_fset l h) f) (h - l)%Z)))
    1%Z ((h - l)%Z + 1%Z)%Z)).

Axiom k_iter_values_gen_const_size :
  forall (f:Z -> matrix t) (l:Z) (h:Z), (constant_size (to_fset l h) f) ->
  ((1%Z <= l)%Z /\ (l < h)%Z) -> forall (i:Z) (j:Z),
  (valid_index (k_iter f l h) i j) ->
  ((get (k_iter f l h) i j) =
   (ind_product
    (fun (k:Z) =>
     (get (f ((l + k)%Z - 1%Z)%Z)
      (kth_nit_l i k (s_rows (to_fset l h) f) (h - l)%Z)
      (kth_nit_l j k (s_columns (to_fset l h) f) (h - l)%Z)))
    1%Z ((h - l)%Z + 1%Z)%Z)).

Parameter ket: Z -> Z -> matrix t.

Axiom ket_def :
  forall (n:Z) (i:Z), (0%Z <= n)%Z ->
  (((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
   ((ket n i) = (set1 (make (power 2%Z n) 1%Z tzero) i 0%Z tone))) /\
  (~ ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
   ((ket n i) = (make 1%Z 1%Z tzero))).

Axiom ket_spec :
  forall (n:Z) (i:Z), (0%Z <= n)%Z ->
  (is_a_ket (ket n i)) /\
  ((((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) -> ((ket_length (ket n i)) = n)) /\
   (((columns (ket n i)) = 1%Z) /\
    ((((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
      ((rows (ket n i)) = (power 2%Z n))) /\
     ((forall (j:Z), (valid_index (ket n i) j 0%Z) ->
       ((get (ket n i) j 0%Z) = (indic j i))) /\
      ((forall (j:Z), (valid_index (ket n i) j 0%Z) -> ~ (i = j) ->
        ((get (ket n i) j 0%Z) = tzero)) /\
       (((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
        ((get (ket n i) i 0%Z) = tone))))))).

Axiom get_ket :
  forall (m:matrix t) (i:Z) (n:Z), (m = (ket n i)) -> (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  (is_a_ket m) /\
  (((ket_length m) = n) /\
   (((columns m) = 1%Z) /\
    (((rows m) = (power 2%Z n)) /\
     ((forall (j:Z), (valid_index m j 0%Z) -> ((get m j 0%Z) = (indic j i))) /\
      ((forall (j:Z), (valid_index m j 0%Z) -> ~ (i = j) ->
        ((get m j 0%Z) = tzero)) /\
       ((get m i 0%Z) = tone)))))).

Axiom get_ket_value :
  forall (i:Z) (n:Z) (j:Z), (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((0%Z <= j)%Z /\ (j < (power 2%Z n))%Z) ->
  ((get (ket n i) j 0%Z) = (indic j i)).

Axiom set_ket :
  forall (m:matrix t) (i:Z) (n:Z), (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) -> ((columns m) = 1%Z) ->
  ((rows m) = (power 2%Z n)) ->
  (forall (j:Z), (valid_index m j 0%Z) -> ((get m j 0%Z) = (indic j i))) ->
  (m = (ket n i)).

(* Why3 assumption *)
Definition is_the_ket_bits (m:matrix t) (i:Z) (n:Z) : Prop :=
  (0%Z <= n)%Z /\
  (((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) /\ (equal m (ket n i))).

Axiom set_is_the_ket_bits :
  forall (m:matrix t) (i:Z) (n:Z), (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) -> (equal m (ket n i)) ->
  is_the_ket_bits m i n.

Axiom set_is_the_ket_bits_det :
  forall (m:matrix t) (i:Z) (n:Z), (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) -> ((rows m) = (power 2%Z n)) ->
  ((columns m) = 1%Z) ->
  (forall (j:Z), (valid_index m j 0%Z) -> ((get m j 0%Z) = (indic i j))) ->
  (is_a_ket m) /\ (((ket_length m) = n) /\ (is_the_ket_bits m i n)).

Axiom get_is_the_ket_bits :
  forall (m:matrix t) (i:Z) (n:Z), (is_the_ket_bits m i n) ->
  (0%Z <= n)%Z /\
  (((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) /\
   ((equal m (ket n i)) /\
    ((is_a_ket m) /\
     (((ket_length m) = n) /\
      forall (j:Z), (valid_index m j 0%Z) -> ((get m j 0%Z) = (indic i j)))))).

Parameter is_a_ket_bits: (matrix t) -> Z -> Prop.

Axiom is_a_ket_bits1 :
  forall (m:matrix t), forall (n:Z), (0%Z <= n)%Z ->
  (is_a_ket_bits m n) <->
  ((is_a_ket m) /\
   exists i:Z,
   ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) /\ (is_the_ket_bits m i n)).

Axiom the_ket_bits_is_a_ket_bits :
  forall (m:matrix t) (n:Z) (i:Z), ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  (0%Z <= n)%Z -> (is_the_ket_bits m i n) ->
  (is_a_ket_bits m n) /\ (is_a_ket m).

Axiom a_ket_bits_is_a_ket :
  forall (m:matrix t) (n:Z), (0%Z <= n)%Z -> (is_a_ket_bits m n) ->
  is_a_ket m.

Axiom usket :
  forall (i:Z) (n:Z), (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) -> is_the_ket_bits (ket n i) i n.

Axiom kronecker_q_ket :
  forall (m:matrix t) (n:matrix t), (is_a_ket m) -> (is_a_ket n) ->
  (is_a_ket (kronecker m n)) /\
  (((ket_length (kronecker m n)) = ((ket_length m) + (ket_length n))%Z) /\
   ((forall (l:Z), (valid_index (kronecker m n) l 0%Z) ->
     ((get (kronecker m n) l 0%Z) =
      (infix_asdt (get n (int.EuclideanDivision.mod1 l (rows n)) 0%Z)
       (get m (int.EuclideanDivision.div l (rows n)) 0%Z)))) /\
    forall (k:Z) (l:Z), (valid_index (kronecker m n) k l) ->
    ((get (kronecker m n) k l) =
     (infix_asdt
      (get n (int.EuclideanDivision.mod1 k (rows n))
       (int.EuclideanDivision.mod1 l (columns n)))
      (get m (int.EuclideanDivision.div k (rows n))
       (int.EuclideanDivision.div l (columns n))))))).

Axiom k_iter_ket :
  forall (f:Z -> matrix t) (l:Z) (h:Z),
  (forall (k:Z), ((l <= k)%Z /\ (k < h)%Z) -> is_a_ket (f k)) ->
  ((0%Z <= l)%Z /\ (l < h)%Z) ->
  (is_a_ket (k_iter f l h)) /\
  (((ket_length (k_iter f l h)) =
    (ind_isum (fun (k:Z) => (ket_length (f k))) l h)) /\
   forall (ind:Z), (valid_index (k_iter f l h) ind 0%Z) ->
   ((get (k_iter f l h) ind 0%Z) =
    (ind_product (fun (k:Z) => (kproj f ind 0%Z k l h)) 1%Z
     ((h - l)%Z + 1%Z)%Z))).

Axiom k_iter_ket_units :
  forall (f:Z -> matrix t) (l:Z) (h:Z), ((1%Z <= l)%Z /\ (l < h)%Z) ->
  (forall (k:Z), ((l <= k)%Z /\ (k < h)%Z) -> is_a_ket (f k)) ->
  (forall (k:Z), ((l <= k)%Z /\ (k < h)%Z) -> ((ket_length (f k)) = 1%Z)) ->
  (is_a_ket (k_iter f l h)) /\
  (((ket_length (k_iter f l h)) = (h - l)%Z) /\
   forall (i:Z), (valid_index (k_iter f l h) i 0%Z) ->
   ((get (k_iter f l h) i 0%Z) =
    (ind_product
     (fun (k:Z) =>
      (get (f ((l + k)%Z - 1%Z)%Z) (kth_bit_l i (h - l)%Z k) 0%Z))
     1%Z ((h - l)%Z + 1%Z)%Z))).

Axiom ket_kronecker_indexes_to_left :
  forall (m:matrix t) (n:matrix t), (is_a_ket m) -> (is_a_ket n) ->
  forall (k:Z) (l:Z),
  (valid_index m (int.EuclideanDivision.div k (rows n)) l) ->
  valid_index (kronecker m n) k l.

Axiom ket_kronecker_indexes :
  forall (m:matrix t) (n:matrix t), (is_a_ket m) -> (is_a_ket n) ->
  forall (k:Z) (l:Z),
  ((valid_index m (int.EuclideanDivision.div k (rows n)) l) /\
   (valid_index n (int.EuclideanDivision.mod1 l (rows n)) l)) <->
  (valid_index (kronecker m n) k l).

Axiom kronecker_ket_bits :
  forall (m:matrix t) (n:matrix t) (i:Z) (j:Z) (il:Z) (jl:Z),
  (0%Z <= jl)%Z -> (0%Z <= il)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z il))%Z) ->
  ((0%Z <= j)%Z /\ (j < (power 2%Z jl))%Z) -> (is_the_ket_bits m i il) ->
  (is_the_ket_bits n j jl) ->
  is_the_ket_bits (kronecker m n) ((i * (rows n))%Z + j)%Z (il + jl)%Z.

Axiom product_ket :
  forall (m:matrix t) (n:matrix t) (i:Z) (j:Z) (il:Z) (jl:Z),
  (0%Z <= jl)%Z -> (0%Z <= il)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z il))%Z) ->
  ((0%Z <= j)%Z /\ (j < (power 2%Z jl))%Z) -> (m = (ket il i)) ->
  (n = (ket jl j)) ->
  ((kronecker m n) = (ket (il + jl)%Z ((i * (rows n))%Z + j)%Z)).

Parameter unary_ket: Z -> matrix t.

Axiom unary_ket_def :
  forall (i:Z), ((0%Z <= i)%Z /\ (i < 2%Z)%Z) ->
  ((unary_ket i) = (set1 (make 2%Z 1%Z tzero) i 0%Z tone)).

Axiom unary_ket_spec :
  forall (i:Z), ((0%Z <= i)%Z /\ (i < 2%Z)%Z) ->
  (is_a_ket (unary_ket i)) /\
  (((ket_length (unary_ket i)) = 1%Z) /\
   (((unary_ket i) = (ket 1%Z i)) /\
    ((unary_ket i) = (make_f 2%Z 1%Z (fun (j:Z) (us:Z) => (indic i j)))))).

Parameter init_ket: Z -> Z -> matrix t.

Parameter result13: Z -> Z -> Z -> matrix t.

Axiom result_def13 :
  forall (i:Z) (n:Z) (k:Z),
  (((1%Z <= k)%Z /\ (k < (n + 1%Z)%Z)%Z) ->
   (((result13 i n) k) = (unary_ket (kth_bit_l i n k)))) /\
  (~ ((1%Z <= k)%Z /\ (k < (n + 1%Z)%Z)%Z) ->
   (((result13 i n) k) = (make 1%Z 1%Z tzero))).

Axiom init_ket_def :
  forall (i:Z) (n:Z), ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  (0%Z < n)%Z -> ((init_ket i n) = (k_iter (result13 i n) 1%Z (n + 1%Z)%Z)).

Axiom init_ket_spec :
  forall (i:Z) (n:Z), ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  (0%Z < n)%Z ->
  (is_a_ket (init_ket i n)) /\
  (((ket_length (init_ket i n)) = n) /\
   forall (j:Z), ((0%Z <= j)%Z /\ (j < (power 2%Z n))%Z) ->
   ((get (init_ket i n) j 0%Z) =
    (ind_product
     (fun (k:Z) => (get (ket 1%Z (kth_bit_l i n k)) (kth_bit_l j n k) 0%Z))
     1%Z (n + 1%Z)%Z))).

Axiom init_ket_espec :
  forall (i:Z) (n:Z), ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  (0%Z < n)%Z -> forall (j:Z), ((0%Z <= j)%Z /\ (j < (power 2%Z n))%Z) ->
  ((get (init_ket i n) j 0%Z) =
   (ind_product
    (fun (k:Z) => (get (ket 1%Z (kth_bit_l i n k)) (kth_bit_l j n k) 0%Z))
    1%Z (n + 1%Z)%Z)).

Axiom get_ket_kth :
  forall (i:Z) (n:Z), ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  forall (k:Z) (j:Z), ((0%Z <= j)%Z /\ (j < 2%Z)%Z) ->
  ((1%Z <= k)%Z /\ (k < (n + 1%Z)%Z)%Z) ->
  ((get (ket 1%Z (kth_bit_l i n k)) j 0%Z) = (indic j (kth_bit_l i n k))).

Axiom init_ket_bv :
  forall (i:Z) (j:Z) (n:Z), ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((0%Z <= j)%Z /\ (j < (power 2%Z n))%Z) -> (0%Z < n)%Z ->
  ((get (init_ket i n) j 0%Z) =
   (ind_product
    (fun (k:Z) =>
     (indic (getbv (int_to_bv i n) k) (getbv (int_to_bv j n) k)))
    1%Z (n + 1%Z)%Z)).

Axiom init_ket_bv_gen :
  forall (i:Z) (n:Z), ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  (0%Z < n)%Z -> forall (j:Z), ((0%Z <= j)%Z /\ (j < (power 2%Z n))%Z) ->
  ((get (init_ket i n) j 0%Z) =
   (ind_product
    (fun (k:Z) =>
     (indic (getbv (int_to_bv i n) k) (getbv (int_to_bv j n) k)))
    1%Z (n + 1%Z)%Z)).

Axiom init_ket_indic :
  forall (i:Z) (n:Z), ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  (0%Z < n)%Z -> forall (j:Z), ((0%Z <= j)%Z /\ (j < (power 2%Z n))%Z) ->
  ((get (init_ket i n) j 0%Z) = (indic i j)).

Axiom l_init_ket :
  forall (i:Z) (n:Z), (0%Z <= i)%Z -> (0%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) -> ((init_ket i n) = (ket n i)).

Parameter ind_basis_mat: Z -> Z -> Z -> Z -> matrix t.

Axiom ind_basis_mat_def :
  forall (i:Z) (j:Z) (r:Z) (c:Z), ((0%Z <= i)%Z /\ (i < r)%Z) ->
  ((0%Z <= j)%Z /\ (j < c)%Z) ->
  ((ind_basis_mat i j r c) =
   (make_f r c (fun (k:Z) (l:Z) => (indic_2 k i l j)))).

Parameter fc15: Z -> Z -> Z -> Z -> (Z* Z)%type -> bool.

Axiom fc_def15 :
  forall (i:Z) (j:Z) (r:Z) (c:Z) (x:(Z* Z)%type),
  (((fc15 i j r c) x) = true) <->
  ((get (ind_basis_mat i j r c) (fir x) (sec x)) = tone).

Axiom ind_basis_mat_spec :
  forall (i:Z) (j:Z) (r:Z) (c:Z), ((0%Z <= i)%Z /\ (i < r)%Z) ->
  ((0%Z <= j)%Z /\ (j < c)%Z) ->
  ((rows (ind_basis_mat i j r c)) = r) /\
  (((columns (ind_basis_mat i j r c)) = c) /\
   ((forall (k:Z) (l:Z), (valid_index (ind_basis_mat i j r c) k l) ->
     ((get (ind_basis_mat i j r c) k l) = (indic_2 k i l j))) /\
    ((cardinal (filter (fc15 i j r c) (mat_indices (ind_basis_mat i j r c))))
     = 1%Z))).

Axiom ind_basis_mat_values :
  forall (i:Z) (j:Z) (r:Z) (c:Z), ((0%Z <= i)%Z /\ (i < r)%Z) ->
  ((0%Z <= j)%Z /\ (j < c)%Z) -> forall (i1:Z) (j1:Z),
  ((0%Z <= i1)%Z /\ (i1 < r)%Z) -> ((0%Z <= j1)%Z /\ (j1 < c)%Z) ->
  ((get (ind_basis_mat i j r c) i1 j1) = (indic_2 i i1 j j1)).

Axiom unic_ind_basis_mat :
  forall (i1:Z) (j1:Z) (i2:Z) (j2:Z) (r:Z) (c:Z),
  ((0%Z <= i1)%Z /\ (i1 < r)%Z) -> ((0%Z <= j1)%Z /\ (j1 < c)%Z) ->
  ((0%Z <= i2)%Z /\ (i2 < r)%Z) -> ((0%Z <= j2)%Z /\ (j2 < c)%Z) ->
  ((ind_basis_mat i1 j1 r c) = (ind_basis_mat i2 j2 r c)) ->
  ((i1, j1) = (i2, j2)).

Parameter basis_mat: Z -> Z -> set (matrix t).

Parameter result14: Z -> Z -> (Z* Z)%type -> matrix t.

Axiom result_def14 :
  forall (r:Z) (c:Z) (o:(Z* Z)%type),
  match o with
  | (i, j) =>
      ((((0%Z <= i)%Z /\ (i < r)%Z) /\ ((0%Z <= j)%Z /\ (j < c)%Z)) ->
       (((result14 r c) o) = (ind_basis_mat i j r c))) /\
      (~ (((0%Z <= i)%Z /\ (i < r)%Z) /\ ((0%Z <= j)%Z /\ (j < c)%Z)) ->
       (((result14 r c) o) = (make r c tzero)))
  end.

Axiom basis_mat_def :
  forall (r:Z) (c:Z), (0%Z < r)%Z -> (0%Z < c)%Z ->
  ((basis_mat r c) =
   (map (result14 r c) (cartesian_product (to_fset 0%Z r) (to_fset 0%Z c)))).

Parameter fc16: (matrix t) -> (Z* Z)%type -> bool.

Axiom fc_def16 :
  forall (m:matrix t) (x:(Z* Z)%type),
  (((fc16 m) x) = true) <-> ((get m (fir x) (sec x)) = tone).

Axiom basis_mat_spec :
  forall (r:Z) (c:Z), (0%Z < r)%Z -> (0%Z < c)%Z ->
  (forall (m:matrix t),
   (mem m (basis_mat r c)) <->
   exists i:Z, exists j:Z,
   ((0%Z <= i)%Z /\ (i < r)%Z) /\
   (((0%Z <= j)%Z /\ (j < c)%Z) /\ (m = (ind_basis_mat i j r c)))) /\
  (((basis_mat r c) =
    (map (fun (o:(Z* Z)%type) => (ind_basis_mat (fir o) (sec o) r c))
     (cartesian_product (to_fset 0%Z r) (to_fset 0%Z c)))) /\
   ((constant_size (basis_mat r c) (fun (y0:matrix t) => y0)) /\
    (((s_columns (basis_mat r c) (fun (y0:matrix t) => y0)) = c) /\
     (((s_rows (basis_mat r c) (fun (y0:matrix t) => y0)) = r) /\
      forall (m:matrix t), (mem m (basis_mat r c)) ->
      ((cardinal (filter (fc16 m) (mat_indices m))) = 1%Z))))).

Parameter basis_mat_indexes: (matrix t) -> (Z* Z)%type.

Parameter result15: (matrix t) -> (Z* Z)%type -> bool.

Axiom result_def15 :
  forall (m:matrix t) (x:(Z* Z)%type),
  (((result15 m) x) = true) <->
  ((mem x (mat_indices m)) /\
   (equal m (ind_basis_mat (fir x) (sec x) (rows m) (columns m)))).

Axiom basis_mat_indexes_def :
  forall (m:matrix t), (mem m (basis_mat (rows m) (columns m))) ->
  ((basis_mat_indexes m) = (element (filter (result15 m) (mat_indices m)))).

Axiom basis_mat_indexes_spec :
  forall (m:matrix t), (mem m (basis_mat (rows m) (columns m))) ->
  (m =
   (ind_basis_mat (fir (basis_mat_indexes m)) (sec (basis_mat_indexes m))
    (rows m) (columns m))) /\
  ((m =
    (make_f (rows m) (columns m)
     (fun (i:Z) (j:Z) =>
      (indic_2 (fir (basis_mat_indexes m)) i (sec (basis_mat_indexes m)) j)))) /\
   (((get m (fir (basis_mat_indexes m)) (sec (basis_mat_indexes m))) = tone) /\
    forall (i:Z) (j:Z), (valid_index m i j) ->
    (i = (fir (basis_mat_indexes m))) ->
    ~ (j = (sec (basis_mat_indexes m))) -> ((get m i j) = tzero))).

Axiom get_basis_mat_indexes :
  forall (m:matrix t), (mem m (basis_mat (rows m) (columns m))) ->
  (m =
   (ind_basis_mat (fir (basis_mat_indexes m)) (sec (basis_mat_indexes m))
    (rows m) (columns m))) /\
  ((m =
    (make_f (rows m) (columns m)
     (fun (i:Z) (j:Z) =>
      (indic_2 (fir (basis_mat_indexes m)) i (sec (basis_mat_indexes m)) j)))) /\
   (((get m (fir (basis_mat_indexes m)) (sec (basis_mat_indexes m))) = tone) /\
    forall (i:Z) (j:Z), (valid_index m i j) ->
    ~ ((basis_mat_indexes m) = (i, j)) -> ((get m i j) = tzero))).

Axiom set_basis_mat_indexes :
  forall (m:matrix t) (i:Z) (j:Z), (valid_index m i j) ->
  (mem m (basis_mat (rows m) (columns m))) -> ((get m i j) = tone) ->
  ((basis_mat_indexes m) = (i, j)) /\
  ((m = (ind_basis_mat i j (rows m) (columns m))) /\
   ((m =
     (make_f (rows m) (columns m) (fun (i1:Z) (j1:Z) => (indic_2 i i1 j j1)))) /\
    forall (i1:Z) (j1:Z), (valid_index m i1 j1) -> (i1 = i) -> ~ (j1 = j) ->
    ((get m i1 j1) = tzero))).

Parameter basis_projection: (matrix t) -> Z -> Z -> matrix t.

Axiom basis_projection_def :
  forall (m:matrix t) (i:Z) (j:Z), ((0%Z <= i)%Z /\ (i < (rows m))%Z) ->
  ((0%Z <= j)%Z /\ (j < (columns m))%Z) ->
  ((basis_projection m i j) =
   (infix_asdtdt (get m i j) (ind_basis_mat i j (rows m) (columns m)))).

Axiom basis_projection_spec :
  forall (m:matrix t) (i:Z) (j:Z), ((0%Z <= i)%Z /\ (i < (rows m))%Z) ->
  ((0%Z <= j)%Z /\ (j < (columns m))%Z) ->
  ((rows (basis_projection m i j)) = (rows m)) /\
  (((columns (basis_projection m i j)) = (columns m)) /\
   (((basis_projection m i j) =
     (make_f (rows m) (columns m)
      (fun (k:Z) (l:Z) => (infix_asdt (get m i j) (indic_2 k i l j))))) /\
    (((get (basis_projection m i j) i j) = (get m i j)) /\
     ((forall (i':Z) (j':Z), (valid_index (basis_projection m i j) i' j') ->
       ~ (i' = i) -> ((get (basis_projection m i j) i' j') = tzero)) /\
      forall (i':Z) (j':Z), (valid_index (basis_projection m i j) i' j') ->
      ~ (j' = j) -> ((get (basis_projection m i j) i' j') = tzero))))).

Axiom basis_projection_null :
  forall (m:matrix t) (i:Z) (j:Z) (k:Z) (l:Z), (valid_index m i j) ->
  (valid_index m k l) -> ((i = k) -> ~ (j = l)) ->
  ((get (basis_projection m i j) k l) = tzero).

Parameter result16: (matrix t) -> (Z* Z)%type -> matrix t.

Axiom result_def16 :
  forall (m:matrix t) (o:(Z* Z)%type),
  ((valid_index m (fir o) (sec o)) ->
   (((result16 m) o) = (basis_projection m (fir o) (sec o)))) /\
  (~ (valid_index m (fir o) (sec o)) -> (((result16 m) o) = m)).

(* Why3 assumption *)
Definition basis_projections (m:matrix t) : set (matrix t) :=
  map (result16 m) (to_indexes m).

Axiom basis_projections_spec :
  forall (m:matrix t),
  ((basis_projections m) =
   (map
    ((fun (y0:Z -> Z -> matrix t) (y1:(Z* Z)%type) => (couple y0 y1))
     ((fun (y0:matrix t) (y1:Z) (y2:Z) => (basis_projection y0 y1 y2)) m))
    (to_indexes m))) /\
  ((forall (e:matrix t), (mem e (basis_projections m)) ->
    ((rows e) = (rows m))) /\
   ((forall (e:matrix t), (mem e (basis_projections m)) ->
     ((columns e) = (columns m))) /\
    (constant_size (basis_projections m) (fun (y0:matrix t) => y0)))).

Parameter fc17: (matrix t) -> (Z* Z)%type -> matrix t.

Axiom fc_def17 :
  forall (m:matrix t) (o:(Z* Z)%type),
  ((valid_index m (fir o) (sec o)) ->
   (((fc17 m) o) = (basis_projection m (fir o) (sec o)))) /\
  (~ (valid_index m (fir o) (sec o)) -> (((fc17 m) o) = m)).

Axiom rewrite_basis_projections :
  forall (m:matrix t),
  ((basis_projections m) = (map (fc17 m) (to_indexes m))).

Parameter result17: (matrix t) -> (Z* Z)%type -> matrix t.

Axiom result_def17 :
  forall (m:matrix t) (o:(Z* Z)%type),
  ((mem o (to_indexes m)) ->
   (((result17 m) o) = (basis_projection m (fir o) (sec o)))) /\
  (~ (mem o (to_indexes m)) -> (((result17 m) o) = m)).

(* Why3 assumption *)
Definition indexes_decomp (m:matrix t) : matrix t :=
  mat_sum (to_indexes m) (result17 m).

Axiom indexes_decomp_spec :
  forall (m:matrix t),
  ((rows (indexes_decomp m)) = (rows m)) /\
  ((columns (indexes_decomp m)) = (columns m)).

Axiom rewrite_indexes_decomp :
  forall (m:matrix t),
  ((indexes_decomp m) =
   (mat_sum (to_indexes m)
    (fun (o:(Z* Z)%type) => (basis_projection m (fir o) (sec o))))).

Axiom indexes_decomp_pre :
  forall (m:matrix t) (i:Z) (j:Z), (valid_index m i j) ->
  ((get m i j) =
   (sum (to_indexes m)
    (fun (o:(Z* Z)%type) => (get (basis_projection m (fir o) (sec o)) i j)))).

Axiom indexes_decomp_pre_gen :
  forall (m:matrix t), forall (i:Z) (j:Z), (valid_index m i j) ->
  ((get m i j) =
   (sum (to_indexes m)
    (fun (o:(Z* Z)%type) => (get (basis_projection m (fir o) (sec o)) i j)))).

Axiom mat_to_indexes_decomp : forall (m:matrix t), (m = (indexes_decomp m)).

(* Why3 assumption *)
Definition basis_decomp (m:matrix t) : matrix t :=
  mat_sum (basis_projections m) (fun (y0:matrix t) => y0).

Axiom basis_decomp_spec :
  forall (m:matrix t),
  ((rows (basis_decomp m)) = (rows m)) /\
  ((columns (basis_decomp m)) = (columns m)).

Axiom indexes_basis_decomp_equal_pre :
  forall (m:matrix t) (i:Z) (j:Z), (valid_index m i j) ->
  ((get (indexes_decomp m) i j) = (get (basis_decomp m) i j)).

Axiom indexes_basis_decomp_equal :
  forall (m:matrix t), ((indexes_decomp m) = (basis_decomp m)).

Axiom mat_to_basis_decomp : forall (m:matrix t), (m = (indexes_decomp m)).

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

Axiom fc_def18 :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:matrix t) (s:set a) (f:a -> matrix t) (a1:a),
  ((mem a1 s) -> (((fc18 m s f) a1) = (mat_mult m (f a1)))) /\
  (~ (mem a1 s) -> (((fc18 m s f) a1) = m)).

Axiom product_mat_sum_r_pre :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:matrix t) (s':set a) (s:set a) (f:a -> matrix t),
  (constant_size s f) -> ((columns m) = (s_rows s f)) -> (subset s' s) ->
  (0%Z < (cardinal s'))%Z ->
  ((mat_mult m (mat_sum s' f)) = (mat_sum s' (fc18 m s f))) /\
  (((mat_mult m (mat_sum s' f)) =
    (mat_sum s' (fun (a1:a) => (mat_mult m (f a1))))) /\
   (((rows (mat_sum s' f)) = (s_rows s f)) /\
    (((columns (mat_sum s' f)) = (s_columns s f)) /\
     (((rows (mat_mult m (mat_sum s' f))) = (rows m)) /\
      ((columns (mat_mult m (mat_sum s' f))) = (s_columns s f)))))).

Axiom product_mat_sum_r :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:matrix t) (s:set a) (f:a -> matrix t), (constant_size s f) ->
  ((columns m) = (s_rows s f)) -> (0%Z < (cardinal s))%Z ->
  ((mat_mult m (mat_sum s f)) =
   (mat_sum s (fun (a1:a) => (mat_mult m (f a1))))).

Axiom p_injective_proj :
  forall (m:matrix t),
  p_injective
  ((fun (y0:Z -> Z -> matrix t) (y1:(Z* Z)%type) => (couple y0 y1))
   ((fun (y0:matrix t) (y1:Z) (y2:Z) => (basis_projection y0 y1 y2)) m))
  (nonn_mat_subset
   ((fun (y0:Z -> Z -> matrix t) (y1:(Z* Z)%type) => (couple y0 y1))
    ((fun (y0:matrix t) (y1:Z) (y2:Z) => (basis_projection y0 y1 y2)) m))
   (to_indexes m)).

Axiom mat_decomp_equal_indexes :
  forall (m:matrix t), (m = (indexes_decomp m)).

Axiom basis_mat_init_ket :
  forall (i:Z) (n:Z), (0%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((init_ket i n) = (ind_basis_mat i 0%Z (power 2%Z n) 1%Z)).

Parameter ket_basis: Z -> set (matrix t).

Axiom ket_basis_def :
  forall (n:Z), (0%Z <= n)%Z ->
  ((ket_basis n) = (basis_mat (power 2%Z n) 1%Z)).

Axiom ket_basis_spec :
  forall (n:Z), (0%Z <= n)%Z ->
  ((ket_basis n) =
   (map
    (fun (o:(Z* Z)%type) =>
     (ind_basis_mat (fir o) (sec o) (power 2%Z n) 1%Z))
    (cartesian_product (to_fset 0%Z (power 2%Z n)) (to_fset 0%Z 1%Z)))) /\
  (((ket_basis n) = (basis_mat (power 2%Z n) 1%Z)) /\
   ((forall (mat:matrix t), (mem mat (ket_basis n)) ->
     ((rows mat) = (power 2%Z n))) /\
    ((forall (mat:matrix t), (mem mat (ket_basis n)) ->
      ((columns mat) = 1%Z)) /\
     forall (mat:matrix t), (mem mat (ket_basis n)) ->
     ((rows mat) = (power 2%Z n)) /\
     (((columns mat) = 1%Z) /\
      exists i:Z,
      (valid_index mat i 0%Z) /\ ((basis_mat_indexes mat) = (i, 0%Z)))))).

Axiom unary_ket_basis :
  forall (n:Z), (0%Z <= n)%Z ->
  ((ket_basis n) =
   (map (fun (i:Z) => (ind_basis_mat i 0%Z (power 2%Z n) 1%Z))
    (to_fset 0%Z (power 2%Z n)))).

Axiom to_ket_basis :
  forall (i:Z) (n:Z), (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  mem (ind_basis_mat i 0%Z (power 2%Z n) 1%Z) (ket_basis n).

Parameter ket_basis_index: (matrix t) -> Z -> Z.

Axiom ket_basis_index_def :
  forall (m:matrix t) (n:Z), (0%Z <= n)%Z -> (mem m (ket_basis n)) ->
  ((ket_basis_index m n) = (fir (basis_mat_indexes m))).

Axiom ket_basis_index_spec :
  forall (m:matrix t) (n:Z), (0%Z <= n)%Z -> (mem m (ket_basis n)) ->
  (mem (ind_basis_mat (ket_basis_index m n) 0%Z (power 2%Z n) 1%Z)
   (ket_basis n)) /\
  ((m =
    (make_f (rows m) 1%Z
     (fun (i:Z) (us:Z) => (indic (ket_basis_index m n) i)))) /\
   ((forall (i:Z), (valid_index m i 0%Z) -> ~ (i = (ket_basis_index m n)) ->
     ((get m i 0%Z) = tzero)) /\
    (valid_index m (ket_basis_index m n) 0%Z))).

Axiom set_ket_basis :
  forall (m:matrix t) (n:Z) (i:Z), (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) -> (mem m (ket_basis n)) ->
  ((get m i 0%Z) = tone) ->
  ((ket_basis_index m n) = i) /\
  ((forall (i1:Z), (valid_index m i1 0%Z) -> ~ (i1 = i) ->
    ((get m i1 0%Z) = tzero)) /\
   ((mem m (ket_basis n)) /\
    (m = (make_f (rows m) (columns m) (fun (i1:Z) (us:Z) => (indic i i1)))))).

Axiom from_ket_basis :
  forall (n:Z) (m:matrix t), (0%Z <= n)%Z -> (mem m (ket_basis n)) ->
  exists i:Z,
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) /\
  (m = (ind_basis_mat i 0%Z (power 2%Z n) 1%Z)).

Axiom int_to_ket_basis :
  forall (n:Z) (i:Z), (0%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) -> mem (ket n i) (ket_basis n).

(* Why3 assumption *)
Definition is_a_ket_basis_elt (m:matrix t) : Prop :=
  (is_a_ket m) /\ (mem m (ket_basis (ket_length m))).

Axiom ket_basis_elt_are_kets :
  forall (m:matrix t), (is_a_ket_basis_elt m) -> is_a_ket m.

Axiom get_is_a_ket_basis_elt :
  forall (m:matrix t), (is_a_ket_basis_elt m) ->
  (is_a_ket m) /\
  ((mem m (ket_basis (ket_length m))) /\
   exists i:Z,
   ((0%Z <= i)%Z /\ (i < (power 2%Z (ket_length m)))%Z) /\
   (m = (ket (ket_length m) i))).

Axiom set_is_a_ket_basis_elt :
  forall (m:matrix t), (is_a_ket m) ->
  (exists i:Z,
   ((0%Z <= i)%Z /\ (i < (power 2%Z (ket_length m)))%Z) /\
   (m = (ket (ket_length m) i))) ->
  (mem m (ket_basis (ket_length m))) -> is_a_ket_basis_elt m.

Axiom set_is_a_ket_basis_elt_exists :
  forall (m:matrix t), (is_a_ket m) ->
  (exists j:Z,
   ((0%Z <= j)%Z /\ (j < (power 2%Z (ket_length m)))%Z) /\
   (m =
    (make_f (power 2%Z (ket_length m)) 1%Z (fun (i:Z) (us:Z) => (indic i j))))) ->
  is_a_ket_basis_elt m.

Axiom ket_func_sets_ket_basis_elts :
  forall (n:Z) (i:Z), (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  (is_a_ket_basis_elt (ket n i)) /\ ((ket_length (ket n i)) = n).

Axiom kronecker_is_a_ket_basis_elt :
  forall (x:matrix t) (y:matrix t), (is_a_ket_basis_elt x) ->
  (is_a_ket_basis_elt y) -> is_a_ket_basis_elt (kronecker x y).

Axiom set_is_a_ket_basis_elt_test :
  forall (m:matrix t) (j:Z), (is_a_ket m) ->
  ((0%Z <= j)%Z /\ (j < (power 2%Z (ket_length m)))%Z) ->
  (m =
   (make_f (power 2%Z (ket_length m)) 1%Z (fun (i:Z) (us:Z) => (indic i j)))) ->
  is_a_ket_basis_elt m.

Axiom ket_apply_is_a_ket_basis_element :
  forall (n:Z) (i:Z), (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  (is_a_ket_basis_elt (ket n i)) /\ ((ket_length (ket n i)) = n).

Axiom ket_apply_is_a_ket_basis_element_gen :
  forall (n:Z), (0%Z <= n)%Z ->
  (forall (i:Z), ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
   is_a_ket_basis_elt (ket n i)) /\
  forall (i:Z), ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((ket_length (ket n i)) = n).

Axiom ket_is_a_ket_basis_elt :
  forall (n:Z) (i:Z), (0%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) -> is_a_ket_basis_elt (ket n i).

Axiom ket_basis_non_null_val :
  forall (m:matrix t) (n:Z) (i:Z), (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) -> (is_a_ket_basis_elt m) ->
  ((ket_length m) = n) -> ~ ((get m i 0%Z) = tzero) -> (m = (ket n i)).

Parameter ket_to_int: (matrix t) -> Z.

Parameter result18: (matrix t) -> Z -> bool.

Axiom result_def18 :
  forall (m:matrix t) (x:Z),
  (((result18 m) x) = true) <-> ((get m x 0%Z) = tone).

Axiom ket_to_int_def :
  forall (m:matrix t), (is_a_ket_basis_elt m) ->
  ((ket_to_int m) =
   (element (filter (result18 m) (to_fset 0%Z (power 2%Z (ket_length m)))))).

Axiom ket_to_int_spec :
  forall (m:matrix t), (is_a_ket_basis_elt m) ->
  ((0%Z <= (ket_to_int m))%Z /\
   ((ket_to_int m) < (power 2%Z (ket_length m)))%Z) /\
  ((m =
    (make_f (power 2%Z (ket_length m)) 1%Z
     (fun (k:Z) (us:Z) => (indic k (ket_to_int m))))) /\
   (m = (ket (ket_length m) (ket_to_int m)))).

Axiom ket_to_int_ket :
  forall (n:Z) (i:Z), (0%Z <= n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) -> ((ket_to_int (ket n i)) = i).

Axiom ket_ket_to_int :
  forall (x:matrix t), (is_a_ket_basis_elt x) ->
  ((ket (ket_length x) (ket_to_int x)) = x).

Axiom ket_ket_to_int_values :
  forall (x:matrix t), (is_a_ket_basis_elt x) -> forall (i:Z) (j:Z),
  (valid_index x i j) -> ((get x i j) = (indic i (ket_to_int x))).

Parameter ket_basis_projection: (matrix t) -> Z -> matrix t.

Axiom ket_basis_projection_def :
  forall (m:matrix t) (j:Z), (is_a_ket m) ->
  ((0%Z <= j)%Z /\ (j < (power 2%Z (ket_length m)))%Z) ->
  ((ket_basis_projection m j) =
   (infix_asdtdt (get m j 0%Z) (ket (ket_length m) j))).

Axiom ket_basis_projection_spec :
  forall (m:matrix t) (j:Z), (is_a_ket m) ->
  ((0%Z <= j)%Z /\ (j < (power 2%Z (ket_length m)))%Z) ->
  ((ket_basis_projection m j) = (basis_projection m j 0%Z)).

Axiom ket_basis_projection_columns :
  forall (m:matrix t) (j:Z), (is_a_ket m) ->
  ((0%Z <= j)%Z /\ (j < (power 2%Z (ket_length m)))%Z) ->
  ((columns (ket_basis_projection m j)) = 1%Z).

Axiom ket_basis_projection_rows :
  forall (m:matrix t) (j:Z), (is_a_ket m) ->
  ((0%Z <= j)%Z /\ (j < (power 2%Z (ket_length m)))%Z) ->
  ((rows (ket_basis_projection m j)) = (rows m)).

Parameter ket_basis_projections: (matrix t) -> set (matrix t).

Parameter result19: (matrix t) -> Z -> matrix t.

Axiom result_def19 :
  forall (m:matrix t) (j:Z),
  ((mem j (to_fset 0%Z (power 2%Z (ket_length m)))) ->
   (((result19 m) j) = (ket_basis_projection m j))) /\
  (~ (mem j (to_fset 0%Z (power 2%Z (ket_length m)))) ->
   (((result19 m) j) = m)).

Axiom ket_basis_projections_def :
  forall (m:matrix t), (is_a_ket m) ->
  ((ket_basis_projections m) =
   (map (result19 m) (to_fset 0%Z (power 2%Z (ket_length m))))).

Axiom ket_basis_projections_spec :
  forall (m:matrix t), (is_a_ket m) ->
  ((ket_basis_projections m) = (basis_projections m)).

Parameter ket_basis_projections_antec: (matrix t) -> unit.

Axiom ket_basis_projections_antec_def :
  forall (m:matrix t), (is_a_ket m) -> ((ket_basis_projections_antec m) = tt).

Axiom ket_basis_projections_antec_spec :
  forall (m:matrix t), (is_a_ket m) ->
  (forall (e:matrix t),
   (mem e (ket_basis_projections m)) <->
   exists j:Z,
   ((0%Z <= j)%Z /\ (j < (power 2%Z (ket_length m)))%Z) /\
   (e = (ket_basis_projection m j))) /\
  forall (e:matrix t),
  (mem e (ket_basis_projections m)) <->
  exists j:Z, exists i:Z,
  (valid_index m j i) /\ (e = (basis_projection m j i)).

Axiom ket_decomp :
  forall (m:matrix t) (n:Z), (0%Z <= n)%Z -> (is_a_ket m) ->
  ((ket_length m) = n) ->
  (m =
   (mat_sum (to_fset 0%Z (power 2%Z n))
    (fun (j:Z) => (infix_asdtdt (get m j 0%Z) (ket n j))))).

Axiom ket_decomp_quant :
  forall (m:matrix t), (is_a_ket m) ->
  (m =
   (mat_sum (to_fset 0%Z (power 2%Z (ket_length m)))
    (fun (j:Z) => (infix_asdtdt (get m j 0%Z) (ket (ket_length m) j))))).

Axiom mat_mult_ket_basis :
  forall (m:matrix t) (x:matrix t), (is_a_ket_basis_elt x) ->
  (((columns m) = (rows m)) /\ ((rows m) = (rows x))) ->
  ((mat_mult m x) =
   (mat_sum (to_fset 0%Z (rows x))
    (fun (k:Z) =>
     (infix_asdtdt (get m k (ket_to_int x)) (ket (ket_length x) k))))).

Parameter fc19: (Z -> Z) -> (set Z) -> (Z -> t) -> Z -> Z -> matrix t.

Parameter fc20:
  (Z -> Z) -> (set Z) -> (set Z) -> (Z -> t) -> Z -> Z -> matrix t.

Axiom fc_def19 :
  forall (f:Z -> Z) (s:set Z) (a:Z -> t) (n:Z) (j:Z),
  ((mem j s) ->
   (((fc19 f s a n) j) =
    (infix_asdtdt (a j) (set1 (make n 1%Z tzero) (f j) 0%Z tone)))) /\
  (~ (mem j s) -> (((fc19 f s a n) j) = (make n 1%Z tzero))).

Axiom fc_def20 :
  forall (f:Z -> Z) (s:set Z) (s':set Z) (a:Z -> t) (n:Z) (j:Z),
  ((mem j s') ->
   (((fc20 f s s' a n) j) =
    (infix_asdtdt (a (inv_func f s s' j))
     (set1 (make n 1%Z tzero) j 0%Z tone)))) /\
  (~ (mem j s') -> (((fc20 f s s' a n) j) = (make n 1%Z tzero))).

Axiom fun_inversion_ :
  forall (f:Z -> Z) (s:set Z) (s':set Z) (a:Z -> t) (n:Z), (0%Z <= n)%Z ->
  (0%Z < (cardinal s))%Z -> (p_bijective f s s') ->
  (subset s (to_fset 0%Z n)) -> (subset s' (to_fset 0%Z n)) ->
  ((mat_sum s (fc19 f s a n)) = (mat_sum s' (fc20 f s s' a n))).

Axiom ket_fun_inversion :
  forall (f:Z -> Z) (a:Z -> t) (m:matrix t) (pow_2_n:Z),
  (pow_2_n = (power 2%Z (ket_length m))) -> (is_a_ket m) ->
  (0%Z < pow_2_n)%Z ->
  (p_bijective f (to_fset 0%Z pow_2_n) (to_fset 0%Z pow_2_n)) ->
  (m =
   (mat_sum (to_fset 0%Z pow_2_n)
    (fun (j:Z) => (infix_asdtdt (a j) (ket (ket_length m) (f j)))))) ->
  (m =
   (mat_sum (to_fset 0%Z pow_2_n)
    (fun (j:Z) =>
     (infix_asdtdt (a (inv_ f (to_fset 0%Z pow_2_n) (to_fset 0%Z pow_2_n) j))
      (ket (ket_length m) j))))).

Parameter min_set: (set Z) -> Z.

Axiom min_set_def :
  forall (s:set Z), (0%Z < (cardinal s))%Z ->
  (((cardinal s) = 1%Z) -> ((min_set s) = (choose s))) /\
  (~ ((cardinal s) = 1%Z) ->
   ((min_set s) =
    (ZArith.BinInt.Z.min (choose s) (min_set (remove (choose s) s))))).

Axiom min_set_spec :
  forall (s:set Z), (0%Z < (cardinal s))%Z ->
  (mem (min_set s) s) /\ forall (e:Z), (mem e s) -> ((min_set s) <= e)%Z.

Parameter max_set: (set Z) -> Z.

Axiom max_set_def :
  forall (s:set Z), (0%Z < (cardinal s))%Z ->
  (((cardinal s) = 1%Z) -> ((max_set s) = (choose s))) /\
  (~ ((cardinal s) = 1%Z) ->
   ((max_set s) =
    (ZArith.BinInt.Z.max (choose s) (max_set (remove (choose s) s))))).

Axiom max_set_spec :
  forall (s:set Z), (0%Z < (cardinal s))%Z ->
  (mem (max_set s) s) /\ forall (e:Z), (mem e s) -> (e <= (max_set s))%Z.

Axiom pre_injective_bv_to_int :
  forall (bv1:bitvec) (bv2:bitvec), ((length bv1) = (length bv2)) ->
  ~ (bv1 = bv2) -> ~ ((bv_to_int bv1) = (bv_to_int bv2)).

Axiom injective_bv_to_int :
  forall (n:Z), (0%Z <= n)%Z ->
  p_injective (fun (y0:bitvec) => (bv_to_int y0)) (n_bvs n).

Axiom bijective_to_int :
  forall (n:Z), (0%Z < n)%Z ->
  p_bijective (fun (y0:bitvec) => (bv_to_int y0)) (n_bvs n)
  (to_fset 0%Z (power 2%Z n)).

Axiom concat_first_term_zero :
  forall (e:bitvec) (i:Z), (0%Z <= i)%Z ->
  (mem e (map (fun (bv:bitvec) => (concat_l bv 0%Z)) (n_bvs i))) ->
  ((getbv e 1%Z) = 0%Z).

Axiom concat_first_term_one :
  forall (e:bitvec) (i:Z), (0%Z <= i)%Z ->
  (mem e (map (fun (bv:bitvec) => (concat_l bv 1%Z)) (n_bvs i))) ->
  ((getbv e 1%Z) = 1%Z).

Axiom sum_concat :
  forall (f:bitvec -> matrix t) (i:Z) (r:Z) (c:Z), (0%Z < i)%Z ->
  (forall (bv:bitvec), ((rows (f bv)) = r)) ->
  (forall (bv:bitvec), ((columns (f bv)) = c)) ->
  ((mat_sum (n_bvs i)
    (fun (bv:bitvec) =>
     (add_mat (f (concat_l bv 0%Z)) (f (concat_l bv 1%Z)))))
   = (mat_sum (n_bvs (i + 1%Z)%Z) f)).

(* Why3 assumption *)
Definition xor (i:Z) (j:Z) : t :=
  i_to_t (int.EuclideanDivision.mod1 (i + j)%Z 2%Z).

(* Why3 assumption *)
Definition xand (i:Z) (j:Z) : t :=
  i_to_t (int.EuclideanDivision.mod1 ((i + 1%Z)%Z - j)%Z 2%Z).

(* Why3 assumption *)
Definition flip (i:Z) : t :=
  i_to_t (1%Z - (int.EuclideanDivision.mod1 i 2%Z))%Z.

Parameter cnot_func: Z -> Z -> t.

Axiom cnot_func_def :
  forall (i:Z) (j:Z),
  (((int.EuclideanDivision.div i 2%Z) = 0%Z) ->
   ((cnot_func i j) =
    (infix_asdt
     (xand (int.EuclideanDivision.div i 2%Z)
      (int.EuclideanDivision.div j 2%Z))
     (xand (int.EuclideanDivision.mod1 i 2%Z)
      (int.EuclideanDivision.mod1 j 2%Z))))) /\
  (~ ((int.EuclideanDivision.div i 2%Z) = 0%Z) ->
   ((cnot_func i j) =
    (infix_asdt
     (xand (int.EuclideanDivision.div i 2%Z)
      (int.EuclideanDivision.div j 2%Z))
     (xor (int.EuclideanDivision.mod1 i 2%Z)
      (int.EuclideanDivision.mod1 j 2%Z))))).

Axiom xorzz :
  forall (i:Z) (j:Z), (i = 0%Z) -> (j = 0%Z) -> ((xor i j) = tzero).

Axiom xorzt :
  forall (i:Z) (j:Z), (i = 0%Z) -> (j = 1%Z) -> ((xor i j) = tone).

Axiom xortz :
  forall (i:Z) (j:Z), (i = 1%Z) -> (j = 0%Z) -> ((xor i j) = tone).

Axiom xortt :
  forall (i:Z) (j:Z), (i = 1%Z) -> (j = 1%Z) -> ((xor i j) = tzero).

Axiom xandzz :
  forall (i:Z) (j:Z), (i = 0%Z) -> (j = 0%Z) -> ((xand i j) = tone).

Axiom xandzt :
  forall (i:Z) (j:Z), (i = 0%Z) -> (j = 1%Z) -> ((xand i j) = tzero).

Axiom xandtz :
  forall (i:Z) (j:Z), (i = 1%Z) -> (j = 0%Z) -> ((xand i j) = tzero).

Axiom xandtt :
  forall (i:Z) (j:Z), (i = 1%Z) -> (j = 1%Z) -> ((xand i j) = tone).

Axiom flipz : forall (i:Z), (i = 0%Z) -> ((flip i) = tone).

Axiom flipt : forall (i:Z), (i = 1%Z) -> ((flip i) = tzero).

Axiom i_to_tz : forall (i:Z), (i = 0%Z) -> ((i_to_t i) = tzero).

Axiom i_to_tt : forall (i:Z), (i = 1%Z) -> ((i_to_t i) = tone).

Axiom cnot_func00 :
  forall (i:Z) (j:Z), (i = 0%Z) -> (j = 0%Z) -> ((cnot_func i j) = tone).

Axiom cnot_func01 :
  forall (i:Z) (j:Z), (i = 0%Z) -> (j = 1%Z) -> ((cnot_func i j) = tzero).

Axiom cnot_func02 :
  forall (i:Z) (j:Z), (i = 0%Z) -> (j = 2%Z) -> ((cnot_func i j) = tzero).

Axiom cnot_func03 :
  forall (i:Z) (j:Z), (i = 0%Z) -> (j = 3%Z) -> ((cnot_func i j) = tzero).

Axiom cnot_func10 :
  forall (i:Z) (j:Z), (i = 1%Z) -> (j = 0%Z) -> ((cnot_func i j) = tzero).

Axiom cnot_func11 :
  forall (i:Z) (j:Z), (i = 1%Z) -> (j = 1%Z) -> ((cnot_func i j) = tone).

Axiom cnot_func12 :
  forall (i:Z) (j:Z), (i = 1%Z) -> (j = 2%Z) -> ((cnot_func i j) = tzero).

Axiom cnot_func13 :
  forall (i:Z) (j:Z), (i = 1%Z) -> (j = 3%Z) -> ((cnot_func i j) = tzero).

Axiom cnot_func20 :
  forall (i:Z) (j:Z), (i = 2%Z) -> (j = 0%Z) -> ((cnot_func i j) = tzero).

Axiom cnot_func21 :
  forall (i:Z) (j:Z), (i = 2%Z) -> (j = 1%Z) -> ((cnot_func i j) = tzero).

Axiom cnot_func22 :
  forall (i:Z) (j:Z), (i = 2%Z) -> (j = 2%Z) -> ((cnot_func i j) = tzero).

Axiom cnot_func23 :
  forall (i:Z) (j:Z), (i = 2%Z) -> (j = 3%Z) -> ((cnot_func i j) = tone).

Axiom cnot_func30 :
  forall (i:Z) (j:Z), (i = 3%Z) -> (j = 0%Z) -> ((cnot_func i j) = tzero).

Axiom cnot_func31 :
  forall (i:Z) (j:Z), (i = 3%Z) -> (j = 1%Z) -> ((cnot_func i j) = tzero).

Axiom cnot_func32 :
  forall (i:Z) (j:Z), (i = 3%Z) -> (j = 2%Z) -> ((cnot_func i j) = tone).

Axiom cnot_func33 :
  forall (i:Z) (j:Z), (i = 3%Z) -> (j = 3%Z) -> ((cnot_func i j) = tzero).

Parameter sum_range: quantum_circuit -> Z.

Axiom sum_range_def :
  forall (c:quantum_circuit),
  match to_pre c with
  | Phase _ => ((sum_range c) = 0%Z)
  | Rx _ => ((sum_range c) = 1%Z)
  | Ry _ => ((sum_range c) = 1%Z)
  | Rz _ => ((sum_range c) = 0%Z)
  | Cnot => ((sum_range c) = 0%Z)
  | Sequence d e =>
      ((sum_range c) = ((sum_range (to_qc d)) + (sum_range (to_qc e)))%Z)
  | Parallel d e =>
      ((sum_range c) = ((sum_range (to_qc d)) + (sum_range (to_qc e)))%Z)
  end.

Axiom sum_range_spec : forall (c:quantum_circuit), (0%Z <= (sum_range c))%Z.

Parameter ket_part: quantum_circuit -> (Z -> Z) -> (Z -> Z) -> Z -> Z.

Axiom ket_part_def :
  forall (c:quantum_circuit) (bvx:Z -> Z) (bvy:Z -> Z) (i:Z), (binary bvx) ->
  (binary bvy) ->
  match to_pre c with
  | Phase _ => ((ket_part c bvx bvy i) = (bvx i))
  | Rx _ => ((ket_part c bvx bvy i) = (bvy i))
  | Ry _ => ((ket_part c bvx bvy i) = (bvy i))
  | Rz _ => ((ket_part c bvx bvy i) = (bvx i))
  | Cnot =>
      ((i = 2%Z) ->
       ((ket_part c bvx bvy i) =
        (int.EuclideanDivision.mod1 ((bvx 1%Z) + (bvx 2%Z))%Z 2%Z))) /\
      (~ (i = 2%Z) -> ((ket_part c bvx bvy i) = (bvx i)))
  | Sequence d e =>
      ((ket_part c bvx bvy i) =
       (ket_part (to_qc e)
        ((((fun (y0:quantum_circuit) (y1:Z -> Z) (y2:Z -> Z) (y3:Z) =>
            (ket_part y0 y1 y2 y3))
           (to_qc d))
          bvx)
         bvy)
        (((fun (y0:Z -> Z) (y1:Z) (y2:Z) => (shift y0 y1 y2)) bvy)
         (sum_range (to_qc d)))
        i))
  | Parallel d e =>
      ((ket_part c bvx bvy i) =
       (concat_fun
        ((((fun (y0:quantum_circuit) (y1:Z -> Z) (y2:Z -> Z) (y3:Z) =>
            (ket_part y0 y1 y2 y3))
           (to_qc d))
          bvx)
         bvy)
        ((((fun (y0:quantum_circuit) (y1:Z -> Z) (y2:Z -> Z) (y3:Z) =>
            (ket_part y0 y1 y2 y3))
           (to_qc e))
          bvx)
         bvy)
        (depth (to_qc d)) i))
  end.

Axiom ket_part_spec :
  forall (c:quantum_circuit) (bvx:Z -> Z) (bvy:Z -> Z) (i:Z), (binary bvx) ->
  (binary bvy) ->
  (0%Z <= (ket_part c bvx bvy i))%Z /\ ((ket_part c bvx bvy i) < 2%Z)%Z.

Axiom binary_ket_part :
  forall (c:quantum_circuit) (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) ->
  (binary bvy) ->
  binary
  ((((fun (y0:quantum_circuit) (y1:Z -> Z) (y2:Z -> Z) (y3:Z) =>
      (ket_part y0 y1 y2 y3))
     c)
    bvx)
   bvy).

Parameter phase_part: quantum_circuit -> (Z -> Z) -> (Z -> Z) -> t.

Axiom phase_part_def :
  forall (c:quantum_circuit) (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) ->
  (binary bvy) ->
  match to_pre c with
  | Phase o => ((phase_part c bvx bvy) = (d_omega o))
  | Rx o =>
      ((phase_part c bvx bvy) =
       (infix_asdt squarert_two
        (infix_mndt
         (infix_asdt (xand (bvx 1%Z) (bvy 1%Z)) (d_cos (div_two o)))
         (infix_asdt (infix_asdt (xor (bvx 1%Z) (bvy 1%Z)) im)
          (d_sin (div_two o))))))
  | Ry o =>
      ((phase_part c bvx bvy) =
       (infix_asdt squarert_two
        (infix_pldt
         (infix_asdt (xand (bvx 1%Z) (bvy 1%Z)) (d_cos (div_two o)))
         (infix_asdt
          (infix_asdt (xor (bvx 1%Z) (bvy 1%Z))
           (cpower (prefix_mndt tone) (bvy 1%Z)))
          (d_sin (div_two o))))))
  | Rz o =>
      ((phase_part c bvx bvy) =
       (d_omega (phase_inv_ (1%Z - (bvx 1%Z))%Z (div_two o))))
  | Cnot => ((phase_part c bvx bvy) = tone)
  | Sequence d e =>
      ((phase_part c bvx bvy) =
       (infix_asdt
        (phase_part (to_qc d) bvx
         (((fun (y0:Z -> Z) (y1:Z) (y2:Z) => (shift y0 y1 y2)) bvy)
          (sum_range (to_qc d))))
        (phase_part (to_qc e)
         ((((fun (y0:quantum_circuit) (y1:Z -> Z) (y2:Z -> Z) (y3:Z) =>
             (ket_part y0 y1 y2 y3))
            (to_qc d))
           bvx)
          (((fun (y0:Z -> Z) (y1:Z) (y2:Z) => (shift y0 y1 y2)) bvy)
           (sum_range (to_qc d))))
         bvy)))
  | Parallel d e =>
      ((phase_part c bvx bvy) =
       (infix_asdt
        (phase_part (to_qc e)
         (((fun (y0:Z -> Z) (y1:Z) (y2:Z) => (shift y0 y1 y2)) bvx)
          (depth (to_qc d)))
         (((fun (y0:Z -> Z) (y1:Z) (y2:Z) => (shift y0 y1 y2)) bvy)
          (sum_range (to_qc d))))
        (phase_part (to_qc d) bvx bvy)))
  end.

Axiom rz_spec1 :
  forall (o:d_frac),
  ((sum_range (rz o)) = 0%Z) /\
  (((depth (rz o)) = 1%Z) /\
   ((forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
     ((ket_part (rz o) bvx bvy 1%Z) = (bvx 1%Z))) /\
    forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
    ((phase_part (rz o) bvx bvy) =
     (d_omega (phase_inv_ (1%Z - (bvx 1%Z))%Z (div_two o)))))).

Axiom ry_spec1 :
  forall (o:d_frac),
  ((sum_range (ry o)) = 1%Z) /\
  (((depth (ry o)) = 1%Z) /\
   ((forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
     ((ket_part (ry o) bvx bvy 1%Z) = (bvy 1%Z))) /\
    forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
    ((phase_part (ry o) bvx bvy) =
     (infix_asdt squarert_two
      (infix_pldt (infix_asdt (xand (bvx 1%Z) (bvy 1%Z)) (d_cos (div_two o)))
       (infix_asdt
        (infix_asdt (xor (bvx 1%Z) (bvy 1%Z))
         (cpower (prefix_mndt tone) (bvy 1%Z)))
        (d_sin (div_two o)))))))).

Axiom rx_spec1 :
  forall (o:d_frac),
  ((sum_range (rx o)) = 1%Z) /\
  (((depth (rx o)) = 1%Z) /\
   ((forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
     ((ket_part (rx o) bvx bvy 1%Z) = (bvy 1%Z))) /\
    forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
    ((phase_part (rx o) bvx bvy) =
     (infix_asdt squarert_two
      (infix_mndt (infix_asdt (xand (bvx 1%Z) (bvy 1%Z)) (d_cos (div_two o)))
       (infix_asdt (infix_asdt (xor (bvx 1%Z) (bvy 1%Z)) im)
        (d_sin (div_two o)))))))).

Axiom cnot_spec :
  ((sum_range cnot) = 0%Z) /\
  (((depth cnot) = 2%Z) /\
   ((forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
     forall (i:Z), ((1%Z <= i)%Z /\ (i <= 2%Z)%Z) ->
     ((i = 2%Z) ->
      ((ket_part cnot bvx bvy i) =
       (int.EuclideanDivision.mod1 ((bvx 1%Z) + (bvx 2%Z))%Z 2%Z))) /\
     (~ (i = 2%Z) -> ((ket_part cnot bvx bvy i) = (bvx i)))) /\
    forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
    ((phase_part cnot bvx bvy) = tone))).

Axiom phase_spec1 :
  forall (o:d_frac),
  ((sum_range (phase o)) = 0%Z) /\
  (((depth (phase o)) = 1%Z) /\
   ((forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
     ((ket_part (phase o) bvx bvy 1%Z) = (bvx 1%Z))) /\
    forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
    ((phase_part (phase o) bvx bvy) = (d_omega o)))).

Axiom parallel_spec1 :
  forall (d:quantum_circuit) (e:quantum_circuit),
  ((depth (parallel d e)) = ((depth d) + (depth e))%Z) /\
  (((sum_range (parallel d e)) = ((sum_range d) + (sum_range e))%Z) /\
   ((forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
     forall (i:Z), ((1%Z <= i)%Z /\ (i <= (depth d))%Z) ->
     ((ket_part (parallel d e) bvx bvy i) =
      (concat_fun
       ((((fun (y0:quantum_circuit) (y1:Z -> Z) (y2:Z -> Z) (y3:Z) =>
           (ket_part y0 y1 y2 y3))
          d)
         bvx)
        bvy)
       ((((fun (y0:quantum_circuit) (y1:Z -> Z) (y2:Z -> Z) (y3:Z) =>
           (ket_part y0 y1 y2 y3))
          e)
         bvx)
        bvy)
       (depth d) i))) /\
    forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
    ((phase_part (parallel d e) bvx bvy) =
     (infix_asdt
      (phase_part e
       (((fun (y0:Z -> Z) (y1:Z) (y2:Z) => (shift y0 y1 y2)) bvx) (depth d))
       (((fun (y0:Z -> Z) (y1:Z) (y2:Z) => (shift y0 y1 y2)) bvy)
        (sum_range d)))
      (phase_part d bvx bvy))))).

Axiom sequence_spec1 :
  forall (d:quantum_circuit) (e:quantum_circuit),
  ((sum_range (sequence d e)) = ((sum_range d) + (sum_range e))%Z) /\
  (((depth (sequence d e)) = (depth d)) /\
   ((forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
     forall (i:Z), ((1%Z <= i)%Z /\ (i <= (depth d))%Z) ->
     ((ket_part (sequence d e) bvx bvy i) =
      (ket_part e
       ((((fun (y0:quantum_circuit) (y1:Z -> Z) (y2:Z -> Z) (y3:Z) =>
           (ket_part y0 y1 y2 y3))
          d)
         bvx)
        bvy)
       (((fun (y0:Z -> Z) (y1:Z) (y2:Z) => (shift y0 y1 y2)) bvy)
        (sum_range d))
       i))) /\
    forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
    ((phase_part (sequence d e) bvx bvy) =
     (infix_asdt
      (phase_part d bvx
       (((fun (y0:Z -> Z) (y1:Z) (y2:Z) => (shift y0 y1 y2)) bvy)
        (sum_range d)))
      (phase_part e
       ((((fun (y0:quantum_circuit) (y1:Z -> Z) (y2:Z -> Z) (y3:Z) =>
           (ket_part y0 y1 y2 y3))
          d)
         bvx)
        (((fun (y0:Z -> Z) (y1:Z) (y2:Z) => (shift y0 y1 y2)) bvy)
         (sum_range d)))
       bvy))))).

(* Why3 assumption *)
Definition bv_inversion (bv:bitvec) : bitvec :=
  make_bv (fun (k:Z) => (getbv bv (((length bv) - k)%Z + 1%Z)%Z)) (length bv).

Axiom bv_inversion_spec :
  forall (bv:bitvec),
  ((length (bv_inversion bv)) = (length bv)) /\
  forall (k:Z), (in_range (bv_inversion bv) k) ->
  ((getbv (bv_inversion bv) k) = (getbv bv (((length bv) - k)%Z + 1%Z)%Z)).

Axiom bv_inversion_value :
  forall (bv:bitvec) (i:Z),
  ((getbv (bv_inversion bv) i) = (getbv bv (((length bv) - i)%Z + 1%Z)%Z)).

Parameter int_bit_inversion: Z -> Z -> Z.

Axiom int_bit_inversion_def :
  forall (i:Z) (n:Z), (0%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((int_bit_inversion i n) = (bv_to_int (bv_inversion (int_to_bv i n)))).

Axiom int_bit_inversion_spec :
  forall (i:Z) (n:Z), (0%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  (0%Z <= (int_bit_inversion i n))%Z /\
  ((int_bit_inversion i n) < (power 2%Z n))%Z.

Axiom int_bit_inversion_onebit :
  forall (i:Z), ((0%Z <= i)%Z /\ (i < 2%Z)%Z) ->
  ((int_bit_inversion i 1%Z) = i).

Axiom bv_to_int_sum_inversion :
  forall (bv:bitvec), (0%Z < (length bv))%Z ->
  ((int_bit_inversion (bv_to_int bv) (length bv)) =
   (ind_isum
    (fun (k:Z) =>
     ((getbv bv (((length bv) - k)%Z + 1%Z)%Z) *
      (power 2%Z ((length bv) - k)%Z))%Z)
    1%Z ((length bv) + 1%Z)%Z)).

Axiom bv_to_int_sum_inversion_inc :
  forall (bv:bitvec), (0%Z < (length bv))%Z ->
  ((int_bit_inversion (bv_to_int bv) (length bv)) =
   (ind_isum (fun (k:Z) => ((getbv bv k) * (power 2%Z (k - 1%Z)%Z))%Z) 1%Z
    ((length bv) + 1%Z)%Z)).

Axiom inversion_to_int_comm :
  forall (bv:bitvec), (0%Z < (length bv))%Z ->
  ((int_to_bv (int_bit_inversion (bv_to_int bv) (length bv)) (length bv)) =
   (bv_inversion bv)).

Axiom bv_inversion_sum :
  forall (i:Z) (n:Z), (0%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((int_bit_inversion i n) =
   (ind_isum
    (fun (k:Z) =>
     ((getbv (int_to_bv i n) ((n - k)%Z + 1%Z)%Z) * (power 2%Z (n - k)%Z))%Z)
    1%Z (n + 1%Z)%Z)).

Axiom bv_to_int_inversion_sum :
  forall (bv:bitvec),
  ((bv_to_int (bv_inversion bv)) =
   (ind_isum
    (fun (k:Z) =>
     ((getbv bv (((length bv) - k)%Z + 1%Z)%Z) *
      (power 2%Z ((length bv) - k)%Z))%Z)
    1%Z ((length bv) + 1%Z)%Z)).

Axiom bv_to_int_bit_inversion :
  forall (bv:bitvec), (0%Z < (length bv))%Z ->
  ((bv_to_int (bv_inversion bv)) =
   (int_bit_inversion (bv_to_int bv) (length bv))).

Axiom bv_to_int_inversion_sum_inc :
  forall (bv:bitvec), (0%Z < (length bv))%Z ->
  ((bv_to_int (bv_inversion bv)) =
   (ind_isum (fun (k:Z) => ((getbv bv k) * (power 2%Z (k - 1%Z)%Z))%Z) 1%Z
    ((length bv) + 1%Z)%Z)).

Axiom bv_m_to_int_bit_inversion :
  forall (f:Z -> Z) (n:Z), (0%Z < n)%Z ->
  ((bv_to_int (bv_inversion (make_bv_m f n))) =
   (int_bit_inversion (bv_to_int (make_bv_m f n)) n)).

Axiom int_bit_inversion_tail_bits :
  forall (i:Z) (n:Z), (1%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((int_bit_inversion (tail_bits i n) (n - 1%Z)%Z) =
   (ind_isum
    (fun (k:Z) =>
     ((getbv (int_to_bv i n) ((n - k)%Z + 1%Z)%Z) *
      (power 2%Z ((n - k)%Z - 1%Z)%Z))%Z)
    1%Z n)).

Axiom tail_bits_int_bit_inversion :
  forall (bv:Z -> Z) (n:Z), (1%Z < n)%Z ->
  ((tail_bits (int_bit_inversion (bv_to_int (make_bv_m bv n)) n) n) =
   (ind_isum
    (fun (k:Z) =>
     ((int.EuclideanDivision.mod1 (bv ((n - k)%Z + 1%Z)%Z) 2%Z) *
      (power 2%Z (n - k)%Z))%Z)
    2%Z (n + 1%Z)%Z)).

Axiom int_bit_inversion_ht :
  forall (i:Z) (n:Z), (1%Z < n)%Z ->
  ((0%Z <= i)%Z /\ (i < (power 2%Z n))%Z) ->
  ((int_bit_inversion i n) =
   ((2%Z * (int_bit_inversion (tail_bits i n) (n - 1%Z)%Z))%Z +
    (head_bit i n))%Z).

Axiom bv_inversion_ht :
  forall (f:Z -> Z) (n:Z), (1%Z < n)%Z ->
  ((bv_to_int (bv_inversion (make_bv_m f n))) =
   ((head (make_bv_m f n)) +
    (2%Z * (bv_to_int (bv_inversion (tail (make_bv_m f n)))))%Z)%Z).

Axiom bv_inversion_ht_bv :
  forall (bv:bitvec), (1%Z < (length bv))%Z ->
  ((bv_to_int (bv_inversion bv)) =
   ((head bv) + (2%Z * (bv_to_int (bv_inversion (tail bv))))%Z)%Z).

Axiom bv_to_int_ht :
  forall (f:Z -> Z) (n:Z), (1%Z < n)%Z ->
  ((bv_to_int (make_bv_m f n)) =
   (((power 2%Z (n - 1%Z)%Z) * (head (make_bv_m f n)))%Z +
    (bv_to_int (tail (make_bv_m f n))))%Z).

Axiom bv_inversion_mult_ht :
  forall (fx:Z -> Z) (fy:Z -> Z) (n:Z), (1%Z < n)%Z ->
  (((bv_to_int (make_bv_m fx n)) *
    (bv_to_int (bv_inversion (make_bv_m fy n))))%Z
   =
   ((((head (make_bv_m fy n)) * (bv_to_int (make_bv_m fx n)))%Z +
     ((bv_to_int (tail (make_bv_m fx n))) *
      (2%Z * (bv_to_int (bv_inversion (tail (make_bv_m fy n)))))%Z)%Z)%Z
    +
    ((power 2%Z n) *
     ((head (make_bv_m fx n)) *
      (bv_to_int (bv_inversion (tail (make_bv_m fy n)))))%Z)%Z)%Z).

Axiom bv_inversion_mult_ht_bv :
  forall (bvx:bitvec) (bvy:bitvec), (1%Z < (length bvx))%Z ->
  ((length bvx) = (length bvy)) ->
  (((bv_to_int bvx) * (bv_to_int (bv_inversion bvy)))%Z =
   ((((head bvy) * (bv_to_int bvx))%Z +
     ((bv_to_int (tail bvx)) *
      (2%Z * (bv_to_int (bv_inversion (tail bvy))))%Z)%Z)%Z
    +
    ((power 2%Z (length bvx)) *
     ((head bvx) * (bv_to_int (bv_inversion (tail bvy))))%Z)%Z)%Z).

Parameter n: Z.

Axiom H : (1%Z <= n)%Z.

Axiom H1 : ((num (dyadic 1%Z n)) = 1%Z).

Axiom H2 : ((den (dyadic 1%Z n)) = n).

Axiom H3 : ((to_values (dyadic 1%Z n)) = (1%Z, n)).

Axiom H4 : ((sum_range (rz (dyadic 1%Z n))) = 0%Z).

Axiom H5 : ((depth (rz (dyadic 1%Z n))) = 1%Z).

Axiom H6 :
  forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
  ((ket_part (rz (dyadic 1%Z n)) bvx bvy 1%Z) = (bvx 1%Z)).

Axiom H7 :
  forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
  ((phase_part (rz (dyadic 1%Z n)) bvx bvy) =
   (d_omega (phase_inv_ (1%Z - (bvx 1%Z))%Z (div_two (dyadic 1%Z n))))).

Axiom H8 : ((num (dyadic 1%Z (n - 1%Z)%Z)) = 1%Z).

Axiom H9 : ((den (dyadic 1%Z (n - 1%Z)%Z)) = (n - 1%Z)%Z).

Axiom H10 : ((to_values (dyadic 1%Z (n - 1%Z)%Z)) = (1%Z, (n - 1%Z)%Z)).

Axiom H11 : ((sum_range (phase (dyadic 1%Z (n - 1%Z)%Z))) = 0%Z).

Axiom H12 : ((depth (phase (dyadic 1%Z (n - 1%Z)%Z))) = 1%Z).

Axiom H13 :
  forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
  ((ket_part (phase (dyadic 1%Z (n - 1%Z)%Z)) bvx bvy 1%Z) = (bvx 1%Z)).

Axiom H14 :
  forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
  ((phase_part (phase (dyadic 1%Z (n - 1%Z)%Z)) bvx bvy) =
   (d_omega (dyadic 1%Z (n - 1%Z)%Z))).

Axiom H15 : ((num (dyadic 1%Z n)) = 1%Z).

Axiom H16 : ((den (dyadic 1%Z n)) = n).

Axiom H17 : ((to_values (dyadic 1%Z n)) = (1%Z, n)).

Axiom H18 : ((to_pre (rz (dyadic 1%Z n))) = (Rz (dyadic 1%Z n))).

Axiom H19 : ((num (dyadic 1%Z (n - 1%Z)%Z)) = 1%Z).

Axiom H20 : ((den (dyadic 1%Z (n - 1%Z)%Z)) = (n - 1%Z)%Z).

Axiom H21 : ((to_values (dyadic 1%Z (n - 1%Z)%Z)) = (1%Z, (n - 1%Z)%Z)).

Axiom H22 :
  ((to_pre (phase (dyadic 1%Z (n - 1%Z)%Z))) =
   (Phase (dyadic 1%Z (n - 1%Z)%Z))).

Axiom H23 :
  ((sum_range
    (sequence (phase (dyadic 1%Z (n - 1%Z)%Z)) (rz (dyadic 1%Z n))))
   =
   ((sum_range (phase (dyadic 1%Z (n - 1%Z)%Z))) +
    (sum_range (rz (dyadic 1%Z n))))%Z).

Axiom H24 :
  ((depth (sequence (phase (dyadic 1%Z (n - 1%Z)%Z)) (rz (dyadic 1%Z n)))) =
   (depth (phase (dyadic 1%Z (n - 1%Z)%Z)))).

Axiom H25 :
  forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
  forall (i:Z),
  ((1%Z <= i)%Z /\ (i <= (depth (phase (dyadic 1%Z (n - 1%Z)%Z))))%Z) ->
  ((ket_part (sequence (phase (dyadic 1%Z (n - 1%Z)%Z)) (rz (dyadic 1%Z n)))
    bvx bvy i)
   =
   (ket_part (rz (dyadic 1%Z n))
    ((((fun (y0:quantum_circuit) (y1:Z -> Z) (y2:Z -> Z) (y3:Z) =>
        (ket_part y0 y1 y2 y3))
       (phase (dyadic 1%Z (n - 1%Z)%Z)))
      bvx)
     bvy)
    (((fun (y0:Z -> Z) (y1:Z) (y2:Z) => (shift y0 y1 y2)) bvy)
     (sum_range (phase (dyadic 1%Z (n - 1%Z)%Z))))
    i)).

Axiom H26 :
  forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
  ((phase_part
    (sequence (phase (dyadic 1%Z (n - 1%Z)%Z)) (rz (dyadic 1%Z n))) bvx bvy)
   =
   (infix_asdt
    (phase_part (phase (dyadic 1%Z (n - 1%Z)%Z)) bvx
     (((fun (y0:Z -> Z) (y1:Z) (y2:Z) => (shift y0 y1 y2)) bvy)
      (sum_range (phase (dyadic 1%Z (n - 1%Z)%Z)))))
    (phase_part (rz (dyadic 1%Z n))
     ((((fun (y0:quantum_circuit) (y1:Z -> Z) (y2:Z -> Z) (y3:Z) =>
         (ket_part y0 y1 y2 y3))
        (phase (dyadic 1%Z (n - 1%Z)%Z)))
       bvx)
      (((fun (y0:Z -> Z) (y1:Z) (y2:Z) => (shift y0 y1 y2)) bvy)
       (sum_range (phase (dyadic 1%Z (n - 1%Z)%Z)))))
     bvy))).

Axiom H27 : ((num (dyadic 1%Z n)) = 1%Z).

Axiom H28 : ((den (dyadic 1%Z n)) = n).

Axiom H29 : ((to_values (dyadic 1%Z n)) = (1%Z, n)).

Axiom H30 : ((to_pre (rz (dyadic 1%Z n))) = (Rz (dyadic 1%Z n))).

Axiom H31 : ((num (dyadic 1%Z (n - 1%Z)%Z)) = 1%Z).

Axiom H32 : ((den (dyadic 1%Z (n - 1%Z)%Z)) = (n - 1%Z)%Z).

Axiom H33 : ((to_values (dyadic 1%Z (n - 1%Z)%Z)) = (1%Z, (n - 1%Z)%Z)).

Axiom H34 :
  ((to_pre (phase (dyadic 1%Z (n - 1%Z)%Z))) =
   (Phase (dyadic 1%Z (n - 1%Z)%Z))).

Axiom H35 :
  ((to_pre (sequence (phase (dyadic 1%Z (n - 1%Z)%Z)) (rz (dyadic 1%Z n)))) =
   (Sequence (to_pre (phase (dyadic 1%Z (n - 1%Z)%Z)))
    (to_pre (rz (dyadic 1%Z n))))).

Axiom H36 :
  ((depth (sequence (phase (dyadic 1%Z (n - 1%Z)%Z)) (rz (dyadic 1%Z n)))) =
   1%Z).

Axiom H37 :
  ((sum_range
    (sequence (phase (dyadic 1%Z (n - 1%Z)%Z)) (rz (dyadic 1%Z n))))
   = 0%Z).

Axiom H38 :
  forall (bvx:Z -> Z) (bvy:Z -> Z), (binary bvx) -> (binary bvy) ->
  ((ket_part (sequence (phase (dyadic 1%Z (n - 1%Z)%Z)) (rz (dyadic 1%Z n)))
    bvx bvy 1%Z)
   = (bvx 1%Z)).

Parameter bvx: Z -> Z.

Parameter bvy: Z -> Z.

Axiom H39 : binary bvx.

Axiom H40 : binary bvy.

Axiom h : ((bvx 1%Z) = 0%Z).

(* Why3 goal *)
Theorem VC_rzp :
  ((infix_asdt (d_omega (dyadic 1%Z (n - 1%Z)%Z))
    (d_omega
     (dyadic ((power (-1%Z)%Z (ZArith.BinInt.Z.abs (1%Z - 0%Z)%Z)) * 1%Z)%Z
      (n + 1%Z)%Z)))
   = (d_omega (dyadic 0%Z n))).
Proof.

Qed.