Coral.Definitions: syntax and small-step semantics of a λ-calculus

Author: Benoît Montagu
Copyright © Inria 2020 CeCILL-B License
Synopsis:
Basic definitions for the syntax of a lambda-calculus in locally-nameless representation, and its small-step reduction semantics.

Require Import Metalib.Metatheory.

Syntax

Terms in the locally-nameless representation. Bound variables are represented by de-Bruin indices. This is Definition 2.1 of the ICFP'20 paper.
Inductive term : Type :=
| BVar (_: nat)
| Var (x: atom)
| Let (t1: term) (t2: term)
| Lam (t: term)
| App (t1: term) (t2: term)
| Unit: term
| Pair (t1: term) (t2: term)
| Fst (t: term)
| Snd (t: term)
| InjL (t: term)
| InjR (t: term)
| Match (t: term) (t1: term) (t2: term)
.

subst u y t substitutes the variable y in t with u.
Fixpoint subst (u:term) (y:atom) (t:term) : term :=
  match t with
  | BVar nBVar n
  | Var xif x == y then u else Var x
  | Let t1 t2Let (subst u y t1) (subst u y t2)
  | Lam tLam (subst u y t)
  | App t1 t2App (subst u y t1) (subst u y t2)
  | UnitUnit
  | Pair t1 t2Pair (subst u y t1) (subst u y t2)
  | Fst tFst (subst u y t)
  | Snd tSnd (subst u y t)
  | InjL tInjL (subst u y t)
  | InjR tInjR (subst u y t)
  | Match t t1 t2Match (subst u y t) (subst u y t1) (subst u y t2)
end.

Free variables.
Fixpoint fv (t:term) : atoms :=
  match t with
  | BVar _{}
  | Var x{{x}}
  | Let t1 t2fv t1 `union` fv t2
  | Lam tfv t
  | App t1 t2fv t1 `union` fv t2
  | Unit{}
  | Pair t1 t2fv t1 `union` fv t2
  | Fst tfv t
  | Snd tfv t
  | InjL tfv t
  | InjR tfv t
  | Match t t1 t2fv t `union` fv t1 `union` fv t2
end.

Opening of a term, intermediate definition.
Fixpoint open_rec (k:nat) (u:term) (e:term) {struct e}: term :=
  match e with
  | BVar n
    match lt_eq_lt_dec n k with
    | inleft (left _) ⇒ BVar n
    | inleft (right _) ⇒ u
    | inright _BVar (n - 1)
    end
  | Var xVar x
  | Let t1 t2Let (open_rec k u t1) (open_rec (S k) u t2)
  | Lam tLam (open_rec (S k) u t)
  | App t1 t2App (open_rec k u t1) (open_rec k u t2)
  | UnitUnit
  | Pair t1 t2Pair (open_rec k u t1) (open_rec k u t2)
  | Fst tFst (open_rec k u t)
  | Snd tSnd (open_rec k u t)
  | InjL tInjL (open_rec k u t)
  | InjR tInjR (open_rec k u t)
  | Match t t1 t2Match (open_rec k u t) (open_rec (S k) u t1) (open_rec (S k) u t2)
end.

Opening of a term.
Definition open e u := open_rec 0 u e.

Module Notations.
Declare Scope term_scope.
Notation "[ z ~> u ] e" := (subst u z e) (at level 0) : term_scope.
Notation "e ^ x" := (open e (Var x)) : term_scope.
End Notations.
Import Notations.
Open Scope term_scope.

Locally-closed terms.
Inductive lc : term Prop :=
| lc_Var : (x:atom),
    lc (Var x)
| lc_Let : (t1 t2:term),
    lc t1
    ( x , lc (t2 ^ x))
    lc (Let t1 t2)
| lc_Lam : (t:term),
    ( x , lc (t ^ x))
    lc (Lam t)
| lc_App : (t1 t2:term),
    lc t1
    lc t2
    lc (App t1 t2)
| lc_Unit :
    lc Unit
| lc_Pair : (t1 t2:term),
    lc t1
    lc t2
    lc (Pair t1 t2)
| lc_Fst : (t:term),
    lc t
    lc (Fst t)
| lc_Snd : (t:term),
    lc t
    lc (Snd t)
