]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/software/components/tactics/equalityTactics.ml
many changes:
[helm.git] / helm / software / components / tactics / equalityTactics.ml
index 8760f36ef46f998bb61ca9a11e4c466308eb99d5..bd73865af94ffcf050498704a9be1be71543ff23 100644 (file)
@@ -34,33 +34,36 @@ module PESR = ProofEngineStructuralRules
 module P    = PrimitiveTactics 
 module T    = Tacticals 
 module R    = CicReduction
+module S    = CicSubstitution
 module TC   = CicTypeChecker
 module LO   = LibraryObjects
 module DTI  = DoubleTypeInference
+module HEL  = HExtlib
 
-let rec rewrite_tac ~direction ~(pattern: ProofEngineTypes.lazy_pattern) equality =
- let _rewrite_tac ~direction ~pattern:(wanted,hyps_pat,concl_pat) equality status
- =
+let rec rewrite_tac ~direction ~pattern:(wanted,hyps_pat,concl_pat) equality =
+ let _rewrite_tac status =
   assert (wanted = None);   (* this should be checked syntactically *)
   let proof,goal = status in
-  let curi, metasenv, pbo, pty = proof in
+  let curi, metasenv, _subst, pbo, pty, attrs = proof in
   let (metano,context,gty) = CicUtil.lookup_meta goal metasenv in
+  let gsort,_ =
+   CicTypeChecker.type_of_aux' metasenv context gty CicUniv.oblivion_ugraph in
   match hyps_pat with
      he::(_::_ as tl) ->
        PET.apply_tactic
-        (Tacticals.then_
+        (T.then_
           (rewrite_tac ~direction
            ~pattern:(None,[he],None) equality)
           (rewrite_tac ~direction ~pattern:(None,tl,concl_pat)
-            (CicSubstitution.lift 1 equality))
+            (S.lift 1 equality))
         ) status
    | [_] as hyps_pat when concl_pat <> None ->
        PET.apply_tactic
-        (Tacticals.then_
+        (T.then_
           (rewrite_tac ~direction
            ~pattern:(None,hyps_pat,None) equality)
           (rewrite_tac ~direction ~pattern:(None,[],concl_pat)
-            (CicSubstitution.lift 1 equality))
+            (S.lift 1 equality))
         ) status
    | _ ->
   let arg,dir2,tac,concl_pat,gty =
@@ -71,25 +74,25 @@ let rec rewrite_tac ~direction ~(pattern: ProofEngineTypes.lazy_pattern) equalit
        function
           [] -> assert false
         | Some (Cic.Name s,Cic.Decl ty)::_ when name = s ->
