PR.contexts

Require Import base.
Require Export Lists.List.

Types

Inductive ty := Base | Fun (A B : ty).
Definition ctx := list ty.

Fixpoint at_ty (G : ctx) (A : ty) : Type :=
  match G with
  | nil False
  | (B :: G') (A = B) + at_ty G' A
  end.

Environment structure

Definition env (G : ctx) (T : ty Type) := A, at_ty G A T A.
Definition ren ( : ctx) := env (at_ty ).

Definition scons {G : ctx} {P : ty Type} {A : ty} (hd : P A) (tl : env G P) : env (A :: G) P :=
  fun B i
    match i with
    | inl p eq_rect_r P hd p
    | inr j tl B j
    end.
Notation "hd .: tl" := (@scons _ _ _ hd tl) (at level 55).

Definition scomp {P Q R : ty Type} (f : A, P A Q A) (g : A, Q A R A) :
   A, P A R A := fun A x g A (f A x).
Notation "eta >> eps" := (scomp eps) (at level 40).

Definition {G : ctx} {A : ty} : at_ty (A :: G) A := inl eq_refl.
Definition shift {G : ctx} {B : ty} : ren G (B :: G) :=
  fun A i inr i.

Definition idren {G : ctx} : ren G G := fun A i i.

Environment simplification

Lemma scons_eta G P A (f : env (A :: G) P) : f A .: shift f = f.
Proof. fext. intros B [|]; auto. Qed.

Lemma scons_eta_id G A : .: shift = @idren (A :: G).
Proof. fext. intros B [|]; auto. Qed.

Lemma scons_comp G P Q A (x : P A) (f : env G P) (g : A, P A Q A) : (x .: f) g = (g A x) .: f g.
Proof. fext. intros B [|]; auto. Qed.

Ltac fsimpl :=
  repeat match goal with
    | [|- context[idren ?f]] change (idren f) with f
    | [|- context[?f idren]] change (f idren) with f
    | [|- context[(?f ?g) ?h]]
        change ((f g) h) with (f (g h))
    | [|- context[@scons ?G ?P ?A ?x ?tl ?B ]]
      change (@scons G P A x tl B ) with x
    | [|- context[shift (? .: ?xr)]]
        change (shift ( .: xr)) with xr
    | [|- context[? .: shift ?f]]
        change with (f _ ); rewrite (@scons_eta _ _ _ f)
    | [|- context[?f _ .: ?g]]
        change g with (shift f); rewrite scons_eta
    | _ first [progress (rewrite scons_comp) | progress (rewrite scons_eta_id)]
  end.