aboutsummaryrefslogtreecommitdiffhomepage
path: root/tactics/class_tactics.ml4
diff options
context:
space:
mode:
authorGravatar msozeau <msozeau@85f007b7-540e-0410-9357-904b9bb8a0f7>2008-03-16 09:53:52 +0000
committerGravatar msozeau <msozeau@85f007b7-540e-0410-9357-904b9bb8a0f7>2008-03-16 09:53:52 +0000
commitb149e6e21f68d0851f4387dd7182aaca2021041d (patch)
treec0170c50e4dfe3f520f31acab6d3c75c52ac3427 /tactics/class_tactics.ml4
parent189770d9cf98db9ba08da66707002c52f092d73f (diff)
Minor fixes on setoid rewriting. Now uses definitions of [relation] and
[id] instead of their expansions. Seems to slow things down a bit (1s. on Ring_polynom). git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@10680 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'tactics/class_tactics.ml4')
-rw-r--r--tactics/class_tactics.ml4203
1 files changed, 107 insertions, 96 deletions
diff --git a/tactics/class_tactics.ml4 b/tactics/class_tactics.ml4
index 079a1422f..8f11989a1 100644
--- a/tactics/class_tactics.ml4
+++ b/tactics/class_tactics.ml4
@@ -106,8 +106,10 @@ and e_trivial_resolve db_list local_db gl =
let e_possible_resolve db_list local_db gl =
try
- List.map snd (e_my_find_search db_list local_db
- (List.hd (head_constr_bound gl [])) gl)
+ List.map snd
+ (List.sort (fun (b, _) (b', _) -> b - b')
+ (e_my_find_search db_list local_db
+ (List.hd (head_constr_bound gl [])) gl))
with Bound | Not_found -> []
let find_first_goal gls =
@@ -118,6 +120,7 @@ type search_state = {
depth : int; (*r depth of search before failing *)
tacres : goal list sigma * validation;
last_tactic : std_ppcmds;
+ custom_tactic : tactic;
dblist : Auto.Hint_db.t list;
localdb : Auto.Hint_db.t list }
@@ -136,23 +139,26 @@ module SearchProblem = struct
prlist (pr_ev evars) (sig_it gls)
let filter_tactics (glls,v) l =
-(* let _ = Proof_trees.db_pr_goal (List.hd (sig_it glls)) in *)
-(* let evars = Evarutil.nf_evars (Refiner.project glls) in *)
-(* msg (str"Goal:" ++ pr_ev evars (List.hd (sig_it glls)) ++ str"\n"); *)
+(* if !debug then *)
+(* (let _ = Proof_trees.db_pr_goal (List.hd (sig_it glls)) in *)
+(* let evars = Evarutil.nf_evars (Refiner.project glls) in *)
+(* msg (str"Goal: " ++ pr_ev evars (List.hd (sig_it glls)) ++ str"\n")); *)
let rec aux = function
| [] -> []
| (tac,pptac) :: tacl ->
try
+(* if !debug then msg (str"\nTrying tactic: " ++ pptac ++ str"\n"); *)
let (lgls,ptl) = apply_tac_list tac glls in
let v' p = v (ptl p) in
-(* if !debug then *)
+(* if !debug then *)
(* begin *)
(* let evars = Evarutil.nf_evars (Refiner.project glls) in *)
-(* msg (str"Goal:" ++ pr_ev evars (List.hd (sig_it glls)) ++ str"\n"); *)
+(* msg (str"\nOn goal: " ++ pr_ev evars (List.hd (sig_it glls)) ++ str"\n"); *)
(* msg (hov 1 (pptac ++ str" gives: \n" ++ pr_goals lgls ++ str"\n")) *)
(* end; *)
((lgls,v'),pptac) :: aux tacl
with e when Logic.catchable_exception e ->
+(* if !debug then msg (str"failed\n"); *)
aux tacl
in aux l
@@ -185,9 +191,8 @@ module SearchProblem = struct
(str "exact" ++ spc () ++ pr_id id)))
(pf_ids_of_hyps g))
in
- List.map (fun (res,pp) -> { depth = s.depth; tacres = res;
- last_tactic = pp; dblist = s.dblist;
- localdb = List.tl s.localdb }) l
+ List.map (fun (res,pp) -> { s with tacres = res;
+ last_tactic = pp; localdb = List.tl s.localdb }) l
in
let intro_tac =
List.map
@@ -195,32 +200,36 @@ module SearchProblem = struct
let g' = first_goal lgls in
let hintl =
make_resolve_hyp (pf_env g') (project g') (pf_last_hyp g')
- in
-
+ in
let ldb = Hint_db.add_list hintl (match s.localdb with [] -> assert false | hd :: _ -> hd) in
- { depth = s.depth; tacres = res;
- last_tactic = pp; dblist = s.dblist;
- localdb = ldb :: List.tl s.localdb })
+ { s with tacres = res;
+ last_tactic = pp;
+ localdb = ldb :: List.tl s.localdb })
(filter_tactics s.tacres [Tactics.intro,(str "intro")])
in
+ let possible_resolve ((lgls,_) as res, pp) =
+ let nbgl' = List.length (sig_it lgls) in
+ if nbgl' < nbgl then
+ { s with tacres = res; last_tactic = pp;
+ localdb = List.tl s.localdb }
+ else
+ { s with
+ depth = pred s.depth; tacres = res;
+ last_tactic = pp;
+ localdb =
+ list_addn (nbgl'-nbgl) (List.hd s.localdb) s.localdb }
+ in
+(* let custom_tac = *)
+(* List.map possible_resolve *)
+(* (filter_tactics s.tacres [s.custom_tactic,(str "custom_tactic")]) *)
+(* in *)
let rec_tacs =
let l =
filter_tactics s.tacres (e_possible_resolve s.dblist (List.hd s.localdb) (pf_concl g))
in
- List.map
- (fun ((lgls,_) as res, pp) ->
- let nbgl' = List.length (sig_it lgls) in
- if nbgl' < nbgl then
- { depth = s.depth; tacres = res; last_tactic = pp;
- dblist = s.dblist; localdb = List.tl s.localdb }
- else
- { depth = pred s.depth; tacres = res;
- dblist = s.dblist; last_tactic = pp;
- localdb =
- list_addn (nbgl'-nbgl) (match s.localdb with [] -> assert false | hd :: _ -> hd) s.localdb })
- l
+ List.map possible_resolve l
in
- List.sort compare (assumption_tacs @ intro_tac @ rec_tacs)
+ List.sort compare (assumption_tacs @ intro_tac (* @ custom_tac *) @ rec_tacs)
let pp s =
msg (hov 0 (str " depth=" ++ int s.depth ++ spc () ++
@@ -230,43 +239,43 @@ end
module Search = Explore.Make(SearchProblem)
-let make_initial_state n gls dblist localdbs =
+let make_initial_state n gls ~(tac:tactic) dblist localdbs =
{ depth = n;
tacres = gls;
last_tactic = (mt ());
+ custom_tactic = tac;
dblist = dblist;
localdb = localdbs }
-let e_depth_search debug p db_list local_dbs gls =
+let e_depth_search debug s =
try
let tac = if debug then
(SearchProblem.debug := true; Search.debug_depth_first) else Search.depth_first in
- let s = tac (make_initial_state p gls db_list local_dbs) in
+ let s = tac s in
s.tacres
with Not_found -> error "EAuto: depth first search failed"
-let e_breadth_search debug n db_list local_dbs gls =
+let e_breadth_search debug s =
try
let tac =
if debug then Search.debug_breadth_first else Search.breadth_first
- in
- let s = tac (make_initial_state n gls db_list local_dbs) in
- s.tacres
+ in let s = tac s in s.tacres
with Not_found -> error "EAuto: breadth first search failed"
-let e_search_auto debug (in_depth,p) lems db_list gls =
+let e_search_auto ~(tac:tactic) debug (in_depth,p) lems db_list gls =
let sigma = Evd.sig_sig (fst gls) and gls' = Evd.sig_it (fst gls) in
let local_dbs = List.map (fun gl -> make_local_hint_db lems ({it = gl; sigma = sigma})) gls' in
+ let state = make_initial_state p gls ~tac db_list local_dbs in
if in_depth then
- e_depth_search debug p db_list local_dbs gls
+ e_depth_search debug state
else
- e_breadth_search debug p db_list local_dbs gls
+ e_breadth_search debug state
-let full_eauto debug n lems gls =
+let full_eauto ~(tac:tactic) debug n lems gls =
let dbnames = current_db_names () in
let dbnames = list_subtract dbnames ["v62"] in
let db_list = List.map searchtable_map dbnames in
- e_search_auto debug n lems db_list gls
+ e_search_auto ~tac debug n lems db_list gls
exception Found of evar_defs
@@ -294,24 +303,22 @@ let valid evm p res_sigma l =
!res_sigma (l, Evd.create_evar_defs !res_sigma)
in raise (Found (snd evd'))
-let refresh_evi evi =
- { evi with
-(* evar_hyps = Environ.map_named_val Termops.refresh_universes evi.evar_hyps ; *)
- evar_concl = Termops.refresh_universes evi.evar_concl }
-
-let resolve_all_evars_once debug (mode, depth) env p evd =
+let default_evars_tactic =
+ fun x -> raise (UserError ("default_evars_tactic", mt()))
+(* tclFAIL 0 (Pp.mt ()) *)
+
+let resolve_all_evars_once ?(tac=default_evars_tactic) debug (mode, depth) env p evd =
let evm = Evd.evars_of evd in
let goals, evm =
Evd.fold
(fun ev evi (gls, evm) ->
-(* let evi = refresh_evi evi in *)
- (if evi.evar_body = Evar_empty && p ev evi then evi :: gls else gls),
+ (if evi.evar_body = Evar_empty && p ev evi then evi :: gls else gls),
Evd.add evm ev evi)
evm ([], Evd.empty)
in
let gls = { it = List.rev goals; sigma = evm } in
let res_sigma = ref evm in
- let gls', valid' = full_eauto debug (mode, depth) [] (gls, valid evm p res_sigma) in
+ let gls', valid' = full_eauto ~tac debug (mode, depth) [] (gls, valid evm p res_sigma) in
res_sigma := Evarutil.nf_evars (sig_sig gls');
try ignore(valid' []); assert(false) with Found evd' -> Evarutil.nf_evar_defs evd'
@@ -320,7 +327,7 @@ exception FoundTerm of constr
let resolve_one_typeclass env gl =
let gls = { it = [ Evd.make_evar (Environ.named_context_val env) gl ] ; sigma = Evd.empty } in
let valid x = raise (FoundTerm (fst (Refiner.extract_open_proof Evd.empty (List.hd x)))) in
- let gls', valid' = full_eauto false (true, 15) [] (gls, valid) in
+ let gls', valid' = full_eauto ~tac:tclIDTAC false (true, 15) [] (gls, valid) in
try ignore(valid' []); assert false with FoundTerm t -> t
let has_undefined p evd =
@@ -328,10 +335,10 @@ let has_undefined p evd =
(evi.evar_body = Evar_empty && p ev evi))
(Evd.evars_of evd) false
-let rec resolve_all_evars debug m env p evd =
+let rec resolve_all_evars ~(tac:tactic) debug m env p evd =
let rec aux n evd =
if has_undefined p evd && n > 0 then
- let evd' = resolve_all_evars_once debug m env p evd in
+ let evd' = resolve_all_evars_once ~tac debug m env p evd in
aux (pred n) evd'
else evd
in aux 3 evd
@@ -374,8 +381,8 @@ let iff_equiv = lazy (gen_constant ["Classes"; "Relations"] "iff_equivalence")
let eq_equiv = lazy (gen_constant ["Classes"; "SetoidClass"] "eq_equivalence")
(* let coq_relation = lazy (gen_constant ["Relations";"Relation_Definitions"] "relation") *)
-(* let coq_relation = lazy (gen_constant ["Classes";"Relations"] "relation") *)
-let coq_relation a = mkProd (Anonymous, a, mkProd (Anonymous, a, mkProp))
+let coq_relation = lazy (gen_constant ["Classes";"Relations"] "relation")
+let coq_relation a = mkApp (Lazy.force coq_relation, [| a |])
let coq_relationT = lazy (gen_constant ["Classes";"Relations"] "relationT")
let setoid_refl_proj = lazy (gen_constant ["Classes"; "SetoidClass"] "equiv_refl")
@@ -391,9 +398,10 @@ let arrow_morphism a b =
if isprop a && isprop b then
Lazy.force impl
else
- mkLambda (Name (id_of_string "A"), a,
- mkLambda (Name (id_of_string "B"), b,
- mkProd (Anonymous, mkRel 2, mkRel 2)))
+ mkApp(Lazy.force arrow, [|a;b|])
+(* mkLambda (Name (id_of_string "A"), a, *)
+(* mkLambda (Name (id_of_string "B"), b, *)
+(* mkProd (Anonymous, mkRel 2, mkRel 2))) *)
let setoid_refl pars x =
applistc (Lazy.force setoid_refl_proj) (pars @ [x])
@@ -410,7 +418,7 @@ let split_head = function
hd :: tl -> hd, tl
| [] -> assert(false)
-let build_signature isevars env m (cstrs : 'a option list) (f : 'a -> constr) =
+let build_signature isevars env m (cstrs : 'a option list) (finalcstr : 'a option) (f : 'a -> constr) =
let new_evar isevars env t =
Evarutil.e_new_evar isevars env
(* ~src:(dummy_loc, ImplicitArg (ConstRef (Lazy.force respectful), (n, Some na))) *) t
@@ -428,15 +436,14 @@ let build_signature isevars env m (cstrs : 'a option list) (f : 'a -> constr) =
| Prod (na, ty, b), obj :: cstrs ->
let (arg, evars) = aux b cstrs in
let relty = mk_relty ty obj in
- let arg' = mkApp (Lazy.force respectful, [| ty ; relty ; b ; arg |]) in
+ let arg' = mkApp (Lazy.force respectful, [| ty ; b ; relty ; arg |]) in
arg', (ty, relty) :: evars
- | _, [finalcstr] ->
+ | _, _ ->
(match finalcstr with
None ->
let rel = mk_relty t None in
rel, [t, rel]
| Some (t, rel) -> rel, [t, rel])
- | _, _ -> assert false
in aux m cstrs
let reflexivity_proof_evar env evars carrier relation x =
@@ -463,7 +470,7 @@ let reflexive_proof env = find_class_proof reflexive_type reflexive_proof env
let symmetric_proof env = find_class_proof symmetric_type symmetric_proof env
let transitive_proof env = find_class_proof transitive_type transitive_proof env
-let resolve_morphism env sigma oldt m args args' cstr evars =
+let resolve_morphism env sigma oldt m ?(fnewt=fun x -> x) args args' cstr evars =
let (morphism_cl, morphism_proj) = Lazy.force morphism_class_proj in
let morph_instance, proj, sigargs, m', args, args' =
(* if is_equiv env sigma m then *)
@@ -489,7 +496,7 @@ let resolve_morphism env sigma oldt m args args' cstr evars =
let appm = mkApp(m, morphargs) in
let appmtype = Typing.type_of env sigma appm in
let cstrs = List.map (function None -> None | Some (_, (a, r, _, _)) -> Some (a, r)) (Array.to_list morphobjs') in
- let signature, sigargs = build_signature evars env appmtype (cstrs @ [cstr]) (fun (a, r) -> r) in
+ let signature, sigargs = build_signature evars env appmtype cstrs cstr (fun (a, r) -> r) in
let cl_args = [| appmtype ; signature ; appm |] in
let app = mkApp (mkInd morphism_cl.cl_impl, cl_args) in
let morph = Evarutil.e_new_evar evars env app in
@@ -514,7 +521,7 @@ let resolve_morphism env sigma oldt m args args' cstr evars =
let proof = applistc proj (List.rev projargs) in
let newt = applistc m' (List.rev typeargs) in
match respars with
- [ a, r ] -> (proof, (a, r, oldt, newt))
+ [ a, r ] -> (proof, (a, r, oldt, fnewt newt))
| _ -> assert(false)
(* Adapted from setoid_replace. *)
@@ -618,9 +625,14 @@ let unify_eqn gl hypinfo t =
let unfold_impl t =
match kind_of_term t with
- | App (arrow, [| a; b |]) when eq_constr arrow (Lazy.force impl) ->
+ | App (arrow, [| a; b |])(* when eq_constr arrow (Lazy.force impl) *) ->
mkProd (Anonymous, a, b)
- | _ -> t
+ | _ -> assert false
+
+let unfold_id t =
+ match kind_of_term t with
+ | App (id, [| a; b |]) (* when eq_constr id (Lazy.force coq_id) *) -> b
+ | _ -> assert false
let build_new gl env sigma occs hypinfo concl cstr evars =
let is_occ occ = occs = [] || List.mem occ occs in
@@ -635,10 +647,10 @@ let build_new gl env sigma occs hypinfo concl cstr evars =
let (car, r, orig, dest) = hypinfo in
let res =
try
- Some (resolve_morphism env sigma t
- (mkLambda (Name (id_of_string "x"), car, mkRel 1))
- (* (Termops.refresh_universes (mkApp (Lazy.force coq_id, [| car |]))) *)
- [| orig |] [| Some x |] cstr evars)
+ Some
+ (resolve_morphism env sigma t ~fnewt:unfold_id
+ (mkApp (Lazy.force coq_id, [| car |]))
+ [| orig |] [| Some x |] cstr evars)
with Not_found -> None
in res, succ occ)
else None, succ occ
@@ -665,13 +677,10 @@ let build_new gl env sigma occs hypinfo concl cstr evars =
if x' = None && b' = None then None
else
(try
- let (proof, (a, r, oldt, newt)) =
- resolve_morphism env sigma t
- (arrow_morphism (pf_type_of gl x) (pf_type_of gl b)) [| x ; b |] [| x' ; b' |]
- cstr evars
- in
- let newt' = unfold_impl newt in
- Some (proof, (a, r, oldt, newt'))
+ Some (resolve_morphism env sigma t
+ ~fnewt:unfold_impl
+ (arrow_morphism (pf_type_of gl x) (pf_type_of gl b)) [| x ; b |] [| x' ; b' |]
+ cstr evars)
with Not_found -> None)
in res, occ
@@ -682,6 +691,21 @@ let resolve_all_typeclasses env evd =
resolve_all_evars false (true, 15) env
(fun ev evi -> Typeclasses.class_of_constr evi.Evd.evar_concl <> None) evd
+let resolve_argument_typeclasses ?(tac=tclIDTAC) d p env evd onlyargs all =
+ let pred =
+ if onlyargs then
+ (fun ev evi -> Typeclasses.is_implicit_arg (snd (Evd.evar_source ev evd)) &&
+ class_of_constr evi.Evd.evar_concl <> None)
+ else
+ (fun ev evi -> class_of_constr evi.Evd.evar_concl <> None)
+ in
+ try
+ resolve_all_evars ~tac d p env pred evd
+ with e ->
+ if all then raise e else evd
+
+let cl_rewrite_tactic = lazy (Tacinterp.interp <:tactic<setoid_rewrite_tac>>)
+
let cl_rewrite_clause_aux hypinfo goal_meta occs clause gl =
let concl, is_hyp =
match clause with
@@ -797,19 +821,6 @@ let pr_depth _prc _prlc _prt = function
ARGUMENT EXTEND depth TYPED AS int option PRINTED BY pr_depth
| [ int_or_var_opt(v) ] -> [ match v with Some (ArgArg i) -> Some i | _ -> None ]
END
-
-let resolve_argument_typeclasses d p env evd onlyargs all =
- let pred =
- if onlyargs then
- (fun ev evi -> Typeclasses.is_implicit_arg (snd (Evd.evar_source ev evd)) &&
- class_of_constr evi.Evd.evar_concl <> None)
- else
- (fun ev evi -> class_of_constr evi.Evd.evar_concl <> None)
- in
- try
- resolve_all_evars d p env pred evd
- with e ->
- if all then raise e else evd
VERNAC COMMAND EXTEND Typeclasses_Settings
| [ "Typeclasses" "eauto" ":=" debug(d) search_mode(s) depth(depth) ] -> [
@@ -995,7 +1006,7 @@ let declare_projection n instance_id r =
let n =
let rec aux t =
match kind_of_term t with
- App (f, [| a ; rel; a'; rel' |]) when eq_constr f (Lazy.force respectful) ->
+ App (f, [| a ; a' ; rel; rel' |]) when eq_constr f (Lazy.force respectful) ->
succ (aux rel')
| _ -> 0
in
@@ -1027,10 +1038,10 @@ let build_morphism_signature m =
match kind_of_term t with
| Prod (na, a, b) ->
None :: aux b
- | _ -> [None]
+ | _ -> []
in aux t
in
- let sig_, evars = build_signature isevars env t cstrs snd in
+ let sig_, evars = build_signature isevars env t cstrs None snd in
let _ = List.iter
(fun (ty, rel) ->
let default = mkApp (Lazy.force default_relation, [| ty; rel |]) in
@@ -1048,10 +1059,10 @@ let default_morphism sign m =
let env = Global.env () in
let isevars = ref (Evd.create_evar_defs Evd.empty) in
let t = Typing.type_of env Evd.empty m in
- let sign, evars =
- build_signature isevars env t sign (fun (ty, rel) -> rel)
+ let sign, evars =
+ build_signature isevars env t (fst sign) (snd sign) (fun (ty, rel) -> rel)
in
- let morph =
+ let morph =
mkApp (mkInd (Lazy.force morphism_class).cl_impl, [| t; sign; m |])
in
let mor = resolve_one_typeclass env morph in