diff options
Diffstat (limited to 'tactics')
-rw-r--r-- | tactics/eauto.ml4 | 2 | ||||
-rw-r--r-- | tactics/equality.ml | 31 | ||||
-rw-r--r-- | tactics/equality.mli | 4 | ||||
-rw-r--r-- | tactics/extratactics.ml4 | 2 | ||||
-rw-r--r-- | tactics/hiddentac.ml | 8 | ||||
-rw-r--r-- | tactics/inv.ml | 13 | ||||
-rw-r--r-- | tactics/leminv.ml | 2 | ||||
-rw-r--r-- | tactics/setoid_replace.ml | 2 | ||||
-rw-r--r-- | tactics/tacticals.ml | 4 | ||||
-rw-r--r-- | tactics/tactics.ml | 81 | ||||
-rw-r--r-- | tactics/tactics.mli | 21 |
11 files changed, 105 insertions, 65 deletions
diff --git a/tactics/eauto.ml4 b/tactics/eauto.ml4 index c450bf622..aceba6e25 100644 --- a/tactics/eauto.ml4 +++ b/tactics/eauto.ml4 @@ -69,7 +69,7 @@ let e_constructor_tac boundopt i lbind gl = | None -> () end; let cons = mkConstruct (ith_constructor_of_inductive mind i) in - let apply_tac = eapply_with_bindings (cons,lbind) in + let apply_tac = eapply_with_ebindings (cons,lbind) in (tclTHENLIST [convert_concl_no_check redcl DEFAULTcast ; intros; apply_tac]) gl diff --git a/tactics/equality.ml b/tactics/equality.ml index d46b6f142..8c8716110 100644 --- a/tactics/equality.ml +++ b/tactics/equality.ml @@ -81,7 +81,7 @@ let elimination_sort_of_clause = function else back to the old approach *) -let general_rewrite_bindings_clause cls lft2rgt (c,l) with_evars gl = +let general_rewrite_ebindings_clause cls lft2rgt (c,l) with_evars gl = let ctype = pf_apply get_type_of gl c in (* A delta-reduction would be here too strong, since it would break search for a defined setoid relation in head position. *) @@ -111,13 +111,20 @@ let general_rewrite_bindings_clause cls lft2rgt (c,l) with_evars gl = in general_elim_clause with_evars cls (c,l) (elim,NoBindings) gl -let general_rewrite_bindings = general_rewrite_bindings_clause None -let general_rewrite l2r c = general_rewrite_bindings l2r (c,NoBindings) false +let general_rewrite_ebindings = + general_rewrite_ebindings_clause None +let general_rewrite_bindings l2r (c,bl) = + general_rewrite_ebindings_clause None l2r (c,inj_ebindings bl) -let general_rewrite_bindings_in l2r id = - general_rewrite_bindings_clause (Some id) l2r +let general_rewrite l2r c = + general_rewrite_bindings l2r (c,NoBindings) false + +let general_rewrite_ebindings_in l2r id = + general_rewrite_ebindings_clause (Some id) l2r +let general_rewrite_bindings_in l2r id (c,bl) = + general_rewrite_ebindings_clause (Some id) l2r (c,inj_ebindings bl) let general_rewrite_in l2r id c = - general_rewrite_bindings_clause (Some id) l2r (c,NoBindings) + general_rewrite_ebindings_clause (Some id) l2r (c,NoBindings) let general_multi_rewrite l2r with_evars c cl = if cl.concl_occs <> [] then @@ -130,12 +137,12 @@ let general_multi_rewrite l2r with_evars c cl = | [] -> tclIDTAC | ((_,id),_) :: l -> tclTHENFIRST - (general_rewrite_bindings_in l2r id c with_evars) + (general_rewrite_ebindings_in l2r id c with_evars) (do_hyps l) in if not cl.onconcl then do_hyps l else tclTHENFIRST - (general_rewrite_bindings l2r c with_evars) + (general_rewrite_ebindings l2r c with_evars) (do_hyps l) | None -> (* Otherwise, if we are told to rewrite in all hypothesis via the @@ -144,7 +151,7 @@ let general_multi_rewrite l2r with_evars c cl = | [] -> (fun gl -> error "Nothing to rewrite.") | id :: l -> tclIFTHENTRYELSEMUST - (general_rewrite_bindings_in l2r id c with_evars) + (general_rewrite_ebindings_in l2r id c with_evars) (do_hyps_atleastonce l) in let do_hyps gl = @@ -156,14 +163,14 @@ let general_multi_rewrite l2r with_evars c cl = in if not cl.onconcl then do_hyps else tclIFTHENTRYELSEMUST - (general_rewrite_bindings l2r c with_evars) + (general_rewrite_ebindings l2r c with_evars) do_hyps (* Conditional rewriting, the success of a rewriting is related to the resolution of the conditions by a given tactic *) let conditional_rewrite lft2rgt tac (c,bl) = - tclTHENSFIRSTn (general_rewrite_bindings lft2rgt (c,bl) false) + tclTHENSFIRSTn (general_rewrite_ebindings lft2rgt (c,bl) false) [|tclIDTAC|] (tclCOMPLETE tac) let rewriteLR_bindings = general_rewrite_bindings true @@ -176,7 +183,7 @@ let rewriteLRin_bindings = general_rewrite_bindings_in true let rewriteRLin_bindings = general_rewrite_bindings_in false let conditional_rewrite_in lft2rgt id tac (c,bl) = - tclTHENSFIRSTn (general_rewrite_bindings_in lft2rgt id (c,bl) false) + tclTHENSFIRSTn (general_rewrite_ebindings_in lft2rgt id (c,bl) false) [|tclIDTAC|] (tclCOMPLETE tac) let rewriteRL_clause = function diff --git a/tactics/equality.mli b/tactics/equality.mli index 9254e5f0d..36fc99594 100644 --- a/tactics/equality.mli +++ b/tactics/equality.mli @@ -26,7 +26,7 @@ open Genarg (*i*) val general_rewrite_bindings : - bool -> constr with_ebindings -> evars_flag -> tactic + bool -> constr with_bindings -> evars_flag -> tactic val general_rewrite : bool -> constr -> tactic @@ -42,7 +42,7 @@ val rewriteRL : constr -> tactic (* Warning: old [general_rewrite_in] is now [general_rewrite_bindings_in] *) val general_rewrite_bindings_in : - bool -> identifier -> constr with_ebindings -> evars_flag -> tactic + bool -> identifier -> constr with_bindings -> evars_flag -> tactic val general_rewrite_in : bool -> identifier -> constr -> evars_flag -> tactic diff --git a/tactics/extratactics.ml4 b/tactics/extratactics.ml4 index ea33ead5d..d51d17aaf 100644 --- a/tactics/extratactics.ml4 +++ b/tactics/extratactics.ml4 @@ -323,7 +323,7 @@ let step left x tac = let l = List.map (fun lem -> tclTHENLAST - (apply_with_bindings (lem, ImplicitBindings [Evd.empty,x])) + (apply_with_bindings (lem, ImplicitBindings [x])) tac) !(if left then transitivity_left_table else transitivity_right_table) in diff --git a/tactics/hiddentac.ml b/tactics/hiddentac.ml index 85a85083e..b6c8f2ef8 100644 --- a/tactics/hiddentac.ml +++ b/tactics/hiddentac.ml @@ -41,7 +41,7 @@ let h_vm_cast_no_check c = abstract_tactic (TacVmCastNoCheck (inj_open c)) (vm_cast_no_check c) let h_apply ev cb = abstract_tactic (TacApply (ev,inj_open_wb cb)) - (apply_with_bindings_gen ev cb) + (apply_with_ebindings_gen ev cb) let h_elim cb cbo = abstract_tactic (TacElim (inj_open_wb cb,option_map inj_open_wb cbo)) (elim cb cbo) @@ -96,9 +96,9 @@ let h_rename id1 id2 = abstract_tactic (TacRename (id1,id2)) (rename_hyp id1 id2) (* Constructors *) -let h_left l = abstract_tactic (TacLeft l) (left l) -let h_right l = abstract_tactic (TacLeft l) (right l) -let h_split l = abstract_tactic (TacSplit (false,l)) (split l) +let h_left l = abstract_tactic (TacLeft l) (left_with_ebindings l) +let h_right l = abstract_tactic (TacLeft l) (right_with_ebindings l) +let h_split l = abstract_tactic (TacSplit (false,l)) (split_with_ebindings l) (* Moved to tacinterp because of dependence in Tacinterp.interp let h_any_constructor t = abstract_tactic (TacAnyConstructor t) (any_constructor t) diff --git a/tactics/inv.ml b/tactics/inv.ml index 47b8ca64b..6a9dc632b 100644 --- a/tactics/inv.ml +++ b/tactics/inv.ml @@ -441,15 +441,14 @@ let rewrite_equations_tac (gene, othin) id neqns names ba = tac -let raw_inversion inv_kind indbinding id status names gl = +let raw_inversion inv_kind id status names gl = let env = pf_env gl and sigma = project gl in let c = mkVar id in let t = strong_prodspine (pf_whd_betadeltaiota gl) (pf_type_of gl c) in let indclause = mk_clenv_from gl (c,t) in - let indclause' = clenv_constrain_with_bindings indbinding indclause in - let newc = clenv_value indclause' in - let ccl = clenv_type indclause' in - check_no_metas indclause' ccl; + let newc = clenv_value indclause in + let ccl = clenv_type indclause in + check_no_metas indclause ccl; let IndType (indf,realargs) = try find_rectype env sigma ccl with Not_found -> @@ -503,13 +502,13 @@ let wrap_inv_error id = function | UserError ("Case analysis",s) -> errorlabstrm "Inv needs Nodep Prop Set" s | UserError("mind_specif_of_mind",_) -> not_inductive_here id | UserError (a,b) -> errorlabstrm "Inv" b - | Invalid_argument (*"it_list2"*) "List.fold_left2" -> dep_prop_prop_message id + | Invalid_argument "List.fold_left2" -> dep_prop_prop_message id | Not_found -> errorlabstrm "Inv" (not_found_message [id]) | e -> raise e (* The most general inversion tactic *) let inversion inv_kind status names id gls = - try (raw_inversion inv_kind [] id status names) gls + try (raw_inversion inv_kind id status names) gls with e -> wrap_inv_error id e (* Specializing it... *) diff --git a/tactics/leminv.ml b/tactics/leminv.ml index 1b308e298..f34c9e38d 100644 --- a/tactics/leminv.ml +++ b/tactics/leminv.ml @@ -292,7 +292,7 @@ let add_inversion_lemma_exn na com comsort bool tac = let lemInv id c gls = try let clause = mk_clenv_type_of gls c in - let clause = clenv_constrain_with_bindings [(-1,(Evd.empty,mkVar id))] clause in + let clause = clenv_constrain_last_binding (mkVar id) clause in Clenvtac.res_pf clause ~allow_K:true gls with | UserError (a,b) -> diff --git a/tactics/setoid_replace.ml b/tactics/setoid_replace.ml index 8fc95b408..1e70bf277 100644 --- a/tactics/setoid_replace.ml +++ b/tactics/setoid_replace.ml @@ -1983,7 +1983,7 @@ let setoid_transitivity c gl = | _ -> assert false in apply_with_bindings - (trans, Rawterm.ExplicitBindings [ dummy_loc, binder, (Evd.empty,c) ]) gl + (trans, Rawterm.ExplicitBindings [ dummy_loc, binder, c ]) gl with Optimize -> transitivity c gl ;; diff --git a/tactics/tacticals.ml b/tactics/tacticals.ml index 4aad135c6..f13897d1f 100644 --- a/tactics/tacticals.ml +++ b/tactics/tacticals.ml @@ -324,7 +324,7 @@ let general_elim_then_using let (ity,t) = pf_reduce_to_quantified_ind gl (pf_type_of gl c) in (* applying elimination_scheme just a little modified *) let indclause = mk_clenv_from gl (c,t) in - let indclause' = clenv_constrain_with_bindings indbindings indclause in + let indclause' = clenv_match_args indbindings indclause in let elimclause = mk_clenv_from gl (elim,pf_type_of gl elim) in let indmv = match kind_of_term (last_arg elimclause.templval.Evd.rebus) with @@ -345,7 +345,7 @@ let general_elim_then_using error ("The elimination combinator " ^ name_elim ^ " is not known") in let elimclause' = clenv_fchain indmv elimclause indclause' in - let elimclause' = clenv_constrain_with_bindings elimbindings elimclause' in + let elimclause' = clenv_match_args elimbindings elimclause' in let branchsigns = compute_construtor_signatures isrec ity in let brnames = compute_induction_names (Array.length branchsigns) allnames in let after_tac ce i gl = diff --git a/tactics/tactics.ml b/tactics/tactics.ml index b042a8422..8b10913de 100644 --- a/tactics/tactics.ml +++ b/tactics/tactics.ml @@ -55,6 +55,23 @@ let rec nb_prod x = | _ -> n in count 0 x +let inj_open c = (Evd.empty,c) + +let inj_occ (occ,c) = (occ,inj_open c) + +let inj_red_expr = function + | Simpl lo -> Simpl (option_map inj_occ lo) + | Fold l -> Fold (List.map inj_open l) + | Pattern l -> Pattern (List.map inj_occ l) + | (ExtraRedExpr _ | CbvVm | Red _ | Hnf | Cbv _ | Lazy _ | Unfold _ as c) + -> c + +let inj_ebindings = function + | NoBindings -> NoBindings + | ImplicitBindings l -> ImplicitBindings (List.map inj_open l) + | ExplicitBindings l -> + ExplicitBindings (List.map (fun (l,id,c) -> (l,id,inj_open c)) l) + (*********************************************) (* Tactics *) (*********************************************) @@ -527,7 +544,7 @@ let clenv_refine_in with_evars id clenv gl = (* Resolution with missing arguments *) -let apply_with_bindings_gen with_evars (c,lbind) gl = +let apply_with_ebindings_gen with_evars (c,lbind) gl = (* The actual type of the theorem. It will be matched against the goal. If this fails, then the head constant will be unfolded step by step. *) @@ -553,24 +570,20 @@ let apply_with_bindings_gen with_evars (c,lbind) gl = else Clenvtac.res_pf clause gl in try_apply thm_ty0 -let apply_with_bindings = apply_with_bindings_gen false -let eapply_with_bindings = apply_with_bindings_gen true +let apply_with_ebindings = apply_with_ebindings_gen false +let eapply_with_ebindings = apply_with_ebindings_gen true -let apply c = apply_with_bindings (c,NoBindings) +let apply_with_bindings (c,bl) = + apply_with_ebindings (c,inj_ebindings bl) -let inj_open c = (Evd.empty,c) - -let inj_occ (occ,c) = (occ,inj_open c) +let eapply_with_bindings (c,bl) = + apply_with_ebindings_gen true (c,inj_ebindings bl) -let inj_red_expr = function - | Simpl lo -> Simpl (option_map inj_occ lo) - | Fold l -> Fold (List.map inj_open l) - | Pattern l -> Pattern (List.map inj_occ l) - | (ExtraRedExpr _ | CbvVm | Red _ | Hnf | Cbv _ | Lazy _ | Unfold _ as c) - -> c +let apply c = + apply_with_ebindings (c,NoBindings) let apply_list = function - | c::l -> apply_with_bindings (c,ImplicitBindings (List.map inj_open l)) + | c::l -> apply_with_bindings (c,ImplicitBindings l) | _ -> assert false (* Resolution with no reduction on the type *) @@ -713,6 +726,7 @@ let rec intros_clearing = function let new_hyp mopt (c,lbind) g = let clause = make_clenv_binding g (c,pf_type_of g c) lbind in + let clause = clenv_unify_meta_types clause in let (thd,tstack) = whd_stack (clenv_value clause) in let nargs = List.length tstack in let cut_pf = @@ -720,7 +734,10 @@ let new_hyp mopt (c,lbind) g = match mopt with | Some m -> if m < nargs then list_firstn m tstack else tstack | None -> tstack) - in + in + if occur_meta cut_pf then + errorlabstrm "" (str "Cannot infer an instance for " ++ + pr_name (meta_name clause.evd (List.hd (collect_metas cut_pf)))); (tclTHENLAST (tclTHEN (tclEVARS (evars_of clause.evd)) (cut (pf_type_of g cut_pf))) ((tclORELSE (apply cut_pf) (exact_no_check cut_pf)))) g @@ -744,21 +761,24 @@ let keep hyps gl = (* Introduction tactics *) (************************) -let constructor_tac boundopt i lbind gl = +let check_number_of_constructors expctdnumopt i nconstr = + if i=0 then error "The constructors are numbered starting from 1"; + begin match expctdnumopt with + | Some n when n <> nconstr -> + error ("Not an inductive goal with "^ + string_of_int n^plural n " constructor") + | _ -> () + end; + if i > nconstr then error "Not enough constructors" + +let constructor_tac expctdnumopt i lbind gl = let cl = pf_concl gl in let (mind,redcl) = pf_reduce_to_quantified_ind gl cl in let nconstr = Array.length (snd (Global.lookup_inductive mind)).mind_consnames in - if i=0 then error "The constructors are numbered starting from 1"; - if i > nconstr then error "Not enough constructors"; - begin match boundopt with - | Some expctdnum -> - if expctdnum <> nconstr then - error "Not the expected number of constructors" - | None -> () - end; + check_number_of_constructors expctdnumopt i nconstr; let cons = mkConstruct (ith_constructor_of_inductive mind i) in - let apply_tac = apply_with_bindings (cons,lbind) in + let apply_tac = apply_with_ebindings (cons,lbind) in (tclTHENLIST [convert_concl_no_check redcl DEFAULTcast; intros; apply_tac]) gl @@ -778,15 +798,20 @@ let any_constructor tacopt gl = tclFIRST (List.map (fun i -> tclTHEN (one_constructor i NoBindings) t) (interval 1 nconstr)) gl -let left = constructor_tac (Some 2) 1 +let left_with_ebindings = constructor_tac (Some 2) 1 +let right_with_ebindings = constructor_tac (Some 2) 2 +let split_with_ebindings = constructor_tac (Some 1) 1 + +let left l = left_with_ebindings (inj_ebindings l) let simplest_left = left NoBindings -let right = constructor_tac (Some 2) 2 +let right l = right_with_ebindings (inj_ebindings l) let simplest_right = right NoBindings -let split = constructor_tac (Some 1) 1 +let split l = split_with_ebindings (inj_ebindings l) let simplest_split = split NoBindings + (********************************************) (* Elimination tactics *) (********************************************) diff --git a/tactics/tactics.mli b/tactics/tactics.mli index 6b0f8413a..0c2024162 100644 --- a/tactics/tactics.mli +++ b/tactics/tactics.mli @@ -30,6 +30,7 @@ open Rawterm val inj_open : constr -> open_constr val inj_red_expr : red_expr -> (open_constr, evaluable_global_reference) red_expr_gen +val inj_ebindings : constr bindings -> open_constr bindings (* Main tactics. *) @@ -169,9 +170,11 @@ val bring_hyps : named_context -> tactic val apply : constr -> tactic val apply_without_reduce : constr -> tactic val apply_list : constr list -> tactic -val apply_with_bindings_gen : evars_flag -> constr with_ebindings -> tactic -val apply_with_bindings : constr with_ebindings -> tactic -val eapply_with_bindings : constr with_ebindings -> tactic +val apply_with_ebindings_gen : evars_flag -> constr with_ebindings -> tactic +val apply_with_bindings : constr with_bindings -> tactic +val apply_with_ebindings : constr with_ebindings -> tactic +val eapply_with_bindings : constr with_bindings -> tactic +val eapply_with_ebindings : constr with_ebindings -> tactic val cut_and_apply : constr -> tactic @@ -271,11 +274,17 @@ val constructor_tac : int option -> int -> open_constr bindings -> tactic val one_constructor : int -> open_constr bindings -> tactic val any_constructor : tactic option -> tactic -val left : open_constr bindings -> tactic + +val left : constr bindings -> tactic +val right : constr bindings -> tactic +val split : constr bindings -> tactic + +val left_with_ebindings : open_constr bindings -> tactic +val right_with_ebindings : open_constr bindings -> tactic +val split_with_ebindings : open_constr bindings -> tactic + val simplest_left : tactic -val right : open_constr bindings -> tactic val simplest_right : tactic -val split : open_constr bindings -> tactic val simplest_split : tactic (*s Logical connective tactics. *) |