(************************************************************************)
(*  v      *   The Coq Proof Assistant  /  The Coq Development Team     *)
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
(*   \VV/  **************************************************************)
(*    //   *      This file is distributed under the terms of the       *)
(*         *       GNU Lesser General Public License Version 2.1        *)
(************************************************************************)
(*i 	$Id$	 i*)
Section MapIter.
Variable A : Type.
Section MapSweepDef.
Variable f : ad -> A -> bool.
Definition MapSweep2 (a0:ad) (y:A) :=
if f a0 y then Some (a0, y) else None.
Fixpoint MapSweep1 (pf:ad -> ad) (m:Map A) {struct m} :
option (ad * A) :=
match m with
| M0 => None
| M1 a y => MapSweep2 (pf a) y
| M2 m m' =>
match MapSweep1 (fun a:ad => pf (Ndouble a)) m with
| Some r => Some r
| None => MapSweep1 (fun a:ad => pf (Ndouble_plus_one a)) m'
end
end.
Definition MapSweep (m:Map A) := MapSweep1 (fun a:ad => a) m.

(* Specifications: *)
Lemma MapSweep_semantics_1_1 :
forall (m:Map A) (pf:ad -> ad) (a:ad) (y:A),
MapSweep1 pf m = Some (a, y) -> f a y = true.
Lemma MapSweep_semantics_1 :
forall (m:Map A) (a:ad) (y:A), MapSweep m = Some (a, y) -> f a y = true.
Lemma MapSweep_semantics_2_1 :
forall (m:Map A) (pf:ad -> ad) (a:ad) (y:A),
MapSweep1 pf m = Some (a, y) -> {a' : ad | a = pf a'}.
Lemma MapSweep_semantics_2_2 :
forall (m:Map A) (pf fp:ad -> ad),
(forall a0:ad, fp (pf a0) = a0) ->
forall (a:ad) (y:A),
MapSweep1 pf m = Some (a, y) -> MapGet A m (fp a) = Some y.
Lemma MapSweep_semantics_2 :
forall (m:Map A) (a:ad) (y:A),
MapSweep m = Some (a, y) -> MapGet A m a = Some y.
Lemma MapSweep_semantics_3_1 :
forall (m:Map A) (pf:ad -> ad),
MapSweep1 pf m = None ->
forall (a:ad) (y:A), MapGet A m a = Some y -> f (pf a) y = false.
Lemma MapSweep_semantics_3 :
forall m:Map A,
MapSweep m = None ->
forall (a:ad) (y:A), MapGet A m a = Some y -> f a y = false.
Lemma MapSweep_semantics_4_1 :
forall (m:Map A) (pf:ad -> ad) (a:ad) (y:A),
MapGet A m a = Some y ->
f (pf a) y = true ->
{a' : ad &  {y' : A | MapSweep1 pf m = Some (a', y')}}.
Lemma MapSweep_semantics_4 :
forall (m:Map A) (a:ad) (y:A),
MapGet A m a = Some y ->
f a y = true -> {a' : ad &  {y' : A | MapSweep m = Some (a', y')}}.