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.

Covering for free contexts

In Ctx/Ctx.v we have instanciated the relevant part of the abstract interface for concrete contexts. Here we tackle the rest of the structure. Basically, we need to provide case-splitting for deciding if a variable i : (Ξ“ +β–Ά Ξ”) βˆ‹ x is in Ξ“ or in Ξ”. We could do this directly but we prove a slight generalization, going through the definition of coverings, a ternary relationship on concrete contexts witnessing that a context is covered by the two others (respecting order).

A covering

This inductive family provides proofs that some context zs is obtained by "zipping" together two other contexts xs and ys.

  Inductive cover : ctx X -> ctx X -> ctx X -> Type :=
  | CNil : βˆ…β‚“ ⊎ βˆ…β‚“  ≑ βˆ…β‚“
  | CLeft  {x xs ys zs} : xs ⊎ ys ≑ zs -> (xs β–Άβ‚“ x) ⊎ ys ≑ (zs β–Άβ‚“ x)
  | CRight {x xs ys zs} : xs ⊎ ys ≑ zs -> xs ⊎ (ys β–Άβ‚“ x) ≑ (zs β–Άβ‚“ x)
  where "a ⊎ b ≑ c" := (cover a b c).

Basic useful coverings.

  Equations cover_nil_r xs : xs ⊎ βˆ…β‚“ ≑ xs :=
    cover_nil_r βˆ…β‚“        := CNil ;
    cover_nil_r (xs β–Άβ‚“ _) := CLeft (cover_nil_r xs) .
  #[global] Arguments cover_nil_r {xs}.

  Equations cover_nil_l xs : βˆ…β‚“ ⊎ xs ≑ xs :=
    cover_nil_l βˆ…β‚“        := CNil ;
    cover_nil_l (xs β–Άβ‚“ _) := CRight (cover_nil_l xs) .
  #[global] Arguments cover_nil_l {xs}.

This is the crucial one: the concatenation is covered by its two components.

  Equations cover_cat {xs} ys : xs ⊎ ys ≑ (xs +β–Ά ys) :=
    cover_cat βˆ…β‚“        := cover_nil_r ;
    cover_cat (ys β–Άβ‚“ _) := CRight (cover_cat ys) .
  #[global] Arguments cover_cat {xs ys}.

A covering gives us two injective renamings, left embedding and right embedding.

  Equations r_cover_l {xs ys zs} : xs ⊎ ys ≑ zs -> xs βŠ† zs :=
    r_cover_l (CLeft c)  _ top     := top ;
    r_cover_l (CLeft c)  _ (pop i) := pop (r_cover_l c _ i) ;
    r_cover_l (CRight c) _ i       := pop (r_cover_l c _ i) .

  Equations r_cover_r {xs ys zs} : xs ⊎ ys ≑ zs -> ys βŠ† zs :=
    r_cover_r (CLeft c)  _ i       := pop (r_cover_r c _ i) ;
    r_cover_r (CRight c) _ top     := top ;
    r_cover_r (CRight c) _ (pop i) := pop (r_cover_r c _ i) .

Injectivity.

  
X: Type
F: Fam₁ X (ctx X)
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
x: X
i, j: xs βˆ‹ x
H: r_cover_l p x i = r_cover_l p x j

i = j
X: Type
F: Fam₁ X (ctx X)
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
x: X
i, j: xs βˆ‹ x
H: r_cover_l p x i = r_cover_l p x j

i = j
X: Type
F: Fam₁ X (ctx X)
x: X
i, j: βˆ…β‚“ βˆ‹ x
H: r_cover_l CNil x i = r_cover_l CNil x j

i = j
X: Type
F: Fam₁ X (ctx X)
x0: X
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
x: X
i, j: xs β–Άβ‚“ x0 βˆ‹ x
H: r_cover_l (CLeft p) x i = r_cover_l (CLeft p) x j
IHp: forall i j : xs βˆ‹ x, r_cover_l p x i = r_cover_l p x j -> i = j
i = j
X: Type
F: Fam₁ X (ctx X)
x0: X
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
x: X
i, j: xs βˆ‹ x
H: r_cover_l (CRight p) x i = r_cover_l (CRight p) x j
IHp: forall i j : xs βˆ‹ x, r_cover_l p x i = r_cover_l p x j -> i = j
i = j
X: Type
F: Fam₁ X (ctx X)
x: X
i, j: βˆ…β‚“ βˆ‹ x
H: r_cover_l CNil x i = r_cover_l CNil x j

