Skip to content

Commit ebc7aaf

Browse files
committed
Add documentation for CClosure.to_constr and
overhaul documentation for esubst lifts
1 parent 8b03949 commit ebc7aaf

File tree

3 files changed

+76
-39
lines changed

3 files changed

+76
-39
lines changed

kernel/cClosure.ml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,20 @@ let subst_context e ctx =
504504
in
505505
snd @@ subst_context ctx
506506

507-
(* The inverse of mk_clos: move back to constr *)
507+
(** The inverse of mk_clos: move back to constr
508+
Assuming [Γ ⊢ lfts : Δ] and [Δ ⊢ v],
509+
we get [Γ ⊢ to_constr lfts v]
510+
511+
Crucially, in the case of [FLIFT]s which are the sole reason
512+
why lifts are needed here, we have the following:
513+
assuming [Γ ⊢ lfts : Δ, Δ'] and [Δ, Δ' ⊢ FLIFT(|Δ'|, v)] (i.e. [Δ ⊢ v])
514+
we get [Γ ⊢ el_shft n lfts : Δ]; so [Γ ⊢ to_constr (el_shftn n lfts) v]
515+
516+
In cases like [FCLOS(t, σ)] where substitutions happen,
517+
we have [Γ ⊢ lfts : Δ], [Δ ⊢ σ : Ξ] and [Ξ ⊢ v]
518+
so we compute [Γ ⊢ comp_subs lfts σ : Ξ]
519+
where [comp_subs lfts σ] returns a constr substitution,
520+
that can be applied to [v] *)
508521
let rec to_constr lfts v =
509522
match v.term with
510523
| FRel i -> mkRel (reloc_rel i lfts)

kernel/esubst.ml

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ open Util
1919
(*********************)
2020

2121
(* Explicit lifts and basic operations *)
22-
(* Invariant to preserve in this module: no lift contains two consecutive
23-
[ELSHFT] nor two consecutive [ELLFT]. *)
22+
(* Invariant to preserve in this module: no lift contains an [ELLFT] of [ELID],
23+
two consecutive [ELLFT] or two consecutive [ELSHFT]. *)
2424

2525
(* Terminology comes from substitution calculi (see e.g. Hardin et al.).
2626
That is, what is called a lift in Rocq is made of what is called in
@@ -29,9 +29,15 @@ open Util
2929
can be iterated as represented in the type [lift] *)
3030
type lift =
3131
| ELID
32-
| ELSHFT of lift * int (* ELSHFT(l,n) == lift of n, then apply lift l *)
33-
| ELLFT of int * lift (* ELLFT(n,l) == apply l to de Bruijn > n *)
34-
(* i.e under n binders *)
32+
(** [id] in substitution calculi; for all [Γ], [Γ ⊢ ELID : Γ] *)
33+
34+
| ELSHFT of lift * int
35+
(** [↑^n ∘ σ] in substitution calculi (i.e. a shift of [n], then [σ]);
36+
assuming [Γ ⊢ σ : Δ, Ξ] and [n = |Ξ|], then [Γ ⊢ ELSHFT (σ, n) : Δ] *)
37+
38+
| ELLFT of int * lift
39+
(** [⇑^n(σ)] in substitution calculi (i.e. [σ] under [n] binders);
40+
assuming [Γ ⊢ σ : Δ] and [n = |Ξ|], then [Γ, Ξ ⊢ ELLFT (n, σ) : Δ, Ξ] *)
3541

3642
let el_id = ELID
3743

@@ -268,21 +274,35 @@ let rec lift_subst mk e s = match s with
268274
module Internal =
269275
struct
270276

271-
type weakening = LIFT of int * weakening | WEAK of int * weakening | ID
272-
(* More intuitive representation for weakenings
273-
Instead of using ELSHFT (s ⟼ ↑^n ∘ s), uses WEAK (s ⟼ s ∘ ↑^n) *)
277+
(** More intuitive representation for weakenings
278+
Instead of using ELSHFT (s ⟼ ↑^n ∘ s), uses WEAK (s ⟼ s ∘ ↑^n) *)
279+
type weakening =
280+
| ID
281+
(** [id] in substitution calculi; for all [Γ], [Γ ⊢ ID : Γ] *)
282+
283+
| LIFT of int * weakening
284+
(** [⇑^n(σ)] in substitution calculi (i.e. [σ] under [n] binders);
285+
assuming [Γ ⊢ σ : Δ] and [n = |Ξ|], then [Γ, Ξ ⊢ LIFT (n, σ) : Δ, Ξ] *)
286+
287+
| WEAK of int * weakening
288+
(** [σ ∘ ↑^n] in substitution calculi (i.e. [σ], then a shift of [n]);
289+
assuming [Γ ⊢ σ : Δ] and [n = |Ξ|], then [Γ, Ξ ⊢ WEAK (n, σ) : Δ] *)
274290

275291
(* compose a relocation of magnitude n *)
276292
let weak n = function
277293
| WEAK (k, w) -> WEAK (k+n, w)
278294
| w -> WEAK (n, w)
295+
296+
(** Assuming [Γ ⊢ σ : Δ] and [|Ξ| = n], then [Γ, Ξ ⊢ weak n σ : Δ] *)
279297
let weak n w = if Int.equal n 0 then w else weak n w
280298

281299
(* cross n binders *)
282300
let lift n = function
283301
| ID -> ID
284302
| LIFT (k, w) -> LIFT (n+k, w)
285303
| w -> LIFT (n, w)
304+
305+
(** Assuming [Γ ⊢ σ : Δ] and [|Ξ| = n], then [Γ, Ξ ⊢ lift n σ : Δ, Ξ] *)
286306
let lift n w = if Int.equal n 0 then w else lift n w
287307

288308
let rec weakening_of_lift pending =

kernel/esubst.mli

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@
1313
(** {6 Explicit substitutions } *)
1414
(** Explicit substitutions for some type of terms ['a].
1515
16-
Assuming terms enjoy a notion of typability Γ ⊢ t : A, where Γ is a
17-
telescope and A a type, substitutions can be typed as Γ ⊢ σ : Δ, where
18-
as a first approximation σ is a list of terms u₁; ...; uₙ s.t.
19-
Δ := (x₁ : A₁), ..., (xₙ : Aₙ) and Γ ⊢ uᵢ : Aᵢ{u₁...uᵢ₋₁} for all 1 ≤ i ≤ n.
16+
Assuming terms enjoy a notion of typability [Γ ⊢ t : A], where [Γ] is a
17+
telescope and [A] a type, substitutions can be typed as [Γ ⊢ σ : Δ], where
18+
as a first approximation [σ] is a list of terms [[u₁; ...; uₙ]] s.t.
19+
[Δ := (x₁ : A₁), ..., (xₙ : Aₙ)] and [Γ ⊢ uᵢ : Aᵢ{u₁...uᵢ₋₁}]
20+
for all [1 ≤ i ≤ n].
2021
2122
Substitutions can be applied to terms as follows, and furthermore
22-
if Γ ⊢ σ : Δ and Δ ⊢ t : A, then Γ ⊢ t{σ} : A{σ}.
23+
if [Γ ⊢ σ : Δ] and [Δ ⊢ t : A], then [Γ ⊢ t{σ} : A{σ}].
2324
2425
We make the typing rules explicit below, but we omit the explicit De Bruijn
2526
fidgetting and leave relocations implicit in terms and types.
@@ -29,79 +30,82 @@ type 'a subs
2930

3031
(** Derived constructors granting basic invariants *)
3132

32-
(** Assuming |Γ| = n, Γ ⊢ subs_id n : Γ *)
33+
(** Assuming [|Γ| = n], [Γ ⊢ subs_id n : Γ] *)
3334
val subs_id : int -> 'a subs
3435

35-
(** Assuming Γ ⊢ σ : Δ and Γ ⊢ t : A{σ}, then Γ ⊢ subs_cons t σ : Δ, A *)
36+
(** Assuming [Γ ⊢ σ : Δ] and [Γ ⊢ t : A{σ}], then [Γ ⊢ subs_cons t σ : Δ, A] *)
3637
val subs_cons: 'a -> 'a subs -> 'a subs
3738

38-
(** Assuming Γ ⊢ σ : Δ and |Ξ| = n, then Γ, Ξ ⊢ subs_shft (n, σ) : Δ *)
39+
(** Assuming [Γ ⊢ σ : Δ] and [|Ξ| = n], then [Γ, Ξ ⊢ subs_shft (n, σ) : Δ] *)
3940
val subs_shft: int * 'a subs -> 'a subs
4041

41-
(** Assuming Γ ⊢ σ : Δ and |Ξ| = n, then Γ, Ξ ⊢ subs_liftn n σ : Δ, Ξ *)
42+
(** Assuming [Γ ⊢ σ : Δ] and [|Ξ| = n], then [Γ, Ξ ⊢ subs_liftn n σ : Δ, Ξ] *)
4243
val subs_liftn: int -> 'a subs -> 'a subs
4344

4445
(** Unary variant of {!subst_liftn}. *)
4546
val subs_lift: 'a subs -> 'a subs
4647

4748
(** [expand_rel k subs] expands de Bruijn [k] in the explicit substitution
48-
[subs]. The result is either (Inl(lams,v)) when the variable is
49-
substituted by value [v] under [lams] binders (i.e. v *has* to be
50-
shifted by [lams]), or (Inr (k',p)) when the variable k is just relocated
51-
as k'; p is None if the variable points inside subs and Some(k) if the
52-
variable points k bindings beyond subs (cf argument of ESID).
49+
[subs]. The result is either [Inl (lams, v)] when the variable is
50+
substituted by value [v] under [lams] binders (i.e. [v] *has* to be
51+
shifted by [lams]), or [Inr (k', p)] when the variable [k] is just
52+
relocated as [k']; [p] is [None] if the variable points inside [subs]
53+
and [Some k] if the variable points [k] bindings beyond [subs]
54+
(cf argument of [ESID]).
5355
*)
5456
val expand_rel: int -> 'a subs -> (int * 'a, int * int option) Util.union
5557

5658
(** Tests whether a substitution behaves like the identity *)
5759
val is_subs_id: 'a subs -> bool
5860

59-
(** {6 Compact representation } *)
61+
(** {6 Compact representation} *)
6062
(** Compact representation of explicit relocations
61-
- [ELSHFT(l,n)] == lift of [n], then apply [lift l].
62-
- [ELLFT(n,l)] == apply [l] to de Bruijn > [n] i.e under n binders.
63+
- [ELID]: identity relocation [id]
64+
- [ELSHFT (σ, n)]: shift of [n], then [σ]; [↑^n ∘ σ] in sigma calculi
65+
- [ELLFT (n, σ)]: apply [σ] to de Bruijn > [n], i.e under [n] binders;
66+
[⇑^n(σ)] in sigma calculi
6367
64-
Invariant ensured by the private flag: no lift contains two consecutive
65-
[ELSHFT] nor two consecutive [ELLFT].
68+
Invariant ensured by the private flag: no lift contains an [ELLFT] of [ELID],
69+
two consecutive [ELLFT] or two consecutive [ELSHFT].
6670
6771
Relocations are a particular kind of substitutions that only contain
68-
variables. In particular, [el_*] enjoys the same typing rules as the
72+
variables. In particular, [el_*] enjoys similar typing rules as the
6973
equivalent substitution function [subs_*].
7074
*)
7175
type lift = private
7276
| ELID
7377
| ELSHFT of lift * int
7478
| ELLFT of int * lift
7579

76-
(** For arbitrary Γ: Γ ⊢ el_id : Γ *)
80+
(** For arbitrary Γ, [Γ ⊢ el_id : Γ] *)
7781
val el_id : lift
7882

79-
(** Assuming Γ ⊢ σ : Δ₁, Δ₂ and |Δ₂| = n, then Γ ⊢ el_shft n σ : Δ *)
83+
(** Assuming [Γ ⊢ σ : Δ, Ξ] and [|Ξ| = n], then [Γ ⊢ el_shft n σ : Δ] *)
8084
val el_shft : int -> lift -> lift
8185

82-
(** Assuming Γ ⊢ σ : Δ and |Ξ| = n, then Γ, Ξ ⊢ el_liftn n σ : Δ, Ξ *)
86+
(** Assuming [Γ ⊢ σ : Δ] and [|Ξ| = n], then [Γ, Ξ ⊢ el_liftn n σ : Δ, Ξ] *)
8387
val el_liftn : int -> lift -> lift
8488

8589
(** Unary variant of {!el_liftn}. *)
8690
val el_lift : lift -> lift
8791

88-
(** Assuming Γ₁, A, Γ₂ ⊢ σ : Δ₁, A, Δ₂ and Δ₁, A, Δ₂ ⊢ n : A,
89-
then Γ₁, A, Γ₂ ⊢ reloc_rel n σ : A *)
92+
(** Assuming [Γ₁, A, Γ₂ ⊢ σ : Δ₁, A, Δ₂] and [Δ₁, A, Δ₂ ⊢ n : A],
93+
then [Γ₁, A, Γ₂ ⊢ reloc_rel n σ : A] *)
9094
val reloc_rel : int -> lift -> int
9195

9296
val is_lift_id : lift -> bool
9397

9498
(** Lift applied to substitution: [lift_subst mk_clos el s] computes a
95-
substitution equivalent to applying el then s. Argument
96-
mk_clos is used when a closure has to be created, i.e. when
97-
el is applied on an element of s.
99+
substitution equivalent to applying [el] then [s]. Argument
100+
[mk_clos] is used when a closure has to be created, i.e. when
101+
[el] is applied on an element of [s].
98102
99-
That is, if Γ ⊢ e : Δ and Δ ⊢ σ : Ξ, then Γ ⊢ lift_subst mk e σ : Ξ.
103+
That is, if [Γ ⊢ e : Δ] and [Δ ⊢ σ : Ξ], then [Γ ⊢ lift_subst mk e σ : Ξ].
100104
*)
101105
val lift_subst : (lift -> 'a -> 'b) -> lift -> 'a subs -> 'b subs
102106

107+
(** Structural equality for lifts *)
103108
val eq_lift : lift -> lift -> bool
104-
(** Equality for lifts *)
105109

106110
(** Debugging utilities *)
107111
module Internal :

0 commit comments

Comments
 (0)