Skip to content

Commit d72e5c1

Browse files
committed
Change the representation of kernel case.
We store bound variable names instead of functions for both branches and predicate, and we furthermore add the parameters in the node. Let bindings are not taken into account and require an environment lookup for retrieval.
1 parent 6632739 commit d72e5c1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+1210
-631
lines changed

checker/values.ml

+5-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ let rec v_constr =
147147
[|v_puniverses v_cst|]; (* Const *)
148148
[|v_puniverses v_ind|]; (* Ind *)
149149
[|v_puniverses v_cons|]; (* Construct *)
150-
[|v_caseinfo;v_constr;v_case_invert;v_constr;Array v_constr|]; (* Case *)
150+
[|v_caseinfo;v_instance; Array v_constr; v_case_return; v_case_invert; v_constr; Array v_case_branch|]; (* Case *)
151151
[|v_fix|]; (* Fix *)
152152
[|v_cofix|]; (* CoFix *)
153153
[|v_proj;v_constr|]; (* Proj *)
@@ -162,6 +162,10 @@ and v_fix = Tuple ("pfixpoint", [|Tuple ("fix2",[|Array Int;Int|]);v_prec|])
162162
and v_cofix = Tuple ("pcofixpoint",[|Int;v_prec|])
163163
and v_case_invert = Sum ("case_inversion", 1, [|[|v_instance;Array v_constr|]|])
164164

165+
and v_case_branch = Tuple ("case_branch", [|Array (v_binder_annot v_name); v_constr|])
166+
167+
and v_case_return = Tuple ("case_return", [|Array (v_binder_annot v_name); v_constr|])
168+
165169
let v_rdecl = v_sum "rel_declaration" 0
166170
[| [|v_binder_annot v_name; v_constr|]; (* LocalAssum *)
167171
[|v_binder_annot v_name; v_constr; v_constr|] |] (* LocalDef *)

dev/top_printers.ml

+18-6
Original file line numberDiff line numberDiff line change
@@ -307,9 +307,9 @@ let constr_display csr =
307307
"MutConstruct(("^(MutInd.to_string sp)^","^(string_of_int i)^"),"
308308
^","^(universes_display u)^(string_of_int j)^")"
309309
| Proj (p, c) -> "Proj("^(Constant.to_string (Projection.constant p))^","^term_display c ^")"
310-
| Case (ci,p,iv,c,bl) ->
310+
| Case (ci,u,pms,(_,p),iv,c,bl) ->
311311
"MutCase(<abs>,"^(term_display p)^","^(term_display c)^","
312-
^(array_display bl)^")"
312+
^(array_display (Array.map snd bl))^")"
313313
| Fix ((t,i),(lna,tl,bl)) ->
314314
"Fix(([|"^(Array.fold_right (fun x i -> (string_of_int x)^(if not(i="")
315315
then (";"^i) else "")) t "")^"|],"^(string_of_int i)^"),"
@@ -420,13 +420,25 @@ let print_pure_constr csr =
420420
print_int i; print_string ","; print_int j;
421421
print_string ","; universes_display u;
422422
print_string ")"
423-
| Case (ci,p,iv,c,bl) ->
423+
| Case (ci,u,pms,p,iv,c,bl) ->
424+
let pr_ctx (nas, c) =
425+
Array.iter (fun na -> print_cut (); name_display na) nas;
426+
print_string " |- ";
427+
box_display c
428+
in
424429
open_vbox 0;
425-
print_string "<"; box_display p; print_string ">";
426430
print_cut(); print_string "Case";
427-
print_space(); box_display c; print_space (); print_string "of";
431+
print_space(); box_display c; print_space ();
432+
print_cut(); print_string "in";
433+
print_cut(); print_string "Ind(";
434+
sp_display (fst ci.ci_ind);
435+
print_string ","; print_int (snd ci.ci_ind); print_string ")";
436+
print_string "@{"; universes_display u; print_string "}";
437+
Array.iter (fun x -> print_space (); box_display x) pms;
438+
print_cut(); print_string "return <"; pr_ctx p; print_string ">";
439+
print_cut(); print_string "with";
428440
open_vbox 0;
429-
Array.iter (fun x -> print_cut(); box_display x) bl;
441+
Array.iter (fun x -> print_cut(); pr_ctx x) bl;
430442
close_box();
431443
print_cut();
432444
print_string "end";