-           Cic.Rel n, CicSubstitution.lift n ty
-        | Some (Cic.Name s,Cic.Def _)::_ -> assert false (*CSC: not implemented yet! But does this make any sense?*)
+           Cic.Rel n, S.lift n ty
+        | Some (Cic.Name s,Cic.Def _)::_ when name = s -> assert false (*CSC: not implemented yet! But does this make any sense?*)
         | _::tl -> find_hyp (n+1) tl
       in
        let arg,gty = find_hyp 1 context in
        let dummy = "dummy" in
         Some arg,false,
          (fun ~term typ ->
-           Tacticals.seq
+           T.seq
             ~tactics:
-              [ProofEngineStructuralRules.rename name dummy;
+              [PESR.rename [name] [dummy];
                P.letin_tac
                 ~mk_fresh_name_callback:(fun _ _ _ ~typ -> Cic.Name name) term;
-               ProofEngineStructuralRules.clearbody name;
+               PESR.clearbody name;
               ReductionTactics.change_tac
                 ~pattern:
                   (None,[name,Cic.Implicit (Some `Hole)], None)
                 (ProofEngineTypes.const_lazy_term typ);
-               ProofEngineStructuralRules.clear [dummy]
+               PESR.clear [dummy]
               ]),
          Some pat,gty
     | _::_ -> assert false
@@ -103,7 +106,7 @@ let rec rewrite_tac ~direction ~(pattern: ProofEngineTypes.lazy_pattern) equalit
     CicTypeChecker.type_of_aux' metasenv context equality 
       CicUniv.empty_ugraph in 
   let (ty_eq,metasenv',arguments,fresh_meta) =
-   ProofEngineHelpers.saturate_term
+   TermUtil.saturate_term
     (ProofEngineHelpers.new_meta_of_proof proof) metasenv context ty_eq 0 in  
   let equality =
    if List.length arguments = 0 then
@@ -116,8 +119,16 @@ let rec rewrite_tac ~direction ~(pattern: ProofEngineTypes.lazy_pattern) equalit
     | C.Appl [C.MutInd (uri, 0, []); ty; t1; t2]
       when LibraryObjects.is_eq_URI uri ->
         let ind_uri =
-         if_right_to_left dir2
-          LibraryObjects.eq_ind_URI LibraryObjects.eq_ind_r_URI
+         match gsort with
+            C.Sort C.Prop ->
+             if_right_to_left dir2
+              LibraryObjects.eq_ind_URI LibraryObjects.eq_ind_r_URI
+          | C.Sort C.Set ->
+             if_right_to_left dir2
+              LibraryObjects.eq_rec_URI LibraryObjects.eq_rec_r_URI
+          | _ ->
+             if_right_to_left dir2
+              LibraryObjects.eq_rect_URI LibraryObjects.eq_rect_r_URI
         in
         let eq_ind = C.Const (ind_uri uri,[]) in
          if dir2 then
@@ -129,16 +140,18 @@ let rec rewrite_tac ~direction ~(pattern: ProofEngineTypes.lazy_pattern) equalit
   let fresh_name = 
     FreshNamesGenerator.mk_fresh_name 
     ~subst:[] metasenv' context C.Anonymous ~typ:ty in
-  let lifted_t1 = CicSubstitution.lift 1 t1x in
-  let lifted_gty = CicSubstitution.lift 1 gty in
+  let lifted_t1 = S.lift 1 t1x in
+  let lifted_gty = S.lift 1 gty in
   let lifted_conjecture =
     metano,(Some (fresh_name,Cic.Decl ty))::context,lifted_gty in
   let lifted_pattern =
     let lifted_concl_pat =
       match concl_pat with
       | None -> None
-      | Some term -> Some (CicSubstitution.lift 1 term) in
-    Some (fun _ m u -> lifted_t1, m, u),[],lifted_concl_pat
+      | Some term -> Some (S.lift 1 term) in
+    Some (fun c m u -> 
+       let distance  = pred (List.length c - List.length context) in
+       S.lift distance lifted_t1, m, u),[],lifted_concl_pat
   in
   let subst,metasenv',ugraph,_,selected_terms_with_context =
    ProofEngineHelpers.select
@@ -168,13 +181,13 @@ let rec rewrite_tac ~direction ~(pattern: ProofEngineTypes.lazy_pattern) equalit
   let metasenv',arg,newtyp =
    match arg with
       None ->
-       let gty' = CicSubstitution.subst t2 abstr_gty in
+       let gty' = S.subst t2 abstr_gty in
        let irl =
         CicMkImplicit.identity_relocation_list_for_metavariable context in
        let metasenv' = (fresh_meta,context,gty')::metasenv' in
         metasenv', C.Meta (fresh_meta,irl), Cic.Rel (-1) (* dummy term, never used *)
     | Some arg ->
-       let gty' = CicSubstitution.subst t1 abstr_gty in
+       let gty' = S.subst t1 abstr_gty in
         metasenv',arg,gty'
   in
   let exact_proof = 
@@ -183,7 +196,7 @@ let rec rewrite_tac ~direction ~(pattern: ProofEngineTypes.lazy_pattern) equalit
   try 
     let (proof',goals) =
       PET.apply_tactic 
-        (tac ~term:exact_proof newtyp) ((curi,metasenv',pbo,pty),goal)
+        (tac ~term:exact_proof newtyp) ((curi,metasenv',_subst,pbo,pty, attrs),goal)
     in
     let goals =
      goals@(ProofEngineHelpers.compare_metasenvs ~oldmetasenv:metasenv
@@ -194,28 +207,29 @@ let rec rewrite_tac ~direction ~(pattern: ProofEngineTypes.lazy_pattern) equalit
      TC.TypeCheckerFailure _ -> 
       let msg = lazy "rewrite: nothing to rewrite" in
       raise (PET.Fail msg)
- in
-  ProofEngineTypes.mk_tactic (_rewrite_tac ~direction ~pattern equality)
-  
-let rewrite_simpl_tac ~direction ~pattern equality =
- let rewrite_simpl_tac ~direction ~pattern equality status =
-  ProofEngineTypes.apply_tactic
-  (Tacticals.then_ 
-   ~start:(rewrite_tac ~direction ~pattern equality)
+ in    
+  PET.mk_tactic _rewrite_tac 
+
+let rewrite_tac ~direction ~pattern equality names =
+   let _, hyps_pat, _ = pattern in 
+   let froms = List.map fst hyps_pat in
+   let start = rewrite_tac ~direction ~pattern equality in
+   let continuation = PESR.rename ~froms ~tos:names in
+   if names = [] then start else T.then_ ~start ~continuation
+
+let rewrite_simpl_tac ~direction ~pattern equality names =
+  T.then_ 
+   ~start:(rewrite_tac ~direction ~pattern equality names)
    ~continuation:
      (ReductionTactics.simpl_tac
-       ~pattern:(ProofEngineTypes.conclusion_pattern None)))
-   status
- in
-   ProofEngineTypes.mk_tactic (rewrite_simpl_tac ~direction ~pattern equality)
-;;
+       ~pattern:(ProofEngineTypes.conclusion_pattern None))
+
 
 let replace_tac ~(pattern: ProofEngineTypes.lazy_pattern) ~with_what =
  let replace_tac ~(pattern: ProofEngineTypes.lazy_pattern) ~with_what status =
   let _wanted, hyps_pat, concl_pat = pattern in
   let (proof, goal) = status in
-  let uri,metasenv,pbo,pty = proof in
+  let uri,metasenv,_subst,pbo,pty, attrs = proof in
   let (_,context,ty) as conjecture = CicUtil.lookup_meta goal metasenv in
   assert (hyps_pat = []); (*CSC: not implemented yet *)
   let eq_URI =
@@ -232,7 +246,7 @@ let replace_tac ~(pattern: ProofEngineTypes.lazy_pattern) ~with_what =
   let with_what = CicMetaSubst.apply_subst subst with_what in
   let pbo = CicMetaSubst.apply_subst subst pbo in
   let pty = CicMetaSubst.apply_subst subst pty in
-  let status = (uri,metasenv,pbo,pty),goal in
+  let status = (uri,metasenv,_subst,pbo,pty, attrs),goal in
   let ty_of_with_what,u =
    CicTypeChecker.type_of_aux'
     metasenv context with_what CicUniv.empty_ugraph in
@@ -274,13 +288,13 @@ let replace_tac ~(pattern: ProofEngineTypes.lazy_pattern) ~with_what =
            (ProofEngineTypes.Fail
              (lazy "Replace: one of the selected terms and the term to be replaced with have not convertible types"))
        ) l in
-  let rec aux n whats status =
+  let rec aux n whats (status : ProofEngineTypes.status) =
    match whats with
       [] -> ProofEngineTypes.apply_tactic T.id_tac status
     | (what,lazy_pattern)::tl ->
-       let what = CicSubstitution.lift n what in
-       let with_what = CicSubstitution.lift n with_what in
-       let ty_of_with_what = CicSubstitution.lift n ty_of_with_what in
+       let what = S.lift n what in
+       let with_what = S.lift n with_what in
+       let ty_of_with_what = S.lift n ty_of_with_what in
        ProofEngineTypes.apply_tactic
          (T.thens
             ~start:(
@@ -293,13 +307,13 @@ let replace_tac ~(pattern: ProofEngineTypes.lazy_pattern) ~with_what =
             ~continuations:[            
               T.then_
                 ~start:(
-                  rewrite_tac ~direction:`LeftToRight ~pattern:lazy_pattern (C.Rel 1))
+                  rewrite_tac ~direction:`LeftToRight ~pattern:lazy_pattern (C.Rel 1) [])
                  ~continuation:(
                    T.then_
                     ~start:(
                       ProofEngineTypes.mk_tactic
                        (function ((proof,goal) as status) ->
-                         let _,metasenv,_,_ = proof in
+                         let _,metasenv,_subst,_,_, _ = proof in
                          let _,context,_ = CicUtil.lookup_meta goal metasenv in
                          let hyps =
                           try
@@ -309,12 +323,12 @@ let replace_tac ~(pattern: ProofEngineTypes.lazy_pattern) ~with_what =
                           with (Failure "hd") -> assert false
                          in
                           ProofEngineTypes.apply_tactic
-                           (ProofEngineStructuralRules.clear ~hyps) status))
+                           (PESR.clear ~hyps) status))
                     ~continuation:(aux_tac (n + 1) tl));
               T.id_tac])
          status
   and aux_tac n tl = ProofEngineTypes.mk_tactic (aux n tl) in
-   aux 0 whats status
+   aux 0 whats (status : ProofEngineTypes.status)
  in
    ProofEngineTypes.mk_tactic (replace_tac ~pattern ~with_what)
 ;;
@@ -328,7 +342,7 @@ let reflexivity_tac =
 
 let symmetry_tac =
  let symmetry_tac (proof, goal) =
-   let (_,metasenv,_,_) = proof in
+   let (_,metasenv,_subst,_,_, _) = proof in
     let metano,context,ty = CicUtil.lookup_meta goal metasenv in
      match (R.whd context ty) with
         (C.Appl [(C.MutInd (uri, 0, [])); _; _; _])
@@ -346,7 +360,7 @@ let symmetry_tac =
 let transitivity_tac ~term =
  let transitivity_tac ~term status =
   let (proof, goal) = status in
-   let (_,metasenv,_,_) = proof in
+   let (_,metasenv,_subst,_,_, _) = proof in
     let metano,context,ty = CicUtil.lookup_meta goal metasenv in
      match (R.whd context ty) with
         (C.Appl [(C.MutInd (uri, 0, [])); _; _; _]) 
@@ -364,70 +378,3 @@ let transitivity_tac ~term =
   ProofEngineTypes.mk_tactic (transitivity_tac ~term)
 ;;
 
-(* FG: subst tactic *********************************************************)
-
-(* FG: This should be replaced by T.try_tactic *)
-let try_tactic ~tactic =
-   let try_tactic status =
-      try PET.apply_tactic tactic status with
-         | PET.Fail _ -> PET.apply_tactic T.id_tac status
-   in
-   PET.mk_tactic try_tactic
-
-let msg0 = lazy "Subst: not found in context"
-let msg1 = lazy "Subst: not a simple equality"
-let msg2 = lazy "Subst: recursive equation" 
-
-let subst_tac ~hyp =
-   let hole = C.Implicit (Some `Hole) in
-   let subst_tac status =
-      let (proof, goal) = status in
-      let (_, metasenv, _, _) = proof in
-      let _, context, _ = CicUtil.lookup_meta goal metasenv in
-      let what = match PEH.get_rel context hyp with
-         | Some t -> t
-        | None   -> raise (PET.Fail msg0)
-      in
-      let ty, _ = TC.type_of_aux' metasenv context what CicUniv.empty_ugraph in
-      let direction, i, t = match ty with
-         | (C.Appl [(C.MutInd (uri, 0, [])); _; C.Rel i; t]) 
-           when LO.is_eq_URI uri -> `LeftToRight, i, t
-         | (C.Appl [(C.MutInd (uri, 0, [])); _; t; C.Rel i]) 
-           when LO.is_eq_URI uri -> `RightToLeft, i, t
-        | _ -> raise (PET.Fail msg1)
-      in    
-      let rewrite pattern =
-         try_tactic ~tactic:(rewrite_tac ~direction ~pattern what)         
-      in
-      let var = match PEH.get_name context i with
-         | Some name -> name
-        | None      -> raise (PET.Fail msg0)   
-      in
-      if DTI.does_not_occur i t then () else raise (PET.Fail msg2);
-      let map self = function
-         | Some (C.Name s, _) when s <> self -> 
-            Some (rewrite (None, [(s, hole)], None))
-         | _                                 -> None
-      in
-      let rew_hips = PEH.list_rev_map_filter (map hyp) context in
-      let rew_concl = rewrite (None, [], Some hole) in
-      let clear = PESR.clear ~hyps:[hyp; var] in
-      let tactics = List.rev_append (rew_concl :: rew_hips) [clear] in
-      PET.apply_tactic (T.seq ~tactics) status
-   in
-   PET.mk_tactic subst_tac
-
-let subst_tac =
-   let subst hyp = try_tactic ~tactic:(subst_tac hyp) in
-   let map = function
-      | Some (C.Name s, _) -> Some (subst s)
-      | _                  -> None
-   in
-   let subst_tac status =
-      let (proof, goal) = status in
-      let (_, metasenv, _, _) = proof in
-      let _, context, _ = CicUtil.lookup_meta goal metasenv in
-      let tactics = PEH.list_rev_map_filter map context in
-      PET.apply_tactic (T.seq ~tactics) status
-   in
-   PET.mk_tactic subst_tac