aboutsummaryrefslogtreecommitdiff
path: root/tactics/pattern.ml
diff options
context:
space:
mode:
Diffstat (limited to 'tactics/pattern.ml')
-rw-r--r--tactics/pattern.ml169
1 files changed, 135 insertions, 34 deletions
diff --git a/tactics/pattern.ml b/tactics/pattern.ml
index 23b6da6e46..19d0207294 100644
--- a/tactics/pattern.ml
+++ b/tactics/pattern.ml
@@ -12,6 +12,7 @@ open Environ
open Proof_trees
open Stock
open Clenv
+open Rawterm
(* The pattern table for tactics. *)
@@ -21,33 +22,38 @@ open Clenv
type module_mark = Stock.module_mark
-type marked_term = constr Stock.stocked
-
-let rec whd_replmeta = function
- | DOP0(XTRA("ISEVAR")) -> DOP0(Meta (new_meta()))
- | DOP2(Cast,c,_) -> whd_replmeta c
- | c -> c
-
-let raw_sopattern_of_compattern env com =
- let c = Astterm.constr_of_com_pattern Evd.empty env com in
- strong (fun _ _ -> whd_replmeta) env Evd.empty c
+let parse_constr s =
+ try
+ Pcoq.parse_string Pcoq.Constr.constr_eoi s
+ with Stdpp.Exc_located (_ , (Stream.Failure | Stream.Error _)) ->
+ error "Syntax error : not a construction"
+(* Patterns *)
let parse_pattern s =
- let com =
- try
- Pcoq.parse_string Pcoq.Constr.constr_eoi s
- with Stdpp.Exc_located (_ , (Stream.Failure | Stream.Error _)) ->
- error "Malformed pattern"
- in
- raw_sopattern_of_compattern (Global.env()) com
+ Astterm.interp_constrpattern Evd.empty (Global.env()) (parse_constr s)
-let (pattern_stock : constr Stock.stock) =
+type marked_pattern = (int list * constr_pattern) Stock.stocked
+
+let (pattern_stock : (int list * constr_pattern) Stock.stock) =
Stock.make_stock { name = "PATTERN"; proc = parse_pattern }
-let make_module_marker = Stock.make_module_marker pattern_stock
let put_pat = Stock.stock pattern_stock
let get_pat = Stock.retrieve pattern_stock
+let make_module_marker = Stock.make_module_marker
+
+(* Squeletons *)
+let parse_squeleton s =
+ Astterm.interp_constr Evd.empty (Global.env()) (parse_constr s)
+
+type marked_term = constr Stock.stocked
+
+let (squeleton_stock : 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
+
(* Second part : Given a term with second-order variables in it,
represented by Meta's, and possibly applied using XTRA[$SOAPP] to
terms, this function will perform second-order, binding-preserving,
@@ -103,7 +109,73 @@ let memb_metavars m n =
match (m,n) with
| (None, _) -> true
| (Some mvs, n) -> List.mem n mvs
-
+
+exception PatternMatchingFailure
+
+let somatch metavars =
+ let rec sorec stk sigma p t =
+ let cT = whd_castapp t in
+ match p,kind_of_term cT with
+ | PSoApp (n,relargs),m ->
+ assert (memb_metavars metavars n);
+ let frels = Intset.elements (free_rels cT) in
+ if list_subset frels relargs then
+ constrain (n,build_dlam relargs stk cT) sigma
+ else
+ raise PatternMatchingFailure
+
+ | PMeta n, m ->
+ if not (memb_metavars metavars n) then
+ (*Ce cas est bizarre : comment les numéros pourraient-ils coincider*)
+ match m with
+ | IsMeta m0 when n=m0 -> sigma
+ | _ -> raise PatternMatchingFailure
+ else
+ let depth = List.length stk in
+ let frels = Intset.elements (free_rels cT) in
+ if List.for_all (fun i -> i > depth) frels then
+ constrain (n,lift (-depth) cT) sigma
+ else
+ raise PatternMatchingFailure
+
+ | 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
+
+ | PRef (RInd (sp1,ctxt1)), IsMutInd (sp2,ctxt2)
+ when sp1 = sp2 && Array.length ctxt1 = Array.length ctxt2 ->
+ array_fold_left2 (sorec stk) sigma ctxt1 ctxt2
+
+ | PRef (RConstruct (sp1,ctxt1)), IsMutConstruct (sp2,ctxt2)
+ when sp1 = sp2 && Array.length ctxt1 = Array.length ctxt2 ->
+ array_fold_left2 (sorec stk) sigma ctxt1 ctxt2
+
+ | PRel n1, IsRel n2 when n1 = n2 -> sigma
+
+ | PSort (RProp c1), IsSort (Prop c2) when c1 = c2 -> sigma
+
+ | PSort RType, IsSort (Type _) -> sigma
+
+ | PApp (c1,arg1), IsAppL (c2,arg2) ->
+ array_fold_left2 (sorec stk) (sorec stk sigma c1 c2)
+ arg1 (Array.of_list arg2)
+
+ | PBinder(BProd,na1,c1,d1), IsProd(na2,c2,d2) ->
+ sorec (na2::stk) (sorec stk sigma c1 c2) d1 d2
+
+ | PBinder(BLambda,na1,c1,d1), IsLambda(na2,c2,d2) ->
+ sorec (na2::stk) (sorec stk sigma c1 c2) d1 d2
+
+ | _, (IsFix _ | IsMutCase _ | IsCoFix _) ->
+ error "somatch: not implemented"
+
+ | _ -> raise PatternMatchingFailure
+
+ in
+ sorec [] []
+(*
let somatch metavars =
let rec sorec stk sigma p t =
let cP = whd_castapp p
@@ -175,26 +247,27 @@ let somatch metavars =
| _ -> error "somatch"
in
sorec [] []
-
+*)
let somatches n pat =
- let m = get_pat pat in
+ let (_,m) = get_pat pat in
try
let _ = somatch None m n in true
with e when Logic.catchable_exception e ->
false
let dest_somatch n pat =
- let m = get_pat pat in
- let mvs = collect_metas m in
+ 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 soinstance pat arglist =
- let m = get_pat pat in
- let mvs = collect_metas m in
+let newsomatch n pat = let _,m = get_pat pat in somatch None m n
+
+let soinstance squel arglist =
+ let c = get_squel squel in
+ let mvs = collect_metas c in
let mvb = List.combine mvs arglist in
Sosub.soexecute (Reduction.strong (fun _ _ -> Reduction.whd_meta mvb)
- empty_env Evd.empty m)
+ empty_env Evd.empty c)
(* I implemented the following functions which test whether a term t
is an inductive but non-recursive type, a general conjuction, a
@@ -300,18 +373,18 @@ let is_unit_type t = op2bool (match_with_unit_type t)
inductive binary relation R, so that R has only one constructor
stablishing its reflexivity. *)
+let refl_rel_pat1 = put_pat mmk "(A : ?)(x:A)(? A x x)"
+let refl_rel_pat2 = put_pat mmk "(x : ?)(? x x)"
+
let match_with_equation t =
let (hdapp,args) = decomp_app t in
match (kind_of_term hdapp) with
| IsMutInd ind ->
- let constr_types =
- Global.mind_lc_without_abstractions ind in
- let refl_rel_term1 = put_pat mmk "(A : ?)(x:A)(? A x x)" in
- let refl_rel_term2 = put_pat mmk "(x : ?)(? x x)" in
+ let constr_types = Global.mind_lc_without_abstractions ind in
let nconstr = Global.mind_nconstr ind in
if nconstr = 1 &&
- (somatches constr_types.(0) refl_rel_term1 ||
- somatches constr_types.(0) refl_rel_term2)
+ (somatches constr_types.(0) refl_rel_pat1 ||
+ somatches constr_types.(0) refl_rel_pat2)
then
Some (hdapp,args)
else
@@ -335,3 +408,31 @@ let is_nottype t = op2bool (match_with_nottype t)
let is_imp_term = function
| DOP2(Prod,_,DLAM(_,b)) -> not (dependent (Rel 1) b)
| _ -> false
+
+let rec pattern_of_constr t =
+ match kind_of_term t with
+ | IsRel n -> PRel n
+ | IsMeta n -> PMeta n
+ | IsVar id -> PRef (RVar id)
+ | IsSort (Prop c) -> PSort (RProp c)
+ | IsSort (Type _) -> PSort RType
+ | IsCast (c,t) -> pattern_of_constr c
+ | IsProd (na,c,b) ->
+ PBinder (BProd,na,pattern_of_constr c,pattern_of_constr b)
+ | IsLambda (na,c,b) ->
+ PBinder (BLambda,na,pattern_of_constr c,pattern_of_constr b)
+ | IsAppL (f,args) ->
+ 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))
+ | IsMutInd (ind_sp,ctxt) ->
+ PRef (RInd (ind_sp,Array.map pattern_of_constr ctxt))
+ | IsMutConstruct (cstr_sp,ctxt) ->
+ PRef (RConstruct (cstr_sp,Array.map pattern_of_constr ctxt))
+ | IsMutCase _ | IsFix _ | IsCoFix _ ->
+ error "pattern_of_constr: destructors currently not supported"
+ | IsEvar _ -> error "pattern_of_constr: an existential variable remains"
+ | IsAbst _ | IsXtra _ -> anomaly "No longer supported"
+
+