engine/eConstr.ml

+78-16
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ include (Evd.MiniEConstr : module type of Evd.MiniEConstr
3535
type types = t
3636
type constr = t
3737
type existential = t pexistential
38+
type case_return = t pcase_return
39+
type case_branch = t pcase_branch
40+
type case_invert = (t, EInstance.t) pcase_invert
41+
type case = (t, t, EInstance.t) pcase
3842
type fixpoint = (t, t) pfixpoint
3943
type cofixpoint = (t, t) pcofixpoint
4044
type unsafe_judgment = (constr, types) Environ.punsafe_judgment
@@ -69,7 +73,7 @@ let mkInd i = of_kind (Ind (in_punivs i))
6973
let mkConstructU pc = of_kind (Construct pc)
7074
let mkConstruct c = of_kind (Construct (in_punivs c))
7175
let mkConstructUi ((ind,u),i) = of_kind (Construct ((ind,i),u))
72-
let mkCase (ci, c, iv, r, p) = of_kind (Case (ci, c, iv, r, p))
76+
let mkCase (ci, u, pms, c, iv, r, p) = of_kind (Case (ci, u, pms, c, iv, r, p))
7377
let mkFix f = of_kind (Fix f)
7478
let mkCoFix f = of_kind (CoFix f)
7579
let mkProj (p, c) = of_kind (Proj (p, c))
@@ -195,7 +199,7 @@ let destCoFix sigma c = match kind sigma c with
195199
| _ -> raise DestKO
196200

197201
let destCase sigma c = match kind sigma c with
198-
| Case (ci, t, iv, c, p) -> (ci, t, iv, c, p)
202+
| Case (ci, u, pms, t, iv, c, p) -> (ci, u, pms, t, iv, c, p)
199203
| _ -> raise DestKO
200204

201205
let destProj sigma c = match kind sigma c with
@@ -320,19 +324,28 @@ let existential_type = Evd.existential_type
320324

321325
let lift n c = of_constr (Vars.lift n (unsafe_to_constr c))
322326

323-
let map_under_context f n c =
324-
let f c = unsafe_to_constr (f (of_constr c)) in
325-
of_constr (Constr.map_under_context f n (unsafe_to_constr c))
326-
let map_branches f ci br =
327-
let f c = unsafe_to_constr (f (of_constr c)) in
328-
of_constr_array (Constr.map_branches f ci (unsafe_to_constr_array br))
329-
let map_return_predicate f ci p =
330-
let f c = unsafe_to_constr (f (of_constr c)) in
331-
of_constr (Constr.map_return_predicate f ci (unsafe_to_constr p))
327+
let of_branches : Constr.case_branch array -> case_branch array =
328+
match Evd.MiniEConstr.unsafe_eq with
329+
| Refl -> fun x -> x
330+
331+
let unsafe_to_branches : case_branch array -> Constr.case_branch array =
332+
match Evd.MiniEConstr.unsafe_eq with
333+
| Refl -> fun x -> x
334+
335+
let of_return : Constr.case_return -> case_return =
336+
match Evd.MiniEConstr.unsafe_eq with
337+
| Refl -> fun x -> x
332338

333-
let map_user_view sigma f c =
339+
let unsafe_to_return : case_return -> Constr.case_return =
340+
match Evd.MiniEConstr.unsafe_eq with
341+
| Refl -> fun x -> x
342+
343+
let map_branches f br =
344+
let f c = unsafe_to_constr (f (of_constr c)) in
345+
of_branches (Constr.map_branches f (unsafe_to_branches br))
346+
let map_return_predicate f p =
334347
let f c = unsafe_to_constr (f (of_constr c)) in
335-
of_constr (Constr.map_user_view f (unsafe_to_constr (whd_evar sigma c)))
348+
of_return (Constr.map_return_predicate f (unsafe_to_return p))
336349

337350
let map sigma f c =
338351
let f c = unsafe_to_constr (f (of_constr c)) in
@@ -346,7 +359,49 @@ let iter sigma f c =
346359
let f c = f (of_constr c) in
347360
Constr.iter f (unsafe_to_constr (whd_evar sigma c))
348361

349-
let iter_with_full_binders sigma g f n c =
362+
let expand_case env _sigma (ci, u, pms, p, iv, c, bl) =
363+
let u = EInstance.unsafe_to_instance u in
364+
let pms = unsafe_to_constr_array pms in
365+
let p = unsafe_to_return p in
366+
let iv = unsafe_to_case_invert iv in
367+
let c = unsafe_to_constr c in
368+
let bl = unsafe_to_branches bl in
369+
let (ci, p, iv, c, bl) = Inductive.expand_case env (ci, u, pms, p, iv, c, bl) in
370+
let p = of_constr p in
371+
let c = of_constr c in
372+
let iv = of_case_invert iv in
373+
let bl = of_constr_array bl in
374+
(ci, p, iv, c, bl)
375+
376+
let expand_branch env _sigma u pms (ind, i) (nas, _br) =
377+
let open Declarations in
378+
let u = EInstance.unsafe_to_instance u in
379+
let pms = unsafe_to_constr_array pms in
380+
let (mib, mip) = Inductive.lookup_mind_specif env ind in
381+
let paramdecl = Vars.subst_instance_context u mib.mind_params_ctxt in
382+
let paramsubst = Vars.subst_of_rel_context_instance paramdecl (Array.to_list pms) in
383+
let subst = paramsubst @ Inductive.ind_subst (fst ind) mib u in
384+
let (ctx, _) = mip.mind_nf_lc.(i - 1) in
385+
let (ctx, _) = List.chop mip.mind_consnrealdecls.(i - 1) ctx in
386+
let ans = Inductive.instantiate_context u subst nas ctx in
387+
let ans : rel_context = match Evd.MiniEConstr.unsafe_eq with Refl -> ans in
388+
ans
389+
390+
let contract_case env _sigma (ci, p, iv, c, bl) =
391+
let p = unsafe_to_constr p in
392+
let iv = unsafe_to_case_invert iv in
393+
let c = unsafe_to_constr c in
394+
let bl = unsafe_to_constr_array bl in
395+
let (ci, u, pms, p, iv, c, bl) = Inductive.contract_case env (ci, p, iv, c, bl) in
396+
let u = EInstance.make u in
397+
let pms = of_constr_array pms in
398+
let p = of_return p in
399+
let iv = of_case_invert iv in
400+
let c = of_constr c in
401+
let bl = of_branches bl in
402+
(ci, u, pms, p, iv, c, bl)
403+
404+
let iter_with_full_binders env sigma g f n c =
350405
let open Context.Rel.Declaration in
351406
match kind sigma c with
352407
| (Rel _ | Meta _ | Var _ | Sort _ | Const _ | Ind _
@@ -357,7 +412,10 @@ let iter_with_full_binders sigma g f n c =
357412
| LetIn (na,b,t,c) -> f n b; f n t; f (g (LocalDef (na, b, t)) n) c
358413
| App (c,l) -> f n c; Array.Fun1.iter f n l
359414
| Evar (_,l) -> List.iter (fun c -> f n c) l
360-
| Case (_,p,iv,c,bl) -> f n p; iter_invert (f n) iv; f n c; Array.Fun1.iter f n bl
415+
| Case (ci,u,pms,p,iv,c,bl) ->
416+
(* FIXME: skip the type annotations *)
417+
let (ci, p, iv, c, bl) = expand_case env sigma (ci, u, pms, p, iv, c, bl) in
418+
f n p; iter_invert (f n) iv; f n c; Array.Fun1.iter f n bl
361419
| Proj (p,c) -> f n c
362420
| Fix (_,(lna,tl,bl)) ->
363421
Array.iter (f n) tl;
@@ -566,9 +624,13 @@ let universes_of_constr sigma c =
566624
| Array (u,_,_,_) ->
567625
let s = LSet.fold LSet.add (Instance.levels (EInstance.kind sigma u)) s in
568626
fold sigma aux s c
569-
| Case (_,_,CaseInvert {univs;args=_},_,_) ->
627+
| Case (_,u,_,_,CaseInvert {univs;args=_},_,_) ->
628+
let s = LSet.fold LSet.add (Instance.levels (EInstance.kind sigma u)) s in
570629
let s = LSet.fold LSet.add (Instance.levels (EInstance.kind sigma univs)) s in
571630
fold sigma aux s c
631+
| Case (_, u, _, _, NoInvert, _, _) ->
632+
let s = LSet.fold LSet.add (Instance.levels (EInstance.kind sigma u)) s in
633+
fold sigma aux s c
572634
| _ -> fold sigma aux s c
573635
in aux LSet.empty c
574636

engine/eConstr.mli

+23-9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ type t = Evd.econstr
2020
type types = t
2121
type constr = t
2222
type existential = t pexistential
23+
type case_return = t pcase_return
24+
type case_branch = t pcase_branch
2325
type fixpoint = (t, t) pfixpoint
2426
type cofixpoint = (t, t) pcofixpoint
2527
type unsafe_judgment = (constr, types) Environ.punsafe_judgment
@@ -58,6 +60,9 @@ sig
5860
val is_empty : t -> bool
5961
end
6062

63+
type case_invert = (t, EInstance.t) pcase_invert
64+
type case = (t, t, EInstance.t) pcase
65+
6166
type 'a puniverses = 'a * EInstance.t
6267

6368
(** {5 Destructors} *)
@@ -128,7 +133,7 @@ val mkIndU : inductive * EInstance.t -> t
128133
val mkConstruct : constructor -> t
129134
val mkConstructU : constructor * EInstance.t -> t
130135
val mkConstructUi : (inductive * EInstance.t) * int -> t
131-
val mkCase : case_info * t * (t,EInstance.t) case_invert * t * t array -> t
136+
val mkCase : case -> t
132137
val mkFix : (t, t) pfixpoint -> t
133138
val mkCoFix : (t, t) pcofixpoint -> t
134139
val mkArrow : t -> Sorts.relevance -> t -> t
@@ -199,7 +204,7 @@ val destConst : Evd.evar_map -> t -> Constant.t * EInstance.t
199204
val destEvar : Evd.evar_map -> t -> t pexistential
200205
val destInd : Evd.evar_map -> t -> inductive * EInstance.t
201206
val destConstruct : Evd.evar_map -> t -> constructor * EInstance.t
202-
val destCase : Evd.evar_map -> t -> case_info * t * (t,EInstance.t) case_invert * t * t array
207+
val destCase : Evd.evar_map -> t -> case
203208
val destProj : Evd.evar_map -> t -> Projection.t * t
204209
val destFix : Evd.evar_map -> t -> (t, t) pfixpoint
205210
val destCoFix : Evd.evar_map -> t -> (t, t) pcofixpoint
@@ -250,14 +255,12 @@ val compare_constr : Evd.evar_map -> (t -> t -> bool) -> t -> t -> bool
250255
(** {6 Iterators} *)
251256

252257
val map : Evd.evar_map -> (t -> t) -> t -> t
253-
val map_user_view : Evd.evar_map -> (t -> t) -> t -> t
254258
val map_with_binders : Evd.evar_map -> ('a -> 'a) -> ('a -> t -> t) -> 'a -> t -> t
255-
val map_under_context : (t -> t) -> int -> t -> t
256-
val map_branches : (t -> t) -> case_info -> t array -> t array
257-
val map_return_predicate : (t -> t) -> case_info -> t -> t
259+
val map_branches : (t -> t) -> case_branch array -> case_branch array
260+
val map_return_predicate : (t -> t) -> case_return -> case_return
258261
val iter : Evd.evar_map -> (t -> unit) -> t -> unit
259262
val iter_with_binders : Evd.evar_map -> ('a -> 'a) -> ('a -> t -> unit) -> 'a -> t -> unit
260-
val iter_with_full_binders : Evd.evar_map -> (rel_declaration -> 'a -> 'a) -> ('a -> t -> unit) -> 'a -> t -> unit
263+
val iter_with_full_binders : Environ.env -> Evd.evar_map -> (rel_declaration -> 'a -> 'a) -> ('a -> t -> unit) -> 'a -> t -> unit
261264
val fold : Evd.evar_map -> ('a -> t -> 'a) -> 'a -> t -> 'a
262265

263266
(** Gather the universes transitively used in the term, including in the
@@ -337,6 +340,17 @@ val fresh_global :
337340
val is_global : Evd.evar_map -> GlobRef.t -> t -> bool
338341
[@@ocaml.deprecated "Use [EConstr.isRefX] instead."]
339342

343+
val expand_case : Environ.env -> Evd.evar_map ->
344+
case -> (case_info * t * case_invert * t * t array)
345+
346+
val expand_branch : Environ.env -> Evd.evar_map ->
347+
EInstance.t -> t array -> constructor -> case_branch -> rel_context
348+
(** Given a universe instance and parameters for the inductive type,
349+
constructs the typed context in which the branch lives. *)
350+
351+
val contract_case : Environ.env -> Evd.evar_map ->
352+
(case_info * t * case_invert * t * t array) -> case
353+
340354
(** {5 Extra} *)
341355

342356
val of_existential : Constr.existential -> existential
@@ -345,7 +359,7 @@ val of_rel_decl : (Constr.t, Constr.types) Context.Rel.Declaration.pt -> (t, typ
345359

346360
val to_rel_decl : Evd.evar_map -> (t, types) Context.Rel.Declaration.pt -> (Constr.t, Constr.types) Context.Rel.Declaration.pt
347361

348-
val of_case_invert : (Constr.t,Univ.Instance.t) case_invert -> (t,EInstance.t) case_invert
362+
val of_case_invert : Constr.case_invert -> case_invert
349363

350364
(** {5 Unsafe operations} *)
351365

@@ -371,7 +385,7 @@ sig
371385
val to_instance : EInstance.t -> Univ.Instance.t
372386
(** Physical identity. Does not care for normalization. *)
373387

374-
val to_case_invert : (t,EInstance.t) case_invert -> (Constr.t,Univ.Instance.t) case_invert
388+
val to_case_invert : case_invert -> Constr.case_invert
375389

376390
val eq : (t, Constr.t) eq
377391
(** Use for transparent cast between types. *)

engine/evarutil.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ let head_evar sigma c =
144144
let c = EConstr.Unsafe.to_constr c in
145145
let rec hrec c = match kind c with
146146
| Evar (evk,_) -> evk
147-
| Case (_,_,_,c,_) -> hrec c
147+
| Case (_, _, _, _, _, c, _) -> hrec c
148148
| App (c,_) -> hrec c
149149
| Cast (c,_,_) -> hrec c
150150
| Proj (p, c) -> hrec c

engine/evd.mli

+2-2
Original file line numberDiff line numberDiff line change
@@ -772,8 +772,8 @@ module MiniEConstr : sig
772772
(Constr.t, Constr.types) Context.Named.Declaration.pt
773773
val unsafe_to_rel_decl : (t, t) Context.Rel.Declaration.pt ->
774774
(Constr.t, Constr.types) Context.Rel.Declaration.pt
775-
val of_case_invert : (constr,Univ.Instance.t) case_invert -> (econstr,EInstance.t) case_invert
776-
val unsafe_to_case_invert : (econstr,EInstance.t) case_invert -> (constr,Univ.Instance.t) case_invert
775+
val of_case_invert : (constr,Univ.Instance.t) pcase_invert -> (econstr,EInstance.t) pcase_invert
776+
val unsafe_to_case_invert : (econstr,EInstance.t) pcase_invert -> (constr,Univ.Instance.t) pcase_invert
777777
val of_rel_decl : (Constr.t, Constr.types) Context.Rel.Declaration.pt ->
778778
(t, t) Context.Rel.Declaration.pt
779779
val to_rel_decl : evar_map -> (t, t) Context.Rel.Declaration.pt ->

0 commit comments

Comments
 (0)