Skip to content

Support for dependently typed labels for variables and binders #1

@JasonGross

Description

@JasonGross

It would be nice to support well-typed-by-construction expression types, such as nested abstract syntax where we have expr : Type -> Type, we label both variables in expr V with labels of type V and we label binders with unit, and we have abs : unit -> expr (option V) -> expr V (i.e., a new binder extends V into option V); or intrinsically typed syntax where we have a type of type codes type, and we label binders with type and we label variables in expr ctx with indices of ctx, where ctx : list type, and where abs : forall (t : type), expr (t :: ctx) -> expr ctx.

I believe (one of) the construction(s) you need for this is to generalize monoid to dependent monoid. I haven't seen this anywhere in the literature, and as far as I know, @Soares came up with it:

Require Import Coq.Unicode.Utf8.
Reserved Infix "▷" (at level 70, right associativity).
Reserved Infix "⊙" (at level 40).
Notation "( x ; y ; .. ; z )" := (existT _ .. (existT _ x y) .. z) : core_scope.
Notation Σ := sigT (only parsing).
Import EqNotations.
Record DependentMonoid (X : Type) (M : X → Type) :=
  { ext : Σ M → X
    where "x ▷ y" := (ext (x; y))
  ; I : ∀ {x : X}, unit → M x
  ; T : ∀ {x : X}, { y : M x & M (x ▷ y) } → M x
    where "y ⊙ z" := (T (y; z))
  ; I_law : ∀ {x : X}, x = (x ▷ I tt)
  ; T_law : ∀ {x : X} {y : M x} {z : M (x ▷ y)}, ((x ▷ y) ▷ z) = (x ▷ (y ⊙ z))

  ; runit : ∀ {x : X} {y : M x}         , y =    y ⊙ I tt
  ; lunit : ∀ {x : X} {y : M (x ▷ I tt)}, y = I tt ⊙ rew [M] I_law in y
  ; assoc : ∀ {x : X} {y : M x} {z : M (x ▷ y)} {w : M ((x ▷ y) ▷ z)},
      (y ⊙ (z ⊙ w)) = ((y ⊙ z) ⊙ rew [M] T_law in w)
  }.

Note that DependentMonoid X M is isomorphic to a category whose objects are X and whose morphisms from x to y are of type { m : M x | ext (x; m) = y }, where composition is given by T. Equivalently, a category with objects X and morphisms Hom x y is isomorphic to a dependent monoid with X := X and M x := { y : X & Hom x y } (ext is "target", i.e., fun v => projT1 (projT2 v), and T is composition). Said another way, a dependent monoid looks like a category where morphisms are indexed only on their source and not also on their target.

You can specialize this to a non-dependent monoid by setting X := unit.

Do you think this will allow handling nested abstract syntax and intrinsically typed syntax?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions