aboutsummaryrefslogtreecommitdiffhomepage
path: root/pretyping/glob_ops.ml
diff options
context:
space:
mode:
authorGravatar Arnaud Spiwack <arnaud@spiwack.net>2014-11-14 09:40:23 +0100
committerGravatar Arnaud Spiwack <arnaud@spiwack.net>2014-11-19 10:11:45 +0100
commitbd2dd62ea83ff9374bd28f089b19d3abba6ac7cb (patch)
tree9be4b23ec2ae2f6d83c1d1d45eedf0bfe74611d3 /pretyping/glob_ops.ml
parent9e1224f452470c3e18e13c88c4d8a00fe0864c16 (diff)
Glob-ops: a name-mapping operation for pattern-matching binders.
Diffstat (limited to 'pretyping/glob_ops.ml')
-rw-r--r--pretyping/glob_ops.ml45
1 files changed, 45 insertions, 0 deletions
diff --git a/pretyping/glob_ops.ml b/pretyping/glob_ops.ml
index fd51545b2..588810eaa 100644
--- a/pretyping/glob_ops.ml
+++ b/pretyping/glob_ops.ml
@@ -328,6 +328,51 @@ let free_glob_vars =
let vs = vars Id.Set.empty Id.Set.empty rt in
Id.Set.elements vs
+(** Mapping of names in binders *)
+
+(* spiwack: I used a smartmap-style kind of mapping here, because the
+ operation will be the identity almost all of the time (with any
+ term outside of Ltac to begin with). But to be honest, there would
+ probably be no significant penalty in doing reallocation as
+ pattern-matching expressions are usually rather small. *)
+
+let map_inpattern_binders f ((loc,id,nal) as x) =
+ let r = CList.smartmap f nal in
+ if r == nal then x
+ else loc,id,r
+
+let map_tomatch_binders f ((c,(na,inp)) as x) : tomatch_tuple =
+ let r = Option.smartmap (fun p -> map_inpattern_binders f p) inp in
+ if r == inp then x
+ else c,(f na, r)
+
+let rec map_case_pattern_binders f = function
+ | PatVar (loc,na) as x ->
+ let r = f na in
+ if r == na then x
+ else PatVar (loc,r)
+ | PatCstr (loc,c,ps,na) as x ->
+ let rna = f na in
+ let rps =
+ CList.smartmap (fun p -> map_case_pattern_binders f p) ps
+ in
+ if rna == na && rps == ps then x
+ else PatCstr(loc,c,rps,rna)
+
+let map_cases_branch_binders f ((loc,il,cll,rhs) as x) : cases_clause =
+ (* spiwack: not sure if I must do something with the list of idents.
+ It is intended to be a superset of the free variable of the
+ right-hand side, if I understand correctly. But I'm not sure when
+ or how they are used. *)
+ let r = List.smartmap (fun cl -> map_case_pattern_binders f cl) cll in
+ if r == cll then x
+ else loc,il,r,rhs
+
+let map_pattern_binders f tomatch branches =
+ CList.smartmap (fun tm -> map_tomatch_binders f tm) tomatch,
+ CList.smartmap (fun br -> map_cases_branch_binders f br) branches
+
+(** /mapping of names in binders *)
let loc_of_glob_constr = function
| GRef (loc,_,_) -> loc