i = j
dependent elimination i.
X: Type
F: Fam₁ X (ctx X)
x0: X
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
x: X
i, j: xs β–Άβ‚“ x0 βˆ‹ x
H: r_cover_l (CLeft p) x i = r_cover_l (CLeft p) x j
IHp: forall i j : xs βˆ‹ x, r_cover_l p x i = r_cover_l p x j -> i = j

i = j
X: Type
F: Fam₁ X (ctx X)
y0: X
Ξ“1, ys, zs: ctx X
p: Ξ“1 ⊎ ys ≑ zs
x: X
v, v0: var x Ξ“1
H: r_cover_l (CLeft p) x (pop v) = r_cover_l (CLeft p) x (pop v0)
IHp: forall i j : Ξ“1 βˆ‹ x, r_cover_l p x i = r_cover_l p x j -> i = j

pop v = pop v0
X: Type
F: Fam₁ X (ctx X)
y0: X
Ξ“1, ys, zs: ctx X
p: Ξ“1 ⊎ ys ≑ zs
x: X
v, v0: var x Ξ“1
H: NoConfusion (r_cover_l (CLeft p) x (pop v)) (r_cover_l (CLeft p) x (pop v0))
IHp: forall i j : Ξ“1 βˆ‹ x, r_cover_l p x i = r_cover_l p x j -> i = j

pop v = pop v0
f_equal; now apply IHp.
X: Type
F: Fam₁ X (ctx X)
x0: X
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
x: X
i, j: xs βˆ‹ x
H: r_cover_l (CRight p) x i = r_cover_l (CRight p) x j
IHp: forall i j : xs βˆ‹ x, r_cover_l p x i = r_cover_l p x j -> i = j

i = j
X: Type
F: Fam₁ X (ctx X)
x0: X
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
x: X
i, j: xs βˆ‹ x
H: NoConfusion (r_cover_l (CRight p) x i) (r_cover_l (CRight p) x j)
IHp: forall i j : xs βˆ‹ x, r_cover_l p x i = r_cover_l p x j -> i = j

i = j
now apply IHp. Qed.
X: Type
F: Fam₁ X (ctx X)
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
y: X
i, j: ys βˆ‹ y
H: r_cover_r p y i = r_cover_r p y j

i = j
X: Type
F: Fam₁ X (ctx X)
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
y: X
i, j: ys βˆ‹ y
H: r_cover_r p y i = r_cover_r p y j

i = j
X: Type
F: Fam₁ X (ctx X)
y: X
i, j: βˆ…β‚“ βˆ‹ y
H: r_cover_r CNil y i = r_cover_r CNil y j

i = j
X: Type
F: Fam₁ X (ctx X)
x: X
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
y: X
i, j: ys βˆ‹ y
H: r_cover_r (CLeft p) y i = r_cover_r (CLeft p) y j
IHp: forall i j : ys βˆ‹ y, r_cover_r p y i = r_cover_r p y j -> i = j
i = j
X: Type
F: Fam₁ X (ctx X)
x: X
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
y: X
i, j: ys β–Άβ‚“ x βˆ‹ y
H: r_cover_r (CRight p) y i = r_cover_r (CRight p) y j
IHp: forall i j : ys βˆ‹ y, r_cover_r p y i = r_cover_r p y j -> i = j
i = j
X: Type
F: Fam₁ X (ctx X)
y: X
i, j: βˆ…β‚“ βˆ‹ y
H: r_cover_r CNil y i = r_cover_r CNil y j

i = j
dependent elimination i.
X: Type
F: Fam₁ X (ctx X)
x: X
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
y: X
i, j: ys βˆ‹ y
H: r_cover_r (CLeft p) y i = r_cover_r (CLeft p) y j
IHp: forall i j : ys βˆ‹ y, r_cover_r p y i = r_cover_r p y j -> i = j

i = j
apply noConfusion_inv in H; now apply IHp.
X: Type
F: Fam₁ X (ctx X)
x: X
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
y: X
i, j: ys β–Άβ‚“ x βˆ‹ y
H: r_cover_r (CRight p) y i = r_cover_r (CRight p) y j
IHp: forall i j : ys βˆ‹ y, r_cover_r p y i = r_cover_r p y j -> i = j

