]> matita.cs.unibo.it Git - helm.git/commitdiff
Many many improvements:
authorClaudio Sacerdoti Coen <claudio.sacerdoticoen@unibo.it>
Mon, 20 May 2002 09:17:54 +0000 (09:17 +0000)
committerClaudio Sacerdoti Coen <claudio.sacerdoticoen@unibo.it>
Mon, 20 May 2002 09:17:54 +0000 (09:17 +0000)
1) First version after the introduction of explicit substitutions and
   the change in the DTD and in the stylesheets.
2) ElimIntros (that didn't work) have been replace by ElimIntrosSimpl
   that now does what the name tells you.
3) Buttons to move to the next and previous open goal introduced.
4) Serious bug in reduce and in simpl fixed: they didn't handle the environment
   properly.
5) replace is now an hygher order function, parametrized w.r.t. the equality
   to use. In some cases the right equality is physical equality. This closes
   some residual bugs.

helm/gTopLevel/cic2Xml.ml
helm/gTopLevel/cic2acic.ml
helm/gTopLevel/gTopLevel.ml
helm/gTopLevel/logicalOperations.ml
helm/gTopLevel/mquery.ml
helm/gTopLevel/proofEngine.ml
helm/gTopLevel/proofEngineReduction.ml
helm/gTopLevel/sequentPp.ml

index a25d7f6709ce20cb0bdd17793b3e1a585c46521f..f04df2f2f6bf4cce1e4b0f376723920dd9f76058 100644 (file)
@@ -49,9 +49,17 @@ let print_term curi ids_to_inner_sorts =
           ["relUri",(string_of_int (cdepth - vdepth)) ^ "," ^
             (U.name_of_uri uri) ;
            "id",id ; "sort",sort]
-     | C.AMeta (id,n) ->
+     | C.AMeta (id,n,l) ->
         let sort = Hashtbl.find ids_to_inner_sorts id in
