(* 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 map.Map.

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

Parameter tzero: t.

Parameter tone: t.

Parameter infix_asdt: t -> t -> t.

Parameter infix_pldt: t -> t -> t.

Parameter infix_lseqdt: t -> t -> Prop.

Parameter prefix_mn: t -> t.

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

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

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

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

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

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

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

Axiom Mul_distr_l :
  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_r :
  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 Comm1 : forall (x:t) (y:t), ((infix_asdt x y) = (infix_asdt y x)).

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

Axiom NonTrivialRing : ~ (tzero = tone).

Axiom Refl : forall (x:t), infix_lseqdt x x.

Axiom Trans :
  forall (x:t) (y:t) (z:t), (infix_lseqdt x y) -> (infix_lseqdt y z) ->
  infix_lseqdt x z.

Axiom Antisymm :
  forall (x:t) (y:t), (infix_lseqdt x y) -> (infix_lseqdt y x) -> (x = y).

Parameter infix_mndt: t -> t -> t.

Axiom infix_mndt_def :
  forall (x:t) (y:t), ((infix_mndt x y) = (infix_pldt x (prefix_mn y))).

Parameter prefix_mndt: t -> t.

Axiom prefix_mndt_def : forall (x:t), ((prefix_mndt x) = (prefix_mn x)).

Parameter infix_lsdt: t -> t -> Prop.

Axiom infix_lsdt_def :
  forall (i:t) (j:t), (infix_lsdt i j) <-> ((infix_lseqdt i j) /\ ~ (i = j)).

Parameter infix_gtdt: t -> t -> Prop.

Axiom infix_gtdt_def :
  forall (i:t) (j:t), (infix_gtdt i j) <-> (infix_lsdt j i).

Parameter infix_gteqdt: t -> t -> Prop.

Axiom infix_gteqdt_def :
  forall (i:t) (j:t), (infix_gteqdt i j) <-> (infix_lseqdt j i).

Parameter requal: t -> t -> bool.

Axiom requal_spec : forall (a:t) (b:t), ((requal a b) = true) <-> (a = b).

Parameter ttwo: t.

Axiom ttwo_def : (ttwo = (infix_pldt tone tone)).

Axiom ZeroLessOne : infix_lsdt tzero tone.

Axiom absorbing_zero : forall (i:t), ((infix_asdt i tzero) = tzero).

Parameter comparable: t -> t -> Prop.

Axiom comparable_def :
  forall (a:t) (b:t),
  (comparable a b) <-> ((infix_lseqdt a b) \/ (infix_lseqdt b a)).

Axiom Transitive_comparable :
  forall (x:t) (y:t) (z:t), (comparable x y) -> (comparable y z) ->
  comparable x z.

Axiom Unitary_comparable :
  forall (x:t) (y:t), (comparable x y) ->
  (comparable x tzero) /\ (comparable x tone).

Axiom CompatStrictOrderAdd :
  forall (x:t) (y:t) (z:t), (infix_lsdt x y) -> (comparable x z) ->
  infix_lsdt (infix_pldt x z) (infix_pldt y z).

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

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

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

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

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

Parameter inv: t -> t.

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

Parameter infix_sldt: t -> t -> t.

Axiom infix_sldt_def :
  forall (x:t) (y:t), ((infix_sldt x y) = (infix_asdt x (inv y))).

Axiom add_div :
  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_div :
  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_div :
  forall (x:t) (y:t), ~ (y = tzero) ->
  ((infix_sldt (prefix_mndt x) y) = (prefix_mndt (infix_sldt x y))).

Axiom assoc_mul_div :
  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_mul :
  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_div :
  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 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 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 singleton: forall {a:Type} {a_WT:WhyType a}, a -> set a.

Axiom singleton_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (x:a), ((singleton x) = (add x (empty : set a))).

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), ((cardinal s) >= 0%Z)%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 op: forall {im:Type} {im_WT:WhyType im}, im -> im -> im.

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

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

(* Why3 assumption *)
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.

Parameter prefix_ex: forall {a:Type} {a_WT:WhyType a}, (ref a) -> a.

Axiom prefix_ex_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (x:ref a), ((prefix_ex x) = (contents x)).

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

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

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

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

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

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

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

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

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

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

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

Axiom injective_def :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b},
  forall (s:set a) (f:a -> b),
  (injective s f) <->
  forall (a1:a) (b1:a), ~ (a1 = b1) -> ~ ((f a1) = (f b1)).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Axiom induction :
  forall {a:Type} {a_WT:WhyType a},
  forall (p:(set a) -> bool) (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)) <->
   match o with
   | (a1, b1) => (mem a1 s1) /\ (mem b1 s2)
   end).

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

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

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

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

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

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

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

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

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

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

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

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

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

Axiom id_def : forall {a:Type} {a_WT:WhyType a}, forall (e:a), ((id e) = e).

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

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

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

Axiom op_neutral_left_def :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (neutral:im),
  (op_neutral_left op1 neutral) <-> forall (e:im), (((op1 neutral) e) = e).

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

Axiom op_neutral_right_def :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (neutral:im),
  (op_neutral_right op1 neutral) <-> forall (e:im), (((op1 e) neutral) = e).

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

Axiom op_assoc_def :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im),
  (op_assoc op1) <->
  forall (a:im) (b:im) (c:im),
  (((op1 ((op1 a) b)) c) = ((op1 a) ((op1 b) c))).

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

Axiom op_neutral_left_c_def :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (neutral:im),
  (op_neutral_left_c op1 neutral) <->
  forall (a:im), (forall (b:im), (((op1 a) b) = b)) -> (a = neutral).

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

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

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

Axiom assoc_def :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im),
  (assoc op1) <->
  forall (a:im) (b:im) (c:im),
  (((op1 ((op1 a) b)) c) = ((op1 a) ((op1 b) c))).

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

Axiom opposite_n_def :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (po1:im -> im -> im) (neutral:im),
  (opposite_n op1 po1 neutral) <-> forall (a:im), (((po1 a) a) = neutral).

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

Axiom inverse_def :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (po1:im -> im -> im) (inver1:im -> im),
  (inverse op1 po1 inver1) <->
  forall (a:im) (b:im), (((po1 a) b) = ((op1 a) (inver1 b))).

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

Axiom opposite_def :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (po1:im -> im -> im),
  (opposite op1 po1) <-> forall (a:im) (b:im), (((op1 ((po1 a) b)) b) = a).

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

Axiom opposite_com_def :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (po1:im -> im -> im),
  (opposite_com op1 po1) <->
  forall (a:im) (b:im), (((po1 ((op1 a) b)) b) = a).

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

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

Axiom neutral_def :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (neutral1:im),
  (neutral op1 neutral1) <->
  ((op_neutral_left op1 neutral1) /\
   ((op_neutral_right op1 neutral1) /\
    ((op_assoc op1) /\ (op_neutral_left_c op1 neutral1)))).

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

Axiom iterates_def :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (neutral1:im),
  (iterates op1 neutral1) <->
  ((op_neutral_left op1 neutral1) /\
   ((op_neutral_right op1 neutral1) /\
    ((op_assoc op1) /\ ((op_neutral_left_c op1 neutral1) /\ (op_refl op1))))).

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

Axiom iterable_def :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im), (iterable op1) <-> exists e:im, iterates op1 e.

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

Axiom neutral_elt_spec :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im), (iterable op1) ->
  iterates op1 (neutral_elt op1).

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

Axiom inverse_tuple_def :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (po1:im -> im -> im) (neutral1:im),
  (inverse_tuple op1 po1 neutral1) <->
  ((opposite_n op1 po1 neutral1) /\
   ((opposite op1 po1) /\ (opposite_com op1 po1))).

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

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

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

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

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

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

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

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

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

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

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

Axiom iterate_application :
  forall {a:Type} {a_WT:WhyType a} {b:Type} {b_WT:WhyType b}
    {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (f:b -> b -> a -> im) (i:b) (j:b),
  ((((fun (i1:b) (j1:b) => (iterate op1 s (fun (e:a) => (((f i1) j1) e)))) i)
    j)
   = (iterate op1 s ((f i) j))).

Axiom int_iterate_application :
  forall {b:Type} {b_WT:WhyType b} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (k:Z) (l:Z) (f:b -> b -> Z -> im) (i:b) (j:b),
  ((((fun (i1:b) (j1:b) =>
      (int_iterate op1 (fun (e:Z) => (((f i1) j1) e)) k l))
     i)
    j)
   = (int_iterate op1 ((f i) j) k l)).

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

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

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

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

Axiom choose_any :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (f:a -> im) (t1:a), (iterable 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} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s1:set a) (f:a -> im) (g:a -> im),
  (iterable op1) ->
  ((iterate op1 s1 (fun (k:a) => ((op1 (f k)) (g k)))) =
   ((op1 (iterate op1 s1 (fun (k:a) => (f k))))
    (iterate op1 s1 (fun (k:a) => (g k))))).

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

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

