aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcoq2002-10-01 07:53:07 +0000
committercoq2002-10-01 07:53:07 +0000
commit02f6cb08e4b8f892594934766a40413a3fa30342 (patch)
tree6c8e85d78ffbad43aa579ec3612cb93b14f1b4b2
parente6afa737d4bcc1c7973cd46094e824b875fede11 (diff)
Vraie substitutivite de autohints
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@3055 85f007b7-540e-0410-9357-904b9bb8a0f7
-rw-r--r--pretyping/cases.ml2
-rw-r--r--pretyping/pattern.ml64
-rw-r--r--pretyping/pattern.mli4
-rw-r--r--proofs/clenv.ml14
-rw-r--r--proofs/clenv.mli3
-rw-r--r--tactics/auto.ml88
6 files changed, 143 insertions, 32 deletions
diff --git a/pretyping/cases.ml b/pretyping/cases.ml
index c552be7d6e..4c6e5bb014 100644
--- a/pretyping/cases.ml
+++ b/pretyping/cases.ml
@@ -1148,7 +1148,7 @@ let specialize_predicate tomatchs deps cs = function
let pred'' = subst_predicate (argsi, copti) pred' in
(* We adjust pred st: gamma, x1..xn, x1..xn |- pred'' *)
let pred''' = liftn_predicate n (n+1) pred'' in
- (* We finally get gamma,x1..xn |- [X1,x1:=R1,x1]..[Xn,xn:=Rn,xn]pred'''*)
+ (* We finally get gamma,x1..xn |- [X1,x1:=R1,x1]..[Xn,xn:=Rn,xn]pred''' *)
snd (List.fold_right2 (expand_arg n) tomatchs deps (n,pred'''))
diff --git a/pretyping/pattern.ml b/pretyping/pattern.ml
index bde1f31bd3..6d79b9d28d 100644
--- a/pretyping/pattern.ml
+++ b/pretyping/pattern.ml
@@ -49,6 +49,57 @@ let rec occur_meta_pattern = function
| PMeta _ | PSoApp _ -> true
| PEvar _ | PVar _ | PRef _ | PRel _ | PSort _ | PFix _ | PCoFix _ -> false
+let rec subst_pattern subst pat = match pat with
+ | PRef ref ->
+ let ref' = subst_global subst ref in
+ if ref' == ref then pat else
+ PRef ref'
+ | PVar _
+ | PEvar _
+ | PRel _ -> pat
+ | PApp (f,args) ->
+ let f' = subst_pattern subst f in
+ let args' = array_smartmap (subst_pattern subst) args in
+ if f' == f && args' == args then pat else
+ PApp (f',args')
+ | PSoApp (i,args) ->
+ let args' = list_smartmap (subst_pattern subst) args in
+ if args' == args then pat else
+ PSoApp (i,args')
+ | PLambda (name,c1,c2) ->
+ let c1' = subst_pattern subst c1 in
+ let c2' = subst_pattern subst c2 in
+ if c1' == c1 && c2' == c2 then pat else
+ PLambda (name,c1',c2')
+ | PProd (name,c1,c2) ->
+ let c1' = subst_pattern subst c1 in
+ let c2' = subst_pattern subst c2 in
+ if c1' == c1 && c2' == c2 then pat else
+ PProd (name,c1',c2')
+ | PLetIn (name,c1,c2) ->
+ let c1' = subst_pattern subst c1 in
+ let c2' = subst_pattern subst c2 in
+ if c1' == c1 && c2' == c2 then pat else
+ PLetIn (name,c1',c2')
+ | PSort _
+ | PMeta _ -> pat
+ | PCase (typ, c, branches) ->
+ let typ' = option_smartmap (subst_pattern subst) typ in
+ let c' = subst_pattern subst c in
+ let branches' = array_smartmap (subst_pattern subst) branches in
+ if typ' == typ && c' == c && branches' == branches then pat else
+ PCase(typ', c', branches')
+ | PFix fixpoint ->
+ let cstr = mkFix fixpoint in
+ let fixpoint' = destFix (subst_mps subst cstr) in
+ if fixpoint' == fixpoint then pat else
+ PFix fixpoint'
+ | PCoFix cofixpoint ->
+ let cstr = mkCoFix cofixpoint in
+ let cofixpoint' = destCoFix (subst_mps subst cstr) in
+ if cofixpoint' == cofixpoint then pat else
+ PCoFix cofixpoint'
+
type constr_label =
| ConstNode of constant
| IndNode of inductive
@@ -63,6 +114,19 @@ let label_of_ref = function
| ConstructRef sp -> CstrNode sp
| VarRef id -> VarNode id
+let ref_of_label = function
+ | ConstNode sp -> ConstRef sp
+ | IndNode sp -> IndRef sp
+ | CstrNode sp -> ConstructRef sp
+ | VarNode id -> VarRef id
+
+let subst_label subst cstl =
+ let ref = ref_of_label cstl in
+ let ref' = subst_global subst ref in
+ if ref' == ref then cstl else
+ label_of_ref ref'
+
+
let rec head_pattern_bound t =
match t with
| PProd (_,_,b) -> head_pattern_bound b
diff --git a/pretyping/pattern.mli b/pretyping/pattern.mli
index 5ff667f90b..943a8d8c3d 100644
--- a/pretyping/pattern.mli
+++ b/pretyping/pattern.mli
@@ -35,6 +35,8 @@ type constr_pattern =
val occur_meta_pattern : constr_pattern -> bool
+val subst_pattern : substitution -> constr_pattern -> constr_pattern
+
type constr_label =
| ConstNode of constant
| IndNode of inductive
@@ -43,6 +45,8 @@ type constr_label =
val label_of_ref : global_reference -> constr_label
+val subst_label : substitution -> constr_label -> constr_label
+
exception BoundPattern
(* [head_pattern_bound t] extracts the head variable/constant of the
diff --git a/proofs/clenv.ml b/proofs/clenv.ml
index 44c5aafb08..1a527cbeaa 100644
--- a/proofs/clenv.ml
+++ b/proofs/clenv.ml
@@ -377,6 +377,20 @@ let mk_clenv_from_n wc n (c,cty) =
let mk_clenv_from wc = mk_clenv_from_n wc None
+let map_fl f cfl = { cfl with rebus=f cfl.rebus }
+
+let map_clb f = function
+ | Cltyp cfl -> Cltyp (map_fl f cfl)
+ | Clval (cfl1,cfl2) -> Clval (map_fl f cfl1,map_fl f cfl2)
+
+let subst_clenv f sub clenv =
+ { templval = map_fl (subst_mps sub) clenv.templval;
+ templtyp = map_fl (subst_mps sub) clenv.templtyp;
+ namenv = clenv.namenv;
+ env = Intmap.map (map_clb (subst_mps sub)) clenv.env;
+ hook = f sub clenv.hook }
+
+
let connect_clenv wc clenv =
{ templval = clenv.templval;
templtyp = clenv.templtyp;
diff --git a/proofs/clenv.mli b/proofs/clenv.mli
index 54334c45a0..efd8dc302c 100644
--- a/proofs/clenv.mli
+++ b/proofs/clenv.mli
@@ -67,6 +67,9 @@ val mk_clenv_rename_from_n : wc -> int option -> constr * constr -> wc clausenv
val mk_clenv_hnf_constr_type_of : wc -> constr -> wc clausenv
val mk_clenv_type_of : wc -> constr -> wc clausenv
+val subst_clenv : (substitution -> 'a -> 'a) ->
+ substitution -> 'a clausenv -> 'a clausenv
+
val connect_clenv : wc -> 'a clausenv -> wc clausenv
val clenv_change_head : constr * constr -> 'a clausenv -> 'a clausenv
val clenv_assign : int -> constr -> 'a clausenv -> 'a clausenv
diff --git a/tactics/auto.ml b/tactics/auto.ml
index 4f8c81c704..ade0b02212 100644
--- a/tactics/auto.ml
+++ b/tactics/auto.ml
@@ -266,8 +266,6 @@ open Vernacexpr
(* declaration of the AUTOHINT library object *)
(**************************************************************************)
-let eager = Lazy.lazy_from_val
-
(* If the database does not exist, it is created *)
(* TODO: should a warning be printed in this case ?? *)
let add_hint dbname hintlist =
@@ -279,11 +277,9 @@ let add_hint dbname hintlist =
let db = Hint_db.add_list hintlist Hint_db.empty in
searchtable_add (dbname,db)
-let cache_autohint (_,(name,l_hintlist)) =
- try add_hint name (Lazy.force l_hintlist) with _ -> anomaly "Auto.add_hint"
+let cache_autohint (_,(name,hintlist)) = add_hint name hintlist
-let subst_autohint (_,subst,((name,l_hintlist) as obj)) =
- let recalc_hints hintlist =
+(* let recalc_hints hintlist =
let env = Global.env() and sigma = Evd.empty in
let recalc_hint ((_,data) as hint) =
match data.code with
@@ -313,19 +309,52 @@ let subst_autohint (_,subst,((name,l_hintlist) as obj)) =
anomaly "Extern hints cannot be substituted!!!"
in
list_smartmap recalc_hint hintlist
+*)
+
+let subst_autohint (_,subst,(name,hintlist as obj)) =
+ let trans_clenv clenv = Clenv.subst_clenv (fun _ a -> a) subst clenv in
+ let trans_data data code =
+ { data with
+ pat = option_smartmap (subst_pattern subst) data.pat ;
+ code = code ;
+ }
in
- let hintlist = Lazy.force l_hintlist in
- try
- let hintlist' = recalc_hints hintlist in
- if hintlist'==hintlist then
- obj
- else
- (name,eager hintlist')
- with
- _ -> (name,lazy (recalc_hints hintlist))
-
-let classify_autohint (_,((name,l_hintlist) as obj)) =
- match Lazy.force l_hintlist with
+ let subst_hint (lab,data as hint) =
+ let lab' = subst_label subst lab in
+ let data' = match data.code with
+ | Res_pf (c, clenv) ->
+ let c' = Term.subst_mps subst c in
+ if c==c' then data else
+ trans_data data (Res_pf (c', trans_clenv clenv))
+ | ERes_pf (c, clenv) ->
+ let c' = Term.subst_mps subst c in
+ if c==c' then data else
+ trans_data data (ERes_pf (c', trans_clenv clenv))
+ | Give_exact c ->
+ let c' = Term.subst_mps subst c in
+ if c==c' then data else
+ trans_data data (Give_exact c')
+ | Res_pf_THEN_trivial_fail (c, clenv) ->
+ let c' = Term.subst_mps subst c in
+ if c==c' then data else
+ let code' = Res_pf_THEN_trivial_fail (c', trans_clenv clenv) in
+ trans_data data code'
+ | Unfold_nth ref ->
+ let ref' = subst_global subst ref in
+ if ref==ref' then data else
+ trans_data data (Unfold_nth ref')
+ | Extern _ ->
+ anomaly "Extern hints cannot be substituted!!!"
+ in
+ if lab' == lab && data' == data then hint else
+ (lab',data')
+ in
+ let hintlist' = list_smartmap subst_hint hintlist in
+ if hintlist' == hintlist then obj else
+ (name,hintlist')
+
+let classify_autohint (_,((name,hintlist) as obj)) =
+ match hintlist with
[] -> Dispose
| (_,{code=Extern _})::_ -> Keep obj (* TODO! should be changed *)
| _ -> Substitute obj
@@ -350,16 +379,13 @@ let add_resolves env sigma clist dbnames =
Lib.add_anonymous_leaf
(inAutoHint
(dbname,
- let l =
- List.flatten
- (List.map
- (fun (name,c) ->
- let ty = type_of env sigma c in
- let verbose = Options.is_verbose() in
- make_resolves env sigma name (true,verbose) (c,ty)) clist
- )
- in
- eager l
+ List.flatten
+ (List.map
+ (fun (name,c) ->
+ let ty = type_of env sigma c in
+ let verbose = Options.is_verbose() in
+ make_resolves env sigma name (true,verbose) (c,ty)) clist
+ )
)))
dbnames
@@ -367,7 +393,7 @@ let add_resolves env sigma clist dbnames =
let add_unfolds l dbnames =
List.iter
(fun dbname -> Lib.add_anonymous_leaf
- (inAutoHint (dbname, eager (List.map make_unfold l))))
+ (inAutoHint (dbname, List.map make_unfold l)))
dbnames
@@ -384,7 +410,7 @@ let add_extern name pri (patmetas,pat) tacast dbname =
(str "The meta-variable ?" ++ int i ++ str" is not bound")
| [] ->
Lib.add_anonymous_leaf
- (inAutoHint(dbname, eager [make_extern name pri pat tacast]))
+ (inAutoHint(dbname, [make_extern name pri pat tacast]))
let add_externs name pri pat tacast dbnames =
List.iter (add_extern name pri pat tacast) dbnames
@@ -394,7 +420,7 @@ let add_trivials env sigma l dbnames =
List.iter
(fun dbname ->
Lib.add_anonymous_leaf (
- inAutoHint(dbname, eager (List.map (make_trivial env sigma) l))))
+ inAutoHint(dbname, List.map (make_trivial env sigma) l)))
dbnames