diff options
Diffstat (limited to 'interp/topconstr.ml')
-rw-r--r-- | interp/topconstr.ml | 101 |
1 files changed, 80 insertions, 21 deletions
diff --git a/interp/topconstr.ml b/interp/topconstr.ml index 5b1d2813b..d2ef146bf 100644 --- a/interp/topconstr.ml +++ b/interp/topconstr.ml @@ -28,9 +28,11 @@ type aconstr = | ALambda of name * aconstr * aconstr | AProd of name * aconstr * aconstr | ALetIn of name * aconstr * aconstr - | ACases of aconstr option * aconstr list * + | ACases of aconstr option * aconstr option * + (aconstr * (name * (inductive * name list) option)) list * (identifier list * cases_pattern list * aconstr) list | AOrderedCase of case_style * aconstr option * aconstr * aconstr array + | ALetTuple of name list * (name * aconstr option) * aconstr * aconstr | ASort of rawsort | AHole of hole_kind | APatVar of patvar @@ -49,13 +51,24 @@ let map_aconstr_with_binders_loc loc g f e = function let na,e = name_app g e na in RProd (loc,na,f e ty,f e c) | ALetIn (na,b,c) -> let na,e = name_app g e na in RLetIn (loc,na,f e b,f e c) - | ACases (tyopt,tml,eqnl) -> + | ACases (tyopt,rtntypopt,tml,eqnl) -> + let cases_predicate_names tml = + List.flatten (List.map (function + | (tm,(na,None)) -> [na] + | (tm,(na,Some (_,nal))) -> na::nal) tml) in + (* TODO: apply g to na (in fact not used) *) + let e' = List.fold_right + (fun na e -> snd (name_app g e na)) (cases_predicate_names tml) e in let fold id (idl,e) = let (id,e) = g id e in (id::idl,e) in let eqnl = List.map (fun (idl,pat,rhs) -> let (idl,e) = List.fold_right fold idl ([],e) in (loc,idl,pat,f e rhs)) eqnl in - RCases (loc,option_app (f e) tyopt,List.map (f e) tml,eqnl) + RCases (loc,(option_app (f e) tyopt, ref (option_app (f e') rtntypopt)), + List.map (fun (tm,(na,x)) -> + (f e tm,ref (na,option_app (fun (x,y) -> (loc,x,y)) x))) tml,eqnl) | AOrderedCase (b,tyopt,tm,bv) -> - ROrderedCase (loc,b,option_app (f e) tyopt,f e tm,Array.map (f e) bv) + ROrderedCase (loc,b,option_app (f e) tyopt,f e tm,Array.map (f e) bv,ref None) + | ALetTuple (nal,(na,po),b,c) -> + RLetTuple (loc,nal,(na,option_app (f e) po),f e b,f e c) | ACast (c,t) -> RCast (loc,f e c,f e t) | ASort x -> RSort (loc,x) | AHole x -> RHole (loc,x) @@ -101,9 +114,17 @@ let rec subst_aconstr subst raw = if r1' == r1 && r2' == r2 then raw else ALetIn (n,r1',r2') - | ACases (ro,rl,branches) -> + | ACases (ro,rtntypopt,rl,branches) -> let ro' = option_smartmap (subst_aconstr subst) ro - and rl' = list_smartmap (subst_aconstr subst) rl + and rtntypopt' = option_smartmap (subst_aconstr subst) rtntypopt + and rl' = list_smartmap + (fun (a,(n,signopt) as x) -> + let a' = subst_aconstr subst a in + let signopt' = option_app (fun ((indkn,i),nal as z) -> + let indkn' = subst_kn subst indkn in + if indkn == indkn' then z else ((indkn',i),nal)) signopt in + if a' == a && signopt' == signopt then x else (a',(n,signopt'))) + rl and branches' = list_smartmap (fun (idl,cpl,r as branch) -> let cpl' = list_smartmap (subst_pat subst) cpl @@ -112,8 +133,9 @@ let rec subst_aconstr subst raw = (idl,cpl',r')) branches in - if ro' == ro && rl' == rl && branches' == branches then raw else - ACases (ro',rl',branches') + if ro' == ro && rtntypopt == rtntypopt' & + rl' == rl && branches' == branches then raw else + ACases (ro',rtntypopt',rl',branches') | AOrderedCase (b,ro,r,ra) -> let ro' = option_smartmap (subst_aconstr subst) ro @@ -122,6 +144,13 @@ let rec subst_aconstr subst raw = if ro' == ro && r' == r && ra' == ra then raw else AOrderedCase (b,ro',r',ra') + | ALetTuple (nal,(na,po),b,c) -> + let po' = option_smartmap (subst_aconstr subst) po + and b' = subst_aconstr subst b + and c' = subst_aconstr subst c in + if po' == po && b' == b && c' == c then raw else + ALetTuple (nal,(na,po'),b',c') + | APatVar _ | ASort _ -> raw | AHole (ImplicitArg (ref,i)) -> @@ -151,13 +180,22 @@ let aconstr_of_rawconstr vars a = | RLambda (_,na,ty,c) -> add_name bound_binders na; ALambda (na,aux ty,aux c) | RProd (_,na,ty,c) -> add_name bound_binders na; AProd (na,aux ty,aux c) | RLetIn (_,na,b,c) -> add_name bound_binders na; ALetIn (na,aux b,aux c) - | RCases (_,tyopt,tml,eqnl) -> + | RCases (_,(tyopt,rtntypopt),tml,eqnl) -> let f (_,idl,pat,rhs) = bound_binders := idl@(!bound_binders); (idl,pat,aux rhs) in - ACases (option_app aux tyopt,List.map aux tml, List.map f eqnl) - | ROrderedCase (_,b,tyopt,tm,bv) -> + ACases (option_app aux tyopt, + option_app aux !rtntypopt, + List.map (fun (tm,{contents = (na,x)}) -> + add_name bound_binders na; + option_iter + (fun (_,_,nl) -> List.iter (add_name bound_binders) nl) x; + (aux tm,(na,option_app (fun (_,ind,nal) -> (ind,nal)) x))) tml, + List.map f eqnl) + | ROrderedCase (_,b,tyopt,tm,bv,_) -> AOrderedCase (b,option_app aux tyopt,aux tm, Array.map aux bv) + | RLetTuple (loc,nal,(na,po),b,c) -> + ALetTuple (nal,(na,option_app aux po),aux b,aux c) | RCast (_,c,t) -> ACast (aux c,aux t) | RSort (_,s) -> ASort s | RHole (_,w) -> AHole w @@ -279,11 +317,13 @@ let rec match_ alp metas sigma a1 a2 = match (a1,a2) with match_binders alp metas (match_ alp metas sigma t1 t2) b1 b2 na1 na2 | RLetIn (_,na1,t1,b1), AProd (na2,t2,b2) -> match_binders alp metas (match_ alp metas sigma t1 t2) b1 b2 na1 na2 - | RCases (_,po1,tml1,eqnl1), ACases (po2,tml2,eqnl2) -> + | RCases (_,(po1,rtno1),tml1,eqnl1), ACases (po2,rtno2,tml2,eqnl2) -> let sigma = option_fold_left2 (match_ alp metas) sigma po1 po2 in - let sigma = List.fold_left2 (match_ alp metas) sigma tml1 tml2 in + (* TODO: match rtno' with their contexts *) + let sigma = List.fold_left2 + (fun s (tm1,_) (tm2,_) -> match_ alp metas s tm1 tm2) sigma tml1 tml2 in List.fold_left2 (match_equations alp metas) sigma eqnl1 eqnl2 - | ROrderedCase (_,st,po1,c1,bl1), AOrderedCase (st2,po2,c2,bl2) -> + | ROrderedCase (_,st,po1,c1,bl1,_), AOrderedCase (st2,po2,c2,bl2) -> let sigma = option_fold_left2 (match_ alp metas) sigma po1 po2 in array_fold_left2 (match_ alp metas) (match_ alp metas sigma c1 c2) bl1 bl2 | RCast(_,c1,t1), ACast(c2,t2) -> @@ -349,7 +389,7 @@ type notation = string type explicitation = int -type proj_flag = bool (* [true] = is projection *) +type proj_flag = int option (* [Some n] = proj of the n-th visible argument *) type cases_pattern_expr = | CPatAlias of loc * cases_pattern_expr * identifier @@ -369,10 +409,13 @@ type constr_expr = | CAppExpl of loc * (proj_flag * reference) * constr_expr list | CApp of loc * (proj_flag * constr_expr) * (constr_expr * explicitation option) list - | CCases of loc * constr_expr option * constr_expr list * + | CCases of loc * (constr_expr option * constr_expr option) * + (constr_expr * (name * (loc * reference * name list) option)) list * (loc * cases_pattern_expr list * constr_expr) list | COrderedCase of loc * case_style * constr_expr option * constr_expr * constr_expr list + | CLetTuple of loc * name list * (name * constr_expr option) * + constr_expr * constr_expr | CHole of loc | CPatVar of loc * (bool * patvar) | CEvar of loc * existential_key @@ -410,6 +453,7 @@ let constr_loc = function | CApp (loc,_,_) -> loc | CCases (loc,_,_,_) -> loc | COrderedCase (loc,_,_,_,_) -> loc + | CLetTuple (loc,_,_,_,_) -> loc | CHole loc -> loc | CPatVar (loc,_) -> loc | CEvar (loc,_) -> loc @@ -448,6 +492,7 @@ let rec occur_var_constr_expr id = function | CHole _ | CEvar _ | CPatVar _ | CSort _ | CNumeral _ | CDynamic _ -> false | CCases (loc,_,_,_) | COrderedCase (loc,_,_,_,_) + | CLetTuple (loc,_,_,_,_) | CFix (loc,_,_) | CCoFix (loc,_,_) -> Pp.warning "Capture check in multiple binders not done"; false @@ -461,7 +506,7 @@ and occur_var_binders id b = function let mkIdentC id = CRef (Ident (dummy_loc, id)) let mkRefC r = CRef r -let mkAppC (f,l) = CApp (dummy_loc, (false,f), List.map (fun x -> (x,None)) l) +let mkAppC (f,l) = CApp (dummy_loc, (None,f), List.map (fun x -> (x,None)) l) let mkCastC (a,b) = CCast (dummy_loc,a,b) let mkLambdaC (idl,a,b) = CLambdaN (dummy_loc,[idl,a],b) let mkLetInC (id,a,b) = CLetIn (dummy_loc,id,a,b) @@ -469,10 +514,11 @@ let mkProdC (idl,a,b) = CProdN (dummy_loc,[idl,a],b) (* Used in correctness and interface *) +let map_binder g e nal = List.fold_right (fun (_,na) -> name_fold g na) nal e + let map_binders f g e bl = (* TODO: avoid variable capture in [t] by some [na] in [List.tl nal] *) - let h (nal,t) (e,bl) = - (List.fold_right (fun (_,na) -> name_fold g na) nal e,(nal,f e t)::bl) in + let h (nal,t) (e,bl) = (map_binder g e nal,(nal,f e t)::bl) in List.fold_right h bl (e,[]) let map_constr_expr_with_binders f g e = function @@ -490,12 +536,25 @@ let map_constr_expr_with_binders f g e = function | CDelimiters (loc,s,a) -> CDelimiters (loc,s,f e a) | CHole _ | CEvar _ | CPatVar _ | CSort _ | CNumeral _ | CDynamic _ | CRef _ as x -> x - | CCases (loc,po,a,bl) -> + | CCases (loc,(po,rtnpo),a,bl) -> (* TODO: apply g on the binding variables in pat... *) let bl = List.map (fun (loc,pat,rhs) -> (loc,pat,f e rhs)) bl in - CCases (loc,option_app (f e) po,List.map (f e) a,bl) + let e' = + List.fold_right + (fun (tm,(na,indnal)) e -> + option_fold_right + (fun (loc,ind,nal) -> + List.fold_right (name_fold g) nal) indnal (name_fold g na e)) + a e + in + CCases (loc,(option_app (f e) po, option_app (f e') rtnpo), + List.map (fun (tm,x) -> (f e tm,x)) a,bl) | COrderedCase (loc,s,po,a,bl) -> COrderedCase (loc,s,option_app (f e) po,f e a,List.map (f e) bl) + | CLetTuple (loc,nal,(na,po),b,c) -> + let e' = List.fold_right (name_fold g) nal e in + let e'' = name_fold g na e in + CLetTuple (loc,nal,(na,option_app (f e'') po),f e b,f e' c) | CFix (loc,id,dl) -> CFix (loc,id,List.map (fun (id,n,t,d) -> (id,n,f e t,f e d)) dl) | CCoFix (loc,id,dl) -> |