-         X.xml_empty "META" ["no",(string_of_int n) ; "id",id ; "sort",sort]
+         X.xml_nempty "META" ["no",(string_of_int n) ; "id",id ; "sort",sort]
+          (List.fold_left
+            (fun i t ->
+              match t with
+                 Some t' ->
+                  [< i ; X.xml_nempty "substitution" [] (aux t') >]
+               | None ->
+                  [< i ; X.xml_empty "substitution" [] >]
+            ) [< >] l)
      | C.ASort (id,s) ->
         let string_of_sort =
          function
@@ -177,10 +185,32 @@ let print_object curi ids_to_inner_sorts =
        C.ACurrentProof (id,n,conjectures,bo,ty) ->
         X.xml_nempty "CurrentProof" ["name",n ; "id", id]
          [< List.fold_left
-             (fun i (n,t) ->
+             (fun i (n,canonical_context,t) ->
                [< i ;
                   X.xml_nempty "Conjecture" ["no",(string_of_int n)]
-                   (print_term curi ids_to_inner_sorts t)
+                   [< List.fold_left
+                       (fun i t ->
+                         [< (match t with
+                               Some (n,C.ADecl t) ->
+                                X.xml_nempty "Decl"
+                                 (match n with
+                                     C.Name n' -> ["name",n']
+                                   | C.Anonimous -> [])
+                                 (print_term curi ids_to_inner_sorts t)
+                             | Some (n,C.ADef t) ->
+                                X.xml_nempty "Def"
+                                 (match n with
+                                     C.Name n' -> ["name",n']
+                                   | C.Anonimous -> [])
+                                 (print_term curi ids_to_inner_sorts t)
+                             | None -> X.xml_empty "Hidden" []
+                            ) ;
+                            i
+                         >]
+                       ) [< >] canonical_context ;
+                      X.xml_nempty "Goal" []
+                       (print_term curi ids_to_inner_sorts t)
+                   >]
                >])
              [<>] conjectures ;
             X.xml_nempty "body" [] (print_term curi ids_to_inner_sorts bo) ;
index 08cb06d9d93b8dcc49a827223fd1b2d7e629c01c..d7688499c7cbfe497d6e30485cf3341cef98b1d1 100644 (file)
@@ -47,13 +47,13 @@ let rec get_nth l n =
   | (_,_) -> raise NotEnoughElements
 ;;
 
-let acic_of_cic_env' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
-     ids_to_inner_types metasenv env t
+let acic_of_cic_context' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
+     ids_to_inner_types metasenv context t
 =
  let module T = CicTypeChecker in
  let module C = Cic in
   let fresh_id' = fresh_id seed ids_to_terms ids_to_father_ids in
-   let rec aux computeinnertypes father bs tt =
+   let rec aux computeinnertypes father context tt =
     let fresh_id'' = fresh_id' father tt in
     let aux' = aux true (Some fresh_id'') in
      (* First of all we compute the inner type and the inner sort *)
@@ -69,19 +69,18 @@ let acic_of_cic_env' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
        | _ -> assert false
      in
       let ainnertype,innertype,innersort =
-       let cicenv = List.map (function (_,ty) -> ty) bs in
 (*CSC: Here we need the algorithm for Coscoy's double type-inference  *)
 (*CSC: (expected type + inferred type). Just for now we use the usual *)
 (*CSC: type-inference, but the result is very poort. As a very weak   *)
 (*CSC: patch, I apply whd to the computed type. Full beta             *)
 (*CSC: reduction would be a much better option.                       *)
         let innertype =
-         CicReduction.whd cicenv (T.type_of_aux' metasenv cicenv tt)
+         CicReduction.whd context (T.type_of_aux' metasenv context tt)
         in
-         let innersort = T.type_of_aux' metasenv cicenv innertype in
+         let innersort = T.type_of_aux' metasenv context innertype in
           let ainnertype =
            if computeinnertypes then
-            Some (aux false (Some fresh_id'') bs innertype)
+            Some (aux false (Some fresh_id'') context innertype)
            else
             None
           in
@@ -95,8 +94,8 @@ let acic_of_cic_env' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
        match tt with
           C.Rel n ->
            let id =
-            match get_nth bs n with
-               (C.Name s,_) -> s
+            match get_nth context n with
+               (Some (C.Name s,_)) -> s
              | _ -> raise NameExpected
            in
             Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
@@ -104,20 +103,24 @@ let acic_of_cic_env' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
         | C.Var uri ->
            Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
            C.AVar (fresh_id'', uri)
-        | C.Meta n ->
+        | C.Meta (n,l) ->
            Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
-           C.AMeta (fresh_id'', n)
+           C.AMeta (fresh_id'', n,
+            (List.map
+              (function None -> None | Some t -> Some (aux' context t)) l))
         | C.Sort s -> C.ASort (fresh_id'', s)
         | C.Implicit -> C.AImplicit (fresh_id'')
         | C.Cast (v,t) ->
            Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
            if innersort = "Prop" then
             add_inner_type fresh_id'' ;
-           C.ACast (fresh_id'', aux' bs v, aux' bs t)
+           C.ACast (fresh_id'', aux' context v, aux' context t)
         | C.Prod (n,s,t) ->
             Hashtbl.add ids_to_inner_sorts fresh_id''
              (string_of_sort innertype) ;
-            C.AProd (fresh_id'', n, aux' bs s, aux' ((n, C.Decl s)::bs) t)
+            C.AProd
+             (fresh_id'', n, aux' context s,
+              aux' ((Some (n, C.Decl s))::context) t)
         | C.Lambda (n,s,t) ->
            Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
            if innersort = "Prop" then
@@ -133,15 +136,19 @@ let acic_of_cic_env' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
               if not father_is_lambda then
                add_inner_type fresh_id''
             end ;
-           C.ALambda (fresh_id'',n, aux' bs s, aux' ((n, C.Decl s)::bs) t)
+           C.ALambda
+            (fresh_id'',n, aux' context s,
+             aux' ((Some (n, C.Decl s)::context)) t)
         | C.LetIn (n,s,t) ->
           Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
-          C.ALetIn (fresh_id'', n, aux' bs s, aux' ((n, C.Def s)::bs) t)
+          C.ALetIn
+           (fresh_id'', n, aux' context s,
+            aux' ((Some (n, C.Def s))::context) t)
         | C.Appl l ->
            Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
            if innersort = "Prop" then
             add_inner_type fresh_id'' ;
-           C.AAppl (fresh_id'', List.map (aux' bs) l)
+           C.AAppl (fresh_id'', List.map (aux' context) l)
         | C.Const (uri,cn) ->
            Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
            C.AConst (fresh_id'', uri, cn)
@@ -154,11 +161,11 @@ let acic_of_cic_env' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
            Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
            if innersort = "Prop" then
             add_inner_type fresh_id'' ;
-           C.AMutCase (fresh_id'', uri, cn, tyno, aux' bs outty,
-            aux' bs term, List.map (aux' bs) patterns)
+           C.AMutCase (fresh_id'', uri, cn, tyno, aux' context outty,
+            aux' context term, List.map (aux' context) patterns)
         | C.Fix (funno, funs) ->
-           let names =
-            List.map (fun (name,_,ty,_) -> C.Name name, C.Decl ty) funs
+           let tys =
+            List.map (fun (name,_,ty,_) -> Some (C.Name name, C.Decl ty)) funs
            in
             Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
             if innersort = "Prop" then
@@ -166,95 +173,38 @@ let acic_of_cic_env' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
             C.AFix (fresh_id'', funno,
              List.map
               (fun (name, indidx, ty, bo) ->
-                (name, indidx, aux' bs ty, aux' (names@bs) bo)
+                (name, indidx, aux' context ty, aux' (tys@context) bo)
               ) funs
            )
         | C.CoFix (funno, funs) ->
-           let names =
-            List.map (fun (name,ty,_) -> C.Name name, C.Decl ty) funs in
+           let tys =
+            List.map (fun (name,ty,_) -> Some (C.Name name, C.Decl ty)) funs in
             Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
             if innersort = "Prop" then
              add_inner_type fresh_id'' ;
             C.ACoFix (fresh_id'', funno,
              List.map
               (fun (name, ty, bo) ->
-                (name, aux' bs ty, aux' (names@bs) bo)
+                (name, aux' context ty, aux' (tys@context) bo)
               ) funs
             )
       in
-       aux true None env t
+       aux true None context t
 ;;
 
-let acic_of_cic_env metasenv env t =
+let acic_of_cic_context metasenv context t =
  let ids_to_terms = Hashtbl.create 503 in
  let ids_to_father_ids = Hashtbl.create 503 in
  let ids_to_inner_sorts = Hashtbl.create 503 in
  let ids_to_inner_types = Hashtbl.create 503 in
  let seed = ref 0 in
-   acic_of_cic_env' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
-    ids_to_inner_types metasenv env t,
+   acic_of_cic_context' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
+    ids_to_inner_types metasenv context t,
    ids_to_terms, ids_to_father_ids, ids_to_inner_sorts, ids_to_inner_types
 ;;
 
 exception Found of (Cic.name * Cic.context_entry) list;;
 
-(* get_context_of_meta meta term                                 *)
-(* returns the context of the occurrence of [meta] in [term].    *)
-(* Warning: if [meta] occurs not linearly in [term], the context *)
-(* of one "random" occurrence is returned.                       *)
-let get_context_of_meta meta term =
- let module C = Cic in
-  let rec aux ctx =
-   function
-      C.Rel _
-    | C.Var _ -> ()
-    | C.Meta i when meta = i -> raise (Found ctx)
-    | C.Meta _
-    | C.Sort _
-    | C.Implicit -> ()
-    | C.Cast (te,ty) -> aux ctx te ; aux ctx ty
-    | C.Prod (n,s,t) -> aux ctx s ; aux ((n, C.Decl s)::ctx) t
-    | C.Lambda (n,s,t) -> aux ctx s ; aux ((n, C.Decl s)::ctx) t
-    | C.LetIn (n,s,t) -> aux ctx s ; aux ((n, C.Def s)::ctx) t
-    | C.Appl l -> List.iter (aux ctx) l
-    | C.Const _ -> ()
-    | C.Abst _ -> assert false
-    | C.MutInd _
-    | C.MutConstruct _ -> ()
-    | C.MutCase (_,_,_,outt,t,pl) ->
-       aux ctx outt ; aux ctx t; List.iter (aux ctx) pl
-    | C.Fix (_,ifl) ->
-       let counter = ref 0 in
-        let ctx' =
-         List.rev_map
-          (function (name,_,ty,bo) ->
-            let res = (C.Name name, C.Def (C.Fix (!counter,ifl))) in
-             incr counter ;
-             res
-          ) ifl
-         @ ctx
-        in
-         List.iter (function (_,_,ty,bo) -> aux ctx ty ; aux ctx' bo) ifl
-    | C.CoFix (_,ifl) ->
-       let counter = ref 0 in
-        let ctx' =
-         List.rev_map
-          (function (name,ty,bo) ->
-            let res = (C.Name name, C.Def (C.CoFix (!counter,ifl))) in
-             incr counter ;
-             res
-          ) ifl
-         @ ctx
-        in
-         List.iter (function (_,ty,bo) -> aux ctx ty ; aux ctx' bo) ifl
-  in
-   try
-    aux [] term ;
-    assert false (* No occurrences found. *)
-   with
-    Found context -> context
-;;
-
 exception NotImplemented;;
 
 let acic_object_of_cic_object obj =
@@ -264,10 +214,10 @@ let acic_object_of_cic_object obj =
   let ids_to_inner_sorts = Hashtbl.create 503 in
   let ids_to_inner_types = Hashtbl.create 503 in
   let seed = ref 0 in
-  let acic_term_of_cic_term_env' =
-   acic_of_cic_env' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
+  let acic_term_of_cic_term_context' =
+   acic_of_cic_context' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
     ids_to_inner_types in
-  let acic_term_of_cic_term' = acic_term_of_cic_term_env' [] [] in
+  let acic_term_of_cic_term' = acic_term_of_cic_term_context' [] [] in
    let aobj =
     match obj with
       C.Definition (id,bo,ty,params) ->
@@ -280,13 +230,32 @@ let acic_object_of_cic_object obj =
     | C.CurrentProof (id,conjectures,bo,ty) ->
        let aconjectures =
         List.map
-         (function (i,term) ->
-           let context = get_context_of_meta i bo in
-            let aterm = acic_term_of_cic_term_env' conjectures context term in
-             (i, aterm))
-         conjectures in
-       let abo = acic_term_of_cic_term_env' conjectures [] bo in
-       let aty = acic_term_of_cic_term_env' conjectures [] ty in
+         (function (i,canonical_context,term) ->
+           let acanonical_context =
+            let rec aux =
+             function
+                [] -> []
+              | (Some (n,C.Decl t))::tl ->
+                  let at =
+                   acic_term_of_cic_term_context' conjectures tl t
+                  in
+                   Some (n,C.ADecl at)::(aux tl)
+              | (Some (n,C.Def t))::tl ->
+                  let at =
+                   acic_term_of_cic_term_context' conjectures tl t
+                  in
+                   Some (n,C.ADef at)::(aux tl)
+               | None::tl -> None::(aux tl)
+            in
+             aux canonical_context
+           in
+            let aterm =
+             acic_term_of_cic_term_context' conjectures canonical_context term
+            in
+             (i, acanonical_context,aterm)
+         ) conjectures in
+       let abo = acic_term_of_cic_term_context' conjectures [] bo in
+       let aty = acic_term_of_cic_term_context' conjectures [] ty in
         C.ACurrentProof ("mettereaposto",id,aconjectures,abo,aty)
     | C.InductiveDefinition (tys,params,paramsno) -> raise NotImplemented
    in
index 47c416d8b60b9ad472098d883f4cacf2f2026345..1d5650b1ca20670fdad520c77412c6a1bd924842 100644 (file)
@@ -151,7 +151,7 @@ let mml_of_cic_object uri annobj ids_to_inner_sorts ids_to_inner_types =
 (*CSC: We save the innertypes to disk so that we can retrieve them in the  *)
 (*CSC: stylesheet. This DOES NOT work when UWOBO and/or the getter are not *)
 (*CSC: local.                                                              *)
-   Xml.pp xmlinnertypes (Some "/public/fguidi/innertypes") ;
+   Xml.pp xmlinnertypes (Some "/public/sacerdot/innertypes") ;
    let output = applyStylesheets input mml_styles mml_args in
     output
 ;;
@@ -181,19 +181,25 @@ let refresh_proof (output : GMathView.math_view) =
      output#load_tree mml ;
      current_cic_infos := Some (ids_to_terms,ids_to_father_ids)
  with
-  e -> raise (RefreshProofException e)
+  e ->
+ match !ProofEngine.proof with
+    None -> assert false
+  | Some (uri,metasenv,bo,ty) ->
+prerr_endline ("Offending proof: " ^ CicPp.ppobj (Cic.CurrentProof ("questa",metasenv,bo,ty))) ; flush stderr ;
+   raise (RefreshProofException e)
 ;;
 
 let refresh_sequent (proofw : GMathView.math_view) =
  try
   match !ProofEngine.goal with
      None -> proofw#unload
-   | Some (_,currentsequent) ->
+   | Some metano ->
       let metasenv =
        match !ProofEngine.proof with
           None -> assert false
         | Some (_,metasenv,_,_) -> metasenv
       in
+      let currentsequent = List.find (function (m,_,_) -> m=metano) metasenv in
        let sequent_gdome,ids_to_terms,ids_to_father_ids =
         SequentPp.XmlPp.print_sequent metasenv currentsequent
        in
@@ -206,7 +212,20 @@ let refresh_sequent (proofw : GMathView.math_view) =
           proofw#load_tree ~dom:sequent_mml ;
           current_goal_infos := Some (ids_to_terms,ids_to_father_ids)
  with
-  e -> raise (RefreshSequentException e)
+  e ->
+let metano =
+  match !ProofEngine.goal with
+     None -> assert false
+   | Some m -> m
+in
+let metasenv =
+ match !ProofEngine.proof with
+    None -> assert false
+  | Some (_,metasenv,_,_) -> metasenv
+in
+let currentsequent = List.find (function (m,_,_) -> m=metano) metasenv in
+prerr_endline ("Offending sequent: " ^ SequentPp.TextualPp.print_sequent currentsequent) ; flush stderr ;
+   raise (RefreshSequentException e)
 ;;
 
 (*
@@ -214,19 +233,23 @@ ignore(domImpl#saveDocumentToFile ~doc:sequent_doc
  ~name:"/public/sacerdot/guruguru1" ~indent:true ()) ;
 *)
 
-let mml_of_cic_term term =
+let mml_of_cic_term metano term =
+ let metasenv =
+  match !ProofEngine.proof with
+     None -> []
+   | Some (_,metasenv,_,_) -> metasenv
+ in
  let context =
   match !ProofEngine.goal with
      None -> []
-   | Some (_,(context,_)) -> context
+   | Some metano ->
+      let (_,canonical_context,_) =
+       List.find (function (m,_,_) -> m=metano) metasenv
+      in
+       canonical_context
  in
-  let metasenv =
-   match !ProofEngine.proof with
-      None -> []
-    | Some (_,metasenv,_,_) -> metasenv
-  in
    let sequent_gdome,ids_to_terms,ids_to_father_ids =
-    SequentPp.XmlPp.print_sequent metasenv (context,term)
+    SequentPp.XmlPp.print_sequent metasenv (metano,context,term)
    in
     let sequent_doc =
      Xml2Gdome.document_of_xml domImpl sequent_gdome
@@ -299,14 +322,23 @@ let call_tactic_with_input tactic rendering_window () =
        None -> assert false
      | Some (curi,_,_,_) -> curi
    in
+   let metasenv =
+    match !ProofEngine.proof with
+       None -> assert false
+     | Some (_,metasenv,_,_) -> metasenv
+   in
    let context =
     List.map
      (function
-         ProofEngine.Definition (n,_)
-       | ProofEngine.Declaration (n,_) -> n)
+         Some (n,_) -> Some n
+       | None -> None)
      (match !ProofEngine.goal with
          None -> assert false
-       | Some (_,(ctx,_)) -> ctx
+       | Some metano ->
+          let (_,canonical_context,_) =
+           List.find (function (m,_,_) -> m=metano) metasenv
+          in
+           canonical_context
      )
    in
     try
@@ -430,14 +462,23 @@ let call_tactic_with_input_and_goal_input tactic rendering_window () =
                     None -> assert false
                   | Some (curi,_,_,_) -> curi
                 in
+                let metasenv =
+                 match !ProofEngine.proof with
+                    None -> assert false
+                  | Some (_,metasenv,_,_) -> metasenv
+                in
                 let context =
                  List.map
                   (function
-                      ProofEngine.Definition (n,_)
-                    | ProofEngine.Declaration (n,_) -> n)
+                      Some (n,_) -> Some n
+                    | None -> None)
                   (match !ProofEngine.goal with
                       None -> assert false
-                    | Some (_,(ctx,_)) -> ctx
+                    | Some metano ->
+                       let (_,canonical_context,_) =
+                        List.find (function (m,_,_) -> m=metano) metasenv
+                       in
+                        canonical_context
                   )
                 in
                  begin
@@ -509,7 +550,7 @@ let call_tactic_with_goal_input_in_scratch tactic scratch_window () =
              Some (term,ids_to_terms, ids_to_father_ids) ->
               let id = xpath in
                let expr = tactic term (Hashtbl.find ids_to_terms id) in
-                let mml = mml_of_cic_term expr in
+                let mml = mml_of_cic_term 111 expr in
                  scratch_window#show () ;
                  scratch_window#mmlwidget#load_tree ~dom:mml
            | None -> assert false (* "ERROR: No current term!!!" *)
@@ -530,8 +571,8 @@ let exact rendering_window =
 let apply rendering_window =
  call_tactic_with_input ProofEngine.apply rendering_window
 ;;
-let elimintros rendering_window =
- call_tactic_with_input ProofEngine.elim_intros rendering_window
+let elimintrossimpl rendering_window =
+ call_tactic_with_input ProofEngine.elim_intros_simpl rendering_window
 ;;
 let whd rendering_window =
  call_tactic_with_goal_input ProofEngine.whd rendering_window
@@ -578,7 +619,7 @@ let simpl_in_scratch scratch_window =
 exception OpenConjecturesStillThere;;
 exception WrongProof;;
 
-let save rendering_window () =
+let qed rendering_window () =
  match !ProofEngine.proof with
     None -> assert false
   | Some (uri,[],bo,ty) ->
@@ -606,6 +647,71 @@ let save rendering_window () =
   | _ -> raise OpenConjecturesStillThere
 ;;
 
+(*????
+let dtdname = "http://www.cs.unibo.it/helm/dtd/cic.dtd";;
+*)
+let dtdname = "/projects/helm/V7/dtd/cic.dtd";;
+
+let save rendering_window () =
+ let outputhtml = (rendering_window#outputhtml : GHtml.xmhtml) in
+  match !ProofEngine.proof with
+     None -> assert false
+   | Some (uri, metasenv, bo, ty) ->
+      let currentproof =
+       Cic.CurrentProof (UriManager.name_of_uri uri,metasenv,bo,ty)
+      in
+       let (acurrentproof,_,_,ids_to_inner_sorts,_) =
+        Cic2acic.acic_object_of_cic_object currentproof
+       in
+        let xml = Cic2Xml.print_object uri ids_to_inner_sorts acurrentproof in
+         let xml' =
+          [< Xml.xml_cdata "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" ;
+             Xml.xml_cdata
+              ("<!DOCTYPE CurrentProof SYSTEM \"" ^ dtdname ^ "\">\n\n") ;
+             xml
+          >]
+         in
+          Xml.pp ~quiet:true xml' (Some "/public/sacerdot/currentproof") ;
+          output_html outputhtml
+           ("<h1 color=\"Green\">Current proof saved to " ^
+             "/public/sacerdot/currentproof</h1>")
+;;
+
+let load rendering_window () =
+ let outputhtml = (rendering_window#outputhtml : GHtml.xmhtml) in
+ let output = (rendering_window#output : GMathView.math_view) in
+ let proofw = (rendering_window#proofw : GMathView.math_view) in
+  try
+   let uri = UriManager.uri_of_string "cic:/dummy.con" in
+    match CicParser.obj_of_xml "/public/sacerdot/currentproof" uri with
+       Cic.CurrentProof (_,metasenv,bo,ty) ->
+        ProofEngine.proof :=
+         Some (uri, metasenv, bo, ty) ;
+        ProofEngine.goal :=
+         (match metasenv with
+             [] -> None
+           | (metano,_,_)::_ -> Some metano
+         ) ;
+        refresh_proof output ;
+        refresh_sequent proofw ;
+         output_html outputhtml
+          ("<h1 color=\"Green\">Current proof loaded from " ^
+            "/public/sacerdot/currentproof</h1>")
+     | _ -> assert false
+  with
+     RefreshSequentException e ->
+      output_html outputhtml
+       ("<h1 color=\"red\">Exception raised during the refresh of the " ^
+        "sequent: " ^ Printexc.to_string e ^ "</h1>")
+   | RefreshProofException e ->
+      output_html outputhtml
+       ("<h1 color=\"red\">Exception raised during the refresh of the " ^
+        "proof: " ^ Printexc.to_string e ^ "</h1>")
+   | e ->
+      output_html outputhtml
+       ("<h1 color=\"red\">" ^ Printexc.to_string e ^ "</h1>") ;
+;;
+
 let proveit rendering_window () =
  let module L = LogicalOperations in
  let module G = Gdome in
@@ -627,8 +733,8 @@ let proveit rendering_window () =
          match !current_cic_infos with
             Some (ids_to_terms, ids_to_father_ids) ->
              let id = xpath in
-              if L.to_sequent id ids_to_terms ids_to_father_ids then
-               refresh_proof rendering_window#output ;
+              L.to_sequent id ids_to_terms ids_to_father_ids ;
+              refresh_proof rendering_window#output ;
               refresh_sequent rendering_window#proofw
           | None -> assert false (* "ERROR: No current term!!!" *)
         with
@@ -647,6 +753,98 @@ let proveit rendering_window () =
   | None -> assert false (* "ERROR: No selection!!!" *)
 ;;
 
+let focus rendering_window () =
+ let module L = LogicalOperations in
+ let module G = Gdome in
+ let outputhtml = (rendering_window#outputhtml : GHtml.xmhtml) in
+  match rendering_window#output#get_selection with
+    Some node ->
+     let xpath =
+      ((node : Gdome.element)#getAttributeNS
+      (*CSC: OCAML DIVERGE
+      ((element : G.element)#getAttributeNS
+      *)
+        ~namespaceURI:helmns
+        ~localName:(G.domString "xref"))#to_string
+     in
+      if xpath = "" then assert false (* "ERROR: No xref found!!!" *)
+      else
+       begin
+        try
+         match !current_cic_infos with
+            Some (ids_to_terms, ids_to_father_ids) ->
+             let id = xpath in
+              L.focus id ids_to_terms ids_to_father_ids ;
+              refresh_sequent rendering_window#proofw
+          | None -> assert false (* "ERROR: No current term!!!" *)
+        with
+           RefreshSequentException e ->
+            output_html outputhtml
+             ("<h1 color=\"red\">Exception raised during the refresh of the " ^
+              "sequent: " ^ Printexc.to_string e ^ "</h1>")
+         | RefreshProofException e ->
+            output_html outputhtml
+             ("<h1 color=\"red\">Exception raised during the refresh of the " ^
+              "proof: " ^ Printexc.to_string e ^ "</h1>")
+         | e ->
+            output_html outputhtml
+             ("<h1 color=\"red\">" ^ Printexc.to_string e ^ "</h1>")
+       end
+  | None -> assert false (* "ERROR: No selection!!!" *)
+;;
+
+exception NoPrevGoal;;
+exception NoNextGoal;;
+
+let prevgoal metasenv metano =
+ let rec aux =
+  function
+     [] -> assert false
+   | [(m,_,_)] -> raise NoPrevGoal
+   | (n,_,_)::(m,_,_)::_ when m=metano -> n
+   | _::tl -> aux tl
+ in
+  aux metasenv
+;;
+
+let nextgoal metasenv metano =
+ let rec aux =
+  function
+     [] -> assert false
+   | [(m,_,_)] when m = metano -> raise NoNextGoal
+   | (m,_,_)::(n,_,_)::_ when m=metano -> n
+   | _::tl -> aux tl
+ in
+  aux metasenv
+;;
+
+let prev_or_next_goal select_goal rendering_window () =
+ let module L = LogicalOperations in
+ let module G = Gdome in
+ let outputhtml = (rendering_window#outputhtml : GHtml.xmhtml) in
+  let metasenv =
+   match !ProofEngine.proof with
+      None -> assert false
+    | Some (_,metasenv,_,_) -> metasenv
+  in
+  let metano =
+   match !ProofEngine.goal with
+      None -> assert false
+    | Some m -> m
+  in
+   try
+    ProofEngine.goal := Some (select_goal metasenv metano) ;
+    refresh_sequent rendering_window#proofw
+   with
+      RefreshSequentException e ->
+       output_html outputhtml
+        ("<h1 color=\"red\">Exception raised during the refresh of the " ^
+         "sequent: " ^ Printexc.to_string e ^ "</h1>")
+    | e ->
+       output_html outputhtml
+        ("<h1 color=\"red\">" ^ Printexc.to_string e ^ "</h1>")
+;;
+
 exception NotADefinition;;
 
 let open_ rendering_window () =
@@ -708,8 +906,8 @@ let state rendering_window () =
           let _  = CicTypeChecker.type_of_aux' [] [] expr in
            ProofEngine.proof :=
             Some (UriManager.uri_of_string "cic:/dummy.con",
-                   [1,expr], Cic.Meta 1, expr) ;
-           ProofEngine.goal := Some (1,([],expr)) ;
+                   [1,[],expr], Cic.Meta (1,[]), expr) ;
+           ProofEngine.goal := Some 1 ;
            refresh_sequent proofw ;
            refresh_proof output ;
      done
@@ -742,18 +940,22 @@ let check rendering_window scratch_window () =
       None -> UriManager.uri_of_string "cic:/dummy.con", []
     | Some (curi,metasenv,_,_) -> curi,metasenv
   in
-  let ciccontext,names_context =
+  let context,names_context =
    let context =
     match !ProofEngine.goal with
        None -> []
-     | Some (_,(ctx,_)) -> ctx
+     | Some metano ->
+        let (_,canonical_context,_) =
+         List.find (function (m,_,_) -> m=metano) metasenv
+        in
+         canonical_context
    in
-    ProofEngine.cic_context_of_named_context context,
-     List.map
-      (function
-          ProofEngine.Declaration (n,_)
-        | ProofEngine.Definition (n,_) -> n
-      ) context
+    context,
+    List.map
+     (function
+         Some (n,_) -> Some n
+       | None -> None
+     ) context
   in
    (* Do something interesting *)
    let lexbuf = Lexing.from_string input in
@@ -767,8 +969,8 @@ let check rendering_window scratch_window () =
          None -> ()
        | Some expr ->
           try
-           let ty  = CicTypeChecker.type_of_aux' metasenv ciccontext expr in
-            let mml = mml_of_cic_term (Cic.Cast (expr,ty)) in
+           let ty  = CicTypeChecker.type_of_aux' metasenv context expr in
+            let mml = mml_of_cic_term 111 (Cic.Cast (expr,ty)) in
              scratch_window#show () ;
              scratch_window#mmlwidget#load_tree ~dom:mml
           with
@@ -799,10 +1001,19 @@ let locate rendering_window () =
 
 let backward rendering_window () =
    let outputhtml = (rendering_window#outputhtml : GHtml.xmhtml) in
+   let metasenv =
+    match !ProofEngine.proof with
+       None -> assert false
+     | Some (_,metasenv,_,_) -> metasenv
+   in
    let result =
       match !ProofEngine.goal with
          | None -> ""
-         | Some (_, (_, t)) -> (Mquery.backward t)
+         | Some metano ->
+            let (_,_,ty) =
+             List.find (function (m,_,_) -> m=metano) metasenv
+            in
+             Mquery.backward ty
       in 
    output_html outputhtml result
       
@@ -1009,9 +1220,15 @@ class rendering_window output proofw (label : GMisc.label) =
  let button_export_to_postscript =
   GButton.button ~label:"export_to_postscript"
   ~packing:(hbox1#pack ~expand:false ~fill:false ~padding:5) () in
+ let qedb =
+  GButton.button ~label:"Qed"
+   ~packing:(hbox1#pack ~expand:false ~fill:false ~padding:5) () in
  let saveb =
   GButton.button ~label:"Save"
    ~packing:(hbox1#pack ~expand:false ~fill:false ~padding:5) () in
+ let loadb =
+  GButton.button ~label:"Load"
+   ~packing:(hbox1#pack ~expand:false ~fill:false ~padding:5) () in
  let closeb =
   GButton.button ~label:"Close"
    ~packing:(hbox1#pack ~expand:false ~fill:false ~padding:5) () in
@@ -1020,6 +1237,15 @@ class rendering_window output proofw (label : GMisc.label) =
  let proveitb =
   GButton.button ~label:"Prove It"
    ~packing:(hbox2#pack ~expand:false ~fill:false ~padding:5) () in
+ let focusb =
+  GButton.button ~label:"Focus"
+   ~packing:(hbox2#pack ~expand:false ~fill:false ~padding:5) () in
+ let prevgoalb =
+  GButton.button ~label:"<"
+   ~packing:(hbox2#pack ~expand:false ~fill:false ~padding:5) () in
+ let nextgoalb =
+  GButton.button ~label:">"
+   ~packing:(hbox2#pack ~expand:false ~fill:false ~padding:5) () in
  let oldinputt = GEdit.text ~editable:false ~width:400 ~height:180
    ~packing:(vbox#pack ~padding:5) () in
  let hbox4 =
@@ -1058,8 +1284,8 @@ class rendering_window output proofw (label : GMisc.label) =
  let applyb =
   GButton.button ~label:"Apply"
    ~packing:(hbox3#pack ~expand:false ~fill:false ~padding:5) () in
- let elimintrosb =
-  GButton.button ~label:"ElimIntros"
+ let elimintrossimplb =
+  GButton.button ~label:"ElimIntrosSimpl"
    ~packing:(hbox3#pack ~expand:false ~fill:false ~padding:5) () in
  let whdb =
   GButton.button ~label:"Whd"
@@ -1108,8 +1334,13 @@ object(self)
    button_export_to_postscript (choose_selection output) in
   ignore(settingsb#connect#clicked settings_window#show) ;
   ignore(button_export_to_postscript#connect#clicked (export_to_postscript output)) ;
+  ignore(qedb#connect#clicked (qed self)) ;
   ignore(saveb#connect#clicked (save self)) ;
+  ignore(loadb#connect#clicked (load self)) ;
   ignore(proveitb#connect#clicked (proveit self)) ;
+  ignore(focusb#connect#clicked (focus self)) ;
+  ignore(prevgoalb#connect#clicked (prev_or_next_goal prevgoal self)) ;
+  ignore(nextgoalb#connect#clicked (prev_or_next_goal nextgoal self)) ;
   ignore(window#event#connect#delete (fun _ -> GMain.Main.quit () ; true )) ;
   ignore(stateb#connect#clicked (state self)) ;
   ignore(openb#connect#clicked (open_ self)) ;
@@ -1118,7 +1349,7 @@ object(self)
   ignore(backwardb#connect#clicked (backward self)) ;
   ignore(exactb#connect#clicked (exact self)) ;
   ignore(applyb#connect#clicked (apply self)) ;
-  ignore(elimintrosb#connect#clicked (elimintros self)) ;
+  ignore(elimintrossimplb#connect#clicked (elimintrossimpl self)) ;
   ignore(whdb#connect#clicked (whd self)) ;
   ignore(reduceb#connect#clicked (reduce self)) ;
   ignore(simplb#connect#clicked (simpl self)) ;
index 80f7d04cbfde32f72f49ef650d6ad412c93087b6..a9274fba6cb0a4035719dfb9d18033a3ded93af9 100644 (file)
@@ -5,7 +5,6 @@ let get_parent id ids_to_terms ids_to_father_ids =
 ;;
 
 let get_context ids_to_terms ids_to_father_ids =
- let module P = ProofEngine in
  let module C = Cic in
   let rec aux id =
    match get_parent id ids_to_terms ids_to_father_ids with
@@ -20,11 +19,11 @@ let get_context ids_to_terms ids_to_father_ids =
          | C.Sort _
          | C.Implicit
          | C.Cast _ -> []
-         | C.Prod (n,s,t) when t == term -> [P.Declaration (n,s)]
+         | C.Prod (n,s,t) when t == term -> [Some (n,C.Decl s)]
          | C.Prod _ -> []
-         | C.Lambda (n,s,t) when t == term -> [P.Declaration (n,s)]
+         | C.Lambda (n,s,t) when t == term -> [Some (n,C.Decl s)]
          | C.Lambda _ -> []
-         | C.LetIn (n,s,t) when t == term -> [P.Definition (n,s)]
+         | C.LetIn (n,s,t) when t == term -> [Some (n,C.Def s)]
          | C.LetIn _ -> []
          | C.Appl _
          | C.Const _ -> []
@@ -37,7 +36,7 @@ let get_context ids_to_terms ids_to_father_ids =
             let counter = ref 0 in
              List.rev_map
               (function (name,_,ty,bo) ->
-                let res = (P.Definition (C.Name name, C.Fix (!counter,ifl))) in
+                let res = Some (C.Name name, (C.Def (C.Fix (!counter,ifl)))) in
                  incr counter ;
                  res
               ) ifl
@@ -45,7 +44,7 @@ let get_context ids_to_terms ids_to_father_ids =
             let counter = ref 0 in
              List.rev_map
               (function (name,ty,bo) ->
-                let res = (P.Definition (C.Name name, C.CoFix (!counter,ifl))) in
+                let res = Some (C.Name name,(C.Def (C.CoFix (!counter,ifl)))) in
                  incr counter ;
                  res
               ) ifl
@@ -57,8 +56,7 @@ let get_context ids_to_terms ids_to_father_ids =
 
 exception NotImplemented;;
 
-(* It returns true iff the proof has been perforated, i.e. if a subterm *)
-(* has been changed into a meta.                                        *)
+(* A subterm is changed into a fresh meta *)
 let to_sequent id ids_to_terms ids_to_father_ids =
  let module P = ProofEngine in
   let term = Hashtbl.find ids_to_terms id in
@@ -68,16 +66,24 @@ let to_sequent id ids_to_terms ids_to_father_ids =
        None -> assert false
      | Some (_,metasenv,_,_) -> metasenv
    in
-    let ty =
-     CicTypeChecker.type_of_aux' metasenv
-      (P.cic_context_of_named_context context) term
-    in
-     let (meta,perforated) =
-      (* If the selected term is already a meta, we return it. *)
-      (* Otherwise, we are trying to refine a non-meta term... *)
-      match term with
-         Cic.Meta n -> P.goal := Some (n,(context,ty)) ; n,false
-       | _ -> P.perforate context term ty,true (* P.perforate also sets the goal *)
-     in
-      perforated
+    let ty = CicTypeChecker.type_of_aux' metasenv context term in
+     P.perforate context term ty (* P.perforate also sets the goal *)
+;;
+
+exception FocusOnlyOnMeta;;
+
+(* If the current selection is a Meta, that Meta becomes the current goal *)
+let focus id ids_to_terms ids_to_father_ids =
+ let module P = ProofEngine in
+  let term = Hashtbl.find ids_to_terms id in
+  let context = get_context ids_to_terms ids_to_father_ids id in
+   let metasenv =
+    match !P.proof with
+       None -> assert false
+     | Some (_,metasenv,_,_) -> metasenv
+   in
+    let ty = CicTypeChecker.type_of_aux' metasenv context term in
+     match term with
+        Cic.Meta (n,_) -> P.goal := Some n
+      | _ -> raise FocusOnlyOnMeta
 ;;
index e9c50bd08be29e2e237d25e5f930aaeacc6a8d80..fb670923d4ab75a5f742dd94daaadcf625bddb5d 100644 (file)
@@ -178,7 +178,7 @@ let inspect_uri main l uri t c =
 
 let rec inspect_term main l = function
    | Rel i                        -> l 
-   | Meta i                       -> l 
+   | Meta (i,_)                   -> l 
    | Sort s                       -> l 
    | Implicit                     -> l 
    | Abst u                       -> l 
index 5457708a0a41a143d8ccd2824b931a2cdb97ed1f..f5f4e42adf0b6b06ca1387754ca4924045025a92 100644 (file)
@@ -1,35 +1,35 @@
-type binder_type =
-   Declaration of Cic.name * Cic.term
- | Definition of Cic.name * Cic.term
-;;
-
-type metasenv = (int * Cic.term) list;;
-
-type named_context = binder_type list;;
-
-type sequent = named_context * Cic.term;;
+(* Copyright (C) 2000, HELM Team.
+ * 
+ * This file is part of HELM, an Hypertextual, Electronic
+ * Library of Mathematics, developed at the Computer Science
+ * Department, University of Bologna, Italy.
+ * 
+ * HELM is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * HELM is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HELM; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA  02111-1307, USA.
+ * 
+ * For details, see the HELM World-Wide-Web page,
+ * http://cs.unibo.it/helm/.
+ *)
 
 let proof =
- ref (None : (UriManager.uri * metasenv * Cic.term * Cic.term) option)
-;;
-(*CSC: Quando facciamo Clear di una ipotesi, cosa succede? *)
-(* Note: the sequent is redundant: it can be computed from the type of the   *)
-(* metavariable and its context in the proof. We keep it just for efficiency *)
-(* because computing the context of a term may be quite expensive.           *)
-let goal = ref (None : (int * sequent) option);;
-
-exception NotImplemented
-
-let cic_context_of_named_context =
- List.map
-  (function
-      Declaration (_,t) -> Cic.Decl t
-    | Definition (_,t) -> Cic.Def t
-  )
+ ref (None : (UriManager.uri * Cic.metasenv * Cic.term * Cic.term) option)
 ;;
+let goal = ref (None : int option);;
 
-(* refine_meta_with_brand_new_metasenv meta term apply_subst_replacing    *)
-(*   newmetasenv                                                          *)
+(*CSC: commento vecchio *)
+(* refine_meta_with_brand_new_metasenv meta term subst_in newmetasenv     *)
 (* This (heavy) function must be called when a tactic can instantiate old *)
 (* metavariables (i.e. existential variables). It substitues the metasenv *)
 (* of the proof with the result of removing [meta] from the domain of     *)
@@ -38,37 +38,63 @@ let cic_context_of_named_context =
 (*  current proof.                                                        *)
 (*CSC: A questo punto perche' passare un bo' gia' istantiato, se tanto poi *)
 (*CSC: ci ripasso sopra apply_subst!!!                                     *)
-(*CSC: Inoltre, potrebbe essere questa funzione ad applicare apply_subst a *)
-(*CSC: newmetasenv!!!                                                      *)
-let refine_meta_with_brand_new_metasenv meta term apply_subst_replacing
- newmetasenv
-=
+(*CSC: Attenzione! Ora questa funzione applica anche [subst_in] a *)
+(*CSC: [newmetasenv].                                             *)
+let subst_meta_and_metasenv_in_current_proof meta subst_in newmetasenv =
  let (uri,bo,ty) =
   match !proof with
      None -> assert false
    | Some (uri,_,bo,ty) -> uri,bo,ty
  in
-  let subst_in t =
-   ProofEngineReduction.replace ~what:(Cic.Meta meta) ~with_what:term ~where:t
+  let bo' = subst_in bo in
+  let metasenv' =
+   List.fold_right
+    (fun metasenv_entry i ->
+      match metasenv_entry with
+         (m,canonical_context,ty) when m <> meta ->
+           let canonical_context' =
+            List.map
+             (function
+                 None -> None
+               | Some (i,Cic.Decl t) -> Some (i,Cic.Decl (subst_in t))
+               | Some (i,Cic.Def t)  -> Some (i,Cic.Def (subst_in t))
+             ) canonical_context
+           in
+            (m,canonical_context',subst_in ty)::i
+       | _ -> i
+    ) newmetasenv []
   in
-   let bo' = apply_subst_replacing (subst_in bo) in
-   let metasenv' = List.remove_assoc meta newmetasenv in
-    proof := Some (uri,metasenv',bo',ty)
+   proof := Some (uri,metasenv',bo',ty) ;
+   metasenv'
 ;;
 
-let refine_meta meta term newmetasenv =
+let subst_meta_in_current_proof meta term newmetasenv =
  let (uri,metasenv,bo,ty) =
   match !proof with
      None -> assert false
    | Some (uri,metasenv,bo,ty) -> uri,metasenv,bo,ty
  in
-  let subst_in t =
-   ProofEngineReduction.replace ~what:(Cic.Meta meta) ~with_what:term ~where:t
-  in
-   let metasenv' = newmetasenv @ (List.remove_assoc meta metasenv) in
-    let metasenv'' = List.map (function i,ty -> i,(subst_in ty)) metasenv' in
-    let bo' = subst_in bo in
-     proof := Some (uri,metasenv'',bo',ty)
+  let subst_in = CicUnification.apply_subst [meta,term] in
+   let metasenv' =
+    newmetasenv @ (List.filter (function (m,_,_) -> m <> meta) metasenv)
+   in
+    let metasenv'' =
+     List.map
+      (function i,canonical_context,ty ->
+        let canonical_context' =
+         List.map
+          (function
+              Some (n,Cic.Decl s) -> Some (n,Cic.Decl (subst_in s))
+            | Some (n,Cic.Def s) -> Some (n,Cic.Def (subst_in s))
+            | None -> None
+          ) canonical_context
+        in
+         i,canonical_context',(subst_in ty)
+      ) metasenv'
+    in
+     let bo' = subst_in bo in
+      proof := Some (uri,metasenv'',bo',ty) ;
+      metasenv''
 ;;
 
 (* Returns the first meta whose number is above the *)
@@ -83,8 +109,8 @@ let new_meta () =
    function
       None,[] -> 1
     | Some n,[] -> n
-    | None,(n,_)::tl -> aux (Some n,tl)
-    | Some m,(n,_)::tl -> if n > m then aux (Some n,tl) else aux (Some m,tl)
+    | None,(n,_,_)::tl -> aux (Some n,tl)
+    | Some m,(n,_,_)::tl -> if n > m then aux (Some n,tl) else aux (Some m,tl)
   in
    1 + aux (None,metasenv)
 ;;
@@ -98,7 +124,7 @@ let metas_in_term term =
    function
       C.Rel _
     | C.Var _ -> []
-    | C.Meta n -> [n]
+    | C.Meta (n,_) -> [n]
     | C.Sort _
     | C.Implicit -> []
     | C.Cast (te,ty) -> (aux te) @ (aux ty)
@@ -128,6 +154,21 @@ let metas_in_term term =
      elim_duplicates metas
 ;;
 
+(* identity_relocation_list_for_metavariable i canonical_context         *)
+(* returns the identity relocation list, which is the list [1 ; ... ; n] *)
+(* where n = List.length [canonical_context]                             *)
+(*CSC: ma mi basta la lunghezza del contesto canonico!!!*)
+let identity_relocation_list_for_metavariable canonical_context =
+ let canonical_context_length = List.length canonical_context in
+  let rec aux =
+   function
+      (_,[]) -> []
+    | (n,None::tl) -> None::(aux ((n+1),tl))
+    | (n,_::tl) -> (Some (Cic.Rel n))::(aux ((n+1),tl))
+  in
+   aux (1,canonical_context)
+;;
+
 (* perforate context term ty                                                 *)
 (* replaces the term [term] in the proof with a new metavariable whose type  *)
 (* is [ty]. [context] must be the context of [term] in the whole proof. This *)
@@ -141,19 +182,24 @@ let perforate context term ty =
     | Some (uri,metasenv,bo,gty) ->
        (* We push the new meta at the end of the list for pretty-printing *)
        (* purposes: in this way metas are ordered.                        *)
-       let metasenv' = metasenv@[newmeta,ty] in
-        let bo' = ProofEngineReduction.replace term (C.Meta newmeta) bo in
+       let metasenv' = metasenv@[newmeta,context,ty] in
+        let irl = identity_relocation_list_for_metavariable context in
+(*CSC: Bug: se ci sono due term uguali nella prova dovrei bucarne uno solo!!!*)
+        let bo' =
+         ProofEngineReduction.replace (==) term (C.Meta (newmeta,irl)) bo
+        in
         (* It may be possible that some metavariables occurred only in *)
         (* the term we are perforating and they now occurs no more. We *)
         (* get rid of them, collecting the really useful metavariables *)
         (* in metasenv''.                                              *)
+(*CSC: Bug: una meta potrebbe non comparire in bo', ma comparire nel tipo *)
+(*CSC: di una metavariabile che compare in bo'!!!!!!!                     *)
          let newmetas = metas_in_term bo' in
           let metasenv'' =
-           List.filter (function (n,_) -> List.mem n newmetas) metasenv'
+           List.filter (function (n,_,_) -> List.mem n newmetas) metasenv'
           in
            proof := Some (uri,metasenv'',bo',gty) ;
-           goal := Some (newmeta,(context,ty)) ;
-           newmeta
+           goal := Some newmeta
 ;;
 
 (************************************************************)
@@ -177,27 +223,32 @@ in
 (* and [bo] = Lambda/LetIn [context].(Meta [newmeta])       *)
 (* So, lambda_abstract is the core of the implementation of *)
 (* the Intros tactic.                                       *)
-let lambda_abstract newmeta ty =
+let lambda_abstract context newmeta ty =
  let module C = Cic in
-  let rec collect_context =
+  let rec collect_context context =
    function
-      C.Cast (te,_)   -> collect_context te
+      C.Cast (te,_)   -> collect_context context te
     | C.Prod (n,s,t)  ->
-       let (ctx,ty,bo) = collect_context t in
-        let n' =
-         match n with
-            C.Name _ -> n
+       let n' =
+        match n with
+           C.Name _ -> n
 (*CSC: generatore di nomi? Chiedere il nome? *)
-          | C.Anonimous -> C.Name (fresh_name ())
+         | C.Anonimous -> C.Name (fresh_name ())
+       in
+        let (context',ty,bo) =
+         collect_context ((Some (n',(C.Decl s)))::context) t
         in
-         ((Declaration (n',s))::ctx,ty,C.Lambda(n',s,bo))
+         (context',ty,C.Lambda(n',s,bo))
     | C.LetIn (n,s,t) ->
-       let (ctx,ty,bo) = collect_context t in
-        ((Definition (n,s))::ctx,ty,C.LetIn(n,s,bo))
-    | _ as t -> [], t, (C.Meta newmeta)
+       let (context',ty,bo) =
+        collect_context ((Some (n,(C.Def s)))::context) t
+       in
+        (context',ty,C.LetIn(n,s,bo))
+    | _ as t ->
+      let irl = identity_relocation_list_for_metavariable context in
+       context, t, (C.Meta (newmeta,irl))
   in
-   let revcontext,ty',bo = collect_context ty in
-    bo,(List.rev revcontext),ty'
+   collect_context context ty
 ;;
 
 let intros () =
@@ -208,16 +259,15 @@ let intros () =
       None -> assert false
     | Some (_,metasenv,_,_) -> metasenv
   in
-  let (metano,context,ty) =
+  let metano,context,ty =
    match !goal with
       None -> assert false
-    | Some (metano,(context,ty)) -> metano,context,ty
+    | Some metano -> List.find (function (m,_,_) -> m=metano) metasenv
   in
    let newmeta = new_meta () in
-    let (bo',newcontext,ty') = lambda_abstract newmeta ty in
-      let context'' = newcontext @ context in
-       refine_meta metano bo' [newmeta,ty'] ;
-       goal := Some (newmeta,(context'',ty'))
+    let (context',ty',bo') = lambda_abstract context newmeta ty in
+     let _ = subst_meta_in_current_proof metano bo' [newmeta,context',ty'] in
+      goal := Some newmeta
 ;;
 
 (* The term bo must be closed in the current context *)
@@ -229,22 +279,21 @@ let exact bo =
       None -> assert false
     | Some (_,metasenv,_,_) -> metasenv
   in
-  let (metano,context,ty) =
+  let metano,context,ty =
    match !goal with
       None -> assert false
-    | Some (metano,(context,ty)) ->
-       assert (ty = List.assoc metano metasenv) ;
-       (* Invariant: context is the actual context of the meta in the proof *)
-       metano,context,ty
+    | Some metano -> List.find (function (m,_,_) -> m=metano) metasenv
   in
-   let context = cic_context_of_named_context context in
-    if R.are_convertible context (T.type_of_aux' metasenv context bo) ty then
-     begin
-      refine_meta metano bo [] ;
-      goal := None
-     end
-    else
-     raise (Fail "The type of the provided term is not the one expected.")
+   if R.are_convertible context (T.type_of_aux' metasenv context bo) ty then
+    begin
+     let metasenv' = subst_meta_in_current_proof metano bo [] in
+      goal :=
+       match metasenv' with
+          [] -> None
+        | (n,_,_)::_ -> Some n
+    end
+   else
+    raise (Fail "The type of the provided term is not the one expected.")
 ;;
 
 (*CSC: The call to the Intros tactic is embedded inside the code of the *)
@@ -255,18 +304,18 @@ let exact bo =
 (* and last new METAs introduced. The nth argument in the list of arguments  *)
 (* is the nth new META lambda-abstracted as much as possible. Hence, this    *)
 (* functions already provides the behaviour of Intros on the new goals.      *)
-let new_metasenv_for_apply_intros ty =
+let new_metasenv_for_apply_intros context ty =
  let module C = Cic in
  let module S = CicSubstitution in
   let rec aux newmeta =
    function
       C.Cast (he,_) -> aux newmeta he
-    | C.Prod (_,s,t) ->
-       let newargument,newcontext,ty' = lambda_abstract newmeta s in
+    | C.Prod (name,s,t) ->
+       let newcontext,ty',newargument = lambda_abstract context newmeta s in
         let (res,newmetasenv,arguments,lastmeta) =
          aux (newmeta + 1) (S.subst newargument t)
         in
-         res,(newmeta,ty')::newmetasenv,newargument::arguments,lastmeta
+         res,(newmeta,newcontext,ty')::newmetasenv,newargument::arguments,lastmeta
     | t -> t,[],[],newmeta
   in
    let newmeta = new_meta () in
@@ -281,18 +330,19 @@ let new_metasenv_for_apply_intros ty =
 (* a list of arguments for the new applications and the indexes of the first *)
 (* and last new METAs introduced. The nth argument in the list of arguments  *)
 (* is just the nth new META.                                                 *)
-let new_metasenv_for_apply ty =
+let new_metasenv_for_apply context ty =
  let module C = Cic in
  let module S = CicSubstitution in
   let rec aux newmeta =
    function
       C.Cast (he,_) -> aux newmeta he
-    | C.Prod (_,s,t) ->
-       let newargument = C.Meta newmeta in
-        let (res,newmetasenv,arguments,lastmeta) =
-         aux (newmeta + 1) (S.subst newargument t)
-        in
-         res,(newmeta,s)::newmetasenv,newargument::arguments,lastmeta
+    | C.Prod (name,s,t) ->
+       let irl = identity_relocation_list_for_metavariable context in
+        let newargument = C.Meta (newmeta,irl) in
+         let (res,newmetasenv,arguments,lastmeta) =
+          aux (newmeta + 1) (S.subst newargument t)
+         in
+          res,(newmeta,context,s)::newmetasenv,newargument::arguments,lastmeta
     | t -> t,[],[],newmeta
   in
    let newmeta = new_meta () in
@@ -304,17 +354,31 @@ let new_metasenv_for_apply ty =
 
 
 (*CSC: ma serve solamente la prima delle new_uninst e l'unione delle due!!! *)
-let classify_metas newmeta in_subst_domain apply_subst metasenv =
+let classify_metas newmeta in_subst_domain subst_in metasenv =
  List.fold_right
-  (fun (i,ty) (old_uninst,new_uninst) ->
+  (fun (i,canonical_context,ty) (old_uninst,new_uninst) ->
     if in_subst_domain i then
      old_uninst,new_uninst
     else
-     let ty' = apply_subst ty in
+     let ty' = subst_in canonical_context ty in
+      let canonical_context' =
+       List.fold_right
+        (fun entry canonical_context' ->
+          let entry' =
+           match entry with
+              Some (n,Cic.Decl s) ->
+               Some (n,Cic.Decl (subst_in canonical_context' s))
+            | Some (n,Cic.Def s) ->
+               Some (n,Cic.Def (subst_in canonical_context' s))
+            | None -> None
+          in
+           entry'::canonical_context'
+        ) canonical_context []
+     in
       if i < newmeta then
-       ((i,ty')::old_uninst),new_uninst
+       ((i,canonical_context',ty')::old_uninst),new_uninst
       else
-       old_uninst,((i,ty')::new_uninst)
+       old_uninst,((i,canonical_context',ty')::new_uninst)
   ) metasenv ([],[])
 ;;
 
@@ -328,50 +392,47 @@ let apply term =
       None -> assert false
     | Some (_,metasenv,_,_) -> metasenv
   in
-  let (metano,context,ty) =
+  let metano,context,ty =
    match !goal with
       None -> assert false
-    | Some (metano,(context,ty)) ->
-       assert (ty = List.assoc metano metasenv) ;
-       (* Invariant: context is the actual context of the meta in the proof *)
-       metano,context,ty
+    | Some metano ->
+       List.find (function (m,_,_) -> m=metano) metasenv
   in
-   let ciccontext = cic_context_of_named_context context in
-    let termty = CicTypeChecker.type_of_aux' metasenv ciccontext term in
-     (* newmeta is the lowest index of the new metas introduced *)
-     let (consthead,newmetas,arguments,newmeta,_) =
-      new_metasenv_for_apply termty
-     in
-      let newmetasenv = newmetas@metasenv in
-       let subst = CicUnification.fo_unif newmetasenv ciccontext consthead ty in
-        let in_subst_domain i = List.exists (function (j,_) -> i=j) subst in
-        let apply_subst = CicUnification.apply_subst subst in
-(*CSC: estremamente inefficiente: fare una passata sola per rimpiazzarle tutte*)
-        let apply_subst_replacing t =
-         List.fold_left
-          (fun t (i,bo) ->
-            ProofEngineReduction.replace
-             ~what:(Cic.Meta i) ~with_what:bo ~where:t)
-          t subst
+   let termty = CicTypeChecker.type_of_aux' metasenv context term in
+    (* newmeta is the lowest index of the new metas introduced *)
+    let (consthead,newmetas,arguments,newmeta,_) =
+     new_metasenv_for_apply context termty
+    in
+     let newmetasenv = newmetas@metasenv in
+      let subst,newmetasenv' =
+       CicUnification.fo_unif newmetasenv context consthead ty
+      in
+       let in_subst_domain i = List.exists (function (j,_) -> i=j) subst in
+       let apply_subst = CicUnification.apply_subst subst in
+        let old_uninstantiatedmetas,new_uninstantiatedmetas =
+         (* subst_in doesn't need the context. Hence the underscore. *)
+         let subst_in _ = CicUnification.apply_subst subst in
+          classify_metas newmeta in_subst_domain subst_in newmetasenv'
         in
-         let old_uninstantiatedmetas,new_uninstantiatedmetas =
-          classify_metas newmeta in_subst_domain apply_subst newmetasenv
+         let bo' =
+          if List.length newmetas = 0 then
+           term
+          else
+           let arguments' = List.map apply_subst arguments in
+            Cic.Appl (term::arguments')
          in
-         let bo' =
-          if List.length newmetas = 0 then
-           term
-          else
-            let arguments' = List.map apply_subst arguments in
-            Cic.Appl (term::arguments')
-         in
-          refine_meta_with_brand_new_metasenv metano bo' apply_subst_replacing
-            (new_uninstantiatedmetas@old_uninstantiatedmetas) ;
-          match new_uninstantiatedmetas with
+          let newmetasenv'' = new_uninstantiatedmetas@old_uninstantiatedmetas in
+         let newmetasenv''' =
+           let subst_in = CicUnification.apply_subst ((metano,bo')::subst) in
+            subst_meta_and_metasenv_in_current_proof metano subst_in
+             newmetasenv''
+          in
+          match newmetasenv''' with
              [] -> goal := None
-           | (i,ty)::_ -> goal := Some (i,(context,ty))
+           | (i,_,_)::_ -> goal := Some i
 ;;
 
-let eta_expand metasenv ciccontext t arg =
+let eta_expand metasenv context t arg =
  let module T = CicTypeChecker in
  let module S = CicSubstitution in
  let module C = Cic in
@@ -413,7 +474,7 @@ let eta_expand metasenv ciccontext t arg =
          C.CoFix (i, substitutedfl)
   in
    let argty =
-    T.type_of_aux' metasenv ciccontext arg
+    T.type_of_aux' metasenv context arg
    in
     (C.Appl [C.Lambda ((C.Name "dummy"),argty,aux 0 t) ; arg])
 ;;
@@ -422,7 +483,7 @@ exception NotAnInductiveTypeToEliminate;;
 exception NotTheRightEliminatorShape;;
 exception NoHypothesesFound;;
 
-let elim_intros term =
+let elim_intros_simpl term =
  let module T = CicTypeChecker in
  let module U = UriManager in
  let module R = CicReduction in
@@ -432,147 +493,165 @@ let elim_intros term =
       None -> assert false
     | Some (curi,metasenv,_,_) -> curi,metasenv
   in
-  let (metano,context,ty) =
+  let metano,context,ty =
    match !goal with
       None -> assert false
-    | Some (metano,(context,ty)) ->
-       assert (ty = List.assoc metano metasenv) ;
-       (* Invariant: context is the actual context of the meta in the proof *)
-       metano,context,ty
+    | Some metano ->
+       List.find (function (m,_,_) -> m=metano) metasenv
   in
-   let ciccontext = cic_context_of_named_context context in
-    let termty = T.type_of_aux' metasenv ciccontext term in
-    let uri,cookingno,typeno,args =
-     match termty with
-        C.MutInd (uri,cookingno,typeno) -> (uri,cookingno,typeno,[])
-      | C.Appl ((C.MutInd (uri,cookingno,typeno))::args) ->
-          (uri,cookingno,typeno,args)
-      | _ -> raise NotAnInductiveTypeToEliminate
+   let termty = T.type_of_aux' metasenv context term in
+   let uri,cookingno,typeno,args =
+    match termty with
+       C.MutInd (uri,cookingno,typeno) -> (uri,cookingno,typeno,[])
+     | C.Appl ((C.MutInd (uri,cookingno,typeno))::args) ->
+         (uri,cookingno,typeno,args)
+     | _ -> raise NotAnInductiveTypeToEliminate
+   in
+    let eliminator_uri =
+     let buri = U.buri_of_uri uri in
+     let name = 
+      match CicEnvironment.get_cooked_obj uri cookingno with
+         C.InductiveDefinition (tys,_,_) ->
+          let (name,_,_,_) = List.nth tys typeno in
+           name
+       | _ -> assert false
+     in
+     let ext =
+      match T.type_of_aux' metasenv context ty with
+         C.Sort C.Prop -> "_ind"
+       | C.Sort C.Set  -> "_rec"
+       | C.Sort C.Type -> "_rect"
+       | _ -> assert false
+     in
+      U.uri_of_string (buri ^ "/" ^ name ^ ext ^ ".con")
     in
-     let eliminator_uri =
-      let buri = U.buri_of_uri uri in
-      let name = 
-       match CicEnvironment.get_cooked_obj uri cookingno with
-          C.InductiveDefinition (tys,_,_) ->
-           let (name,_,_,_) = List.nth tys typeno in
-            name
-        | _ -> assert false
-      in
-      let ext =
-       match T.type_of_aux' metasenv ciccontext ty with
-          C.Sort C.Prop -> "_ind"
-        | C.Sort C.Set  -> "_rec"
-        | C.Sort C.Type -> "_rect"
-        | _ -> assert false
-      in
-       U.uri_of_string (buri ^ "/" ^ name ^ ext ^ ".con")
+     let eliminator_cookingno =
+      UriManager.relative_depth curi eliminator_uri 0
      in
-      let eliminator_cookingno =
-       UriManager.relative_depth curi eliminator_uri 0
+     let eliminator_ref = C.Const (eliminator_uri,eliminator_cookingno) in
+      let ety =
+       T.type_of_aux' [] [] eliminator_ref
       in
-      let eliminator_ref = C.Const (eliminator_uri,eliminator_cookingno) in
-       let ety =
-        T.type_of_aux' [] [] eliminator_ref
+       let (econclusion,newmetas,arguments,newmeta,lastmeta) =
+(*
+        new_metasenv_for_apply context ety
+*)
+        new_metasenv_for_apply_intros context ety
        in
-        let (econclusion,newmetas,arguments,newmeta,lastmeta) =
-         new_metasenv_for_apply ety
-        in
-         (* Here we assume that we have only one inductive hypothesis to *)
-         (* eliminate and that it is the last hypothesis of the theorem. *)
-         (* A better approach would be fingering the hypotheses in some  *)
-         (* way.                                                         *)
-         let meta_of_corpse = Cic.Meta (lastmeta - 1) in
-         let newmetasenv = newmetas @ metasenv in
-prerr_endline ("ECONCLUSION: " ^ CicPp.ppterm econclusion) ;
-flush stderr ;
-         let subst1 =
-          CicUnification.fo_unif newmetasenv ciccontext term meta_of_corpse
+        (* Here we assume that we have only one inductive hypothesis to *)
+        (* eliminate and that it is the last hypothesis of the theorem. *)
+        (* A better approach would be fingering the hypotheses in some  *)
+        (* way.                                                         *)
+        let meta_of_corpse =
+         let (_,canonical_context,_) =
+          List.find (function (m,_,_) -> m=(lastmeta - 1)) newmetas
          in
-          let ueconclusion = CicUnification.apply_subst subst1 econclusion in
-prerr_endline ("ECONCLUSION DOPO UNWIND: " ^ CicPp.ppterm ueconclusion) ;
-flush stderr ;
-           (* The conclusion of our elimination principle is *)
-           (*  (?i farg1 ... fargn)                         *)
-           (* The conclusion of our goal is ty. So, we can   *)
-           (* eta-expand ty w.r.t. farg1 .... fargn to get   *)
-           (* a new ty equal to (P farg1 ... fargn). Now     *)
-           (* ?i can be instantiated with P and we are ready *)
-           (* to refine the term.                            *)
-           let emeta, fargs =
-            match ueconclusion with
-(*CSC: Code to be used for Apply *)
-               C.Appl ((C.Meta emeta)::fargs) -> emeta,fargs
-             | C.Meta emeta -> emeta,[]
-(*CSC: Code to be used for ApplyIntros
-               C.Appl (he::fargs) ->
-                let rec find_head =
-                 function
-                    C.Meta emeta -> emeta
-                  | C.Lambda (_,_,t) -> find_head t
-                  | C.LetIn (_,_,t) -> find_head t
-                  | _ ->raise NotTheRightEliminatorShape
-                in
-                 find_head he,fargs
+          let irl =
+           identity_relocation_list_for_metavariable canonical_context
+          in
+           Cic.Meta (lastmeta - 1, irl)
+        in
+        let newmetasenv = newmetas @ metasenv in
+        let subst1,newmetasenv' =
+         CicUnification.fo_unif newmetasenv context term meta_of_corpse
+        in
+         let ueconclusion = CicUnification.apply_subst subst1 econclusion in
+          (* The conclusion of our elimination principle is *)
+          (*  (?i farg1 ... fargn)                         *)
+          (* The conclusion of our goal is ty. So, we can   *)
+          (* eta-expand ty w.r.t. farg1 .... fargn to get   *)
+          (* a new ty equal to (P farg1 ... fargn). Now     *)
+          (* ?i can be instantiated with P and we are ready *)
+          (* to refine the term.                            *)
+          let emeta, fargs =
+           match ueconclusion with
+(*CSC: Code to be used for Apply
+              C.Appl ((C.Meta (emeta,_))::fargs) -> emeta,fargs
+            | C.Meta (emeta,_) -> emeta,[]
 *)
-             | _ -> raise NotTheRightEliminatorShape
+(*CSC: Code to be used for ApplyIntros *)
+              C.Appl (he::fargs) ->
+               let rec find_head =
+                function
+                   C.Meta (emeta,_) -> emeta
+                 | C.Lambda (_,_,t) -> find_head t
+                 | C.LetIn (_,_,t) -> find_head t
+                 | _ ->raise NotTheRightEliminatorShape
+               in
+                find_head he,fargs
+(* *)
+            | _ -> raise NotTheRightEliminatorShape
+          in
+           let ty' = CicUnification.apply_subst subst1 ty in
+           let eta_expanded_ty =
+(*CSC: newmetasenv' era metasenv ??????????? *)
+            List.fold_left (eta_expand newmetasenv' context) ty' fargs
            in
-            let ty' = CicUnification.apply_subst subst1 ty in
-            let eta_expanded_ty =
-             List.fold_left (eta_expand metasenv ciccontext) ty' fargs
-            in
-prerr_endline ("ETAEXPANDEDTY:" ^ CicPp.ppterm eta_expanded_ty) ; flush stdout ;
-             let subst2 =
-(*CSC: passo newmetasenv, ma alcune variabili sono gia' state sostituite
+            let subst2,newmetasenv'' =
+(*CSC: passo newmetasenv', ma alcune variabili sono gia' state sostituite
 da subst1!!!! Dovrei rimuoverle o sono innocue?*)
-              CicUnification.fo_unif
-               newmetasenv ciccontext ueconclusion eta_expanded_ty
+             CicUnification.fo_unif
+              newmetasenv' context ueconclusion eta_expanded_ty
+            in
+             let in_subst_domain i =
+              let eq_to_i = function (j,_) -> i=j in
+               List.exists eq_to_i subst1 ||
+               List.exists eq_to_i subst2
              in
-prerr_endline "Dopo la seconda unificazione" ; flush stdout ;
-prerr_endline "unwind"; flush stderr;
-              let in_subst_domain i =
-               let eq_to_i = function (j,_) -> i=j in
-                List.exists eq_to_i subst1 ||
-                List.exists eq_to_i subst2
+(*CSC: codice per l'elim
+              (* When unwinding the META that corresponds to the elimination *)
+              (* predicate (which is emeta), we must also perform one-step   *)
+              (* beta-reduction. apply_subst doesn't need the context. Hence *)
+              (* the underscore.                                             *)
+              let apply_subst _ t =
+               let t' = CicUnification.apply_subst subst1 t in
+                CicUnification.apply_subst_reducing
+                 subst2 (Some (emeta,List.length fargs)) t'
               in
-               (* When unwinding the META that corresponds to the elimination *)
-               (* predicate (which is emeta), we must also perform one-step   *)
-               (* beta-reduction.                                             *)
-               let apply_subst t =
-                let t' = CicUnification.apply_subst subst1 t in
-                 CicUnification.apply_subst_reducing
-                  subst2 (Some (emeta,List.length fargs)) t'
-               in
-(*CSC: estremamente inefficiente: fare una passata sola per rimpiazzarle tutte*)
-               let apply_subst_replacing t =
-                let t' =
-                 List.fold_left
-                  (fun t (i,bo) ->
-                    ProofEngineReduction.replace
-                     ~what:(Cic.Meta i) ~with_what:bo ~where:t)
-                  t subst1
-                in
-                 List.fold_left
-                  (fun t (i,bo) ->
-                    ProofEngineReduction.replace
-                     ~what:(Cic.Meta i) ~with_what:bo ~where:t)
-                  t' subst2
-               in
-                let newmetasenv' =
-                 List.map (function (i,ty) -> i, apply_subst ty) newmetasenv
+*)
+(*CSC: codice per l'elim_intros_simpl. Non effettua semplificazione. *)
+              let apply_subst context t =
+               let t' = CicUnification.apply_subst (subst1@subst2) t in
+                ProofEngineReduction.simpl context t'
+              in
+(* *)
+                let old_uninstantiatedmetas,new_uninstantiatedmetas =
+                 classify_metas newmeta in_subst_domain apply_subst
+                  newmetasenv''
                 in
-                 let old_uninstantiatedmetas,new_uninstantiatedmetas =
-                  classify_metas newmeta in_subst_domain apply_subst newmetasenv
-                 in
-                  let arguments' = List.map apply_subst arguments in
-                   let bo' = Cic.Appl (eliminator_ref::arguments') in
-prerr_endline ("BODY': " ^ CicPp.ppterm bo') ; flush stdout ;
-List.iter (function (i,t) -> prerr_endline ("?" ^ string_of_int i ^ ": " ^ CicPp.ppterm t)) (new_uninstantiatedmetas@old_uninstantiatedmetas) ; flush stderr ;
-                   refine_meta_with_brand_new_metasenv metano bo'
-                     apply_subst_replacing
-                     (new_uninstantiatedmetas@old_uninstantiatedmetas) ;
-                   match new_uninstantiatedmetas with
-                      [] -> goal := None
-                    | (i,ty)::_ -> goal := Some (i,(context,ty))
+                 let arguments' = List.map (apply_subst context) arguments in
+                  let bo' = Cic.Appl (eliminator_ref::arguments') in
+                   let newmetasenv''' =
+                    new_uninstantiatedmetas@old_uninstantiatedmetas
+                   in
+                    let newmetasenv'''' =
+                     (* When unwinding the META that corresponds to the *)
+                     (* elimination predicate (which is emeta), we must *)
+                     (* also perform one-step beta-reduction.           *)
+                     (* The only difference w.r.t. apply_subst is that  *)
+                     (* we also substitute metano with bo'.             *)
+                     (*CSC: Nota: sostituire nuovamente subst1 e' superfluo, *)
+                     (*CSC: no?                                              *)
+(*CSC: codice per l'elim
+                     let apply_subst' t =
+                      let t' = CicUnification.apply_subst subst1 t in
+                       CicUnification.apply_subst_reducing
+                        ((metano,bo')::subst2)
+                        (Some (emeta,List.length fargs)) t'
+                     in
+*)
+(*CSC: codice per l'elim_intros_simpl *)
+                     let apply_subst' t =
+                      CicUnification.apply_subst
+                       ((metano,bo')::(subst1@subst2)) t
+                     in
+(* *)
+                      subst_meta_and_metasenv_in_current_proof metano
+                       apply_subst' newmetasenv'''
+                    in
+                    match newmetasenv'''' with
+                       [] -> goal := None
+                     | (i,_,_)::_ -> goal := Some i
 ;;
 
 let reduction_tactic reduction_function term =
@@ -581,51 +660,54 @@ let reduction_tactic reduction_function term =
      None -> assert false
    | Some (curi,metasenv,bo,ty) -> curi,metasenv,bo,ty
  in
- let (metano,context,ty) =
+ let metano,context,ty =
   match !goal with
      None -> assert false
-   | Some (metano,(context,ty)) -> metano,context,ty
+   | Some metano -> List.find (function (m,_,_) -> m=metano) metasenv
  in
-  let ciccontext = cic_context_of_named_context context in
-  let term' = reduction_function ciccontext term in
+  let term' = reduction_function context term in
    (* We don't know if [term] is a subterm of [ty] or a subterm of *)
    (* the type of one metavariable. So we replace it everywhere.   *)
    (*CSC: ma si potrebbe ovviare al problema. Ma non credo *)
    (*CSC: che si guadagni nulla in fatto di efficienza.    *) 
-   let replace = ProofEngineReduction.replace ~what:term ~with_what:term' in
+   let replace =
+    ProofEngineReduction.replace ~equality:(==) ~what:term ~with_what:term'
+   in
     let ty' = replace ty in
     let context' =
      List.map
       (function
-          Definition  (n,t) -> Definition  (n,replace t)
-        | Declaration (n,t) -> Declaration (n,replace t)
+          Some (name,Cic.Def  t) -> Some (name,Cic.Def  (replace t))
+        | Some (name,Cic.Decl t) -> Some (name,Cic.Decl (replace t))
+        | None -> None
       ) context
     in
      let metasenv' = 
       List.map
        (function
-           (n,_) when n = metano -> (metano,ty')
+           (n,_,_) when n = metano -> (metano,context',ty')
          | _ as t -> t
        ) metasenv
      in
       proof := Some (curi,metasenv',pbo,pty) ;
-      goal := Some (metano,(context',ty'))
+      goal := Some metano
 ;;
 
-let reduction_tactic_in_scratch reduction_function ty term =
+(* Reduces [term] using [reduction_function] in the current scratch goal [ty] *)
+let reduction_tactic_in_scratch reduction_function term ty =
  let metasenv =
   match !proof with
      None -> []
    | Some (_,metasenv,_,_) -> metasenv
  in
- let context =
+ let metano,context,_ =
   match !goal with
-     None -> []
-   | Some (_,(context,_)) -> context
+     None -> assert false
+   | Some metano -> List.find (function (m,_,_) -> m=metano) metasenv
  in
-  let ciccontext = cic_context_of_named_context context in
-  let term' = reduction_function ciccontext term in
-   ProofEngineReduction.replace ~what:term ~with_what:term' ~where:ty
+  let term' = reduction_function context term in
+   ProofEngineReduction.replace
+    ~equality:(==) ~what:term ~with_what:term' ~where:ty
 ;;
 
 let whd    = reduction_tactic CicReduction.whd;;
@@ -645,35 +727,37 @@ let fold term =
      None -> assert false
    | Some (curi,metasenv,bo,ty) -> curi,metasenv,bo,ty
  in
- let (metano,context,ty) =
+ let metano,context,ty =
   match !goal with
      None -> assert false
-   | Some (metano,(context,ty)) -> metano,context,ty
+   | Some metano -> List.find (function (m,_,_) -> m=metano) metasenv
  in
-  let ciccontext = cic_context_of_named_context context in
-  let term' = CicReduction.whd ciccontext term in
+  let term' = CicReduction.whd context term in
    (* We don't know if [term] is a subterm of [ty] or a subterm of *)
    (* the type of one metavariable. So we replace it everywhere.   *)
    (*CSC: ma si potrebbe ovviare al problema. Ma non credo *)
    (*CSC: che si guadagni nulla in fatto di efficienza.    *) 
-   let replace = ProofEngineReduction.replace ~what:term' ~with_what:term in
+   let replace = ProofEngineReduction.replace
+    ~equality:(==) ~what:term' ~with_what:term
+   in
     let ty' = replace ty in
     let context' =
      List.map
       (function
-          Declaration (n,t) -> Declaration (n,replace t)
-        | Definition  (n,t) -> Definition (n,replace t)
+          Some (n,Cic.Decl t) -> Some (n,Cic.Decl (replace t))
+        | Some (n,Cic.Def t)  -> Some (n,Cic.Def  (replace t))
+        | None -> None
       ) context
     in
      let metasenv' = 
       List.map
        (function
-           (n,_) when n = metano -> (metano,ty')
+           (n,_,_) when n = metano -> (metano,context',ty')
          | _ as t -> t
        ) metasenv
      in
       proof := Some (curi,metasenv',pbo,pty) ;
-      goal := Some (metano,(context',ty'))
+      goal := Some metano
 ;;
 
 let cut term =
@@ -683,25 +767,29 @@ let cut term =
       None -> assert false
     | Some (curi,metasenv,bo,ty) -> curi,metasenv,bo,ty
   in
-  let (metano,context,ty) =
+  let metano,context,ty =
    match !goal with
       None -> assert false
-    | Some (metano,(context,ty)) -> metano,context,ty
+    | Some metano -> List.find (function (m,_,_) -> m=metano) metasenv
   in
    let newmeta1 = new_meta () in
    let newmeta2 = newmeta1 + 1 in
+   let context_for_newmeta1 =
+    (Some (C.Name "dummy_for_cut",C.Decl term))::context in
+   let irl1 =
+    identity_relocation_list_for_metavariable context_for_newmeta1 in
+   let irl2 = identity_relocation_list_for_metavariable context in
     let newmeta1ty = CicSubstitution.lift 1 ty in
     let bo' =
      C.Appl
-      [C.Lambda (C.Name "dummy_for_cut",term,C.Meta newmeta1) ;
-       C.Meta newmeta2]
+      [C.Lambda (C.Name "dummy_for_cut",term,C.Meta (newmeta1,irl1)) ;
+       C.Meta (newmeta2,irl2)]
     in
-prerr_endline ("BO': " ^ CicPp.ppterm bo') ; flush stderr ;
-     refine_meta metano bo' [newmeta2,term; newmeta1,newmeta1ty];
-     goal :=
-      Some
-       (newmeta1,((Declaration (C.Name "dummy_for_cut", term))::context,
-        newmeta1ty))
+     let _ =
+      subst_meta_in_current_proof metano bo'
+       [newmeta2,context,term; newmeta1,context_for_newmeta1,newmeta1ty];
+     in
+      goal := Some newmeta1
 ;;
 
 let letin term =
@@ -711,21 +799,21 @@ let letin term =
       None -> assert false
     | Some (curi,metasenv,bo,ty) -> curi,metasenv,bo,ty
   in
-  let (metano,context,ty) =
+  let metano,context,ty =
    match !goal with
       None -> assert false
-    | Some (metano,(context,ty)) -> metano,context,ty
+    | Some metano -> List.find (function (m,_,_) -> m=metano) metasenv
   in
-   let ciccontext = cic_context_of_named_context context in
-   let _ = CicTypeChecker.type_of_aux' metasenv ciccontext term in
+   let _ = CicTypeChecker.type_of_aux' metasenv context term in
     let newmeta = new_meta () in
+    let context_for_newmeta =
+     (Some (C.Name "dummy_for_letin",C.Def term))::context in
+    let irl =
+     identity_relocation_list_for_metavariable context_for_newmeta in
      let newmetaty = CicSubstitution.lift 1 ty in
-     let bo' = C.LetIn (C.Name "dummy_for_letin",term,C.Meta newmeta) in
-      refine_meta metano bo' [newmeta,newmetaty];
-      goal :=
-       Some
-        (newmeta,
-         ((Definition (C.Name "dummy_for_letin", term))::context, newmetaty))
+     let bo' = C.LetIn (C.Name "dummy_for_letin",term,C.Meta (newmeta,irl)) in
+      let _ = subst_meta_in_current_proof metano bo' [newmeta,context_for_newmeta,newmetaty] in
+       goal := Some newmeta
 ;;
 
 exception NotConvertible;;
@@ -740,27 +828,38 @@ let change ~goal_input ~input =
      None -> assert false
    | Some (curi,metasenv,bo,ty) -> curi,metasenv,bo,ty
  in
- let (metano,context,ty) =
+ let metano,context,ty =
   match !goal with
      None -> assert false
-   | Some (metano,(context,ty)) -> metano,context,ty
+   | Some metano -> List.find (function (m,_,_) -> m=metano) metasenv
  in
-  let ciccontext = cic_context_of_named_context context in
-   (* are_convertible works only on well-typed terms *)
-   ignore (CicTypeChecker.type_of_aux' metasenv ciccontext input) ;
-   if CicReduction.are_convertible ciccontext goal_input input then
-    begin
-     let ty' = ProofEngineReduction.replace goal_input input ty in
-      let metasenv' = 
-       List.map
-        (function
-            (n,_) when n = metano -> (metano,ty')
-          | _ as t -> t
-        ) metasenv
-      in
-       proof := Some (curi,metasenv',pbo,pty) ;
-       goal := Some (metano,(context,ty'))
-    end
+  (* are_convertible works only on well-typed terms *)
+  ignore (CicTypeChecker.type_of_aux' metasenv context input) ;
+  if CicReduction.are_convertible context goal_input input then
+   begin
+    let replace =
+     ProofEngineReduction.replace
+      ~equality:(==) ~what:goal_input ~with_what:input
+    in
+    let ty' = replace ty in
+    let context' =
+     List.map
+      (function
+          Some (name,Cic.Def  t) -> Some (name,Cic.Def  (replace t))
+        | Some (name,Cic.Decl t) -> Some (name,Cic.Decl (replace t))
+        | None -> None
+      ) context
+    in
+     let metasenv' = 
+      List.map
+       (function
+           (n,_,_) when n = metano -> (metano,context',ty')
+         | _ as t -> t
+       ) metasenv
+     in
+      proof := Some (curi,metasenv',pbo,pty) ;
+      goal := Some metano
+   end
   else
    raise NotConvertible
 ;;
index 94e5b353de3534df42cba3016327de56abffdd6c..7d4a799601dad71082943a92b5685480996b60da 100644 (file)
@@ -43,13 +43,14 @@ exception ReferenceToVariable;;
 exception ReferenceToCurrentProof;;
 exception ReferenceToInductiveDefinition;;
 exception WrongUriToInductiveDefinition;;
+exception RelToHiddenHypothesis;;
 
 (* "textual" replacement of a subterm with another one *)
-let replace ~what ~with_what ~where =
+let replace ~equality ~what ~with_what ~where =
  let module C = Cic in
   let rec aux =
    function
-      t when t = what -> with_what
+      t when (equality t what) -> with_what
     | C.Rel _ as t -> t
     | C.Var _ as t  -> t
     | C.Meta _ as t -> t
@@ -92,11 +93,16 @@ let replace ~what ~with_what ~where =
 (* Takes a well-typed term and fully reduces it. *)
 (*CSC: It does not perform reduction in a Case *)
 let reduce context =
- let rec reduceaux l =
+ let rec reduceaux context l =
   let module C = Cic in
   let module S = CicSubstitution in
    function
-      C.Rel _ as t -> if l = [] then t else C.Appl (t::l)
+      C.Rel n as t ->
+       (match List.nth context (n-1) with
+           Some (_,C.Decl _) -> if l = [] then t else C.Appl (t::l)
+         | Some (_,C.Def bo) -> reduceaux context l (S.lift n bo)
+        | None -> raise RelToHiddenHypothesis
+       )
     | C.Var uri as t ->
        (match CicEnvironment.get_cooked_obj uri 0 with
            C.Definition _ -> raise ReferenceToDefinition
@@ -104,32 +110,39 @@ let reduce context =
          | C.CurrentProof _ -> raise ReferenceToCurrentProof
          | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
          | C.Variable (_,None,_) -> if l = [] then t else C.Appl (t::l)
-         | C.Variable (_,Some body,_) -> reduceaux l body
+         | C.Variable (_,Some body,_) -> reduceaux context l body
        )
     | C.Meta _ as t -> if l = [] then t else C.Appl (t::l)
     | C.Sort _ as t -> t (* l should be empty *)
     | C.Implicit as t -> t
-    | C.Cast (te,ty) -> reduceaux l te  (*CSC E' GIUSTO BUTTARE IL CAST? *)
+    | C.Cast (te,ty) ->
+       C.Cast (reduceaux context l te, reduceaux context l ty)
     | C.Prod (name,s,t) ->
        assert (l = []) ;
-       C.Prod (name, reduceaux [] s, reduceaux [] t)
+       C.Prod (name,
+        reduceaux context [] s,
+        reduceaux ((Some (name,C.Decl s))::context) [] t)
     | C.Lambda (name,s,t) ->
        (match l with
-           [] -> C.Lambda (name, reduceaux [] s, reduceaux [] t)
-         | he::tl -> reduceaux tl (S.subst he t)
+           [] ->
+            C.Lambda (name,
+             reduceaux context [] s,
+             reduceaux ((Some (name,C.Decl s))::context) [] t)
+         | he::tl -> reduceaux context tl (S.subst he t)
            (* when name is Anonimous the substitution should be superfluous *)
        )
-    | C.LetIn (n,s,t) -> reduceaux l (S.subst (reduceaux [] s) t)
+    | C.LetIn (n,s,t) ->
+       reduceaux context l (S.subst (reduceaux context [] s) t)
     | C.Appl (he::tl) ->
-       let tl' = List.map (reduceaux []) tl in
-        reduceaux (tl'@l) he
+       let tl' = List.map (reduceaux context []) tl in
+        reduceaux context (tl'@l) he
     | C.Appl [] -> raise (Impossible 1)
     | C.Const (uri,cookingsno) as t ->
        (match CicEnvironment.get_cooked_obj uri cookingsno with
-           C.Definition (_,body,_,_) -> reduceaux l body
+           C.Definition (_,body,_,_) -> reduceaux context l body
          | C.Axiom _ -> if l = [] then t else C.Appl (t::l)
          | C.Variable _ -> raise ReferenceToVariable
-         | C.CurrentProof (_,_,body,_) -> reduceaux l body
+         | C.CurrentProof (_,_,body,_) -> reduceaux context l body
          | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
        )
     | C.Abst _ as t -> t (*CSC l should be empty ????? *)
@@ -139,30 +152,36 @@ let reduce context =
        let decofix =
         function
            C.CoFix (i,fl) as t ->
-            let (_,_,body) = List.nth fl i in
-             let body' =
-              let counter = ref (List.length fl) in
-               List.fold_right
-                (fun _ -> decr counter ; S.subst (C.CoFix (!counter,fl)))
-                fl
-                body
-             in
-              reduceaux [] body'
+            let tys =
+             List.map (function (name,ty,_) -> Some (C.Name name, C.Decl ty)) fl
+            in
+             let (_,_,body) = List.nth fl i in
+              let body' =
+               let counter = ref (List.length fl) in
+                List.fold_right
+                 (fun _ -> decr counter ; S.subst (C.CoFix (!counter,fl)))
+                 fl
+                 body
+              in
+               reduceaux (tys@context) [] body'
          | C.Appl (C.CoFix (i,fl) :: tl) ->
-            let (_,_,body) = List.nth fl i in
-             let body' =
-              let counter = ref (List.length fl) in
-               List.fold_right
-                (fun _ -> decr counter ; S.subst (C.CoFix (!counter,fl)))
-                fl
-                body
-             in
-              let tl' = List.map (reduceaux []) tl in
-               reduceaux tl body'
+            let tys =
+             List.map (function (name,ty,_) -> Some (C.Name name, C.Decl ty)) fl
+            in
+             let (_,_,body) = List.nth fl i in
+              let body' =
+               let counter = ref (List.length fl) in
+                List.fold_right
+                 (fun _ -> decr counter ; S.subst (C.CoFix (!counter,fl)))
+                 fl
+                 body
+              in
+               let tl' = List.map (reduceaux context []) tl in
+                reduceaux (tys@context) tl' body'
          | t -> t
        in
-        (match decofix (reduceaux [] term) with
-            C.MutConstruct (_,_,_,j) -> reduceaux l (List.nth pl (j-1))
+        (match decofix (reduceaux context [] term) with
+            C.MutConstruct (_,_,_,j) -> reduceaux context l (List.nth pl (j-1))
           | C.Appl (C.MutConstruct (_,_,_,j) :: tl) ->
              let (arity, r, num_ingredients) =
               match CicEnvironment.get_obj mutind with
@@ -187,66 +206,72 @@ let reduce context =
                 in
                  eat_first (num_to_eat,tl)
               in
-               reduceaux (ts@l) (List.nth pl (j-1))
+               reduceaux context (ts@l) (List.nth pl (j-1))
          | C.Abst _ | C.Cast _ | C.Implicit ->
             raise (Impossible 2) (* we don't trust our whd ;-) *)
          | _ ->
-           let outtype' = reduceaux [] outtype in
-           let term' = reduceaux [] term in
-           let pl' = List.map (reduceaux []) pl in
+           let outtype' = reduceaux context [] outtype in
+           let term' = reduceaux context [] term in
+           let pl' = List.map (reduceaux context []) pl in
             let res =
              C.MutCase (mutind,cookingsno,i,outtype',term',pl')
             in
              if l = [] then res else C.Appl (res::l)
        )
     | C.Fix (i,fl) ->
-       let t' () =
-        let fl' =
-         List.map
-          (function (n,recindex,ty,bo) ->
-            (n,recindex,reduceaux [] ty, reduceaux [] bo)
-          ) fl
-        in
-         C.Fix (i, fl')
+       let tys =
+        List.map (function (name,_,ty,_) -> Some (C.Name name, C.Decl ty)) fl
        in
-        let (_,recindex,_,body) = List.nth fl i in
-         let recparam =
-          try
-           Some (List.nth l recindex)
-          with
-           _ -> None
+        let t' () =
+         let fl' =
+          List.map
+           (function (n,recindex,ty,bo) ->
+             (n,recindex,reduceaux context [] ty, reduceaux (tys@context) [] bo)
+           ) fl
          in
-          (match recparam with
-              Some recparam ->
-               (match reduceaux [] recparam with
-                   C.MutConstruct _
-                 | C.Appl ((C.MutConstruct _)::_) ->
-                    let body' =
-                     let counter = ref (List.length fl) in
-                      List.fold_right
-                       (fun _ -> decr counter ; S.subst (C.Fix (!counter,fl)))
-                       fl
-                       body
-                    in
-                     (* Possible optimization: substituting whd recparam in l *)
-                     reduceaux l body'
-                 | _ -> if l = [] then t' () else C.Appl ((t' ())::l)
-               )
-            | None -> if l = [] then t' () else C.Appl ((t' ())::l)
-          )
-    | C.CoFix (i,fl) ->
-       let t' =
-        let fl' =
-         List.map
-          (function (n,ty,bo) ->
-            (n,reduceaux [] ty, reduceaux [] bo)
-          ) fl
+          C.Fix (i, fl')
         in
-         C.CoFix (i, fl')
+         let (_,recindex,_,body) = List.nth fl i in
+          let recparam =
+           try
+            Some (List.nth l recindex)
+           with
+            _ -> None
+          in
+           (match recparam with
+               Some recparam ->
+                (match reduceaux context [] recparam with
+                    C.MutConstruct _
+                  | C.Appl ((C.MutConstruct _)::_) ->
+                     let body' =
+                      let counter = ref (List.length fl) in
+                       List.fold_right
+                        (fun _ -> decr counter ; S.subst (C.Fix (!counter,fl)))
+                        fl
+                        body
+                     in
+                      (* Possible optimization: substituting whd recparam in l*)
+                      reduceaux context l body'
+                  | _ -> if l = [] then t' () else C.Appl ((t' ())::l)
+                )
+             | None -> if l = [] then t' () else C.Appl ((t' ())::l)
+           )
+    | C.CoFix (i,fl) ->
+       let tys =
+        List.map (function (name,ty,_) -> Some (C.Name name, C.Decl ty)) fl
        in
-        if l = [] then t' else C.Appl (t'::l)
+        let t' =
+         let fl' =
+          List.map
+           (function (n,ty,bo) ->
+             (n,reduceaux context [] ty, reduceaux (tys@context) [] bo)
+           ) fl
+         in
+          C.CoFix (i, fl')
+        in
+         if l = [] then t' else C.Appl (t'::l)
  in
-  reduceaux []
+  reduceaux context []
 ;;
 
 exception WrongShape;;
@@ -278,11 +303,16 @@ let simpl context =
  (* reduceaux is equal to the reduceaux locally defined inside *)
  (*reduce, but for the const case.                             *) 
  (**** Step 1 ****)
- let rec reduceaux l =
+ let rec reduceaux context l =
   let module C = Cic in
   let module S = CicSubstitution in
    function
-      C.Rel _ as t -> if l = [] then t else C.Appl (t::l)
+      C.Rel n as t ->
+       (match List.nth context (n-1) with
+           Some (_,C.Decl _) -> if l = [] then t else C.Appl (t::l)
+         | Some (_,C.Def bo) -> reduceaux context l (S.lift n bo)
+        | None -> raise RelToHiddenHypothesis
+       )
     | C.Var uri as t ->
        (match CicEnvironment.get_cooked_obj uri 0 with
            C.Definition _ -> raise ReferenceToDefinition
@@ -290,25 +320,32 @@ let simpl context =
          | C.CurrentProof _ -> raise ReferenceToCurrentProof
          | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
          | C.Variable (_,None,_) -> if l = [] then t else C.Appl (t::l)
-         | C.Variable (_,Some body,_) -> reduceaux l body
+         | C.Variable (_,Some body,_) -> reduceaux context l body
        )
     | C.Meta _ as t -> if l = [] then t else C.Appl (t::l)
     | C.Sort _ as t -> t (* l should be empty *)
     | C.Implicit as t -> t
-    | C.Cast (te,ty) -> reduceaux l te  (*CSC E' GIUSTO BUTTARE IL CAST? *)
+    | C.Cast (te,ty) ->
+       C.Cast (reduceaux context l te, reduceaux context l ty)
     | C.Prod (name,s,t) ->
        assert (l = []) ;
-       C.Prod (name, reduceaux [] s, reduceaux [] t)
+       C.Prod (name,
+        reduceaux context [] s,
+        reduceaux ((Some (name,C.Decl s))::context) [] t)
     | C.Lambda (name,s,t) ->
        (match l with
-           [] -> C.Lambda (name, reduceaux [] s, reduceaux [] t)
-         | he::tl -> reduceaux tl (S.subst he t)
+           [] ->
+            C.Lambda (name,
+             reduceaux context [] s,
+             reduceaux ((Some (name,C.Decl s))::context) [] t)
+         | he::tl -> reduceaux context tl (S.subst he t)
            (* when name is Anonimous the substitution should be superfluous *)
        )
-    | C.LetIn (n,s,t) -> reduceaux l (S.subst (reduceaux [] s) t)
+    | C.LetIn (n,s,t) ->
+       reduceaux context l (S.subst (reduceaux context [] s) t)
     | C.Appl (he::tl) ->
-       let tl' = List.map (reduceaux []) tl in
-        reduceaux (tl'@l) he
+       let tl' = List.map (reduceaux context []) tl in
+        reduceaux context (tl'@l) he
     | C.Appl [] -> raise (Impossible 1)
     | C.Const (uri,cookingsno) as t ->
        (match CicEnvironment.get_cooked_obj uri cookingsno with
@@ -330,28 +367,33 @@ let simpl context =
                     end
                  | C.LetIn (_,_,_) -> raise WhatShouldIDo (*CSC: ?????????? *)
                  | C.Fix (i,fl) as t ->
-                    let (_,recindex,_,body) = List.nth fl i in
-                     let recparam =
-                      try
-                       List.nth l recindex
-                      with
-                       _ -> raise AlreadySimplified
-                     in
-                      (match CicReduction.whd context recparam with
-                          C.MutConstruct _
-                        | C.Appl ((C.MutConstruct _)::_) ->
-                           let body' =
-                            let counter = ref (List.length fl) in
-                             List.fold_right
-                              (function _ ->
-                                decr counter ; S.subst (C.Fix (!counter,fl))
-                              ) fl body
-                           in
-                            (* Possible optimization: substituting whd *)
-                            (* recparam in l                           *)
-                            reduceaux l body', List.rev rev_constant_args
-                        | _ -> raise AlreadySimplified
-                      )
+                    let tys =
+                     List.map (function (name,_,ty,_) ->
+                      Some (C.Name name, C.Decl ty)) fl
+                    in
+                     let (_,recindex,_,body) = List.nth fl i in
+                      let recparam =
+                       try
+                        List.nth l recindex
+                       with
+                        _ -> raise AlreadySimplified
+                      in
+                       (match CicReduction.whd context recparam with
+                           C.MutConstruct _
+                         | C.Appl ((C.MutConstruct _)::_) ->
+                            let body' =
+                             let counter = ref (List.length fl) in
+                              List.fold_right
+                               (function _ ->
+                                 decr counter ; S.subst (C.Fix (!counter,fl))
+                               ) fl body
+                            in
+                             (* Possible optimization: substituting whd *)
+                             (* recparam in l                           *)
+                             reduceaux (tys@context) l body',
+                              List.rev rev_constant_args
+                         | _ -> raise AlreadySimplified
+                       )
                  | _ -> raise WrongShape
                in
                 aux [] l body
@@ -363,14 +405,12 @@ let simpl context =
                  | _ -> C.Appl ((C.Const (uri,cookingsno))::constant_args)
                in
                 let reduced_term_to_fold = reduce context term_to_fold in
-prerr_endline ("TERM TO FOLD: " ^ CicPp.ppterm term_to_fold) ; flush stderr ;
-prerr_endline ("REDUCED TERM TO FOLD: " ^ CicPp.ppterm reduced_term_to_fold) ; flush stderr ;
-                 replace reduced_term_to_fold term_to_fold res
+                 replace (=) reduced_term_to_fold term_to_fold res
              with
                 WrongShape ->
                  (* The constant does not unfold to a Fix lambda-abstracted   *)
                  (* w.r.t. zero or more variables. We just perform reduction. *)
-                 reduceaux l body
+                 reduceaux context l body
               | AlreadySimplified ->
                  (* If we performed delta-reduction, we would find a Fix   *)
                  (* not applied to a constructor. So, we refuse to perform *)
@@ -382,7 +422,7 @@ prerr_endline ("REDUCED TERM TO FOLD: " ^ CicPp.ppterm reduced_term_to_fold) ; f
             end
          | C.Axiom _ -> if l = [] then t else C.Appl (t::l)
          | C.Variable _ -> raise ReferenceToVariable
-         | C.CurrentProof (_,_,body,_) -> reduceaux l body
+         | C.CurrentProof (_,_,body,_) -> reduceaux context l body
          | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
        )
     | C.Abst _ as t -> t (*CSC l should be empty ????? *)
@@ -392,30 +432,34 @@ prerr_endline ("REDUCED TERM TO FOLD: " ^ CicPp.ppterm reduced_term_to_fold) ; f
        let decofix =
         function
            C.CoFix (i,fl) as t ->
-            let (_,_,body) = List.nth fl i in
-             let body' =
-              let counter = ref (List.length fl) in
-               List.fold_right
-                (fun _ -> decr counter ; S.subst (C.CoFix (!counter,fl)))
-                fl
-                body
-             in
-              reduceaux [] body'
+            let tys =
+             List.map (function (name,ty,_) -> Some (C.Name name, C.Decl ty)) fl            in
+             let (_,_,body) = List.nth fl i in
+              let body' =
+               let counter = ref (List.length fl) in
+                List.fold_right
+                 (fun _ -> decr counter ; S.subst (C.CoFix (!counter,fl)))
+                 fl
+                 body
+              in
+               reduceaux (tys@context) [] body'
          | C.Appl (C.CoFix (i,fl) :: tl) ->
-            let (_,_,body) = List.nth fl i in
-             let body' =
-              let counter = ref (List.length fl) in
-               List.fold_right
-                (fun _ -> decr counter ; S.subst (C.CoFix (!counter,fl)))
-                fl
-                body
-             in
-              let tl' = List.map (reduceaux []) tl in
-               reduceaux tl body'
+            let tys =
+             List.map (function (name,ty,_) -> Some (C.Name name, C.Decl ty)) fl            in
+             let (_,_,body) = List.nth fl i in
+              let body' =
+               let counter = ref (List.length fl) in
+                List.fold_right
+                 (fun _ -> decr counter ; S.subst (C.CoFix (!counter,fl)))
+                 fl
+                 body
+              in
+               let tl' = List.map (reduceaux context []) tl in
+                reduceaux (tys@context) tl body'
          | t -> t
        in
-        (match decofix (reduceaux [] term) with
-            C.MutConstruct (_,_,_,j) -> reduceaux l (List.nth pl (j-1))
+        (match decofix (reduceaux context [] term) with
+            C.MutConstruct (_,_,_,j) -> reduceaux context l (List.nth pl (j-1))
           | C.Appl (C.MutConstruct (_,_,_,j) :: tl) ->
              let (arity, r, num_ingredients) =
               match CicEnvironment.get_obj mutind with
@@ -440,64 +484,70 @@ prerr_endline ("REDUCED TERM TO FOLD: " ^ CicPp.ppterm reduced_term_to_fold) ; f
                 in
                  eat_first (num_to_eat,tl)
               in
-               reduceaux (ts@l) (List.nth pl (j-1))
+               reduceaux context (ts@l) (List.nth pl (j-1))
          | C.Abst _ | C.Cast _ | C.Implicit ->
             raise (Impossible 2) (* we don't trust our whd ;-) *)
          | _ ->
-           let outtype' = reduceaux [] outtype in
-           let term' = reduceaux [] term in
-           let pl' = List.map (reduceaux []) pl in
+           let outtype' = reduceaux context [] outtype in
+           let term' = reduceaux context [] term in
+           let pl' = List.map (reduceaux context []) pl in
             let res =
              C.MutCase (mutind,cookingsno,i,outtype',term',pl')
             in
              if l = [] then res else C.Appl (res::l)
        )
     | C.Fix (i,fl) ->
-       let t' () =
-        let fl' =
-         List.map
-          (function (n,recindex,ty,bo) ->
-            (n,recindex,reduceaux [] ty, reduceaux [] bo)
-          ) fl
-        in
-         C.Fix (i, fl')
+       let tys =
+        List.map (function (name,_,ty,_) -> Some (C.Name name, C.Decl ty)) fl
        in
-        let (_,recindex,_,body) = List.nth fl i in
-         let recparam =
-          try
-           Some (List.nth l recindex)
-          with
-           _ -> None
+        let t' () =
+         let fl' =
+          List.map
+           (function (n,recindex,ty,bo) ->
+             (n,recindex,reduceaux context [] ty, reduceaux (tys@context) [] bo)
+           ) fl
          in
-          (match recparam with
-              Some recparam ->
-               (match reduceaux [] recparam with
-                   C.MutConstruct _
-                 | C.Appl ((C.MutConstruct _)::_) ->
-                    let body' =
-                     let counter = ref (List.length fl) in
-                      List.fold_right
-                       (fun _ -> decr counter ; S.subst (C.Fix (!counter,fl)))
-                       fl
-                       body
-                    in
-                     (* Possible optimization: substituting whd recparam in l *)
-                     reduceaux l body'
-                 | _ -> if l = [] then t' () else C.Appl ((t' ())::l)
-               )
-            | None -> if l = [] then t' () else C.Appl ((t' ())::l)
-          )
-    | C.CoFix (i,fl) ->
-       let t' =
-        let fl' =
-         List.map
-          (function (n,ty,bo) ->
-            (n,reduceaux [] ty, reduceaux [] bo)
-          ) fl
+          C.Fix (i, fl')
         in
+         let (_,recindex,_,body) = List.nth fl i in
+          let recparam =
+           try
+            Some (List.nth l recindex)
+           with
+            _ -> None
+          in
+           (match recparam with
+               Some recparam ->
+                (match reduceaux context [] recparam with
+                    C.MutConstruct _
+                  | C.Appl ((C.MutConstruct _)::_) ->
+                     let body' =
+                      let counter = ref (List.length fl) in
+                       List.fold_right
+                        (fun _ -> decr counter ; S.subst (C.Fix (!counter,fl)))
+                        fl
+                        body
+                     in
+                      (* Possible optimization: substituting whd recparam in l*)
+                      reduceaux context l body'
+                  | _ -> if l = [] then t' () else C.Appl ((t' ())::l)
+                )
+             | None -> if l = [] then t' () else C.Appl ((t' ())::l)
+           )
+    | C.CoFix (i,fl) ->
+       let tys =
+        List.map (function (name,ty,_) -> Some (C.Name name, C.Decl ty)) fl
+       in
+        let t' =
+         let fl' =
+          List.map
+           (function (n,ty,bo) ->
+             (n,reduceaux context [] ty, reduceaux (tys@context) [] bo)
+           ) fl
+         in
          C.CoFix (i, fl')
        in
-        if l = [] then t' else C.Appl (t'::l)
+         if l = [] then t' else C.Appl (t'::l)
  in
-  reduceaux []
+  reduceaux context []
 ;;
index fb040dfd82dc71c8f8e9afc7f2fa161390b1f87c..bffb3030c27cc81b76693b7e1d83c3221697f3e0 100644 (file)
@@ -2,74 +2,74 @@ module TextualPp =
  struct
   (* It also returns the pretty-printing context! *)
   let print_context ctx =
-   let module P = ProofEngine in
     let print_name =
      function
         Cic.Name n -> n
       | Cic.Anonimous -> "_"
     in
      List.fold_right
-      (fun i env ->
-        match i with
-           P.Declaration (n,t) ->
-             print_endline (print_name n ^ ":" ^ CicPp.pp t env) ;
-             flush stdout ;
-             n::env
-         | P.Definition (n,t) ->
-             print_endline (print_name n ^ ":=" ^ CicPp.pp t env) ;
-             flush stdout ;
-             n::env
-      ) ctx []
+      (fun i (output,context) ->
+        let (newoutput,context') =
+         match i with
+            Some (n,Cic.Decl t) ->
+              print_name n ^ ":" ^ CicPp.pp t context ^ "\n", (Some n)::context
+          | Some (n,Cic.Def t) ->
+              print_name n ^ ":=" ^ CicPp.pp t context ^ "\n", (Some n)::context
+          | None ->
+              "_ ?= _\n", None::context
+        in
+         output^newoutput,context'
+      ) ctx ("",[])
   ;;
 
   exception NotImplemented;;
 
-  let print_sequent (context,goal) =
+  let print_sequent (metano,context,goal) =
    let module P = ProofEngine in
-    print_newline () ;
-    let pretty_printer_env_of_context =
-     print_context context
-    in
-    print_endline "----------------------" ;
-    print_endline (CicPp.pp goal pretty_printer_env_of_context) ; flush stdout
+    "\n" ^
+     let (output,pretty_printer_context_of_context) = print_context context in
+      output ^
+       "---------------------- ?" ^ string_of_int metano ^ "\n" ^
+        CicPp.pp goal pretty_printer_context_of_context
   ;;
  end
 ;;
 
 module XmlPp =
  struct
-  let print_sequent metasenv (context,goal) =
+  let print_sequent metasenv (metano,context,goal) =
    let module X = Xml in
     let ids_to_terms = Hashtbl.create 503 in
     let ids_to_father_ids = Hashtbl.create 503 in
     let ids_to_inner_sorts = Hashtbl.create 503 in
     let ids_to_inner_types = Hashtbl.create 503 in
     let seed = ref 0 in
-     let acic_of_cic_env =
-      Cic2acic.acic_of_cic_env' seed ids_to_terms ids_to_father_ids
+     let acic_of_cic_context =
+      Cic2acic.acic_of_cic_context' seed ids_to_terms ids_to_father_ids
        ids_to_inner_sorts ids_to_inner_types metasenv
      in
-      let final_s,final_env =
+      let final_s,_ =
        (List.fold_right
-         (fun binding (s,env) ->
-           let b,n,t,cicbinding =
-            match binding with
-               ProofEngine.Definition  (n,t) -> "Def", n, t,Cic.Def t
-             | ProofEngine.Declaration (n,t) -> "Decl", n, t, Cic.Decl t
-           in
-            let acic = acic_of_cic_env env t in
-             [< s ;
-                X.xml_nempty b
-                 ["name",(match n with Cic.Name n -> n | _ -> assert false)]
-                 (Cic2Xml.print_term
-                   (UriManager.uri_of_string "cic:/dummy.con")
-                   ids_to_inner_sorts acic)
-             >],((n,cicbinding)::env)
+         (fun binding (s,context) ->
+           match binding with
+              (Some (n,(Cic.Def t as b)) as entry)
+            | (Some (n,(Cic.Decl t as b)) as entry) ->
+               let acic = acic_of_cic_context context t in
+                [< s ;
+                   X.xml_nempty
+                    (match b with Cic.Decl _ -> "Decl" | Cic.Def _ -> "Def")
+                    ["name",(match n with Cic.Name n -> n | _ -> assert false)]
+                    (Cic2Xml.print_term
+                      (UriManager.uri_of_string "cic:/dummy.con")
+                      ids_to_inner_sorts acic)
+                >], (entry::context)
+            | None ->
+               [< s ; X.xml_empty "Hidden" [] >], (None::context)
          ) context ([<>],[])
        )
       in
-       let acic = acic_of_cic_env final_env goal in
-        X.xml_nempty "Sequent" []
+       let acic = acic_of_cic_context context goal in
+        X.xml_nempty "Sequent" ["no",string_of_int metano]
          [< final_s ;
             Xml.xml_nempty "Goal" []
              (Cic2Xml.print_term (UriManager.uri_of_string "cic:/dummy.con")