aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--parsing/astterm.ml22
-rw-r--r--parsing/termast.ml10
-rw-r--r--pretyping/classops.mli2
-rw-r--r--pretyping/detyping.ml12
-rw-r--r--pretyping/pretyping.ml3
-rw-r--r--pretyping/rawterm.ml5
-rw-r--r--pretyping/rawterm.mli4
-rw-r--r--tactics/equality.ml134
-rw-r--r--tactics/pattern.ml132
-rw-r--r--tactics/pattern.mli29
-rw-r--r--tactics/tacticals.ml7
-rw-r--r--tactics/tacticals.mli2
12 files changed, 186 insertions, 176 deletions
diff --git a/parsing/astterm.ml b/parsing/astterm.ml
index fd32cda39..dd2f1b5d8 100644
--- a/parsing/astterm.ml
+++ b/parsing/astterm.ml
@@ -90,12 +90,14 @@ let ident_of_nvar loc s =
user_err_loc (loc,"ident_of_nvar", [< 'sTR "Unexpected wildcard" >])
else (id_of_string s)
+(*
let rctxt_of_ctxt =
Array.map
(function
| VAR id -> RRef (dummy_loc,RVar id)
| _ ->
error "Astterm: arbitrary substitution of references not yet implemented")
+*)
let ids_of_ctxt ctxt =
Array.to_list
@@ -119,7 +121,9 @@ let dbize_ctxt ctxt =
let l =
List.map
(function
- | Nvar (loc,s) -> RRef (dummy_loc,RVar (ident_of_nvar loc s))
+ | Nvar (loc,s) ->
+ (* RRef (dummy_loc,RVar (ident_of_nvar loc s)) *)
+ VAR (ident_of_nvar loc s)
| _ -> anomaly "Bad ast for local ctxt of a global reference") ctxt
in
Array.of_list l
@@ -139,10 +143,10 @@ let dbize_global loc = function
[< 'sTR "Bad ast for this global a reference">])
let ref_from_constr = function
- | DOPN (Const sp,ctxt) -> RConst (sp,rctxt_of_ctxt ctxt)
- | DOPN (Evar ev,ctxt) -> REVar (ev,rctxt_of_ctxt ctxt)
- | DOPN (MutConstruct (spi,j),ctxt) -> RConstruct ((spi,j),rctxt_of_ctxt ctxt)
- | DOPN (MutInd (sp,i),ctxt) -> RInd ((sp,i),rctxt_of_ctxt ctxt)
+ | DOPN (Const sp,ctxt) -> RConst (sp, ctxt)
+ | DOPN (Evar ev,ctxt) -> REVar (ev, ctxt)
+ | DOPN (MutConstruct (spi,j),ctxt) -> RConstruct ((spi,j), ctxt)
+ | DOPN (MutInd (sp,i),ctxt) -> RInd ((sp,i), ctxt)
| VAR id -> RVar id (* utilisé dans trad pour coe_value (tmp) *)
| _ -> anomaly "Not a reference"
@@ -561,10 +565,10 @@ let ctxt_of_ids ids =
Array.of_list (List.map (function id -> VAR id) ids)
let rec pat_of_ref metas vars = function
- | RConst (sp,ctxt) -> RConst (sp, Array.map (pat_of_raw metas vars) ctxt)
- | RInd (ip,ctxt) -> RInd (ip, Array.map (pat_of_raw metas vars) ctxt)
- | RConstruct(cp,ctxt) ->RConstruct(cp,Array.map (pat_of_raw metas vars) ctxt)
- | REVar (n,ctxt) -> REVar (n,Array.map (pat_of_raw metas vars) ctxt)
+ | RConst (sp,ctxt) -> RConst (sp, ctxt)
+ | RInd (ip,ctxt) -> RInd (ip, ctxt)
+ | RConstruct(cp,ctxt) ->RConstruct(cp, ctxt)
+ | REVar (n,ctxt) -> REVar (n, ctxt)
| RMeta n -> RMeta n
| RAbst _ -> error "pattern_of_rawconstr: not implemented"
| RVar _ -> assert false (* Capturé dans pattern_of_raw *)
diff --git a/parsing/termast.ml b/parsing/termast.ml
index bcdc21f05..3587ba01e 100644
--- a/parsing/termast.ml
+++ b/parsing/termast.ml
@@ -50,6 +50,7 @@ let with_coercions f = with_option print_coercions f
(**********************************************************************)
(* conversion of references *)
+(*
let ids_of_rctxt ctxt =
Array.to_list
(Array.map
@@ -59,6 +60,7 @@ let ids_of_rctxt ctxt =
error
"Termast: arbitrary substitution of references not yet implemented")
ctxt)
+*)
let ids_of_ctxt ctxt =
Array.to_list
@@ -122,14 +124,14 @@ let ast_of_inductive_ref ((sp,tyi) as ind_sp,ids) =
let ast_of_inductive (ev,ctxt) = ast_of_inductive_ref (ev,ids_of_ctxt ctxt)
let ast_of_ref = function
- | RConst (sp,ctxt) -> ast_of_constant_ref (sp,ids_of_rctxt ctxt)
+ | RConst (sp,ctxt) -> ast_of_constant_ref (sp,ids_of_ctxt ctxt)
| RAbst (sp) ->
ope("ABST", (path_section dummy_loc sp)
::(List.map ast_of_ident (* on triche *) []))
- | RInd (ind,ctxt) -> ast_of_inductive_ref (ind,ids_of_rctxt ctxt)
- | RConstruct (cstr,ctxt) -> ast_of_constructor_ref (cstr,ids_of_rctxt ctxt)
+ | RInd (ind,ctxt) -> ast_of_inductive_ref (ind,ids_of_ctxt ctxt)
+ | RConstruct (cstr,ctxt) -> ast_of_constructor_ref (cstr,ids_of_ctxt ctxt)
| RVar id -> nvar (string_of_id id)
- | REVar (ev,ctxt) -> ast_of_existential_ref (ev,ids_of_rctxt ctxt)
+ | REVar (ev,ctxt) -> ast_of_existential_ref (ev,ids_of_ctxt ctxt)
| RMeta n -> ope("META",[num n])
(**********************************************************************)
diff --git a/pretyping/classops.mli b/pretyping/classops.mli
index 98d6fce9c..ab9410cc6 100644
--- a/pretyping/classops.mli
+++ b/pretyping/classops.mli
@@ -53,7 +53,7 @@ val coercion_exists : coe_typ -> bool
val coercion_info : coe_typ -> (int * coe_info_typ)
val coercion_info_from_index : int -> coe_typ * coe_info_typ
val coercion_params :
- rawconstr array reference -> int (* raise [Not_found] if not a coercion *)
+ 'a array reference -> int (* raise [Not_found] if not a coercion *)
val constructor_at_head : constr -> cl_typ * int
(* raises [Not_found] if not convertible to a class *)
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index 2dd49e4b7..a7c84dd3c 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -315,17 +315,13 @@ let rec detype avoid env t =
| IsAppL (f,args) ->
RApp (dummy_loc,detype avoid env f,List.map (detype avoid env) args)
| IsConst (sp,cl) ->
- RRef(dummy_loc,RConst(sp,Array.map (detype avoid env) cl))
+ RRef(dummy_loc,RConst(sp,cl))
| IsEvar (ev,cl) ->
- RRef(dummy_loc,REVar(ev,Array.map (detype avoid env) cl))
+ RRef(dummy_loc,REVar(ev,cl))
| IsAbst (sp,cl) ->
anomaly "bdize: Abst should no longer occur in constr"
- | IsMutInd (ind_sp,cl) ->
- let ctxt = Array.map (detype avoid env) cl in
- RRef (dummy_loc,RInd (ind_sp,ctxt))
- | IsMutConstruct (cstr_sp,cl) ->
- let ctxt = Array.map (detype avoid env) cl in
- RRef (dummy_loc,RConstruct (cstr_sp,ctxt))
+ | IsMutInd (ind_sp,cl) -> RRef (dummy_loc,RInd (ind_sp,cl))
+ | IsMutConstruct (cstr_sp,cl) -> RRef (dummy_loc,RConstruct (cstr_sp,cl))
| IsMutCase (annot,p,c,bl) ->
let synth_type = synthetize_type () in
let tomatch = detype avoid env c in
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index 5a1a9df46..609567771 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -144,12 +144,15 @@ let transform_rec loc env sigma cl (ct,pt) =
(***********************************************************************)
+(*
let ctxt_of_ids ids =
Array.map
(function
| RRef (_,RVar id) -> VAR id
| _ -> error "pretyping: arbitrary subst of ref not implemented")
ids
+*)
+let ctxt_of_ids cl = cl
let mt_evd = Evd.empty
diff --git a/pretyping/rawterm.ml b/pretyping/rawterm.ml
index ab3075f45..4090e5815 100644
--- a/pretyping/rawterm.ml
+++ b/pretyping/rawterm.ml
@@ -32,8 +32,9 @@ type 'ctxt reference =
| REVar of int * 'ctxt
| RMeta of int
+(*i Pas beau ce constr dans rawconstr, mais mal compris ce ctxt des ref i*)
type rawconstr =
- | RRef of loc * rawconstr array reference
+ | RRef of loc * Term.constr array reference
| RApp of loc * rawconstr * rawconstr list
| RBinder of loc * binder_kind * name * rawconstr * rawconstr
| RCases of loc * Term.case_style * rawconstr option * rawconstr list *
@@ -73,7 +74,7 @@ let loc_of_rawconstr = function
| RCast (loc,_,_) -> loc
type constr_pattern =
- | PRef of constr_pattern array reference
+ | PRef of Term.constr array reference
| PRel of int
| PApp of constr_pattern * constr_pattern array
| PSoApp of int * int list
diff --git a/pretyping/rawterm.mli b/pretyping/rawterm.mli
index f78520a16..5f67a8a92 100644
--- a/pretyping/rawterm.mli
+++ b/pretyping/rawterm.mli
@@ -32,7 +32,7 @@ type 'ctxt reference =
| RMeta of int
type rawconstr =
- | RRef of loc * rawconstr array reference
+ | RRef of loc * Term.constr array reference
| RApp of loc * rawconstr * rawconstr list
| RBinder of loc * binder_kind * name * rawconstr * rawconstr
| RCases of loc * Term.case_style * rawconstr option * rawconstr list *
@@ -61,7 +61,7 @@ val dummy_loc : loc
val loc_of_rawconstr : rawconstr -> loc
type constr_pattern =
- | PRef of constr_pattern array reference
+ | PRef of Term.constr array reference
| PRel of int
| PApp of constr_pattern * constr_pattern array
| PSoApp of int * int list
diff --git a/tactics/equality.ml b/tactics/equality.ml
index 1880b5a09..ff62150a0 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -173,10 +173,10 @@ let find_constructor env sigma c =
| _ -> error "find_constructor"
type leibniz_eq = {
- eq : marked_pattern;
- ind : marked_pattern;
+ eq : marked_term;
+ ind : marked_term;
rrec : marked_pattern option;
- rect : marked_pattern option;
+ rect : marked_term option;
congr: marked_pattern;
sym : marked_pattern }
@@ -187,21 +187,24 @@ let eq_pattern = put_pat mmk "(eq ? ? ?)"
let not_pattern = put_pat mmk "(not ?)"
let imp_False_pattern = put_pat mmk "? -> False"
-let pat_True = put_pat mmk "True"
-let pat_False = put_pat mmk "False"
-let pat_I = put_pat mmk "I"
-
-let eq= { eq = put_pat mmk "eq";
- ind = put_pat mmk "eq_ind" ;
+let eq= { eq = put_squel mmk "eq";
+ ind = put_squel mmk "eq_ind" ;
rrec = Some (put_pat mmk "eq_rec");
- rect = Some (put_pat mmk "eq_rect");
+ rect = Some (put_squel mmk "eq_rect");
congr = put_pat mmk "f_equal" ;
sym = put_pat mmk "sym_eq" }
+
+let build_eq eq = get_squel eq.eq
+let build_ind eq = get_squel eq.ind
+let build_rect eq =
+ match eq.rect with
+ | None -> assert false
+ | Some sq -> get_squel sq
let eqT_pattern = put_pat mmk "(eqT ? ? ?)"
-let eqT= { eq = put_pat mmk "eqT";
- ind = put_pat mmk "eqT_ind" ;
+let eqT= { eq = put_squel mmk "eqT";
+ ind = put_squel mmk "eqT_ind" ;
rrec = None;
rect = None;
congr = put_pat mmk "congr_eqT" ;
@@ -209,16 +212,33 @@ let eqT= { eq = put_pat mmk "eqT";
let idT_pattern = put_pat mmk "(identityT ? ? ?)"
-let idT = { eq = put_pat mmk "identityT";
- ind = put_pat mmk "identityT_ind" ;
+let idT = { eq = put_squel mmk "identityT";
+ ind = put_squel mmk "identityT_ind" ;
rrec = Some (put_pat mmk "identityT_rec") ;
- rect = Some (put_pat mmk "identityT_rect");
+ rect = Some (put_squel mmk "identityT_rect");
congr = put_pat mmk "congr_idT" ;
sym = put_pat mmk "sym_idT" }
+(* List of constructions depending of the initial state *)
+
+(* Initialisation part *)
+let squel_EmptyT = put_squel mmk "EmptyT"
+let squel_True = put_squel mmk "True"
+let squel_False = put_squel mmk "False"
+let squel_UnitT = put_squel mmk "UnitT"
+let squel_IT = put_squel mmk "IT"
+let squel_I = put_squel mmk "I"
+
+(* Runtime part *)
+let build_EmptyT () = get_squel squel_EmptyT
+let build_True () = get_squel squel_True
+let build_False () = get_squel squel_False
+let build_UnitT () = get_squel squel_UnitT
+let build_IT () = get_squel squel_IT
+let build_I () = get_squel squel_I
+
+let pat_False = put_pat mmk "False"
let pat_EmptyT = put_pat mmk "EmptyT"
-let pat_UnitT = put_pat mmk "UnitT"
-let pat_IT = put_pat mmk "IT"
let notT_pattern = put_pat mmk "(notT ?)"
let rec hd_of_prod prod =
@@ -253,14 +273,14 @@ let necessary_elimination sort_arity sort =
[< 'sTR "no primitive equality on proofs" >]
let find_eq_pattern aritysort sort =
- let mt =
+(* let mt =*)
match necessary_elimination aritysort sort with
| Set_Type -> eq.eq
| Type_Type -> idT.eq
| Set_SetorProp -> eq.eq
| Type_SetorProp -> eqT.eq
- in
- get_pat mt
+(* in
+ get_pat mt*)
(* [find_positions t1 t2]
@@ -468,12 +488,11 @@ let construct_discriminator sigma env dirn c sort =
let (true_0,false_0,sort_0) =
match necessary_elimination arsort (destSort sort) with
| Type_Type ->
- get_pat pat_UnitT, get_pat pat_EmptyT,
+ build_UnitT (), build_EmptyT (),
(DOP0(Sort (Type(dummy_univ))))
| _ ->
- get_pat pat_True, get_pat pat_False, (DOP0(Sort (Prop Null)))
+ build_True (), build_False (), (DOP0(Sort (Prop Null)))
in
- let eq = find_eq_pattern arsort (destSort sort) in
let p = lam_it sort_0 arsign in
let bty,_ = type_case_branches env sigma indspec (type_of env sigma p) p c in
let build_branch i =
@@ -500,8 +519,10 @@ let rec build_discriminator sigma env dirn c sort = function
let subval = build_discriminator sigma cnum_env dirn newc sort l in
(match necessary_elimination arsort (destSort sort) with
| Type_Type ->
- kont subval (get_pat pat_EmptyT,DOP0(Sort(Type(dummy_univ))))
- | _ -> kont subval (get_pat pat_False,DOP0(Sort(Prop Null))))
+ kont subval (build_EmptyT (),DOP0(Sort(Type(dummy_univ))))
+ | _ -> kont subval (build_False ()
+
+,DOP0(Sort(Prop Null))))
| _ -> assert false
let dest_somatch_eq eqn eq_pat =
@@ -546,11 +567,10 @@ let discrimination_pf e (t,t1,t2) discriminator lbeq gls =
let sort = pf_type_of gls (pf_concl gls) in
match necessary_elimination (destSort(hd_of_prod arity)) (destSort sort) with
| Type_Type ->
- let rect = match lbeq.rect with Some x -> x | _ -> assert false in
- let eq_elim = get_pat rect in
- let eq_term = get_pat lbeq.eq in
- let i = get_pat pat_IT in
- let absurd_term = get_pat pat_EmptyT in
+ let eq_elim = build_rect lbeq in
+ let eq_term = build_eq lbeq in
+ let i = build_IT () in
+ let absurd_term = build_EmptyT () in
let h = pf_get_new_id (id_of_string "HH")gls in
let pred= mkNamedLambda e t
(mkNamedLambda h (applist (eq_term, [t;t1;(Rel 1)]))
@@ -558,9 +578,11 @@ let discrimination_pf e (t,t1,t2) discriminator lbeq gls =
in (applist(eq_elim, [t;t1;pred;i;t2]), absurd_term)
| _ ->
- let i = get_pat pat_I in
- let absurd_term = get_pat pat_False in
- let eq_elim = get_pat lbeq.ind in
+ let i = build_I () in
+ let absurd_term = build_False ()
+
+ in
+ let eq_elim = build_ind lbeq in
(applist (eq_elim, [t;t1;mkNamedLambda e t discriminator;i;t2]),
absurd_term)
@@ -650,29 +672,41 @@ let h_discrHyp = hide_ident_tactic "DiscrHyp" discrHyp
let bind_ith na i t = lift i (DLAM(na,lift (-(i-1)) t))
-let existS_term = put_pat mmk "existS"
+let existS_term = put_squel mmk "existS"
let existS_pattern = put_pat mmk "(existS ? ? ? ?)"
-let sigS_term = put_pat mmk "sigS"
-let projS1_term = put_pat mmk "projS1"
-let projS2_term = put_pat mmk "projS2"
-let sigS_rec_term = put_pat mmk "sigS_rec"
+let sigS_term = put_squel mmk "sigS"
+let projS1_term = put_squel mmk "projS1"
+let projS2_term = put_squel mmk "projS2"
+let sigS_rec_term = put_squel mmk "sigS_rec"
-let existT_term = put_pat mmk "existT"
+let existT_term = put_squel mmk "existT"
let existT_pattern = put_pat mmk "(existT ? ? ? ?)"
-let sigT_term = put_pat mmk "sigT"
-let projT1_term = put_pat mmk "projT1"
-let projT2_term = put_pat mmk "projT2"
-let sigT_rect_term = put_pat mmk "sigT_rect"
+let sigT_term = put_squel mmk "sigT"
+let projT1_term = put_squel mmk "projT1"
+let projT2_term = put_squel mmk "projT2"
+let sigT_rect_term = put_squel mmk "sigT_rect"
+
+let build_sigma_prop () =
+ (get_squel projS1_term,
+ get_squel projS2_term,
+ get_squel sigS_rec_term,
+ get_squel existS_term,
+ get_squel sigS_term)
+
+let build_sigma_type () =
+ (get_squel projT1_term,
+ get_squel projT2_term,
+ get_squel sigT_rect_term,
+ get_squel existT_term,
+ get_squel sigT_term)
(* returns the sigma type (sigS, sigT) with the respective
constructor depending on the sort *)
let find_sigma_data s =
match strip_outer_cast s with
- | DOP0(Sort(Prop Pos)) -> (* Set *)
- (projS1_term,projS2_term,sigS_rec_term,existS_term, sigS_term)
- | DOP0(Sort(Type(_))) -> (* Type *)
- (projT1_term, projT2_term, sigT_rect_term, existT_term, sigT_term)
+ | DOP0(Sort(Prop Pos)) -> build_sigma_prop () (* Set *)
+ | DOP0(Sort(Type(_))) -> build_sigma_type () (* Type *)
| _ -> error "find_sigma_data"
(* [make_tuple env na lind rterm rty]
@@ -698,8 +732,8 @@ let make_tuple sigma env na lind rterm rty =
let a = type_of env sigma (Rel lind) in
let p = DOP2(Lambda,a,
bind_ith (fst(lookup_rel lind env)) lind rty) in
- (applist(get_pat exist_term,[a;p;(Rel lind);rterm]),
- applist(get_pat sig_term,[a;p]))
+ (applist(exist_term,[a;p;(Rel lind);rterm]),
+ applist(sig_term,[a;p]))
else
(rterm,rty)
@@ -752,7 +786,7 @@ let sig_clausale_forme env sigma sort_of_ty siglen ty =
let mv = new_meta() in
let rty = applist(p,[DOP0(Meta mv)]) in
let (rpat,headinfo,mvenv) = sigrec_clausale_forme (siglen-1) rty in
- (applist(get_pat exist_term,[a;p;DOP0(Meta mv);rpat]),
+ (applist(exist_term,[a;p;DOP0(Meta mv);rpat]),
headinfo,
(mv,a)::mvenv)
in
diff --git a/tactics/pattern.ml b/tactics/pattern.ml
index 19d020729..04f845adc 100644
--- a/tactics/pattern.ml
+++ b/tactics/pattern.ml
@@ -44,15 +44,16 @@ let make_module_marker = Stock.make_module_marker
(* Squeletons *)
let parse_squeleton s =
- Astterm.interp_constr Evd.empty (Global.env()) (parse_constr s)
+ let c = Astterm.interp_constr Evd.empty (Global.env()) (parse_constr s) in
+ (collect_metas c, c)
-type marked_term = constr Stock.stocked
+type marked_term = (int list * constr) Stock.stocked
-let (squeleton_stock : constr Stock.stock) =
+let (squeleton_stock : (int list * constr) Stock.stock) =
Stock.make_stock { name = "SQUELETON"; proc = parse_squeleton }
let put_squel = Stock.stock squeleton_stock
-let get_squel = Stock.retrieve squeleton_stock
+let get_squel_core = Stock.retrieve squeleton_stock
(* Second part : Given a term with second-order variables in it,
represented by Meta's, and possibly applied using XTRA[$SOAPP] to
@@ -110,9 +111,11 @@ let memb_metavars m n =
| (None, _) -> true
| (Some mvs, n) -> List.mem n mvs
+let eq_context ctxt1 ctxt2 = array_for_all2 eq_constr ctxt1 ctxt2
+
exception PatternMatchingFailure
-let somatch metavars =
+let somatch_core convert metavars =
let rec sorec stk sigma p t =
let cT = whd_castapp t in
match p,kind_of_term cT with
@@ -141,16 +144,13 @@ let somatch metavars =
| PRef (RVar v1), IsVar v2 when v1 = v2 -> sigma
| PRef (RConst (sp1,ctxt1)), IsConst (sp2,ctxt2)
- when sp1 = sp2 && Array.length ctxt1 = Array.length ctxt2 ->
- array_fold_left2 (sorec stk) sigma ctxt1 ctxt2
+ when sp1 = sp2 && eq_context ctxt1 ctxt2 -> sigma
| PRef (RInd (sp1,ctxt1)), IsMutInd (sp2,ctxt2)
- when sp1 = sp2 && Array.length ctxt1 = Array.length ctxt2 ->
- array_fold_left2 (sorec stk) sigma ctxt1 ctxt2
+ when sp1 = sp2 && eq_context ctxt1 ctxt2 -> sigma
| PRef (RConstruct (sp1,ctxt1)), IsMutConstruct (sp2,ctxt2)
- when sp1 = sp2 && Array.length ctxt1 = Array.length ctxt2 ->
- array_fold_left2 (sorec stk) sigma ctxt1 ctxt2
+ when sp1 = sp2 && eq_context ctxt1 ctxt2 -> sigma
| PRel n1, IsRel n2 when n1 = n2 -> sigma
@@ -168,6 +168,11 @@ let somatch metavars =
| PBinder(BLambda,na1,c1,d1), IsLambda(na2,c2,d2) ->
sorec (na2::stk) (sorec stk sigma c1 c2) d1 d2
+ | PRef (RConst (sp1,ctxt1)), _ when convert <> None ->
+ let (env,evars) = out_some convert in
+ if is_conv env evars (mkConst (sp1,ctxt1)) cT then sigma
+ else raise PatternMatchingFailure
+
| _, (IsFix _ | IsMutCase _ | IsCoFix _) ->
error "somatch: not implemented"
@@ -175,79 +180,14 @@ let somatch metavars =
in
sorec [] []
-(*
-let somatch metavars =
- let rec sorec stk sigma p t =
- let cP = whd_castapp p
- and cT = whd_castapp t in
- match dest_soapp_operator cP with
- | Some (n,ok_args) ->
- if not (memb_metavars metavars n) then error "somatch";
- let frels = Intset.elements (free_rels cT) in
- if list_subset frels ok_args then
- constrain (n,build_dlam ok_args stk cT) sigma
- else
- error "somatch"
-
- | None ->
- match (cP,cT) with
- | (DOP0(Meta n),m) ->
- if not (memb_metavars metavars n) then
- match m with
- | DOP0(Meta m_0) ->
- if n=m_0 then sigma else error "somatch"
- | _ -> error "somatch"
- else
- let depth = List.length stk in
- let frels = Intset.elements (free_rels m) in
- if List.for_all (fun i -> i > depth) frels then
- constrain (n,lift (-depth) m) sigma
- else
- error "somatch"
-
- | (VAR v1,VAR v2) ->
- if v1 = v2 then sigma else error "somatch"
-
- | (Rel n1,Rel n2) ->
- if n1 = n2 then sigma else error "somatch"
-
- | (DOP0 op1,DOP0 op2) ->
- if op1 = op2 then sigma else error "somatch"
-
- | (DOP1(op1,c1), DOP1(op2,c2)) ->
- if op1 = op2 then sorec stk sigma c1 c2 else error "somatch"
-
- | (DOP2(op1,c1,d1), DOP2(op2,c2,d2)) ->
- if op1 = op2 then
- sorec stk (sorec stk sigma c1 c2) d1 d2
- else
- error "somatch"
-
- | (DOPN(op1,cl1), DOPN(op2,cl2)) ->
- if op1 = op2 & Array.length cl1 = Array.length cl2 then
- array_fold_left2 (sorec stk) sigma cl1 cl2
- else
- error "somatch"
-
- | (DOPL(op1,cl1), DOPL(op2,cl2)) ->
- if op1 = op2 & List.length cl1 = List.length cl2 then
- List.fold_left2 (sorec stk) sigma cl1 cl2
- else
- error "somatch"
-
- | (DLAM(_,c1), DLAM(na,c2)) ->
- sorec (na::stk) sigma c1 c2
-
- | (DLAMV(_,cl1), DLAMV(na,cl2)) ->
- if Array.length cl1 = Array.length cl2 then
- array_fold_left2 (sorec (na::stk)) sigma cl1 cl2
- else
- error "somatch"
-
- | _ -> error "somatch"
- in
- sorec [] []
-*)
+
+let somatch = somatch_core None
+
+let dest_somatch n pat =
+ let mvs,m = get_pat pat in
+ let mvb = somatch (Some (list_uniquize mvs)) m n in
+ List.map (fun b -> List.assoc b mvb) mvs
+
let somatches n pat =
let (_,m) = get_pat pat in
try
@@ -255,20 +195,26 @@ let somatches n pat =
with e when Logic.catchable_exception e ->
false
-let dest_somatch n pat =
+let dest_somatch_conv env sigma n pat =
let mvs,m = get_pat pat in
- let mvb = somatch (Some (list_uniquize mvs)) m n in
- List.map (fun b -> List.assoc b mvb) mvs
+ somatch_core (Some (env,sigma)) (Some (list_uniquize mvs)) m n
-let newsomatch n pat = let _,m = get_pat pat in somatch None m n
+let somatches_conv env sigma n pat =
+ try
+ let _ = dest_somatch_conv env sigma n pat in true
+ with e when Logic.catchable_exception e ->
+ false
let soinstance squel arglist =
- let c = get_squel squel in
- let mvs = collect_metas c in
+ let mvs,c = get_squel_core squel in
let mvb = List.combine mvs arglist in
Sosub.soexecute (Reduction.strong (fun _ _ -> Reduction.whd_meta mvb)
empty_env Evd.empty c)
+let get_squel m =
+ let mvs, c = get_squel_core m in
+ if mvs = [] then c else error "Not a closed squeleton, use 'soinstance'"
+
(* I implemented the following functions which test whether a term t
is an inductive but non-recursive type, a general conjuction, a
general disjunction, or a type with no constructors.
@@ -425,11 +371,11 @@ let rec pattern_of_constr t =
PApp (pattern_of_constr f,
Array.of_list (List.map pattern_of_constr args))
| IsConst (cst_sp,ctxt) ->
- PRef (RConst (cst_sp,Array.map pattern_of_constr ctxt))
+ PRef (RConst (cst_sp, ctxt))
| IsMutInd (ind_sp,ctxt) ->
- PRef (RInd (ind_sp,Array.map pattern_of_constr ctxt))
+ PRef (RInd (ind_sp, ctxt))
| IsMutConstruct (cstr_sp,ctxt) ->
- PRef (RConstruct (cstr_sp,Array.map pattern_of_constr ctxt))
+ PRef (RConstruct (cstr_sp, ctxt))
| IsMutCase _ | IsFix _ | IsCoFix _ ->
error "pattern_of_constr: destructors currently not supported"
| IsEvar _ -> error "pattern_of_constr: an existential variable remains"
diff --git a/tactics/pattern.mli b/tactics/pattern.mli
index ae59ddef3..e16a8ea77 100644
--- a/tactics/pattern.mli
+++ b/tactics/pattern.mli
@@ -98,11 +98,38 @@ i*)
(*i Devrait être une fonction de filtrage externe i*)
val somatch : int list option -> Rawterm.constr_pattern -> constr -> (int * constr) list
-val somatches : constr -> marked_pattern -> bool
+
+exception PatternMatchingFailure
+
+(* [dest_somatch c pat] matches [c] against [pat] and returns the resulting
+ assignment of metavariables; it raises [PatternMatchingFailure] if
+ not matchable *)
+
val dest_somatch : constr -> marked_pattern -> constr list
+(* [somatches c pat] just tells if [c] matches against [pat] *)
+
+val somatches : constr -> marked_pattern -> bool
+
+
+(* [dest_somatch_conv env sigma] matches up to conversion in
+ environment [(env,sgima)] when constants in pattern are concerned;
+ it raises [PatternMatchingFailure] if not matchable *)
+
+val dest_somatch_conv :
+ Environ.env -> 'a evar_map -> constr -> marked_pattern -> (int * constr) list
+
+(* [somatches_conv env sigma c pat] tells if [c] matches against [pat]
+ up to conversion for constants in patterns *)
+
+val somatches_conv :
+ Environ.env -> 'a evar_map -> constr -> marked_pattern -> bool
+
val soinstance : marked_term -> constr list -> constr
+(* This works only for squeleton without metavariables *)
+val get_squel : marked_term -> constr
+
val is_imp_term : constr -> bool
(*s I implemented the following functions which test whether a term [t]
diff --git a/tactics/tacticals.ml b/tactics/tacticals.ml
index baae41399..6425bdc28 100644
--- a/tactics/tacticals.ml
+++ b/tactics/tacticals.ml
@@ -118,12 +118,9 @@ let clause_type cls gl =
(* Functions concerning matching of clausal environments *)
-let matches gls n m =
+let matches gls n pat =
let (wc,_) = startWalk gls in
- try
- let _ = Clenv.unify_0 [] wc m n in true
- with e when Logic.catchable_exception e ->
- false
+ somatches_conv (w_env wc) (w_Underlying wc) n pat
let dest_match gls n m =
let mvs = collect_metas m in
diff --git a/tactics/tacticals.mli b/tactics/tacticals.mli
index e7d8cff25..f863bad68 100644
--- a/tactics/tacticals.mli
+++ b/tactics/tacticals.mli
@@ -53,7 +53,7 @@ val matches : goal sigma -> constr -> marked_term -> bool
val dest_match : goal sigma -> constr -> marked_term -> constr list
*)
(* The second argument is the pattern *)
-val matches : goal sigma -> constr -> constr -> bool
+val matches : goal sigma -> constr -> marked_pattern -> bool
val dest_match : goal sigma -> constr -> constr -> constr list
val allHyps : goal sigma -> clause list