Ssr.CR

Require Import mathcomp.ssreflect.ssreflect.
From mathcomp Require Import ssreflect ssrfun ssrbool eqtype ssrnat seq.
Require Import AutosubstSsr ARS.

Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.

Untyped Lambda Calculus


Inductive term : Type :=
| Var (x : var)
| App (s t : term)
| Lam (s : {bind term}).

Instance Ids_term : Ids term. derive. Defined.
Instance Rename_term : Rename term. derive. Defined.
Instance Subst_term : Subst term. derive. Defined.
Instance SubstLemmas_term : SubstLemmas term. derive. Qed.

One-Step Reduction


Inductive step : term term Prop :=
| step_beta s t :
    step (App (Lam s) t) s.[t/]
| step_appL t :
    step step (App t) (App t)
| step_appR s :
    step step (App s ) (App s )
| step_lam :
    step step (Lam ) (Lam ).

Notation red := (star step).
Notation "s === t" := (conv step s t) (at level 50).

(*
Lemma step_ebeta (s t u : term) : s.t/ = u -> step (App (Lam s) t) u.
Proof. move<-. exact: step_beta. Qed.

Lemma step_subst sigma s t : step s t -> step s. t..
Proof.
  move=> st. elim: st sigma => /={s t}; eauto using step.
  move=> s t sigma. apply: step_ebeta. by autosubst.
Qed.
 *)


Many-Step Reduction


Lemma red_app :
  red red red (App ) (App ).
Proof.
  move A B. apply: (star_trans (App )).
  - apply: (star_hom (App^~ )) A x y. exact: step_appL.
  - apply: star_hom B x y. exact: step_appR.
Qed.


Lemma red_lam : red red (Lam ) (Lam ).
Proof. apply: star_hom x y. exact: step_lam. Qed.

Hint Resolve red_app red_lam : red_congr.

Church-Rosser theorem


Inductive pstep : term term Prop :=
| pstep_beta ( : term) :
    pstep pstep pstep (App (Lam ) ) .[/]
| pstep_var (x : var) :
    pstep (Var x) (Var x)
| pstep_app ( : term) :
    pstep pstep pstep (App ) (App )
| pstep_lam ( : term) :
    pstep pstep (Lam ) (Lam ).

Definition psstep ( : var term) :=
   x, pstep ( x) ( x).

Fixpoint (s : term) : term :=
  match s with
    | App (Lam s) t ( s).[ t/]
    | App s t App ( s) ( t)
    | Lam s Lam ( s)
    | x x
  end.

Lemma pstep_ebeta u :
  .[/] = u pstep pstep pstep (App (Lam ) ) u.
Proof. move. exact: pstep_beta. Qed.

Lemma pstep_refl s : pstep s s.
Proof. elim: s; eauto using pstep. Qed.
Hint Resolve pstep_refl.

Lemma step_pstep s t : step s t pstep s t.
Proof. elim; eauto using pstep. Qed.

Lemma pstep_red s t : pstep s t red s t.
Proof with eauto with red_congr.
  elim {s t} //=... move _ A _ B.
  apply: (star_trans (App (Lam ) ))... exact/star1/step_beta.
Qed.


Lemma pstep_subst s t :
  pstep s t pstep s.[] t.[].
Proof with eauto using pstep.
  move A. elim: A /=... move _ A _ B .
  eapply pstep_ebeta... by autosubst.
Qed.


Lemma psstep_up :
  psstep psstep (up ) (up ).
Proof.
  move A [|n] //=; asimpl. apply: pstep_subst. exact: A.
Qed.


Lemma pstep_compat s t :
  psstep pstep s t pstep s.[] t.[].
Proof with eauto using pstep, psstep_up.
  move A B. elim: B A; asimpl...
  move _ A _ B C.
  apply: (@pstep_ebeta _ (.[up ]) _ (.[])); asimpl...
Qed.


Lemma pstep_compat_beta :
  pstep pstep pstep .[/] .[/].
Proof.
  move A B. by apply: pstep_compat A -[|].
Qed.


Lemma rho_triangle : triangle pstep .
Proof with eauto using pstep.
  move s t. elim {s t} //=...
  - move _ A _ B. exact: pstep_compat_beta.
  - move A _ . case: A //=...
    move s A . inv A. inv ...
Qed.


Theorem church_rosser :
   s t, s t joinable red s t.
Proof.
  apply: (cr_method ( := pstep) ( := )).
    exact: step_pstep. exact: pstep_red. exact: rho_triangle.
Qed.