Module Esubst
Explicit substitutions
type 'a subsExplicit substitutions for some type of terms
'a.Assuming terms enjoy a notion of typability Γ ⊢ t : A, where Γ is a telescope and A a type, substitutions can be typed as Γ ⊢ σ : Δ, where as a first approximation σ is a list of terms u₁; ...; uₙ s.t. Δ := (x₁ : A₁), ..., (xₙ : Aₙ) and Γ ⊢ uᵢ : Aᵢ
u₁...uᵢ₋₁for all 1 ≤ i ≤ n.Substitutions can be applied to terms as follows, and furthermore if Γ ⊢ σ : Δ and Δ ⊢ t : A, then Γ ⊢ t
σ: Aσ.We make the typing rules explicit below, but we omit the explicit De Bruijn fidgetting and leave relocations implicit in terms and types.
val subs_id : int -> 'a subsAssuming |Γ| = n, Γ ⊢ subs_id n : Γ
val subs_cons : 'a -> 'a subs -> 'a subsAssuming Γ ⊢ σ : Δ and Γ ⊢ t : A
σ, then Γ ⊢ subs_cons t σ : Δ, A
val subs_shft : (int * 'a subs) -> 'a subsAssuming Γ ⊢ σ : Δ and |Ξ| = n, then Γ, Ξ ⊢ subs_shft (n, σ) : Δ
val subs_liftn : int -> 'a subs -> 'a subsAssuming Γ ⊢ σ : Δ and |Ξ| = n, then Γ, Ξ ⊢ subs_liftn n σ : Δ, Ξ
val expand_rel : int -> 'a subs -> (int * 'a, int * int option) Util.unionexpand_rel k subsexpands de Bruijnkin the explicit substitutionsubs. The result is either (Inl(lams,v)) when the variable is substituted by valuevunder lams binders (i.e. v *has* to be shifted by lams), or (Inr (k',p)) when the variable k is just relocated as k'; p is None if the variable points inside subs and Some(k) if the variable points k bindings beyond subs (cf argument of ESID).
val is_subs_id : 'a subs -> boolTests whether a substitution behaves like the identity
type lift= private|ELID|ELSHFT of lift * int|ELLFT of int * liftCompact representation of explicit relocations
ELSHFT(l,n)== lift ofn, then applylift l.ELLFT(n,l)== applylto de Bruijn >ni.e under n binders.
Invariant ensured by the private flag: no lift contains two consecutive
ELSHFTnor two consecutiveELLFT.Relocations are a particular kind of substitutions that only contain variables. In particular,
el_*enjoys the same typing rules as the equivalent substitution functionsubs_*.
val el_id : liftval el_shft : int -> lift -> liftval el_liftn : int -> lift -> liftval el_lift : lift -> liftval reloc_rel : int -> lift -> intval is_lift_id : lift -> boolval lift_subst : (lift -> 'a -> 'b) -> lift -> 'a subs -> 'b subsLift applied to substitution:
lift_subst mk_clos el scomputes a substitution equivalent to applying el then s. Argument mk_clos is used when a closure has to be created, i.e. when el is applied on an element of s.That is, if Γ ⊢ e : Δ and Δ ⊢ σ : Ξ, then Γ ⊢ lift_subst mk e σ : Ξ.
module Internal : sig ... endDebugging utilities