| lc_InjL : (t:term),
    lc t
    lc (InjL t)
| lc_InjR : (t:term),
    lc t
    lc (InjR t)
| lc_Match : (t t1 t2:term),
    lc t
    ( x , lc (t1 ^ x))
    ( x , lc (t2 ^ x))
    lc (Match t t1 t2)
.

Semantics

Values of the language. This is Definition 2.2 of the ICFP'20 paper.
Fixpoint is_value (t : term) : Prop :=
  match t with
  | Lam _True
  | UnitTrue
  | Pair t1 t2is_value t1 is_value t2
  | InjL tis_value t
  | InjR tis_value t
  | _False
  end.

Extended values of the language. This is the definition in Section 4.1 of the ICFP'20 paper.
Fixpoint is_extended_value (t: term) : Prop :=
  match t with
  | BVar _False
  | Var _ | Lam _ | UnitTrue
  | Pair t1 t2is_extended_value t1 is_extended_value t2
  | InjL t | InjR tis_extended_value t
  | Let _ _ | App _ _ | Fst _ | Snd _ | Match _ _ _False
  end.

One-step reduction relation. This is Figure 1 of the ICFP'20 paper.
Inductive step : term term Prop :=
 | step_App_beta : t1 t2,
     is_value t2
     step (App (Lam t1) t2) (open t1 t2)
 | step_App_left : t1 t2 t1',
     step t1 t1'
     step (App t1 t2) (App t1' t2)
 | step_App_right : t1 t2 t2',
     is_value t1
     step t2 t2'
     step (App t1 t2) (App t1 t2')
 | step_Let_beta_v : t1 t2,
     is_value t1
     step (Let t1 t2) (open t2 t1)
 | step_Let_left : t1 t2 t1',
     step t1 t1'
     step (Let t1 t2) (Let t1' t2)
| step_Pair_Fst : t1 t2,
    is_value t1
    is_value t2
    step (Fst (Pair t1 t2)) t1
| step_Pair_Snd : t1 t2,
    is_value t1
    is_value t2
    step (Snd (Pair t1 t2)) t2
| step_Pair_left : t1 t2 t1',
    step t1 t1'
    step (Pair t1 t2) (Pair t1' t2)
| step_Pair_right : t1 t2 t2',
    is_value t1
    step t2 t2'
    step (Pair t1 t2) (Pair t1 t2')
| step_Fst : t t',
    step t t'
    step (Fst t) (Fst t')
| step_Snd : t t',
    step t t'
    step (Snd t) (Snd t')
| step_InjL : t t',
    step t t'
    step (InjL t) (InjL t')
| step_InjR : t t',
    step t t'
    step (InjR t) (InjR t')
| step_Match_InjL: t t1 t2,
    is_value t
    step (Match (InjL t) t1 t2) (open t1 t)
| step_Match_InjR: t t1 t2,
    is_value t
    step (Match (InjR t) t1 t2) (open t2 t)
| step_Match: t t' t1 t2,
    step t t'
    step (Match t t1 t2) (Match t' t1 t2)
.

Hint Constructors step lc : core.

Substituting x for Var x in t always gives back t. This lemma seems to be missing from the infrastructure generated lemmas.
Lemma subst_refl x t: subst (Var x) x t = t.
Proof.
  induction t; simpl; f_equal; auto.
  destruct (x0 == x); congruence.
Qed.

Require Relations.Relation_Operators.

Many-step relation
Evalation relation: whether a term reaches a value after some steps.
Definition eval t v :=
  steps t v is_value v.

A good value is a value that is locally-closed and that has no free variables.
Definition good_value (v: term) : Prop :=
  lc v
   is_value v
   fv v [<=] empty.

A good value is locally-closed.
Lemma good_value_lc v: good_value v lc v.
Proof.
  unfold good_value. tauto.
Qed.
Hint Resolve good_value_lc : core.

A good value is a value.
Lemma good_value_value v: good_value v is_value v.
Proof.
  unfold good_value. tauto.
Qed.
Hint Resolve good_value_value : core.

A good value has no free variable.
Lemma good_value_closed v: good_value v fv v [<=] empty.
Proof.
  unfold good_value. tauto.
Qed.
Hint Resolve good_value_closed : core.