diff --git a/lib/coq.ml b/lib/coq.ml
index 24d7972ad97d886d44648ad2b38dc5703d9ffd8e..1ad71548977996be896fe4669c070a6ace4b284d 100644
--- a/lib/coq.ml
+++ b/lib/coq.ml
@@ -9,6 +9,8 @@ type stmt =
   | VarMaxImplicit of string * Formula.t
   | Hyp of string * Formula.t
   | Lemma of string * Formula.t * stmt list (* tactics *)
+  | Parameter of string * Formula.t *Formula.t (* Module *)
+  | Parameterlem of string * Formula.t  (* Module *)
   | InstanceLemma of string * Formula.t * stmt list (* tactics *)
   | Def of string * Formula.t * Formula.t
   | Notation of string * Formula.t
@@ -17,6 +19,9 @@ type stmt =
   | Instance of string * Formula.t * Formula.t
   | ExistingInstance of Formula.t
   | Section of string * stmt list
+  | Module of string * stmt list
+  | ModuleType of string * stmt list
+  |ModuleImpType  of string * string * stmt list
   | Proof of stmt list
   | Require of bool * string list (* bool = Import *)
   | Import of string list
@@ -41,6 +46,10 @@ let rec pretty fmt st =
   | Lemma(s,f,lst) ->
      p fmt "@[<v 0>@[<hov 2>Lemma %s: %a.@]@,@[<v 2>Proof.@,%a@]@,Qed.@]"
        s prtyf f (Pp.print_list Pp.brk pretty) lst
+  | Parameter(s,f,lst) -> p fmt "@[<hov 2>@[<hov 2>Parameter %s:@ %a@] ->@ %a.@]\n"
+    s prtyf f prtyf lst 
+  | Parameterlem(s,f) -> p fmt "@[<v 0>@[<hov 2>Parameter %s: %a.@]"
+      s prtyf f 
   | InstanceLemma(s,f,lst) ->
      p fmt "@[<v 0>@[<hov 2>Instance %s: %a.@]@,@[<v 2>Proof.@,%a@]@,Defined.@]"
        s prtyf f (Pp.print_list Pp.brk pretty) lst
@@ -56,6 +65,12 @@ let rec pretty fmt st =
   | ExistingInstance(f) -> p fmt "@[<hov 2>@[<hov 2>Existing Instance %a.@]@]" prtyf f
   | Section (s,lst) -> p fmt "@[<v 0>@[<v 2>Section %s.@,%a@]@\nEnd %s.@]"
                          s (Pp.print_list Pp.cut pretty) lst s
+  | Module (s,lst) ->  p fmt "@[<v 0>@[<v 2>Module %s.@,%a@]@\nEnd %s.@]"
+  s (Pp.print_list Pp.cut pretty) lst s
+  | ModuleType (s,lst) ->  p fmt "@[<v 0>@[<v 2>Module Type %s_type.@,%a@]@\nEnd %s_type.@]"
+  s (Pp.print_list Pp.cut pretty) lst s
+  | ModuleImpType (s,st,lst) ->  p fmt "@[<v 0>@[<v 2>Module %s : %s.@,%a@]@\nEnd %s.@]"
+  s st (Pp.print_list Pp.cut pretty) lst s
   | Proof (lst) -> p fmt "@[<v 0>@[<v 2>Proof.@,%a@]@\nEnd.@]"
                      (Pp.print_list Pp.cut pretty) lst
   | Require (_,[]) -> ()
diff --git a/lib/gencoq.ml b/lib/gencoq.ml
index 3c2a4b11b5ef97570df064cca815aba5641b958c..766eef7c2056aeda8cdad31752d4b8b80c0b06f2 100644
--- a/lib/gencoq.ml
+++ b/lib/gencoq.ml
@@ -367,21 +367,21 @@ match l with
   | h::tl -> Or(Cst(h),generate_or tl) 
   | _ -> Cst("")
 
-(**[generate_definition_phase g]returns the list of stmt to generate the coq code for the definition of the phases of the graph [g]*)
-let generate_definition_phase (g : G.t) : stmt list =
+(**[generate_definition_phase g]returns the list of stmt to generate the coq code for the definition in module type of the phases of the graph [g] and the list of stmt to generate the def in module proof*)
+let generate_definition_phase (g : G.t) : (stmt list * stmt list) =
   Topological.fold (fun v acc -> 
-    let func_name = string_of_expression v ^" (config : configuration)" in 
-    RawCoq(["Definition "^func_name^":= (* To_Complete *)."])::acc
-    ) g []
+    let func_name = string_of_expression v  in 
+    (RawCoq(["Parameter "^func_name^": configuration -> bool."])::(fst acc), Def(func_name^"(config: configuration)",Cst("bool"),Cst("(* TODO *)"))::(snd acc))
+    ) g ([],[])
 
 (**[generate_measure_per_phase g] returns the list of stmt generating the coq code of the measurement functions for each phase
     @param g [G.t]
     @return [stmt list]*)