Axiom iterate_disjoint_transitivity :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s1:set a) (s2:set a) (t1:a -> im),
  (iterable 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} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (f:a -> im) (g:a -> im),
  (forall (x:a), (mem x s) -> ((f x) = (g x))) ->
  ((iterate op1 s f) = (iterate op1 s g)).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Axiom result_def :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (t1:a -> im) (a1:a),
  (((result op1 t1) a1) = true) <-> ~ ((t1 a1) = (neutral_elt op1)).

Axiom nonnull_part_def :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable op1) ->
  ((nonnull_part op1 s t1) = (filter (result op1 t1) s)).

Axiom nonnull_part_spec :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable op1) ->
  forall (a1:a),
  (mem a1 (nonnull_part op1 s t1)) <->
  ((mem a1 s) /\ ~ ((t1 a1) = (neutral_elt op1))).

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

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

Axiom result_def1 :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (t1:a -> im) (a1:a),
  (((result1 op1 t1) a1) = true) <-> ((t1 a1) = (neutral_elt op1)).

Axiom null_part_def :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable op1) ->
  ((null_part op1 s t1) = (filter (result1 op1 t1) s)).

Axiom null_part_spec :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable op1) ->
  forall (a1:a),
  (mem a1 (null_part op1 s t1)) <->
  ((mem a1 s) /\ ((t1 a1) = (neutral_elt op1))).

Axiom nullity_partition :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable op1) ->
  (s = (union (nonnull_part op1 s t1) (null_part op1 s t1))) /\
  ((inter (nonnull_part op1 s t1) (null_part op1 s t1)) = (empty : set a)).

Axiom iterate_neutral :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable 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} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable op1) ->
  ((iterate op1 s t1) = (iterate op1 (nonnull_part op1 s t1) t1)).

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 iterate_cardone :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable op1) ->
  ((cardinal s) = 1%Z) -> ((iterate op1 s t1) = (t1 (element s))).

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

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

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

Axiom sum_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> t),
  ((sum s t1) = (iterate (fun (y0:t) (y1:t) => (infix_pldt y0 y1)) s t1)).

Axiom sum_iter : iterates (fun (y0:t) (y1:t) => (infix_pldt y0 y1)) tzero.

Axiom sum_iter__ : iterable (fun (y0:t) (y1:t) => (infix_pldt y0 y1)).

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

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

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

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

Axiom product_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> t),
  ((product s t1) = (iterate (fun (y0:t) (y1:t) => (infix_asdt y0 y1)) s t1)).

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)))) /\
   ((op_neutral_left_c (fun (y0:t) (y1:t) => (infix_asdt y0 y1)) tone) /\
    ((op_refl (fun (y0:t) (y1:t) => (infix_asdt y0 y1))) /\
     (iterates (fun (y0:t) (y1:t) => (infix_asdt y0 y1)) tone)))).

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

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

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

Axiom ind_product_def :
  forall (f:Z -> t) (i:Z) (j:Z),
  ((ind_product f i j) =
   (int_iterate (fun (y0:t) (y1:t) => (infix_asdt y0 y1)) f i j)).

(* Why3 assumption *)
Definition matrix (a:Type) := Z -> Z -> a.

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

Axiom rows_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:Z -> Z -> a), (0%Z < (rows m))%Z.

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

Axiom columns_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:Z -> Z -> a), (0%Z < (columns m))%Z.

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

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

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

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

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

Axiom make_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (r:Z) (c:Z) (v:a), ((r >= 0%Z)%Z /\ (c >= 0%Z)%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)) ->
   ((((make r c v) i) j) = v)).

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

Axiom set_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:Z -> Z -> a) (r:Z) (c:Z) (v:a), (valid_index a1 r c) ->
  ((set1 a1 r c v) =
   (map.Map.mixfix_lblsmnrb a1 r (map.Map.mixfix_lblsmnrb (a1 r) c v))).

