Built with Alectryon, running Coq+SerAPI v8.17.0+0.17.1. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+πŸ–±οΈ to focus. On Mac, use ⌘ instead of Ctrl.

Free context structure

Here we instanciate our abstract notion of context structure with the most common example: lists and DeBruijn indices. More pedantically, this is the free context structure over a given set X.

Contexts

Contexts are simply lists, with the purely aesthetic choice of representing cons as coming from the right. Note on paper: we write here "Ξ“ β–Ά x" instead of "Ξ“ , x".

Inductive ctx (X : Type) : Type :=
| cnil : ctx X
| ccon : ctx X -> X -> ctx X.
#[global] Notation "βˆ…β‚“" := (cnil) : ctx_scope.
#[global] Notation "Ξ“ β–Άβ‚“ x" := (ccon Ξ“%ctx x) (at level 40, left associativity) : ctx_scope.

We wish to manipulate intrinsically typed terms. We hence need a tightly typed notion of position in the context: rather than a loose index, var x Ξ“ is a proof of membership of x to Ξ“: a well-scoped and well-typed DeBruijn index.

Inductive var {X} (x : X) : ctx X -> Type :=
| top {Ξ“} : var x (Ξ“ β–Άβ‚“ x)
| pop {Ξ“ y} : var x Ξ“ -> var x (Ξ“ β–Άβ‚“ y).
Definition cvar {X} Ξ“ x := @var X x Ξ“.

A couple basic functions: length, concatenation and pointwise function application.

Equations c_length {X} (Ξ“ : ctx X) : nat :=
  c_length βˆ…β‚“       := Datatypes.O ;
  c_length (Ξ“ β–Άβ‚“ _) := Datatypes.S (c_length Ξ“) .

Equations ccat {X} : ctx X -> ctx X -> ctx X :=
  ccat Ξ“ βˆ…β‚“       := Ξ“ ;
  ccat Ξ“ (Ξ” β–Άβ‚“ x) := ccat Ξ“ Ξ” β–Άβ‚“ x .

Equations c_map {X Y} : (X -> Y) -> ctx X -> ctx Y :=
  c_map f βˆ…β‚“       := cnil ;
  c_map f (Ξ“ β–Άβ‚“ x) := c_map f Ξ“ β–Άβ‚“ f x .

Implementation of the revelant part of the abstract context interface.

#[global] Instance free_context {X} : context X (ctx X) :=
  {| c_emp := cnil ; c_cat := ccat ; c_var := cvar |}.

Basic theory.

X: Type
Ξ“: ctx X

βˆ… +β–Ά Ξ“ = Ξ“
X: Type
Ξ“: ctx X

βˆ… +β–Ά Ξ“ = Ξ“
induction Ξ“; eauto; cbn; f_equal; apply IHΞ“. Qed.
X: Type
Ξ“: ctx X

Ξ“ +β–Ά βˆ… = Ξ“
X: Type
Ξ“: ctx X

Ξ“ +β–Ά βˆ… = Ξ“
reflexivity. Qed.
X, Y: Type
f: X -> Y
Ξ“, Ξ”: ctx X

c_map f (Ξ“ +β–Ά Ξ”) = c_map f Ξ“ +β–Ά c_map f Ξ”
X, Y: Type
f: X -> Y
Ξ“, Ξ”: ctx X

c_map f (Ξ“ +β–Ά Ξ”) = c_map f Ξ“ +β–Ά c_map f Ξ”
induction Ξ”; eauto; cbn; f_equal; apply IHΞ”. Qed.

A view-based inversion package for variables in mapped contexts.

Equations map_has {X Y} {f : X -> Y} (Ξ“ : ctx X) {x} (i : Ξ“ βˆ‹ x) : c_map f Ξ“ βˆ‹ f x :=
  map_has (Ξ“ β–Άβ‚“ _) top     := top ;
  map_has (Ξ“ β–Άβ‚“ _) (pop i) := pop (map_has Ξ“ i) .
#[global] Arguments map_has {X Y f Ξ“ x}.

Variant has_map_view {X Y} {f : X -> Y} {Ξ“} : forall {y}, c_map f Ξ“ βˆ‹ y -> Type :=
| HasMapV {x} (i : Ξ“ βˆ‹ x) : has_map_view (map_has i).

X, Y: Type
f: X -> Y
Ξ“: ctx X
y: Y
i: c_map f Ξ“ βˆ‹ y

has_map_view i
X, Y: Type
f: X -> Y
Ξ“: ctx X
y: Y
i: c_map f Ξ“ βˆ‹ y

has_map_view i
X, Y: Type
f: X -> Y
Ξ“: ctx X
x: X
IHΞ“: forall i : c_map f Ξ“ βˆ‹ f x, has_map_view i

