]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/software/components/ng_tactics/nTactics.ml
Analizyng the inductive type of the eliminated term and
[helm.git] / helm / software / components / ng_tactics / nTactics.ml
index 1d3a4aeff3323fc7dbac0e55d9b884e4376da395..b34a3a34dd0b4c594ffc7812e92dc437184778dc 100644 (file)
@@ -20,6 +20,9 @@ open Continuationals.Stack
 open NTacStatus
 module Ast = CicNotationPt
 
+let id_tac status = status ;;
+let print_tac message status = prerr_endline message; status ;;
+
 let dot_tac status =
   let new_gstatus = 
     match status.gstatus with
@@ -153,8 +156,13 @@ let block_tac l status =
 let compare_statuses ~past ~present =
  let _,_,past,_,_ = past.pstatus in 
  let _,_,present,_,_ = present.pstatus in 
- List.map fst (List.filter (fun (i,_) -> not (List.mem_assoc i past)) present),
- List.map fst (List.filter (fun (i,_) -> not (List.mem_assoc i present)) past)
+ let closed = 
+  List.map fst (List.filter (fun (i,_) -> not (List.mem_assoc i present)) past)
+ in
+ let opened = 
+   List.map fst (List.filter (fun (i,_) -> not(List.mem_assoc i past)) present)
+ in
+ opened, closed
 ;;
 
 
@@ -165,6 +173,7 @@ let compare_statuses ~past ~present =
          distribute_tac (exec tac) [s]::G = (G1@...Gn)::G'
     3) tac G = distribute_tac (exec tac) G if  
        tac = distribute_tac lowtac
+    4) atomic_tac t === distribute_tac (exec t)
 
    Note that executing an high tactic on a set of goals may be stronger
    than executing the same tactic on those goals, but once at a time
@@ -184,7 +193,9 @@ let distribute_tac tac status =
       debug_print (lazy ("context length " ^string_of_int (List.length g)));
       let rec aux s go gc =
         function
-        | [] -> s, go, gc
+        | [] -> 
+            debug_print (lazy "no selected goals");
+            s, go, gc
         | loc :: loc_tl ->
             debug_print (lazy "inner eval tactical");
             let s, go, gc =
@@ -196,7 +207,7 @@ let distribute_tac tac status =
                 | Open n -> 
                    let sn = tac s n in
                    let go', gc' = compare_statuses ~past:s ~present:sn in
-                   sn, (go @- gc') @+ go', gc @+ gc'
+                   sn, ((go @+ [n]) @- gc') @+ go', gc @+ gc'
             in
             aux s go gc loc_tl
       in
@@ -212,6 +223,8 @@ let distribute_tac tac status =
        { gstatus = stack; istatus = sn }
 ;;
 
+let atomic_tac htac = distribute_tac (exec htac) ;;
+
 let exact t status goal =
  let goalty = get_goalty status goal in
  let status, t = disambiguate status t (Some goalty) (ctx_of goalty) in
@@ -244,47 +257,53 @@ let clear names status goal =
   { status with pstatus = n,h,metasenv,subst,o }
 ;;
 
-let clear_tac names = distribute_tac (clear names);;
+let clear_tac names =
+ if names = [] then id_tac else distribute_tac (clear names)
+;;
 
-let select ~where:(wanted,_,where) status goal = 
- let goalty = get_goalty status goal in
- let path = 
-   match where with None -> NCic.Implicit `Term | Some where -> where 
- in
- let status, newgoalty = select_term status goalty (wanted,path) in
- let status, instance = 
-   mk_meta status (ctx_of newgoalty) (`Decl newgoalty) 
- in
- instantiate status goal instance
+let generalize0_tac args =
+ if args = [] then id_tac
+ else exact_tac ("",0,Ast.Appl (Ast.Implicit :: args))
 ;;
 
-let select_tac ~where = distribute_tac (select ~where) ;;
+let select0_tac ~where:(wanted,_,where) ~argsno = 
+ distribute_tac (fun status goal ->
+   let goalty = get_goalty status goal in
+   let path = 
+     match where with None -> NCic.Implicit `Term | Some where -> where 
+   in
+   let status, newgoalty = select_term status argsno goalty (wanted,path) in
+   let status, instance = 
+     mk_meta status (ctx_of newgoalty) (`Decl newgoalty) 
+   in
+   instantiate status goal instance)
+;;
 
