diff options
Diffstat (limited to 'pretyping')
-rw-r--r-- | pretyping/detyping.ml | 128 | ||||
-rw-r--r-- | pretyping/detyping.mli | 12 | ||||
-rw-r--r-- | pretyping/inductiveops.ml | 9 | ||||
-rw-r--r-- | pretyping/patternops.ml | 20 |
4 files changed, 95 insertions, 74 deletions
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml index e9a1174b4..2d7c7b146 100644 --- a/pretyping/detyping.ml +++ b/pretyping/detyping.ml @@ -172,7 +172,7 @@ let computable p k = works for normal eta-expanded term. For non eta-expanded or non-normal terms, it may affirm the pred is synthetisable because of an undetected ultimate dependent variable in the second - clause, or else, it may affirms the pred non synthetisable + clause, or else, it may affirm the pred non synthetisable because of a non normal term in the fourth clause. A solution could be to store, in the MutCase, the eta-expanded normal form of pred to decide if it depends on its variables @@ -239,26 +239,29 @@ let update_name na ((_,(e,_)),c) = | _ -> na -let rec decomp_branch ndecls nargs nal b (avoid,env as e) c = +let rec decomp_branch tags nal b (avoid,env as e) c = let flag = if b then RenamingForGoal else RenamingForCasesPattern (fst env,c) in - if Int.equal ndecls 0 then (List.rev nal,(e,c)) - else - let na,c,f,nargs',body,t = - match kind_of_term (strip_outer_cast c) with - | Lambda (na,t,c) -> na,c,compute_displayed_let_name_in,nargs-1,None,Some t - | LetIn (na,b,t,c) when ndecls>nargs -> - na,c,compute_displayed_name_in,nargs,Some b,Some t - | _ -> + match tags with + | [] -> (List.rev nal,(e,c)) + | b::tags -> + let na,c,f,body,t = + match kind_of_term (strip_outer_cast c), b with + | Lambda (na,t,c),false -> na,c,compute_displayed_let_name_in,None,Some t + | LetIn (na,b,t,c),true -> + na,c,compute_displayed_name_in,Some b,Some t + | _, false -> Name default_dependent_ident,(applist (lift 1 c, [mkRel 1])), - compute_displayed_name_in,nargs-1,None,None + compute_displayed_name_in,None,None + | _, true -> + Anonymous,lift 1 c,compute_displayed_name_in,None,None in let na',avoid' = f flag avoid na c in - decomp_branch (ndecls-1) nargs' (na'::nal) b + decomp_branch tags (na'::nal) b (avoid', add_name_opt na' body t env) c let rec build_tree na isgoal e ci cl = let mkpat n rhs pl = PatCstr(dl,(ci.ci_ind,n+1),pl,update_name na rhs) in - let cnl = ci.ci_cstr_ndecls in + let cnl = ci.ci_pp_info.cstr_tags in let cna = ci.ci_cstr_nargs in List.flatten (List.init (Array.length cl) @@ -271,7 +274,7 @@ and align_tree nal isgoal (e,c as rhs) = match nal with | Case (ci,p,c,cl) when eq_constr c (mkRel (List.index Name.equal na (fst (snd e)))) && (* don't contract if p dependent *) - computable p (ci.ci_pp_info.ind_nargs) -> + computable p (List.length ci.ci_pp_info.ind_tags) (* FIXME: can do better *) -> let clauses = build_tree na isgoal e ci cl in List.flatten (List.map (fun (pat,rhs) -> @@ -284,7 +287,7 @@ and align_tree nal isgoal (e,c as rhs) = match nal with List.map (fun (hd,rest) -> pat::hd,rest) mat and contract_branch isgoal e (cdn,can,mkpat,b) = - let nal,rhs = decomp_branch cdn can [] isgoal e b in + let nal,rhs = decomp_branch cdn [] isgoal e b in let mat = align_tree nal isgoal rhs in List.map (fun (hd,rhs) -> (mkpat rhs hd,rhs)) mat @@ -292,27 +295,32 @@ and contract_branch isgoal e (cdn,can,mkpat,b) = (* Transform internal representation of pattern-matching into list of *) (* clauses *) -let is_nondep_branch c n = +let is_nondep_branch c l = try - let sign,ccl = decompose_lam_n_assum n c in + (* FIXME: do better using tags from l *) + let sign,ccl = decompose_lam_n_assum (List.length l) c in noccur_between 1 (rel_context_length sign) ccl with e when Errors.noncritical e -> (* Not eta-expanded or not reduced *) false -let extract_nondep_branches test c b n = - let rec strip n r = if Int.equal n 0 then r else - match r with - | GLambda (_,_,_,_,t) -> strip (n-1) t - | GLetIn (_,_,_,t) -> strip (n-1) t - | _ -> assert false in - if test c n then Some (strip n b) else None - -let it_destRLambda_or_LetIn_names n c = - let rec aux n nal c = - if Int.equal n 0 then (List.rev nal,c) else match c with - | GLambda (_,na,_,_,c) -> aux (n-1) (na::nal) c - | GLetIn (_,na,_,c) -> aux (n-1) (na::nal) c - | _ -> +let extract_nondep_branches test c b l = + let rec strip l r = + match r,l with + | r, [] -> r + | GLambda (_,_,_,_,t), false::l -> strip l t + | GLetIn (_,_,_,t), true::l -> strip l t + (* FIXME: do we need adjustment? *) + | _,_ -> assert false in + if test c l then Some (strip l b) else None + +let it_destRLambda_or_LetIn_names l c = + let rec aux l nal c = + match c, l with + | _, [] -> (List.rev nal,c) + | GLambda (_,na,_,_,c), false::l -> aux l (na::nal) c + | GLetIn (_,na,_,c), true::l -> aux l (na::nal) c + | _, true::l -> (* let-expansion *) aux l (Anonymous :: nal) c + | _, false::l -> (* eta-expansion *) let next l = let x = next_ident_away default_dependent_ident l in @@ -322,14 +330,14 @@ let it_destRLambda_or_LetIn_names n c = in let x = next (free_glob_vars c) in let a = GVar (dl,x) in - aux (n-1) (Name x :: nal) + aux l (Name x :: nal) (match c with | GApp (loc,p,l) -> GApp (loc,p,l@[a]) | _ -> (GApp (dl,c,[a]))) - in aux n [] c + in aux l [] c let detype_case computable detype detype_eqns testdep avoid data p c bl = - let (indsp,st,consnargsl,k) = data in + let (indsp,st,constagsl,k) = data in let synth_type = synthetize_type () in let tomatch = detype c in let alias, aliastyp, pred= @@ -367,20 +375,20 @@ let detype_case computable detype detype_eqns testdep avoid data p c bl = match tag, aliastyp with | LetStyle, None -> let bl' = Array.map detype bl in - let (nal,d) = it_destRLambda_or_LetIn_names consnargsl.(0) bl'.(0) in + let (nal,d) = it_destRLambda_or_LetIn_names constagsl.(0) bl'.(0) in GLetTuple (dl,nal,(alias,pred),tomatch,d) | IfStyle, None -> let bl' = Array.map detype bl in let nondepbrs = - Array.map3 (extract_nondep_branches testdep) bl bl' consnargsl in + Array.map3 (extract_nondep_branches testdep) bl bl' constagsl in if Array.for_all ((!=) None) nondepbrs then GIf (dl,tomatch,(alias,pred), Option.get nondepbrs.(0),Option.get nondepbrs.(1)) else - let eqnl = detype_eqns constructs consnargsl bl in + let eqnl = detype_eqns constructs constagsl bl in GCases (dl,tag,pred,[tomatch,(alias,aliastyp)],eqnl) | _ -> - let eqnl = detype_eqns constructs consnargsl bl in + let eqnl = detype_eqns constructs constagsl bl in GCases (dl,tag,pred,[tomatch,(alias,aliastyp)],eqnl) let detype_sort = function @@ -513,12 +521,12 @@ let rec detype flags avoid env sigma t = | Construct (cstr_sp,u) -> GRef (dl, ConstructRef cstr_sp, detype_instance u) | Case (ci,p,c,bl) -> - let comp = computable p (ci.ci_pp_info.ind_nargs) in + let comp = computable p (List.length (ci.ci_pp_info.ind_tags)) in detype_case comp (detype flags avoid env sigma) (detype_eqns flags avoid env sigma ci comp) is_nondep_branch avoid (ci.ci_ind,ci.ci_pp_info.style, - ci.ci_cstr_ndecls,ci.ci_pp_info.ind_nargs) + ci.ci_pp_info.cstr_tags,ci.ci_pp_info.ind_tags) (Some p) c bl | Fix (nvn,recdef) -> detype_fix flags avoid env sigma nvn recdef | CoFix (n,recdef) -> detype_cofix flags avoid env sigma n recdef @@ -610,31 +618,35 @@ and detype_eqn (lax,isgoal as flags) avoid env sigma constr construct_nargs bran let na,avoid' = compute_displayed_name_in flag avoid x b in PatVar (dl,na),avoid',(add_name na body ty env),add_vname ids na in - let rec buildrec ids patlist avoid env n b = - if Int.equal n 0 then - (dl, Id.Set.elements ids, - [PatCstr(dl, constr, List.rev patlist,Anonymous)], - detype flags avoid env sigma b) - else - match kind_of_term b with - | Lambda (x,t,b) -> + let rec buildrec ids patlist avoid env l b = + match kind_of_term b, l with + | _, [] -> + (dl, Id.Set.elements ids, + [PatCstr(dl, constr, List.rev patlist,Anonymous)], + detype flags avoid env sigma b) + | Lambda (x,t,b), false::l -> let pat,new_avoid,new_env,new_ids = make_pat x avoid env b None t ids in - buildrec new_ids (pat::patlist) new_avoid new_env (n-1) b + buildrec new_ids (pat::patlist) new_avoid new_env l b - | LetIn (x,b,t,b') -> + | LetIn (x,b,t,b'), true::l -> let pat,new_avoid,new_env,new_ids = make_pat x avoid env b' (Some b) t ids in - buildrec new_ids (pat::patlist) new_avoid new_env (n-1) b' + buildrec new_ids (pat::patlist) new_avoid new_env l b' + + | Cast (c,_,_), l -> (* Oui, il y a parfois des cast *) + buildrec ids patlist avoid env l c - | Cast (c,_,_) -> (* Oui, il y a parfois des cast *) - buildrec ids patlist avoid env n c + | _, true::l -> + let pat = PatVar (dl,Anonymous) in + buildrec ids (pat::patlist) avoid env l b - | _ -> (* eta-expansion : n'arrivera plus lorsque tous les - termes seront construits à partir de la syntaxe Cases *) + | _, false::l -> + (* eta-expansion : n'arrivera plus lorsque tous les + termes seront construits à partir de la syntaxe Cases *) (* nommage de la nouvelle variable *) let new_b = applist (lift 1 b, [mkRel 1]) in let pat,new_avoid,new_env,new_ids = make_pat Anonymous avoid env new_b None mkProp ids in - buildrec new_ids (pat::patlist) new_avoid new_env (n-1) new_b + buildrec new_ids (pat::patlist) new_avoid new_env l new_b in buildrec Id.Set.empty [] avoid env construct_nargs branch @@ -800,6 +812,6 @@ let simple_cases_matrix_of_branches ind brs = (Loc.ghost,ids,[p],c)) brs -let return_type_of_predicate ind nrealargs_ctxt pred = - let nal,p = it_destRLambda_or_LetIn_names (nrealargs_ctxt+1) pred in +let return_type_of_predicate ind nrealargs_tags pred = + let nal,p = it_destRLambda_or_LetIn_names (nrealargs_tags@[false]) pred in (List.hd nal, Some (Loc.ghost, ind, List.tl nal)), Some p diff --git a/pretyping/detyping.mli b/pretyping/detyping.mli index b2fc92557..8a8312990 100644 --- a/pretyping/detyping.mli +++ b/pretyping/detyping.mli @@ -34,10 +34,10 @@ val detype : ?lax:bool -> bool -> Id.t list -> env -> evar_map -> constr -> glob val detype_case : bool -> ('a -> glob_constr) -> - (constructor array -> int array -> 'a array -> + (constructor array -> bool list array -> 'a array -> (Loc.t * Id.t list * cases_pattern list * glob_constr) list) -> - ('a -> int -> bool) -> - Id.t list -> inductive * case_style * int array * int -> + ('a -> bool list -> bool) -> + Id.t list -> inductive * case_style * bool list array * bool list -> 'a option -> 'a -> 'a array -> glob_constr val detype_sort : sorts -> glob_sort @@ -55,11 +55,11 @@ val synthetize_type : unit -> bool (** Utilities to transform kernel cases to simple pattern-matching problem *) -val it_destRLambda_or_LetIn_names : int -> glob_constr -> Name.t list * glob_constr +val it_destRLambda_or_LetIn_names : bool list -> glob_constr -> Name.t list * glob_constr val simple_cases_matrix_of_branches : - inductive -> (int * int * glob_constr) list -> cases_clauses + inductive -> (int * bool list * glob_constr) list -> cases_clauses val return_type_of_predicate : - inductive -> int -> glob_constr -> predicate_pattern * glob_constr option + inductive -> bool list -> glob_constr -> predicate_pattern * glob_constr option val subst_genarg_hook : (substitution -> Genarg.glob_generic_argument -> Genarg.glob_generic_argument) Hook.t diff --git a/pretyping/inductiveops.ml b/pretyping/inductiveops.ml index 91072dce8..70c670e3f 100644 --- a/pretyping/inductiveops.ml +++ b/pretyping/inductiveops.ml @@ -273,7 +273,14 @@ let projection_nparams p = projection_nparams_env (Global.env ()) p (* Annotation for cases *) let make_case_info env ind style = let (mib,mip) = Inductive.lookup_mind_specif env ind in - let print_info = { ind_nargs = mip.mind_nrealdecls; style = style } in + let ind_tags = + rel_context_tags (List.firstn mip.mind_nrealargs mip.mind_arity_ctxt) in + let cstr_tags = + Array.map2 (fun c n -> + let d,_ = decompose_prod_assum c in + rel_context_tags (List.firstn n d)) + mip.mind_nf_lc mip.mind_consnrealdecls in + let print_info = { ind_tags; cstr_tags; style } in { ci_ind = ind; ci_npar = mib.mind_nparams; ci_cstr_ndecls = mip.mind_consnrealdecls; diff --git a/pretyping/patternops.ml b/pretyping/patternops.ml index 8c553f613..0576ec57b 100644 --- a/pretyping/patternops.ml +++ b/pretyping/patternops.ml @@ -26,7 +26,7 @@ open Environ let case_info_pattern_eq i1 i2 = i1.cip_style == i2.cip_style && Option.equal eq_ind i1.cip_ind i2.cip_ind && - Option.equal Int.equal i1.cip_ind_args i2.cip_ind_args && + Option.equal (List.equal (==)) i1.cip_ind_tags i2.cip_ind_tags && i1.cip_extensible == i2.cip_extensible let rec constr_pattern_eq p1 p2 = match p1, p2 with @@ -63,7 +63,7 @@ let rec constr_pattern_eq p1 p2 = match p1, p2 with (** FIXME: fixpoint and cofixpoint should be relativized to pattern *) and pattern_eq (i1, j1, p1) (i2, j2, p2) = - Int.equal i1 i2 && Int.equal j1 j2 && constr_pattern_eq p1 p2 + Int.equal i1 i2 && List.equal (==) j1 j2 && constr_pattern_eq p1 p2 and fixpoint_eq ((arg1, i1), r1) ((arg2, i2), r2) = Int.equal i1 i2 && @@ -167,11 +167,11 @@ let pattern_of_constr env sigma t = let cip = { cip_style = ci.ci_pp_info.style; cip_ind = Some ci.ci_ind; - cip_ind_args = Some (ci.ci_pp_info.ind_nargs); + cip_ind_tags = Some ci.ci_pp_info.ind_tags; cip_extensible = false } in let branch_of_constr i c = - (i, ci.ci_cstr_ndecls.(i), pattern_of_constr env c) + (i, ci.ci_pp_info.cstr_tags.(i), pattern_of_constr env c) in PCase (cip, pattern_of_constr env p, pattern_of_constr env a, Array.to_list (Array.mapi branch_of_constr br)) @@ -360,17 +360,18 @@ let rec pat_of_raw metas vars = function let cip = { cip_style = LetStyle; cip_ind = None; - cip_ind_args = None; + cip_ind_tags = None; cip_extensible = false } in + let tags = List.map (fun _ -> false) nal (* Approximation which can be without let-ins... *) in PCase (cip, PMeta None, pat_of_raw metas vars b, - [0,1,pat_of_raw metas vars c]) + [0,tags,pat_of_raw metas vars c]) | GCases (loc,sty,p,[c,(na,indnames)],brs) -> let get_ind = function | (_,_,[PatCstr(_,(ind,_),_,_)],_)::_ -> Some ind | _ -> None in - let ind_nargs,ind = match indnames with + let ind_tags,ind = match indnames with | Some (_,ind,nal) -> Some (List.length nal), Some ind | None -> None, get_ind brs in @@ -385,7 +386,7 @@ let rec pat_of_raw metas vars = function let info = { cip_style = sty; cip_ind = ind; - cip_ind_args = ind_nargs; + cip_ind_tags = None; cip_extensible = ext } in (* Nota : when we have a non-trivial predicate, @@ -416,7 +417,8 @@ and pats_of_glob_branches loc metas vars ind brs = let vars' = List.rev lna @ vars in let pat = rev_it_mkPLambda lna (pat_of_raw metas vars' br) in let ext,pats = get_pat (Int.Set.add (j-1) indexes) brs in - ext, ((j-1, List.length lv, pat) :: pats) + let tags = List.map (fun _ -> false) lv (* approximation, w/o let-in *) in + ext, ((j-1, tags, pat) :: pats) | (loc,_,_,_) :: _ -> err loc (Pp.str "Non supported pattern.") in get_pat Int.Set.empty brs |