has_map_view top
X, Y: Type
f: X -> Y
Ξ“: ctx X
x: X
y: Y
v: var y (c_map f Ξ“)
IHΞ“: forall i : c_map f Ξ“ βˆ‹ y, has_map_view i
has_map_view (pop v)
X, Y: Type
f: X -> Y
Ξ“: ctx X
x: X
IHΞ“: forall i : c_map f Ξ“ βˆ‹ f x, has_map_view i

has_map_view top
exact (HasMapV top).
X, Y: Type
f: X -> Y
Ξ“: ctx X
x: X
y: Y
v: var y (c_map f Ξ“)
IHΞ“: forall i : c_map f Ξ“ βˆ‹ y, has_map_view i

has_map_view (pop v)
destruct (IHΞ“ v); exact (HasMapV (pop i)). Qed.

Additional goodies.

Definition r_pop {X} {Ξ“ : ctx X} {x} : Ξ“ βŠ† (Ξ“ β–Άβ‚“ x) :=
  fun _ i => pop i.
#[global] Arguments r_pop _ _ _ _/.

Equations a_append {X} {Ξ“ Ξ” : ctx X} {F : Fam₁ X (ctx X)} {a}
  : Ξ“ =[F]> Ξ” -> F Ξ” a -> (Ξ“ β–Άβ‚“ a) =[F]> Ξ” :=
  a_append s z _ top     := z ;
  a_append s z _ (pop i) := s _ i .
#[global] Notation "[ u ,β‚“ x ]" := (a_append u x) (at level 9) : asgn_scope.

X: Type
Ξ“, Ξ”: ctx X
F: Fam₁ X (ctx X)
a: X

Proper (asgn_eq Ξ“ Ξ” ==> eq ==> asgn_eq (Ξ“ β–Άβ‚“ a) Ξ”) a_append
X: Type
Ξ“, Ξ”: ctx X
F: Fam₁ X (ctx X)
a: X

Proper (asgn_eq Ξ“ Ξ” ==> eq ==> asgn_eq (Ξ“ β–Άβ‚“ a) Ξ”) a_append
X: Type
Ξ“, Ξ”: ctx X
F: Fam₁ X (ctx X)
a: X
x, y: Ξ“ =[ F ]> Ξ”
Hu: x ≑ₐ y
x0, y0: F Ξ” a
Hx: x0 = y0
a0: X
i: Ξ“ β–Άβ‚“ a βˆ‹ a0

([x,β‚“ x0])%asgn a0 i = ([y,β‚“ y0])%asgn a0 i
X: Type
Ξ“0, Ξ”: ctx X
F: Fam₁ X (ctx X)
a0: X
x, y: Ξ“0 =[ F ]> Ξ”
Hu: x ≑ₐ y
x0, y0: F Ξ” a0
Hx: x0 = y0

x0 = y0
X: Type
Ξ“1, Ξ”: ctx X
F: Fam₁ X (ctx X)
y1: X
x, y: Ξ“1 =[ F ]> Ξ”
Hu: x ≑ₐ y
x0, y0: F Ξ” y1
Hx: x0 = y0
a0: X
v: var a0 Ξ“1
x a0 v = y a0 v
X: Type
Ξ“0, Ξ”: ctx X
F: Fam₁ X (ctx X)
a0: X
x, y: Ξ“0 =[ F ]> Ξ”
Hu: x ≑ₐ y
x0, y0: F Ξ” a0
Hx: x0 = y0

x0 = y0
exact Hx.
X: Type
Ξ“1, Ξ”: ctx X
F: Fam₁ X (ctx X)
y1: X
x, y: Ξ“1 =[ F ]> Ξ”
Hu: x ≑ₐ y
x0, y0: F Ξ” y1
Hx: x0 = y0
a0: X
v: var a0 Ξ“1

x a0 v = y a0 v
now apply Hu. Qed.

These concrete definition of shifts compute better than their generic counterpart.

Definition r_shift1 {X} {Ξ“ Ξ” : ctx X} {a} (f : Ξ“ βŠ† Ξ”)
  : (Ξ“ β–Άβ‚“ a) βŠ† (Ξ” β–Άβ‚“ a)
  := [ f α΅£βŠ› r_pop ,β‚“ top ].

Definition r_shift2 {X} {Ξ“ Ξ” : ctx X} {a b} (f : Ξ“ βŠ† Ξ”)
  : (Ξ“ β–Άβ‚“ a β–Άβ‚“ b) βŠ† (Ξ” β–Άβ‚“ a β–Άβ‚“ b)
  := [ [ f α΅£βŠ› r_pop α΅£βŠ› r_pop ,β‚“ pop top ] ,β‚“ top ].