i = j
X: Type
F: Fam₁ X (ctx X)
y1: X
xs, Ξ“1, zs: ctx X
p: xs ⊎ Ξ“1 ≑ zs
y: X
v, v0: var y Ξ“1
H: r_cover_r (CRight p) y (pop v) = r_cover_r (CRight p) y (pop v0)
IHp: forall i j : Ξ“1 βˆ‹ y, r_cover_r p y i = r_cover_r p y j -> i = j

pop v = pop v0
X: Type
F: Fam₁ X (ctx X)
y1: X
xs, Ξ“1, zs: ctx X
p: xs ⊎ Ξ“1 ≑ zs
y: X
v, v0: var y Ξ“1
H: NoConfusion (r_cover_r (CRight p) y (pop v)) (r_cover_r (CRight p) y (pop v0))
IHp: forall i j : Ξ“1 βˆ‹ y, r_cover_r p y i = r_cover_r p y j -> i = j

pop v = pop v0
f_equal; now apply IHp. Qed.

The two embeddings have disjoint images.

  
X: Type
F: Fam₁ X (ctx X)
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
a: X
i: xs βˆ‹ a
j: ys βˆ‹ a
H: r_cover_l p a i = r_cover_r p a j

T0
X: Type
F: Fam₁ X (ctx X)
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
a: X
i: xs βˆ‹ a
j: ys βˆ‹ a
H: r_cover_l p a i = r_cover_r p a j

T0
X: Type
F: Fam₁ X (ctx X)
a: X
i, j: βˆ…β‚“ βˆ‹ a
H: r_cover_l CNil a i = r_cover_r CNil a j

T0
X: Type
F: Fam₁ X (ctx X)
x: X
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
a: X
i: xs β–Άβ‚“ x βˆ‹ a
j: ys βˆ‹ a
H: r_cover_l (CLeft p) a i = r_cover_r (CLeft p) a j
IHp: forall (i : xs βˆ‹ a) (j : ys βˆ‹ a), Β¬ (r_cover_l p a i = r_cover_r p a j)
T0
X: Type
F: Fam₁ X (ctx X)
x: X
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
a: X
i: xs βˆ‹ a
j: ys β–Άβ‚“ x βˆ‹ a
H: r_cover_l (CRight p) a i = r_cover_r (CRight p) a j
IHp: forall (i : xs βˆ‹ a) (j : ys βˆ‹ a), Β¬ (r_cover_l p a i = r_cover_r p a j)
T0
X: Type
F: Fam₁ X (ctx X)
a: X
i, j: βˆ…β‚“ βˆ‹ a
H: r_cover_l CNil a i = r_cover_r CNil a j

T0
inversion i.
X: Type
F: Fam₁ X (ctx X)
x: X
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
a: X
i: xs β–Άβ‚“ x βˆ‹ a
j: ys βˆ‹ a
H: r_cover_l (CLeft p) a i = r_cover_r (CLeft p) a j
IHp: forall (i : xs βˆ‹ a) (j : ys βˆ‹ a), Β¬ (r_cover_l p a i = r_cover_r p a j)

T0
X: Type
F: Fam₁ X (ctx X)
a: X
Ξ“, ys, zs: ctx X
p: Ξ“ ⊎ ys ≑ zs
j: ys βˆ‹ a
H: r_cover_l (CLeft p) a top = r_cover_r (CLeft p) a j
IHp: forall (i : Ξ“ βˆ‹ a) (j : ys βˆ‹ a), Β¬ (r_cover_l p a i = r_cover_r p a j)

T0
X: Type
F: Fam₁ X (ctx X)
y: X
Ξ“0, ys, zs: ctx X
p: Ξ“0 ⊎ ys ≑ zs
a: X
v: var a Ξ“0
j: ys βˆ‹ a
H: r_cover_l (CLeft p) a (pop v) = r_cover_r (CLeft p) a j
IHp: forall (i : Ξ“0 βˆ‹ a) (j : ys βˆ‹ a), Β¬ (r_cover_l p a i = r_cover_r p a j)
T0
X: Type
F: Fam₁ X (ctx X)
a: X
Ξ“, ys, zs: ctx X
p: Ξ“ ⊎ ys ≑ zs
j: ys βˆ‹ a
H: r_cover_l (CLeft p) a top = r_cover_r (CLeft p) a j
IHp: forall (i : Ξ“ βˆ‹ a) (j : ys βˆ‹ a), Β¬ (r_cover_l p a i = r_cover_r p a j)