Axiom set_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:Z -> Z -> 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)) -> ((((set1 a1 r c v) i) j) = v)) /\
     (~ ((i = r) /\ (j = c)) -> ((((set1 a1 r c v) i) j) = ((a1 i) j)))) /\
    (((((set1 a1 r c v) r) c) = v) /\
     ((forall (i:Z) (j:Z), (valid_index (set1 a1 r c v) i j) -> ~ (i = r) ->
       ((((set1 a1 r c v) i) j) = ((a1 i) j))) /\
      forall (i:Z) (j:Z), (valid_index (set1 a1 r c v) i j) -> ~ (j = c) ->
      ((((set1 a1 r c v) i) j) = ((a1 i) j)))))).

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

Axiom make_f_spec :
  forall {a:Type} {a_WT:WhyType a},
  forall (r:Z) (c:Z) (f:Z -> Z -> a),
  ((rows (make_f r c f)) = r) /\
  (((columns (make_f r c f)) = c) /\
   forall (i:Z) (j:Z), (valid_index (make_f r c f) i j) ->
   ((((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) ->
  ((((make_f r c f) i) j) = ((f i) j)).

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

Axiom equal_mat :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:Z -> Z -> a) (n:Z -> Z -> a),
  (equal m n) <->
  ((((rows m) = (rows n)) /\ ((columns m) = (columns n))) /\
   forall (i:Z) (j:Z), (valid_index m i j) -> (((m i) j) = ((n i) j))).

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

Axiom square_mat :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:Z -> Z -> a), (square m) <-> ((rows m) = (columns m)).

Axiom equal_sym :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:Z -> Z -> a) (n:Z -> Z -> a), (equal m n) <-> (equal n m).

Axiom equal_rex :
  forall {a:Type} {a_WT:WhyType a}, forall (m:Z -> Z -> a), equal m m.

Axiom equal_trans :
  forall {a:Type} {a_WT:WhyType a},
  forall (m:Z -> Z -> a) (n:Z -> Z -> a) (o:Z -> Z -> a), (equal m n) ->
  (equal n o) -> equal m o.

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

Axiom equal_mat_funct :
  forall {a:Type} {a_WT:WhyType a},
  forall (f:Z -> Z -> Z -> a) (g:Z -> Z -> Z -> 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).

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

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

Axiom result_def2 :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (t1:a -> im) (a1:a),
  (((result2 op1 t1) a1) = true) <-> ~ ((t1 a1) = (neutral_elt op1)).

Axiom nonnull_part_def1 :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable op1) ->
  ((nonnull_part1 op1 s t1) = (filter (result2 op1 t1) s)).

Axiom nonnull_part_spec1 :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable op1) ->
  forall (a1:a),
  (mem a1 (nonnull_part1 op1 s t1)) <->
  ((mem a1 s) /\ ~ ((t1 a1) = (neutral_elt op1))).

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

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

Axiom result_def3 :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (t1:a -> im) (a1:a),
  (((result3 op1 t1) a1) = true) <-> ((t1 a1) = (neutral_elt op1)).

Axiom null_part_def1 :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable op1) ->
  ((null_part1 op1 s t1) = (filter (result3 op1 t1) s)).

Axiom null_part_spec1 :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable op1) ->
  forall (a1:a),
  (mem a1 (null_part1 op1 s t1)) <->
  ((mem a1 s) /\ ((t1 a1) = (neutral_elt op1))).

Axiom nullity_partition1 :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable op1) ->
  (s = (union (nonnull_part1 op1 s t1) (null_part1 op1 s t1))) /\
  ((inter (nonnull_part1 op1 s t1) (null_part1 op1 s t1)) = (empty : set a)).

Axiom iterate_neutral1 :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable 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} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable op1) ->
  ((iterate op1 s t1) = (iterate op1 (nonnull_part1 op1 s t1) t1)).

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

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

Axiom iterate_cardone1 :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable op1) ->
  ((cardinal s) = 1%Z) -> ((iterate op1 s t1) = (t1 (element1 s))).

