(* OK: *)

Definition P_degree_per(m:fmap)(z:dart)(n1 n2:nat):
  Prop:= inv_hmap m -> exd m z -> 0 < n1 -> n2 <= ndN m ->  
   Iter (f m) n2 z = z.

(* Specifications: *)
Lemma degree_per_aux: forall(m:fmap)(z:dart), P_degree_per m z 1 (degree m z).
Theorem degree_per: forall (m:fmap)(z:dart), inv_hmap m -> exd m z -> Iter (f m) (degree m z) z = z.
Theorem degree_lub: forall(m:fmap)(z:dart), inv_hmap m -> exd m z -> let p:= degree m z in 0 < p /\ Iter (f m) p z = z /\ forall i:nat, 0 < i < p -> Iter (f m) i z <> z.
Theorem upb_eq_degree:forall(m:fmap)(z:dart), inv_hmap m -> exd m z -> Iter_upb m z = degree m z.
Theorem expo_degree : forall(m:fmap)(z t:dart), inv_hmap m -> expo m z t -> degree m z = degree m t.
Theorem degree_uniform : forall(m:fmap)(z:dart)(i:nat), inv_hmap m -> exd m z -> degree m z = degree m (Iter (f m) i z).
Theorem degree_unicity:forall(m:fmap)(z:dart)(j k:nat), inv_hmap m -> exd m z -> let p := degree m z in j < p -> k < p -> Iter (f m) j z = Iter (f m) k z -> j = k.
Lemma incls_orbit:forall(m:fmap)(x:dart), inv_hmap m -> exd m x -> incls (Iter_orb m x) (fmap_to_set m).
Lemma exds_orb_exd:forall(m:fmap)(x z:dart), inv_hmap m -> exd m x -> exds (Iter_orb m x) z -> exd m z.
Lemma incls_rem:forall(m:fmap)(x:dart), inv_hmap m -> exd m x -> incls (Iter_rem m x) (fmap_to_set m).
Lemma card_orbit:forall(m:fmap)(x:dart), inv_hmap m -> exd m x -> card (Iter_orb m x) = Iter_upb m x.
Lemma exds_orb_ex :forall(m:fmap)(z t:dart), inv_hmap m -> exd m z -> let s:= Iter_orb m z in let p:= Iter_upb m z in exds s t -> {i : nat | (i < p)%nat /\ Iter (f m) i z = t}.
Theorem exds_orb_eq_ex :forall(m:fmap)(z t:dart), inv_hmap m -> exd m z -> let s:= Iter_orb m z in let p:= Iter_upb m z in (exds s t <-> exists i:nat,(i < p)%nat /\ Iter (f m) i z = t).
Theorem exds_orb_eq_ex_large :forall(m:fmap)(z t:dart), inv_hmap m -> exd m z -> let s:= Iter_orb m z in let p:= Iter_upb m z in (exds s t <-> exists i:nat, Iter (f m) i z = t).
Theorem expo_eq_exds_orb :forall(m:fmap)(z t:dart), inv_hmap m -> exd m z -> (expo m z t <-> exds (Iter_orb m z) t).
Theorem expo1_eq_exds_orb :forall(m:fmap)(z t:dart), inv_hmap m -> exd m z -> (expo1 m z t <-> exds (Iter_orb m z) t).
Lemma impls_orb:forall(m:fmap)(x y:dart), inv_hmap m -> exd m x -> expo m x y -> impls (Iter_orb m x) (Iter_orb m y).
Lemma eqs_orb:forall(m:fmap)(x y:dart), inv_hmap m -> expo m x y -> eqs (Iter_orb m x) (Iter_orb m y).
Lemma orb_impls_expo:forall(m:fmap)(x y:dart), inv_hmap m -> exd m x -> exd m y -> impls (Iter_orb m x) (Iter_orb m y) -> expo m x y.
Theorem expo_eq_eqs_orb:forall(m:fmap)(x y:dart), inv_hmap m -> exd m x -> exd m y -> (expo m x y <-> eqs (Iter_orb m x) (Iter_orb m y)).
Lemma disjs_orb:forall(m:fmap)(x y:dart), inv_hmap m -> exd m x -> exd m y -> ~expo m x y -> disjs (Iter_orb m x) (Iter_orb m y).
Lemma disjs_orb_not_expo:forall(m:fmap)(x y:dart), inv_hmap m -> exd m x -> exd m y -> disjs (Iter_orb m x) (Iter_orb m y) -> ~expo m x y.
Theorem not_expo_disjs_orb:forall(m:fmap)(x y:dart), inv_hmap m -> exd m x -> exd m y -> (~expo m x y <-> disjs (Iter_orb m x) (Iter_orb m y)).
Lemma incls_minus: forall(m:fmap)(x y:dart), inv_hmap m -> exd m x -> exd m y -> ~expo m x y -> let s:= fmap_to_set m in let sx:= Iter_orb m x in let sy:= Iter_orb m y in incls sy (set_minus s sx).
Theorem upb_sum_bound: forall(m:fmap)(x y:dart), inv_hmap m -> exd m x -> exd m y -> ~expo m x y -> Iter_upb m x + Iter_upb m y <= ndN m.
Theorem degree_sum_bound: forall(m:fmap)(x y:dart), inv_hmap m -> exd m x -> exd m y -> ~expo m x y -> degree m x + degree m y <= ndN m.