T0
inversion H.
X: Type
F: Fam₁ X (ctx X)
y: X
Ξ“0, ys, zs: ctx X
p: Ξ“0 ⊎ ys ≑ zs
a: X
v: var a Ξ“0
j: ys βˆ‹ a
H: r_cover_l (CLeft p) a (pop v) = r_cover_r (CLeft p) a j
IHp: forall (i : Ξ“0 βˆ‹ a) (j : ys βˆ‹ a), Β¬ (r_cover_l p a i = r_cover_r p a j)

T0
X: Type
F: Fam₁ X (ctx X)
y: X
Ξ“0, ys, zs: ctx X
p: Ξ“0 ⊎ ys ≑ zs
a: X
v: var a Ξ“0
j: ys βˆ‹ a
H: r_cover_l p a v = r_cover_r p a j
IHp: forall (i : Ξ“0 βˆ‹ a) (j : ys βˆ‹ a), Β¬ (r_cover_l p a i = r_cover_r p a j)

T0
exact (IHp v j H).
X: Type
F: Fam₁ X (ctx X)
x: X
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
a: X
i: xs βˆ‹ a
j: ys β–Άβ‚“ x βˆ‹ a
H: r_cover_l (CRight p) a i = r_cover_r (CRight p) a j
IHp: forall (i : xs βˆ‹ a) (j : ys βˆ‹ a), Β¬ (r_cover_l p a i = r_cover_r p a j)

T0
X: Type
F: Fam₁ X (ctx X)
a: X
xs, Ξ“, zs: ctx X
p: xs ⊎ Ξ“ ≑ zs
i: xs βˆ‹ a
H: r_cover_l (CRight p) a i = r_cover_r (CRight p) a top
IHp: forall (i : xs βˆ‹ a) (j : Ξ“ βˆ‹ a), Β¬ (r_cover_l p a i = r_cover_r p a j)

T0
X: Type
F: Fam₁ X (ctx X)
y: X
xs, Ξ“0, zs: ctx X
p: xs ⊎ Ξ“0 ≑ zs
a: X
i: xs βˆ‹ a
v: var a Ξ“0
H: r_cover_l (CRight p) a i = r_cover_r (CRight p) a (pop v)
IHp: forall (i : xs βˆ‹ a) (j : Ξ“0 βˆ‹ a), Β¬ (r_cover_l p a i = r_cover_r p a j)
T0
X: Type
F: Fam₁ X (ctx X)
a: X
xs, Ξ“, zs: ctx X
p: xs ⊎ Ξ“ ≑ zs
i: xs βˆ‹ a
H: r_cover_l (CRight p) a i = r_cover_r (CRight p) a top
IHp: forall (i : xs βˆ‹ a) (j : Ξ“ βˆ‹ a), Β¬ (r_cover_l p a i = r_cover_r p a j)

T0
inversion H.
X: Type
F: Fam₁ X (ctx X)
y: X
xs, Ξ“0, zs: ctx X
p: xs ⊎ Ξ“0 ≑ zs
a: X
i: xs βˆ‹ a
v: var a Ξ“0
H: r_cover_l (CRight p) a i = r_cover_r (CRight p) a (pop v)
IHp: forall (i : xs βˆ‹ a) (j : Ξ“0 βˆ‹ a), Β¬ (r_cover_l p a i = r_cover_r p a j)

T0
X: Type
F: Fam₁ X (ctx X)
y: X
xs, Ξ“0, zs: ctx X
p: xs ⊎ Ξ“0 ≑ zs
a: X
i: xs βˆ‹ a
v: var a Ξ“0
H: r_cover_l p a i = r_cover_r p a v
IHp: forall (i : xs βˆ‹ a) (j : Ξ“0 βˆ‹ a), Β¬ (r_cover_l p a i = r_cover_r p a j)

T0
exact (IHp i v H). Qed.

Now we can start proving that the copairing of the two embeddings has non-empty fibers, ie, we can case split.

  Variant cover_view {xs ys zs} (p : xs ⊎ ys ≑ zs) [z] : zs βˆ‹ z -> Type :=
  | Vcov_l  (i : xs βˆ‹ z) : cover_view p (r_cover_l p _ i)
  | Vcov_r (j : ys βˆ‹ z) : cover_view p (r_cover_r p _ j)
  .
  #[global] Arguments Vcov_l {xs ys zs p z}.
  #[global] Arguments Vcov_r {xs ys zs p z}.