Axiom iterate_cardzero1 :
  forall {a:Type} {a_WT:WhyType a} {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (s:set a) (t1:a -> im), (iterable op1) ->
  ((cardinal s) = 0%Z) -> ((iterate op1 s t1) = (neutral_elt op1)).

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

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 indic_comm :
  forall {a:Type} {a_WT:WhyType a},
  forall (a1:a) (a':a), ((indic a1 a') = (indic a' 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))).

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

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

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

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

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

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

Axiom int_iterate_transitivity :
  forall {im:Type} {im_WT:WhyType im},
  forall (op1:im -> im -> im) (f:Z -> im) (i:Z) (k:Z) (j:Z), (assoc op1) ->
  (neutral 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_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)) -> (assoc op1) ->
  (assoc op2) ->
  ((int_iterate op2 (fun (e:Z) => (f (t1 e))) i j) =
   (f (int_iterate op1 t1 i j))).

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

Axiom isum_def :
  forall {a:Type} {a_WT:WhyType a},
  forall (s:set a) (t1:a -> Z),
  ((isum s t1) = (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_iter_ :
  (opposite_n (fun (y0:Z) (y1:Z) => (y0 + y1)%Z)
   (fun (y0:Z) (y1:Z) => (y0 - y1)%Z) 0%Z) /\
  ((opposite (fun (y0:Z) (y1:Z) => (y0 + y1)%Z)
    (fun (y0:Z) (y1:Z) => (y0 - y1)%Z)) /\
   ((opposite_com (fun (y0:Z) (y1:Z) => (y0 + y1)%Z)
     (fun (y0:Z) (y1:Z) => (y0 - y1)%Z)) /\
    (inverse_tuple (fun (y0:Z) (y1:Z) => (y0 + y1)%Z)
     (fun (y0:Z) (y1:Z) => (y0 - y1)%Z) 0%Z))).

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

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

Axiom ind_isum_def :
  forall (f:Z -> Z) (i:Z) (j:Z),
  ((ind_isum f i j) = (int_iterate (fun (y0:Z) (y1:Z) => (y0 + y1)%Z) f i j)).

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

Parameter m: Z -> Z -> t.

Parameter n: Z -> Z -> t.

Axiom H : ((columns m) = (rows n)).

Parameter o: Z -> Z -> t.

Axiom o_def :
  (o =
   (fun (i:Z) (j:Z) =>
    (int_iterate (fun (y0:t) (y1:t) => (infix_pldt y0 y1))
     (fun (k:Z) => (infix_pldt ((m i) k) ((n k) j))) 0%Z (columns m)))).

Parameter o1: Z.

Axiom o_def1 : (o1 = (columns n)).

Axiom H1 : (0%Z < o1)%Z.

Parameter o2: Z.

Axiom o_def2 : (o2 = (rows m)).

Axiom H2 : (0%Z < o2)%Z.

Parameter result4: Z -> Z -> t.

Axiom result_def4 : (result4 = (make_f o2 o1 o)).

Axiom H3 : ((rows result4) = o2).

Axiom H4 : ((columns result4) = o1).

Axiom H5 :
  forall (i:Z) (j:Z), (valid_index result4 i j) ->
  (((result4 i) j) =
   (((fun (i1:Z) (j1:Z) =>
      (int_iterate (fun (y0:t) (y1:t) => (infix_pldt y0 y1))
       (fun (k:Z) => (infix_pldt ((m i1) k) ((n k) j1))) 0%Z (columns m)))
     i)
    j)).

Axiom H6 : ((rows result4) = (rows m)).

Axiom H7 : ((columns result4) = (columns n)).

Parameter i: Z.

Parameter j: Z.

Axiom H8 : valid_index result4 i j.

Axiom Hinst :
  (((result4 i) j) =
   (((fun (i1:Z) (j1:Z) =>
      (int_iterate (fun (y0:t) (y1:t) => (infix_pldt y0 y1))
       (fun (k:Z) => (infix_pldt ((m i1) k) ((n k) j1))) 0%Z (columns m)))
     i)
    j)).

(* Why3 goal *)
Theorem VC_product :
  ((((fun (i1:Z) (j1:Z) =>
      (int_iterate (fun (y0:t) (y1:t) => (infix_pldt y0 y1))
       (fun (k:Z) => (infix_pldt ((m i1) k) ((n k) j1))) 0%Z (columns m)))
     i)
    j)
   =
   (int_iterate (fun (y0:t) (y1:t) => (infix_pldt y0 y1))
    (fun (k:Z) => (infix_pldt ((m i) k) ((n k) j))) 0%Z (columns m))).
Proof.
intuition.

Qed.