-let select_tac ~where move_down_hyps = 
+let select_tac ~where ~argsno move_down_hyps = 
  let (wanted,hyps,where) = GrafiteDisambiguate.disambiguate_npattern where in
  let path = 
   match where with None -> NCic.Implicit `Term | Some where -> where in
  if not move_down_hyps then
-  select_tac ~where:(wanted,hyps,Some path)
+  select0_tac ~where:(wanted,hyps,Some path) ~argsno
  else
   let path = 
    List.fold_left
      (fun path (name,path_name) -> NCic.Prod ("_",path_name,path))
      path (List.rev hyps)
   in
-   let generalize_tac =
-    distribute_tac
-     (exec (exact_tac 
-         ("",0,Ast.Appl 
-           (Ast.Implicit :: List.map (fun (name,_) -> Ast.Ident (name,None)) 
-             hyps))))
-   in
    block_tac [ 
-     generalize_tac; 
-     select_tac ~where:(wanted,[],Some path);
+     generalize0_tac (List.map (fun (name,_) -> Ast.Ident (name,None)) hyps);
+     select0_tac ~where:(wanted,[],Some path) ~argsno;
      clear_tac (List.map fst hyps) ]
 ;;
 
+(*
+let generalize_tac ~where = 
+ block_tac [ select_tac ~where true ; generalize0_tac ???? ]
+;;
+*)
+
+
 let reopen status =
  let n,h,metasenv,subst,o = status.pstatus in
  let subst, newm = 
@@ -313,7 +332,7 @@ let change ~where ~with_what status goal =
  let path = 
    match where with None -> NCic.Implicit `Term | Some where -> where 
  in
- let status, newgoalty = select_term status goalty (wanted,path) in
+ let status, newgoalty = select_term status goalty (wanted,path) in
  let status, in_scope, out_scope = reopen status in
  let status =  List.fold_left (exact with_what) status in_scope in
 
@@ -335,24 +354,79 @@ let apply t status goal = exact t status goal;;
 let apply_tac t = distribute_tac (apply t) ;;
 let change_tac ~where ~with_what = distribute_tac (change ~where ~with_what) ;;
 