-let generate_measure_per_phase (g: Ast.G.t) : stmt list =
+let generate_measure_per_phase (g: Ast.G.t) : (stmt list * stmt list) =
   Topological.fold (fun v acc -> 
-      let func_name = string_of_expression v ^"_meas (config : configuration)" in 
-      Def(func_name,Raw("nat"),Raw("(* To_Complete *)"))::acc
-      ) g []
+      let func_name = string_of_expression v ^"_meas" in 
+      (RawCoq(["Parameter "^func_name^": configuration -> nat."])::(fst acc),Def(func_name^"(config : configuration)",Raw("nat"),Raw("(* To_Complete *)"))::(snd acc))
+      ) g ([],[])
       
 
 (**[generate_lemmas g] returns the list of stmt corresponding to the lemmas extracted from the graph g
@@ -394,67 +394,152 @@ let generate_lemmas (g : Ast.G.t) : (stmt list * string list) =
     if succs <> [] then
       let string_succs = (List.map string_of_expression succs) in
       let rcs = List.map (fun x -> x ^ " (round robogram da config) = true") string_succs in
-      (Lemma(string_v^"_next_"^String.concat "_or_" string_succs ^" da",
-            Forall("config",InfixOp(Raw(string_v^" config = true"),"->",(generate_or rcs) )),[Comment("TODO")])::acc,
+      (Parameterlem(string_v^"_next_"^String.concat "_or_" string_succs ,
+            Forall("config da",InfixOp(Raw(string_v^" config = true"),"->",(generate_or rcs) )))::acc,
       ("("^string_v ^" config)")::s)
     else
       (acc,s)
     ) g ([],[])
 
+    let generate_lemmas_proof (g : Ast.G.t) : (stmt list * string list)  =
+      Topological.fold (fun v (acc,s) ->
+      let string_v = string_of_expression v in
+      let succs = Ast.G.succ g v in
+      if succs <> [] then
+        let string_succs = (List.map string_of_expression succs) in
+        let rcs = List.map (fun x -> x ^ " (round robogram da config) = true") string_succs in
+       ( Lemma(string_v^"_next_"^String.concat "_or_" string_succs ,
+              Forall("config da",InfixOp(Raw(string_v^" config = true"),"->",(generate_or rcs))), proof_to_complete)::acc,
+              ("("^string_v ^" config)")::s)
+      else
+        (acc,s)
+      ) g ([],[])
+
 (**[generate_if_measure] generates the body of the measure function 
     @param g [G.t]
     @return [Formula.t]*)
 let generate_if_measure (g: Ast.G.t) : Formula.t  =
 let rec aux l = 
   match l with
-  |(phase,height)::[] -> Formula.Cst("("^ string_of_int height^", "^string_of_expression phase ^"_meas config)")
-  |(phase,height)::tl -> If(Cst(string_of_expression phase ^" config"),Cst("("^ string_of_int height^", "^string_of_expression phase ^"_meas config)"),aux tl )
+  |(phase,height)::[] -> Formula.Cst("("^ string_of_int height^"%nat, "^string_of_expression phase ^"_meas config)")
+  |(phase,height)::tl -> If(Cst(string_of_expression phase ^" config"),Cst("("^ string_of_int height^"%nat, "^string_of_expression phase ^"_meas config)"),aux tl )
   | _ -> Cst("")
 in
   aux (Ast.assign_height g)
 
-(**[generate_measure m] returns the list of stmt corresponding to the generation of the measurement
+let generate_measure_def (g : G.t)(ret : string) =
+  let to_change = generate_if_measure g in
+  Def("measure (config : configuration)",Cst(ret),to_change)
+
+
+(**[generate_measure m] returns the list of stmt corresponding to the generation of the measure
     @param m [measure]
     @return [stmt list] *)
 
-let generate_measure (Measure(g): measure) (name_png : string) : stmt list = 
+let generate_measure_lemme (Measure(g): measure) (name_png : string) : stmt list = 
  let ret = "nat*nat" in
-  let to_change = generate_if_measure g in
+  let m = generate_measure_def g ret in 
   Ast.png_from_graph g name_png;
   Ast.png_from_graph2 (Ast.scc_graph g;) "scc_graph";
   let measure_per_phase = generate_measure_per_phase g in 
-  let lemsgen = let lems = generate_lemmas g in 
-    Comment("Definition of phase")::generate_definition_phase g
-    @Comment("Definition of measure per phase ")::measure_per_phase
-    @Lemma("InGraph",Forall("config",generate_or (snd lems)),[Comment("TODO")])
+  let lemsgen = 
+    let lems = generate_lemmas g in 
+    Comment("Definition of phase")::fst (generate_definition_phase g)
+    @Comment("Definition of measure per phase "):: fst measure_per_phase
+    @Parameterlem("InGraph",Forall("config",generate_or (List.map (fun x -> x ^" = true")(snd lems))))
     ::List.rev (fst lems) in 
     lemsgen@
-    Def("measure (config : configuration)",Cst(ret),to_change)::
-  RawCoq(["Instance measure_compat : Proper (equiv ==> Logic.eq) measure."])::proof_to_complete
+    m::
+  RawCoq(["Parameter measure_compat : Proper (equiv ==> Logic.eq) measure."])::[]
+
+let generate_lt_type = 
+    RawCoq(["Definition lt_config x y := Lexprod.lexprod lt lt (measure (x)) (measure (y))."])
+    :: Parameterlem("wf_lt_config",Cst("well_founded lt_config"))
+    :: Parameterlem("lt_config_compat",Cst ("Proper (equiv ==> equiv ==> iff) lt_config"))
+    :: Parameterlem("round_lt_config" , Cst("forall config,
+    moving robogram da config <> nil ->
+    lt_config (round robogram da config) config")) ::[]
+
 
 let generate_lt = 
-    RawCoq(["Definition lt_config x y := Lexprod.lexprod lt lt (measure (!! x)) (measure (!! y))."])
-    :: Lemma("wf_lt_config",Cst("well_founded lt_config"),[Comment("TODO")])
-    :: RawCoq(["Instance lt_config_compat : Proper (equiv ==> equiv ==> iff) lt_config."])
-    ::proof_to_complete
-    @ RawCoq(["Theorem round_lt_config : forall config,
-    moving robogram da config <> nil ->
-    lt_config (round robogram da config) config."]) ::[]
+   RawCoq(["Definition lt_config x y := Lexprod.lexprod lt lt (measure (x)) (measure (y))."])
+   :: Lemma("wf_lt_config",Cst("well_founded lt_config"),[Comment("TODO")])
+   :: Lemma("lt_config_compat",Cst ("Proper (equiv ==> equiv ==> iff) lt_config"),[Comment("TODO")])
+   :: Lemma("round_lt_config" , Cst("forall config,
+   moving robogram da config <> nil ->
+   lt_config (round robogram da config) config"),[Comment("TODO")]) ::[]
+ let generate_module_type (m : measure) (s:string) =
+   newline
+   ::ModuleType(s,RawCoq(["Import World."])::Parameterlem("da",Cst("demonic_action"))::generate_measure_lemme m s
+   @newline::generate_lt_type)::[]
+
+  let generate_module_proof (Measure g : measure)(s:string) =
+    let lems = generate_lemmas_proof g in 
+    ModuleImpType(s^"_proof",s^"_type", RawCoq(["Import World.";"Variable da : demonic_action."])::snd(generate_definition_phase g)@snd (generate_measure_per_phase g)
+
+    @Lemma("InGraph",Forall("config",generate_or (List.map (fun x -> x ^" = true")(snd lems))),proof_to_complete)::List.rev (fst lems)@(generate_measure_def g "nat*nat")::generate_lt)
+
+
+    let keyword = "  End test_type." 
+
+    let read_and_save_after_keyword filename keyword =
+     
+      let in_channel = open_in filename in
+      let rec loop lines =
+        try
+          let line = input_line in_channel in
+          loop (line :: lines)
+        with End_of_file ->
+          close_in in_channel;
+          List.rev lines
+      in
+      let lines = loop [] in
+      let rec find_keyword lines =
+        match lines with
+        | [] -> []
+        | line :: rest ->
+          try
+            ignore (Str.search_forward (Str.regexp keyword) line 0);
+            rest
+          with Not_found ->
+            find_keyword rest
+      in
+      String.concat "\n" (find_keyword lines)
+
 
 (**[generate_coq d s] generated from the complete description (world, robogram, measure) [d] the named coq instance [s]
     @param description of
     @param string s
     @return[unit] *)
 let generate_coq (Description(d,r,m) : description) (section_name : string)=
+  
+  let file_exists =
+  Sys.file_exists ("./generate/"^section_name^".v") in
+
+  let proof = if file_exists then RawCoq([read_and_save_after_keyword  ("./generate/"^section_name^".v") keyword ])
+
+  else generate_module_proof m section_name 
+  in
+  print_endline (read_and_save_after_keyword  ("./generate/"^section_name^".v") keyword) ;
+
   if Ast.check_description (Description(d,r,m)) 
    then
     let file_out = open_out ("./generate/"^section_name^".v") in 
     let format_file = Format.formatter_of_out_channel file_out in
-    let section = Section(section_name,(generate_instances d)@newline::generate_robogram r d
-                                                             @newline::generate_measure m section_name
-                                                             @newline::generate_lt) in
-    Format.fprintf format_file "%a@." Coq.pretty_l ((generate_requires d)@[section]);
+    let module_world_type = Module("World",(generate_instances d)@newline::generate_robogram r d)::
+                                                             generate_module_type m section_name in
+
+    
+   
+    Format.fprintf format_file "%a@." Coq.pretty_l ((generate_requires d)@module_world_type@[proof]);
+
     close_out file_out;
-    print_endline(section_name^".v is generated")
+print_endline(section_name^".v is generated")
   else 
-    ()
\ No newline at end of file
+    () 
+
+    
+
+
+
+