Indeed!

  
X: Type
F: Fam₁ X (ctx X)
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
z: X
i: zs βˆ‹ z

cover_view p i
X: Type
F: Fam₁ X (ctx X)
xs, ys, zs: ctx X
p: xs ⊎ ys ≑ zs
z: X
i: zs βˆ‹ z

cover_view p i
X: Type
F: Fam₁ X (ctx X)
Ξ“: ctx X
z: X
IHzs: forall (i : Ξ“ βˆ‹ z) (xs ys : ctx X) (p : xs ⊎ ys ≑ Ξ“), cover_view p i
xs, ys: ctx X
p: xs ⊎ ys ≑ (Ξ“ β–Άβ‚“ z)

cover_view p top
X: Type
F: Fam₁ X (ctx X)
Ξ“0: ctx X
y, z: X
v: var z Ξ“0
IHzs: forall (i : Ξ“0 βˆ‹ z) (xs ys : ctx X) (p : xs ⊎ ys ≑ Ξ“0), cover_view p i
xs, ys: ctx X
p: xs ⊎ ys ≑ (Ξ“0 β–Άβ‚“ y)
cover_view p (pop v)
X: Type
F: Fam₁ X (ctx X)
Ξ“: ctx X
z: X
IHzs: forall (i : Ξ“ βˆ‹ z) (xs ys : ctx X) (p : xs ⊎ ys ≑ Ξ“), cover_view p i
xs, ys: ctx X
p: xs ⊎ ys ≑ (Ξ“ β–Άβ‚“ z)

cover_view p top
dependent elimination p; [ exact (Vcov_l top) | exact (Vcov_r top) ].
X: Type
F: Fam₁ X (ctx X)
Ξ“0: ctx X
y, z: X
v: var z Ξ“0
IHzs: forall (i : Ξ“0 βˆ‹ z) (xs ys : ctx X) (p : xs ⊎ ys ≑ Ξ“0), cover_view p i
xs, ys: ctx X
p: xs ⊎ ys ≑ (Ξ“0 β–Άβ‚“ y)

cover_view p (pop v)
X: Type
F: Fam₁ X (ctx X)
zs: ctx X
x, z: X
v: var z zs
IHzs: forall (i : zs βˆ‹ z) (xs ys : ctx X) (p : xs ⊎ ys ≑ zs), cover_view p i
xs0, ys0: ctx X
c: xs0 ⊎ ys0 ≑ zs

cover_view (CLeft c) (pop v)
X: Type
F: Fam₁ X (ctx X)
zs0: ctx X
x0, z: X
v: var z zs0
IHzs: forall (i : zs0 βˆ‹ z) (xs ys : ctx X) (p : xs ⊎ ys ≑ zs0), cover_view p i
xs1, ys1: ctx X
c0: xs1 ⊎ ys1 ≑ zs0
cover_view (CRight c0) (pop v)
X: Type
F: Fam₁ X (ctx X)
zs: ctx X
x, z: X
v: var z zs
IHzs: forall (i : zs βˆ‹ z) (xs ys : ctx X) (p : xs ⊎ ys ≑ zs), cover_view p i
xs0, ys0: ctx X
c: xs0 ⊎ ys0 ≑ zs

cover_view (CLeft c) (pop v)
destruct (IHzs v _ _ c); [ exact (Vcov_l (pop i)) | exact (Vcov_r j) ].
X: Type
F: Fam₁ X (ctx X)
zs0: ctx X
x0, z: X
v: var z zs0
IHzs: forall (i : zs0 βˆ‹ z) (xs ys : ctx X) (p : xs ⊎ ys ≑ zs0), cover_view p i
xs1, ys1: ctx X
c0: xs1 ⊎ ys1 ≑ zs0

cover_view (CRight c0) (pop v)
destruct (IHzs v _ _ c0); [ exact (Vcov_l i) | exact (Vcov_r (pop j)) ]. Qed.

Finishing the instanciation of the abstract interface for ctx X.

  #[global] Instance free_context_cat_wkn : context_cat_wkn X (ctx X) :=
    {| r_cat_l _ _ := r_cover_l cover_cat ;
       r_cat_r _ _ := r_cover_r cover_cat |}.

  #[global] Program Instance free_context_laws : context_laws X (ctx X).
  