-let elim_tac ~what ~where status =
- block_tac
-   [ select_tac ~where true;
-     distribute_tac (fun status goal ->
-       let goalty = get_goalty status goal in
+type indtyinfo = {
+        rightno: int;
+        leftno: int;
+        consno: int;
+        lefts: NCic.term list;
+        rights: NCic.term list;
+        reference: NReference.reference;
+ }
+;;
+
+let analyze_indty_tac ~what indtyref = distribute_tac (fun status goal ->
+  let goalty = get_goalty status goal in
+  let status, what = disambiguate status what None (ctx_of goalty) in
+  let ty_what = typeof status (ctx_of what) what in 
+  let r,consno,lefts,rights = analyse_indty status ty_what in
+  let leftno = List.length rights in
+  let rightno = List.length rights in
+  indtyref := Some { 
+    rightno = rightno; leftno = leftno; consno = consno;
+    lefts = lefts; rights = rights; reference = r;
+  };
+  prerr_endline "FO";
+  exec id_tac status goal)
+;;
+
+let force f s = Lazy.force f s;;
+
+let elim_tac ~what ~where = 
+  let indtyinfo = ref None in
+  let sort = ref None in
+  let compute_goal_sort_tac = distribute_tac (fun status goal ->
+    let goalty = get_goalty status goal in
+    let goalsort = typeof status (ctx_of goalty) goalty in
+    prerr_endline "XXXXXXXX";
+    sort := Some goalsort;
+    exec id_tac status goal)
+  in
+  atomic_tac (block_tac [
+    analyze_indty_tac ~what indtyinfo;    
+    force (lazy (select_tac 
+      ~where ~argsno:((HExtlib.unopt !indtyinfo).rightno+1) true));
+    print_tac "CIAO";
+    compute_goal_sort_tac;
+    print_tac "CIAO2";
+    force (lazy (
+     let sort = HExtlib.unopt !sort in
+     let ity = HExtlib.unopt !indtyinfo in
+     let NReference.Ref (uri, _) = ity.reference in
+     let name = NUri.name_of_uri uri ^
+      match term_of_cic_term sort (ctx_of sort) with
+       | NCic.Sort NCic.Prop -> "_ind"
+       | NCic.Sort _ -> "_rect"
+       | _ -> assert false 
+     in
+     let holes = 
+       HExtlib.mk_list Ast.Implicit (ity.leftno+1+ ity.consno + ity.rightno) in
+     let eliminator = 
        let _,_,w = what in
-       let status, what = 
-         disambiguate status what None (ctx_of goalty) in
-       let _ty_what = typeof status (ctx_of what) what in 
-       (* check inductive... find eliminator *)
-       let holes = [ 
-         Ast.Implicit;Ast.Implicit;Ast.Implicit]
-       in
-       let eliminator = 
-         Ast.Appl(Ast.Ident("nat_ind",None)::holes @ [ w ])
-       in
-       exec (apply_tac ("",0,eliminator)) status goal) ] 
-   status
+       Ast.Appl(Ast.Ident(name,None)::holes @ [ w ])
+     in
+     exact_tac ("",0,eliminator))) ]) 
+;;
+
+let rewrite_tac ~dir ~what:(_,_,what) ~where =
+ let name =
+  match dir with `LeftToRight -> "eq_elim_r" | `RightToLeft -> "eq_ind"
+ in
+  block_tac
+   [ select_tac ~where ~argsno:2 true;
+     exact_tac
+      ("",0,
+       Ast.Appl(Ast.Ident(name,None)::HExtlib.mk_list Ast.Implicit 5 @
+        [what]))]
 ;;
 
 let intro_tac name =
@@ -360,14 +434,14 @@ let intro_tac name =
   [ exact_tac
     ("",0,(Ast.Binder (`Lambda,
      (Ast.Ident (name,None),None),Ast.Implicit)));
-     if name = "_" then clear_tac [name] else fun x -> x ]
+     if name = "_" then clear_tac [name] else id_tac ]
 ;;
 
 let cases ~what status goal =
  let gty = get_goalty status goal in
  let status, what = disambiguate status what None (ctx_of gty) in
  let ty = typeof status (ctx_of what) what in
- let ref, consno, left, right = analyse_indty status ty in
+ let ref, consno, _, _ = analyse_indty status ty in
  let t =
   NCic.Match (ref,NCic.Implicit `Term, term_of_cic_term what (ctx_of gty),
     HExtlib.mk_list (NCic.Implicit `Term) consno)
@@ -378,7 +452,12 @@ let cases ~what status goal =
 ;;
 
 let cases_tac ~what ~where = 
-        block_tac [ select_tac ~where true ; distribute_tac (cases ~what) ]
+  let indtyinfo = ref None in
+  atomic_tac 
+   (block_tac [
+      analyze_indty_tac ~what indtyinfo;
+      select_tac ~where ~argsno:((HExtlib.unopt !indtyinfo).rightno+1) true;
+      distribute_tac (cases ~what) ])
 ;;
 
 let case1_tac name =
@@ -387,5 +466,5 @@ let case1_tac name =
              cases_tac 
               ~where:("",0,(None,[],None)) 
               ~what:("",0,Ast.Ident (name,None));
-              if name = "_clearme" then clear_tac ["_clearme"] else fun x -> x ]
+              if name = "_clearme" then clear_tac ["_clearme"] else id_tac ]
 ;;