]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/software/components/ng_tactics/nTactics.ml
- Procedural: generation of "exact" is now complete
[helm.git] / helm / software / components / ng_tactics / nTactics.ml
index a6ae87be720456623a3aaf9da1adaaea7a7dbb9f..8d07811ea3333d450caf68f347e39f1b6a1772e6 100644 (file)
@@ -274,9 +274,6 @@ let select0_tac ~where:(wanted,hyps,where) ~job  =
    let path = 
      match where with None -> NCic.Implicit `Term | Some where -> where 
    in
-   let status, newgoalty = 
-     select_term status ~found ~postprocess goalty (wanted,path) 
-   in
    let status, newgoalctx =
       List.fold_right
        (fun (name,d as entry) (status,ctx) ->
@@ -299,6 +296,16 @@ let select0_tac ~where:(wanted,hyps,where) ~job  =
           Not_found -> status, entry::ctx
        ) (ctx_of goalty) (status,[])
    in
+   let status, newgoalty = 
+     select_term status ~found ~postprocess goalty (wanted,path) in
+   (* WARNING: the next two lines simply change the context of newgoalty
+      from the old to the new one. Otherwise mk_meta will do that herself,
+      calling relocate that calls delift. However, newgoalty is now
+      ?[out_scope] and thus the delift would trigger the special unification
+      case, which is wrong now :-( *)
+   let status,newgoalty = term_of_cic_term status newgoalty (ctx_of goalty) in
+   let newgoalty = mk_cic_term newgoalctx newgoalty in
+
    let status, instance = 
      mk_meta status newgoalctx (`Decl newgoalty) 
    in
@@ -363,6 +370,25 @@ let change_tac ~where ~with_what =
   select0_tac ~where ~job:(`ChangeWith change)
 ;;
 
+let letin_tac ~where:(_,_,(m,hyp,gp)) ~what:(_,_,w) name =
+  assert(m = None);
+  let where = Some w, [], 
+     match gp with 
+     | None -> Some Ast.Implicit
+     | Some where -> 
+         Some 
+          (List.fold_left 
+           (fun t _ -> 
+              Ast.Binder(`Pi,(Ast.Ident("_",None),Some Ast.UserInput),t)) 
+           where hyp)
+  in
+  block_tac [
+   generalize0_tac (List.map (fun (name,_) -> Ast.Ident (name,None)) hyp);
+   exact_tac ("",0,Ast.LetIn((Ast.Ident (name,None),None),w,Ast.Implicit));
+   change_tac ~where:("",0,where) ~with_what:("",0,Ast.Ident (name,None))
+  ]
+;;
+
 let apply_tac = exact_tac;;
 
 type indtyinfo = {
@@ -475,5 +501,55 @@ let case1_tac name =
              cases_tac 
               ~where:("",0,(None,[],None)) 
               ~what:("",0,Ast.Ident (name,None));
-              if name = "_clearme" then clear_tac ["_clearme"] else id_tac ]
+             if name = "_clearme" then clear_tac ["_clearme"] else id_tac ]
+;;
+
+let assert0_tac (hyps,concl) = distribute_tac (fun status goal ->
+ let gty = get_goalty status goal in
+ let eq status ctx t1 t2 =
+  let status,t1 = disambiguate status t1 None ctx in
+  let status,t1 = apply_subst status ctx t1 in
+  let status,t1 = term_of_cic_term status t1 ctx in
+  let t2 = mk_cic_term ctx t2 in
+  let status,t2 = apply_subst status ctx t2 in
+  let status,t2 = term_of_cic_term status t2 ctx in
+  prerr_endline ("COMPARING: " ^ NCicPp.ppterm ~subst:[] ~metasenv:[] ~context:ctx t1 ^ " vs " ^ NCicPp.ppterm ~subst:[] ~metasenv:[] ~context:ctx t2);
+  assert (t1=t2);
+  status
+ in
+ let status,gty' = term_of_cic_term status gty (ctx_of gty) in
+ let status = eq status (ctx_of gty) concl gty' in
+ let status,_ =
+  List.fold_right2
+   (fun (id1,e1) ((id2,e2) as item) (status,ctx) ->
+     assert (id1=id2);
+     match e1,e2 with
+        `Decl t1, NCic.Decl t2 ->
+          let status = eq status ctx t1 t2 in
+          status,item::ctx
+      | `Def (b1,t1), NCic.Def (b2,t2) ->
+          let status = eq status ctx t1 t2 in
+          let status = eq status ctx b1 b2 in
+          status,item::ctx
+      | _ -> assert false
+   ) hyps (ctx_of gty) (status,[])
+ in
+  exec id_tac status goal)
+;;
+
+let assert_tac seqs status =
+ match status.gstatus with
+  | [] -> assert false
+  | (g,_,_,_) :: s ->
+     assert (List.length g = List.length seqs);
+     (match seqs with
+         [] -> id_tac
+       | [seq] -> assert0_tac seq
+       | _ ->
+         block_tac
+          (branch_tac::
+          HExtlib.list_concat ~sep:[shift_tac]
+            (List.map (fun seq -> [assert0_tac seq]) seqs)@
+          [merge_tac])
+     ) status
 ;;