X: Type
F: Fam₁ X (ctx X)
t: X
i: cvar βˆ…β‚“ t

c_emp_view t i
dependent elimination i. Qed.
X: Type
F: Fam₁ X (ctx X)
Ξ“, Ξ”: ctx X
t: X
i: cvar (ccat Ξ“ Ξ”) t

c_cat_view Ξ“ Ξ” t i
X: Type
F: Fam₁ X (ctx X)
Ξ“, Ξ”: ctx X
t: X
i: Ξ“ βˆ‹ t

c_cat_view Ξ“ Ξ” t (r_cover_l cover_cat t i)
X: Type
F: Fam₁ X (ctx X)
Ξ“, Ξ”: ctx X
t: X
j: Ξ” βˆ‹ t
c_cat_view Ξ“ Ξ” t (r_cover_r cover_cat t j)
X: Type
F: Fam₁ X (ctx X)
Ξ“, Ξ”: ctx X
t: X
j: Ξ” βˆ‹ t

c_cat_view Ξ“ Ξ” t (r_cover_r cover_cat t j)
now refine (Vcat_r _). Qed.
X: Type
F: Fam₁ X (ctx X)
Ξ“, Ξ”: ctx X
t: X

injective (r_cover_l cover_cat t)
intros ?? H; now apply r_cover_l_inj in H. Qed.
X: Type
F: Fam₁ X (ctx X)
Ξ“, Ξ”: ctx X
t: X

injective (r_cover_r cover_cat t)
intros ?? H; now apply r_cover_r_inj in H. Qed.
X: Type
F: Fam₁ X (ctx X)
Ξ“, Ξ”: ctx X
t: X
i: cvar Ξ“ t
j: cvar Ξ” t
H: r_cover_l cover_cat t i = r_cover_r cover_cat t j

T0
now apply r_cover_disj in H. Qed.

Additional utilities.

  Definition a_cover {Ξ“1 Ξ“2 Ξ“3 Ξ”} (p : Ξ“1 ⊎ Ξ“2 ≑ Ξ“3) (u : Ξ“1 =[F]> Ξ”) (v : Ξ“2 =[F]> Ξ”)
    : Ξ“3 =[F]> Ξ”
    := fun _ i => match view_cover p i with
               | Vcov_l i  => u _ i
               | Vcov_r j => v _ j
               end .
  #[global] Arguments a_cover _ _ _ _ _ _ _ _ /.

  
X: Type
F: Fam₁ X (ctx X)
Ξ“1, Ξ“2, Ξ“3, Ξ”: ctx X
H: Ξ“1 ⊎ Ξ“2 ≑ Ξ“3

Proper (asgn_eq Ξ“1 Ξ” ==> asgn_eq Ξ“2 Ξ” ==> asgn_eq Ξ“3 Ξ”) (a_cover H)
X: Type
F: Fam₁ X (ctx X)
Ξ“1, Ξ“2, Ξ“3, Ξ”: ctx X
H: Ξ“1 ⊎ Ξ“2 ≑ Ξ“3

Proper (asgn_eq Ξ“1 Ξ” ==> asgn_eq Ξ“2 Ξ” ==> asgn_eq Ξ“3 Ξ”) (a_cover H)
X: Type
F: Fam₁ X (ctx X)
Ξ“1, Ξ“2, Ξ“3, Ξ”: ctx X
H: Ξ“1 ⊎ Ξ“2 ≑ Ξ“3
x, y: Ξ“1 =[ F ]> Ξ”
H1: x ≑ₐ y
x0, y0: Ξ“2 =[ F ]> Ξ”
H2: x0 ≑ₐ y0
a: X
i: Ξ“3 βˆ‹ a

match view_cover H i with | Vcov_l i => x a i | Vcov_r j => x0 a j end = match view_cover H i with | Vcov_l i => y a i | Vcov_r j => y0 a j end
destruct (view_cover H i); [ now apply H1 | now apply H2 ]. Qed. End with_param. #[global] Notation "a ⊎ b ≑ c" := (cover a b c). #[global] Notation "a ▢ₐ v" := (a_append a v) : asgn_scope. #[global] Notation "[ u , H , v ]" := (a_cover H u v) : asgn_scope.