Definition r_shift3 {X} {Ξ“ Ξ” : ctx X} {a b c} (f : Ξ“ βŠ† Ξ”)
  : (Ξ“ β–Άβ‚“ a β–Άβ‚“ b β–Άβ‚“ c) βŠ† (Ξ” β–Άβ‚“ a β–Άβ‚“ b β–Άβ‚“ c)
  := [ [ [ f α΅£βŠ› r_pop α΅£βŠ› r_pop α΅£βŠ› r_pop ,β‚“ pop (pop top) ] ,β‚“ pop top ] ,β‚“ top ].

X: Type
Ξ“, Ξ”: ctx X
a: X

Proper (asgn_eq Ξ“ Ξ” ==> asgn_eq (Ξ“ β–Άβ‚“ a) (Ξ” β–Άβ‚“ a)) r_shift1
X: Type
Ξ“, Ξ”: ctx X
a: X

Proper (asgn_eq Ξ“ Ξ” ==> asgn_eq (Ξ“ β–Άβ‚“ a) (Ξ” β–Άβ‚“ a)) r_shift1
intros ?? Hu; unfold r_shift1; now rewrite Hu. Qed.
X: Type
Ξ“, Ξ”: ctx X
a, b: X

Proper (asgn_eq Ξ“ Ξ” ==> asgn_eq (Ξ“ β–Άβ‚“ a β–Άβ‚“ b) (Ξ” β–Άβ‚“ a β–Άβ‚“ b)) r_shift2
X: Type
Ξ“, Ξ”: ctx X
a, b: X

Proper (asgn_eq Ξ“ Ξ” ==> asgn_eq (Ξ“ β–Άβ‚“ a β–Άβ‚“ b) (Ξ” β–Άβ‚“ a β–Άβ‚“ b)) r_shift2
intros ?? Hu; unfold r_shift2; now rewrite Hu. Qed.
X: Type
Ξ“, Ξ”: ctx X
a, b, c: X

Proper (asgn_eq Ξ“ Ξ” ==> asgn_eq (Ξ“ β–Άβ‚“ a β–Άβ‚“ b β–Άβ‚“ c) (Ξ” β–Άβ‚“ a β–Άβ‚“ b β–Άβ‚“ c)) r_shift3
X: Type
Ξ“, Ξ”: ctx X
a, b, c: X

Proper (asgn_eq Ξ“ Ξ” ==> asgn_eq (Ξ“ β–Άβ‚“ a β–Άβ‚“ b β–Άβ‚“ c) (Ξ” β–Άβ‚“ a β–Άβ‚“ b β–Άβ‚“ c)) r_shift3
intros ?? Hu; unfold r_shift3; now rewrite Hu. Qed.
X: Type
Ξ“: ctx X
a: X

r_shift1 r_id ≑ₐ r_id
intros ? v; now repeat (dependent elimination v; auto). Qed.
X: Type
Ξ“: ctx X
a, b: X

r_shift2 r_id ≑ₐ r_id
intros ? v; now repeat (dependent elimination v; auto). Qed.
X: Type
Ξ“: ctx X
a, b, c: X

r_shift3 r_id ≑ₐ r_id
intros ? v; now repeat (dependent elimination v; auto). Qed.
X: Type
Ξ“1, Ξ“2, Ξ“3: ctx X
a: X
r1: Ξ“1 βŠ† Ξ“2
r2: Ξ“2 βŠ† Ξ“3

r_shift1 (r1 α΅£βŠ› r2) ≑ₐ r_shift1 r1 α΅£βŠ› r_shift1 r2
intros ? v; now repeat (dependent elimination v; auto). Qed.
X: Type
Ξ“1, Ξ“2, Ξ“3: ctx X
a, b: X
r1: Ξ“1 βŠ† Ξ“2
r2: Ξ“2 βŠ† Ξ“3

r_shift2 (r1 α΅£βŠ› r2) ≑ₐ r_shift2 r1 α΅£βŠ› r_shift2 r2
intros ? v; now repeat (dependent elimination v; auto). Qed.
X: Type
Ξ“1, Ξ“2, Ξ“3: ctx X
a, b, c: X
r1: Ξ“1 βŠ† Ξ“2
r2: Ξ“2 βŠ† Ξ“3

r_shift3 (r1 α΅£βŠ› r2) ≑ₐ r_shift3 r1 α΅£βŠ› r_shift3 r2
intros ? v; now repeat (dependent elimination v; auto). Qed.

This is the end for now, but we have not yet instanciated the rest of the abstract context structure. This is a bit more work, it takes place in another file: Ctx/Covering.v