{-# OPTIONS --without-K --exact-split #-}
module Confluence where
open import selfcontained using (Nat ; suc ; Eq ; refl ; Eq-sym ;
Eq-transport ; Sigma ; mkSigma ; Pair ;
Fin ; fzero ; fsuc ;
Expr ; Var ; U ; Pi ; Lam ; App ;
Ren ; liftRen ; renExpr ; wkRen ; wkExpr ;
Sub ; liftSub ; substExpr ; subst1Sub ; subst1 ;
Eq-trans ; Eq-cong2-Expr ; substExpr-ext ; subst-ren ; ren-subst ;
subst-subst1-comm)
data Empty : Set where
ren-subst1 : {n m : Nat} (r : Ren n m) (B : Expr (suc n)) (a : Expr n) ->
Eq (renExpr r (subst1 B a)) (subst1 (renExpr (liftRen r) B) (renExpr r a))
ren-subst1 r B a =
Eq-trans (ren-subst r (subst1Sub a) B)
(Eq-trans (substExpr-ext _ _ ext B)
(Eq-sym (subst-ren (subst1Sub (renExpr r a)) (liftRen r) B)))
where
ext : (i : Fin _) ->
Eq (renExpr r (subst1Sub a i))
(subst1Sub (renExpr r a) (liftRen r i))
ext fzero = refl
ext (fsuc i) = refl
data Beta1 : {n : Nat} -> Expr n -> Expr n -> Set where
beta : {n : Nat} {A : Expr n} {M : Expr (suc n)} {N : Expr n} ->
Beta1 (App (Lam A M) N) (subst1 M N)
beta-Pi1 : {n : Nat} {A A' : Expr n} {B : Expr (suc n)} ->
Beta1 A A' -> Beta1 (Pi A B) (Pi A' B)
beta-Pi2 : {n : Nat} {A : Expr n} {B B' : Expr (suc n)} ->
Beta1 B B' -> Beta1 (Pi A B) (Pi A B')
beta-Lam1 : {n : Nat} {A A' : Expr n} {M : Expr (suc n)} ->
Beta1 A A' -> Beta1 (Lam A M) (Lam A' M)
beta-Lam2 : {n : Nat} {A : Expr n} {M M' : Expr (suc n)} ->
Beta1 M M' -> Beta1 (Lam A M) (Lam A M')
beta-App1 : {n : Nat} {M M' N : Expr n} ->
Beta1 M M' -> Beta1 (App M N) (App M' N)
beta-App2 : {n : Nat} {M N N' : Expr n} ->
Beta1 N N' -> Beta1 (App M N) (App M N')
data Beta : {n : Nat} -> Expr n -> Expr n -> Set where
beta-refl : {n : Nat} {M : Expr n} -> Beta M M
beta-step : {n : Nat} {M N P : Expr n} ->
Beta1 M N -> Beta N P -> Beta M P
Beta-trans : {n : Nat} {M N P : Expr n} -> Beta M N -> Beta N P -> Beta M P
Beta-trans beta-refl r2 = r2
Beta-trans (beta-step s r1) r2 = beta-step s (Beta-trans r1 r2)
Beta-one : {n : Nat} {M N : Expr n} -> Beta1 M N -> Beta M N
Beta-one s = beta-step s beta-refl
data Conv : {n : Nat} -> Expr n -> Expr n -> Set where
conv-beta : {n : Nat} {A : Expr n} {M : Expr (suc n)} {N : Expr n} ->
Conv (App (Lam A M) N) (subst1 M N)
conv-refl : {n : Nat} {M : Expr n} -> Conv M M
conv-sym : {n : Nat} {M N : Expr n} -> Conv M N -> Conv N M
conv-trans : {n : Nat} {M N P : Expr n} -> Conv M N -> Conv N P -> Conv M P
conv-Pi : {n : Nat} {A A' : Expr n} {B B' : Expr (suc n)} ->
Conv A A' -> Conv B B' -> Conv (Pi A B) (Pi A' B')
conv-Lam : {n : Nat} {A A' : Expr n} {M M' : Expr (suc n)} ->
Conv A A' -> Conv M M' -> Conv (Lam A M) (Lam A' M')
conv-App : {n : Nat} {M M' N N' : Expr n} ->
Conv M M' -> Conv N N' -> Conv (App M N) (App M' N')
Beta-Pi1 : {n : Nat} {A A' : Expr n} {B : Expr (suc n)} ->
Beta A A' -> Beta (Pi A B) (Pi A' B)
Beta-Pi1 beta-refl = beta-refl
Beta-Pi1 (beta-step s r) = beta-step (beta-Pi1 s) (Beta-Pi1 r)
Beta-Pi2 : {n : Nat} {A : Expr n} {B B' : Expr (suc n)} ->
Beta B B' -> Beta (Pi A B) (Pi A B')
Beta-Pi2 beta-refl = beta-refl
Beta-Pi2 (beta-step s r) = beta-step (beta-Pi2 s) (Beta-Pi2 r)
Beta-Pi : {n : Nat} {A A' : Expr n} {B B' : Expr (suc n)} ->
Beta A A' -> Beta B B' -> Beta (Pi A B) (Pi A' B')
Beta-Pi rA rB = Beta-trans (Beta-Pi1 rA) (Beta-Pi2 rB)
Beta-Lam1 : {n : Nat} {A A' : Expr n} {M : Expr (suc n)} ->
Beta A A' -> Beta (Lam A M) (Lam A' M)
Beta-Lam1 beta-refl = beta-refl
Beta-Lam1 (beta-step s r) = beta-step (beta-Lam1 s) (Beta-Lam1 r)
Beta-Lam2 : {n : Nat} {A : Expr n} {M M' : Expr (suc n)} ->
Beta M M' -> Beta (Lam A M) (Lam A M')
Beta-Lam2 beta-refl = beta-refl
Beta-Lam2 (beta-step s r) = beta-step (beta-Lam2 s) (Beta-Lam2 r)
Beta-Lam : {n : Nat} {A A' : Expr n} {M M' : Expr (suc n)} ->
Beta A A' -> Beta M M' -> Beta (Lam A M) (Lam A' M')
Beta-Lam rA rM = Beta-trans (Beta-Lam1 rA) (Beta-Lam2 rM)
Beta-App1 : {n : Nat} {M M' N : Expr n} ->
Beta M M' -> Beta (App M N) (App M' N)
Beta-App1 beta-refl = beta-refl
Beta-App1 (beta-step s r) = beta-step (beta-App1 s) (Beta-App1 r)
Beta-App2 : {n : Nat} {M N N' : Expr n} ->
Beta N N' -> Beta (App M N) (App M N')
Beta-App2 beta-refl = beta-refl
Beta-App2 (beta-step s r) = beta-step (beta-App2 s) (Beta-App2 r)
Beta-App : {n : Nat} {M M' N N' : Expr n} ->
Beta M M' -> Beta N N' -> Beta (App M N) (App M' N')
Beta-App rM rN = Beta-trans (Beta-App1 rM) (Beta-App2 rN)
data Par : {n : Nat} -> Expr n -> Expr n -> Set where
par-var : {n : Nat} {i : Fin n} -> Par (Var i) (Var i)
par-U : {n : Nat} -> Par {n} U U
par-Pi : {n : Nat} {A A' : Expr n} {B B' : Expr (suc n)} ->
Par A A' -> Par B B' -> Par (Pi A B) (Pi A' B')
par-Lam : {n : Nat} {A A' : Expr n} {M M' : Expr (suc n)} ->
Par A A' -> Par M M' -> Par (Lam A M) (Lam A' M')
par-App : {n : Nat} {M M' N N' : Expr n} ->
Par M M' -> Par N N' -> Par (App M N) (App M' N')
par-beta : {n : Nat} {A : Expr n} {M M' : Expr (suc n)} {N N' : Expr n} ->
Par M M' -> Par N N' -> Par (App (Lam A M) N) (subst1 M' N')
par-refl : {n : Nat} (M : Expr n) -> Par M M
par-refl (Var i) = par-var
par-refl U = par-U
par-refl (Pi A B) = par-Pi (par-refl A) (par-refl B)
par-refl (Lam A M) = par-Lam (par-refl A) (par-refl M)
par-refl (App M N) = par-App (par-refl M) (par-refl N)
beta1-Par : {n : Nat} {M N : Expr n} -> Beta1 M N -> Par M N
beta1-Par (beta {M = M} {N = N}) = par-beta (par-refl M) (par-refl N)
beta1-Par (beta-Pi1 {B = B} s) = par-Pi (beta1-Par s) (par-refl B)
beta1-Par (beta-Pi2 {A = A} s) = par-Pi (par-refl A) (beta1-Par s)
beta1-Par (beta-Lam1 {M = M} s) = par-Lam (beta1-Par s) (par-refl M)
beta1-Par (beta-Lam2 {A = A} s) = par-Lam (par-refl A) (beta1-Par s)
beta1-Par (beta-App1 {N = N} s) = par-App (beta1-Par s) (par-refl N)
beta1-Par (beta-App2 {M = M} s) = par-App (par-refl M) (beta1-Par s)
Par-Beta : {n : Nat} {M N : Expr n} -> Par M N -> Beta M N
Par-Beta par-var = beta-refl
Par-Beta par-U = beta-refl
Par-Beta (par-Pi p q) = Beta-Pi (Par-Beta p) (Par-Beta q)
Par-Beta (par-Lam p q) = Beta-Lam (Par-Beta p) (Par-Beta q)
Par-Beta (par-App p q) = Beta-App (Par-Beta p) (Par-Beta q)
Par-Beta (par-beta p q) =
Beta-trans (Beta-App (Beta-Lam2 (Par-Beta p)) (Par-Beta q)) (Beta-one beta)
Par-ren : {n m : Nat} (r : Ren n m) {M M' : Expr n} ->
Par M M' -> Par (renExpr r M) (renExpr r M')
Par-ren r par-var = par-var
Par-ren r par-U = par-U
Par-ren r (par-Pi p q) = par-Pi (Par-ren r p) (Par-ren (liftRen r) q)
Par-ren r (par-Lam p q) = par-Lam (Par-ren r p) (Par-ren (liftRen r) q)
Par-ren r (par-App p q) = par-App (Par-ren r p) (Par-ren r q)
Par-ren r (par-beta {M' = M'} {N' = N'} p q) =
Eq-transport (\ X -> Par _ X) (Eq-sym (ren-subst1 r M' N'))
(par-beta (Par-ren (liftRen r) p) (Par-ren r q))
ParSub : {h g : Nat} -> Sub h g -> Sub h g -> Set
ParSub {g = g} sigma tau = (i : Fin g) -> Par (sigma i) (tau i)
liftSub-ParSub : {h g : Nat} (sigma tau : Sub h g) ->
ParSub sigma tau -> ParSub (liftSub sigma) (liftSub tau)
liftSub-ParSub sigma tau ps fzero = par-var
liftSub-ParSub sigma tau ps (fsuc i) = Par-ren wkRen (ps i)
Par-subst : {h g : Nat} (sigma tau : Sub h g) -> ParSub sigma tau ->
{M M' : Expr g} -> Par M M' -> Par (substExpr sigma M) (substExpr tau M')
Par-subst sigma tau ps (par-var {i = i}) = ps i
Par-subst sigma tau ps par-U = par-U
Par-subst sigma tau ps (par-Pi p q) =
par-Pi (Par-subst sigma tau ps p)
(Par-subst (liftSub sigma) (liftSub tau) (liftSub-ParSub sigma tau ps) q)
Par-subst sigma tau ps (par-Lam p q) =
par-Lam (Par-subst sigma tau ps p)
(Par-subst (liftSub sigma) (liftSub tau) (liftSub-ParSub sigma tau ps) q)
Par-subst sigma tau ps (par-App p q) =
par-App (Par-subst sigma tau ps p) (Par-subst sigma tau ps q)
Par-subst sigma tau ps (par-beta {M' = M'} {N' = N'} p q) =
Eq-transport (\ X -> Par _ X) (subst-subst1-comm tau M' N')
(par-beta
(Par-subst (liftSub sigma) (liftSub tau) (liftSub-ParSub sigma tau ps) p)
(Par-subst sigma tau ps q))
Par-subst1 : {n : Nat} {M M' : Expr (suc n)} {N N' : Expr n} ->
Par M M' -> Par N N' -> Par (subst1 M N) (subst1 M' N')
Par-subst1 {N = N} {N' = N'} p q =
Par-subst (subst1Sub N) (subst1Sub N') ext p
where
ext : ParSub (subst1Sub N) (subst1Sub N')
ext fzero = q
ext (fsuc i) = par-var
Common : {n : Nat} -> Expr n -> Expr n -> Set
Common {n} M N = Sigma (Expr n) (\ Z -> Pair (Par M Z) (Par N Z))
Par-diamond : {n : Nat} {M1 M2 M3 : Expr n} ->
Par M1 M2 -> Par M1 M3 -> Common M2 M3
Par-diamond {M2 = M2} par-var par-var = mkSigma M2 (mkSigma par-var par-var)
Par-diamond {M2 = M2} par-U par-U = mkSigma M2 (mkSigma par-U par-U)
Par-diamond (par-Pi p q) (par-Pi p' q') =
let mkSigma A4 (mkSigma a1 a2) = Par-diamond p p'
mkSigma B4 (mkSigma b1 b2) = Par-diamond q q'
in mkSigma (Pi A4 B4) (mkSigma (par-Pi a1 b1) (par-Pi a2 b2))
Par-diamond (par-Lam p q) (par-Lam p' q') =
let mkSigma A4 (mkSigma a1 a2) = Par-diamond p p'
mkSigma M4 (mkSigma m1 m2) = Par-diamond q q'
in mkSigma (Lam A4 M4) (mkSigma (par-Lam a1 m1) (par-Lam a2 m2))
Par-diamond (par-App p q) (par-App p' q') =
let mkSigma M4 (mkSigma m1 m2) = Par-diamond p p'
mkSigma N4 (mkSigma n1 n2) = Par-diamond q q'
in mkSigma (App M4 N4) (mkSigma (par-App m1 n1) (par-App m2 n2))
Par-diamond (par-App (par-Lam pA pM) pN) (par-beta qM qN) =
let mkSigma M4 (mkSigma m1 m2) = Par-diamond pM qM
mkSigma N4 (mkSigma n1 n2) = Par-diamond pN qN
in mkSigma (subst1 M4 N4)
(mkSigma (par-beta m1 n1) (Par-subst1 m2 n2))
Par-diamond (par-beta pM pN) (par-App (par-Lam qA qM) qN) =
let mkSigma M4 (mkSigma m1 m2) = Par-diamond pM qM
mkSigma N4 (mkSigma n1 n2) = Par-diamond pN qN
in mkSigma (subst1 M4 N4)
(mkSigma (Par-subst1 m1 n1) (par-beta m2 n2))
Par-diamond (par-beta pM pN) (par-beta qM qN) =
let mkSigma M4 (mkSigma m1 m2) = Par-diamond pM qM
mkSigma N4 (mkSigma n1 n2) = Par-diamond pN qN
in mkSigma (subst1 M4 N4)
(mkSigma (Par-subst1 m1 n1) (Par-subst1 m2 n2))
data ParStar : {n : Nat} -> Expr n -> Expr n -> Set where
ps-refl : {n : Nat} {M : Expr n} -> ParStar M M
ps-step : {n : Nat} {M N P : Expr n} ->
Par M N -> ParStar N P -> ParStar M P
ParStar-trans : {n : Nat} {M N P : Expr n} ->
ParStar M N -> ParStar N P -> ParStar M P
ParStar-trans ps-refl r2 = r2
ParStar-trans (ps-step p r1) r2 = ps-step p (ParStar-trans r1 r2)
CommonStar : {n : Nat} -> Expr n -> Expr n -> Set
CommonStar {n} M N = Sigma (Expr n) (\ Z -> Pair (ParStar M Z) (ParStar N Z))
Strip : {n : Nat} -> Expr n -> Expr n -> Set
Strip {n} M N = Sigma (Expr n) (\ Z -> Pair (ParStar M Z) (Par N Z))
Par-strip : {n : Nat} {M1 M2 M3 : Expr n} ->
Par M1 M2 -> ParStar M1 M3 -> Strip M2 M3
Par-strip {M2 = M2} p ps-refl = mkSigma M2 (mkSigma ps-refl p)
Par-strip p (ps-step q qs) =
let mkSigma Z (mkSigma pz qz) = Par-diamond p q
mkSigma W (mkSigma zw mw) = Par-strip qz qs
in mkSigma W (mkSigma (ps-step pz zw) mw)
ParStar-diamond : {n : Nat} {M1 M2 M3 : Expr n} ->
ParStar M1 M2 -> ParStar M1 M3 -> CommonStar M2 M3
ParStar-diamond {M3 = M3} ps-refl qs = mkSigma M3 (mkSigma qs ps-refl)
ParStar-diamond (ps-step p ps) qs =
let mkSigma Z (mkSigma pz qz) = Par-strip p qs
mkSigma W (mkSigma zw mw) = ParStar-diamond ps pz
in mkSigma W (mkSigma zw (ps-step qz mw))
Beta-ParStar : {n : Nat} {M N : Expr n} -> Beta M N -> ParStar M N
Beta-ParStar beta-refl = ps-refl
Beta-ParStar (beta-step s r) = ps-step (beta1-Par s) (Beta-ParStar r)
ParStar-Beta : {n : Nat} {M N : Expr n} -> ParStar M N -> Beta M N
ParStar-Beta ps-refl = beta-refl
ParStar-Beta (ps-step p r) = Beta-trans (Par-Beta p) (ParStar-Beta r)
CommonBeta : {n : Nat} -> Expr n -> Expr n -> Set
CommonBeta {n} M N = Sigma (Expr n) (\ Z -> Pair (Beta M Z) (Beta N Z))
Beta-confluent : {n : Nat} {M1 M2 M3 : Expr n} ->
Beta M1 M2 -> Beta M1 M3 -> CommonBeta M2 M3
Beta-confluent r1 r2 =
let mkSigma Z (mkSigma z1 z2) =
ParStar-diamond (Beta-ParStar r1) (Beta-ParStar r2)
in mkSigma Z (mkSigma (ParStar-Beta z1) (ParStar-Beta z2))
Conv-common : {n : Nat} {M N : Expr n} -> Conv M N -> CommonBeta M N
Conv-common (conv-beta {M = M} {N = N}) =
mkSigma (subst1 M N) (mkSigma (Beta-one beta) beta-refl)
Conv-common (conv-refl {M = M}) = mkSigma M (mkSigma beta-refl beta-refl)
Conv-common (conv-sym c) =
let mkSigma Z (mkSigma z1 z2) = Conv-common c
in mkSigma Z (mkSigma z2 z1)
Conv-common (conv-trans c1 c2) =
let mkSigma Z1 (mkSigma m1 n1) = Conv-common c1
mkSigma Z2 (mkSigma n2 l2) = Conv-common c2
mkSigma W (mkSigma w1 w2) = Beta-confluent n1 n2
in mkSigma W (mkSigma (Beta-trans m1 w1) (Beta-trans l2 w2))
Conv-common (conv-Pi c1 c2) =
let mkSigma A4 (mkSigma a1 a2) = Conv-common c1
mkSigma B4 (mkSigma b1 b2) = Conv-common c2
in mkSigma (Pi A4 B4) (mkSigma (Beta-Pi a1 b1) (Beta-Pi a2 b2))
Conv-common (conv-Lam c1 c2) =
let mkSigma A4 (mkSigma a1 a2) = Conv-common c1
mkSigma M4 (mkSigma m1 m2) = Conv-common c2
in mkSigma (Lam A4 M4) (mkSigma (Beta-Lam a1 m1) (Beta-Lam a2 m2))
Conv-common (conv-App c1 c2) =
let mkSigma M4 (mkSigma m1 m2) = Conv-common c1
mkSigma N4 (mkSigma n1 n2) = Conv-common c2
in mkSigma (App M4 N4) (mkSigma (Beta-App m1 n1) (Beta-App m2 n2))
church-rosser : {n : Nat} {M N : Expr n} -> Conv M N -> CommonBeta M N
church-rosser = Conv-common
BConv : {n : Nat} -> Expr n -> Expr n -> Set
BConv M N = CommonBeta M N
BConv-red : {n : Nat} {M N : Expr n} -> Beta M N -> BConv M N
BConv-red {N = N} r = mkSigma N (mkSigma r beta-refl)
BConv-beta : {n : Nat} {A : Expr n} {M : Expr (suc n)} {N : Expr n} ->
BConv (App (Lam A M) N) (subst1 M N)
BConv-beta = BConv-red (Beta-one beta)
BConv-refl : {n : Nat} {M : Expr n} -> BConv M M
BConv-refl {M = M} = mkSigma M (mkSigma beta-refl beta-refl)
BConv-sym : {n : Nat} {M N : Expr n} -> BConv M N -> BConv N M
BConv-sym c =
let mkSigma Z (mkSigma z1 z2) = c
in mkSigma Z (mkSigma z2 z1)
BConv-trans : {n : Nat} {M N P : Expr n} -> BConv M N -> BConv N P -> BConv M P
BConv-trans c1 c2 =
let mkSigma Z1 (mkSigma m1 n1) = c1
mkSigma Z2 (mkSigma n2 p2) = c2
mkSigma W (mkSigma w1 w2) = Beta-confluent n1 n2
in mkSigma W (mkSigma (Beta-trans m1 w1) (Beta-trans p2 w2))
BConv-Pi : {n : Nat} {A A' : Expr n} {B B' : Expr (suc n)} ->
BConv A A' -> BConv B B' -> BConv (Pi A B) (Pi A' B')
BConv-Pi c1 c2 =
let mkSigma A4 (mkSigma a1 a2) = c1
mkSigma B4 (mkSigma b1 b2) = c2
in mkSigma (Pi A4 B4) (mkSigma (Beta-Pi a1 b1) (Beta-Pi a2 b2))
BConv-Lam : {n : Nat} {A A' : Expr n} {M M' : Expr (suc n)} ->
BConv A A' -> BConv M M' -> BConv (Lam A M) (Lam A' M')
BConv-Lam c1 c2 =
let mkSigma A4 (mkSigma a1 a2) = c1
mkSigma M4 (mkSigma m1 m2) = c2
in mkSigma (Lam A4 M4) (mkSigma (Beta-Lam a1 m1) (Beta-Lam a2 m2))
BConv-App : {n : Nat} {M M' N N' : Expr n} ->
BConv M M' -> BConv N N' -> BConv (App M N) (App M' N')
BConv-App c1 c2 =
let mkSigma M4 (mkSigma m1 m2) = c1
mkSigma N4 (mkSigma n1 n2) = c2
in mkSigma (App M4 N4) (mkSigma (Beta-App m1 n1) (Beta-App m2 n2))
Beta1-Conv : {n : Nat} {M N : Expr n} -> Beta1 M N -> Conv M N
Beta1-Conv beta = conv-beta
Beta1-Conv (beta-Pi1 s) = conv-Pi (Beta1-Conv s) conv-refl
Beta1-Conv (beta-Pi2 s) = conv-Pi conv-refl (Beta1-Conv s)
Beta1-Conv (beta-Lam1 s) = conv-Lam (Beta1-Conv s) conv-refl
Beta1-Conv (beta-Lam2 s) = conv-Lam conv-refl (Beta1-Conv s)
Beta1-Conv (beta-App1 s) = conv-App (Beta1-Conv s) conv-refl
Beta1-Conv (beta-App2 s) = conv-App conv-refl (Beta1-Conv s)
Beta-Conv : {n : Nat} {M N : Expr n} -> Beta M N -> Conv M N
Beta-Conv beta-refl = conv-refl
Beta-Conv (beta-step s r) = conv-trans (Beta1-Conv s) (Beta-Conv r)
Conv-BConv : {n : Nat} {M N : Expr n} -> Conv M N -> BConv M N
Conv-BConv = church-rosser
BConv-Conv : {n : Nat} {M N : Expr n} -> BConv M N -> Conv M N
BConv-Conv c =
let mkSigma Z (mkSigma z1 z2) = c
in conv-trans (Beta-Conv z1) (conv-sym (Beta-Conv z2))
Empty-elim : {A : Set} -> Empty -> A
Empty-elim ()
NF : {n : Nat} -> Expr n -> Set
NF {n} M = (N : Expr n) -> Beta1 M N -> Empty
NF-Beta-refl : {n : Nat} {M Z : Expr n} -> NF M -> Beta M Z -> Eq M Z
NF-Beta-refl nf beta-refl = refl
NF-Beta-refl nf (beta-step {N = N} s r) = Empty-elim (nf N s)
NF-unique : {n : Nat} {M M1 M2 : Expr n} ->
Beta M M1 -> Beta M M2 -> NF M1 -> NF M2 -> Eq M1 M2
NF-unique r1 r2 nf1 nf2 =
let mkSigma Z (mkSigma z1 z2) = Beta-confluent r1 r2
in Eq-trans (NF-Beta-refl nf1 z1) (Eq-sym (NF-Beta-refl nf2 z2))
NF-unique-BConv : {n : Nat} {M1 M2 : Expr n} ->
BConv M1 M2 -> NF M1 -> NF M2 -> Eq M1 M2
NF-unique-BConv c nf1 nf2 =
let mkSigma Z (mkSigma z1 z2) = c
in Eq-trans (NF-Beta-refl nf1 z1) (Eq-sym (NF-Beta-refl nf2 z2))
NF-unique-Conv : {n : Nat} {M1 M2 : Expr n} ->
Conv M1 M2 -> NF M1 -> NF M2 -> Eq M1 M2
NF-unique-Conv c = NF-unique-BConv (church-rosser c)
Pi-Eq-inv : {n : Nat} {A A' : Expr n} {B B' : Expr (suc n)} ->
Eq (Pi A B) (Pi A' B') -> Pair (Eq A A') (Eq B B')
Pi-Eq-inv refl = mkSigma refl refl
PiReduct : {n : Nat} -> Expr n -> Expr (suc n) -> Expr n -> Set
PiReduct {n} A B Z =
Sigma (Expr n) (\ A2 ->
Sigma (Expr (suc n)) (\ B2 ->
Pair (Eq Z (Pi A2 B2)) (Pair (Beta A A2) (Beta B B2))))
Beta-Pi-inv : {n : Nat} {A : Expr n} {B : Expr (suc n)} {Z : Expr n} ->
Beta (Pi A B) Z -> PiReduct A B Z
Beta-Pi-inv {A = A} {B = B} beta-refl =
mkSigma A (mkSigma B (mkSigma refl (mkSigma beta-refl beta-refl)))
Beta-Pi-inv (beta-step (beta-Pi1 s) r) =
let mkSigma A2 (mkSigma B2 (mkSigma e (mkSigma ra rb))) = Beta-Pi-inv r
in mkSigma A2 (mkSigma B2 (mkSigma e (mkSigma (beta-step s ra) rb)))
Beta-Pi-inv (beta-step (beta-Pi2 s) r) =
let mkSigma A2 (mkSigma B2 (mkSigma e (mkSigma ra rb))) = Beta-Pi-inv r
in mkSigma A2 (mkSigma B2 (mkSigma e (mkSigma ra (beta-step s rb))))
Pi-inj-BConv : {n : Nat} {A A' : Expr n} {B B' : Expr (suc n)} ->
Conv (Pi A B) (Pi A' B') -> Pair (BConv A A') (BConv B B')
Pi-inj-BConv {A' = A'} {B' = B'} c =
let mkSigma Z (mkSigma z1 z2) = church-rosser c
mkSigma A2 (mkSigma B2 (mkSigma e1 (mkSigma ra1 rb1))) = Beta-Pi-inv z1
mkSigma A3 (mkSigma B3 (mkSigma e2 (mkSigma ra2 rb2))) = Beta-Pi-inv z2
mkSigma eA eB = Pi-Eq-inv (Eq-trans (Eq-sym e1) e2)
in mkSigma
(mkSigma A2 (mkSigma ra1 (Eq-transport (\ X -> Beta A' X) (Eq-sym eA) ra2)))
(mkSigma B2 (mkSigma rb1 (Eq-transport (\ X -> Beta B' X) (Eq-sym eB) rb2)))
Pi-inj : {n : Nat} {A A' : Expr n} {B B' : Expr (suc n)} ->
Conv (Pi A B) (Pi A' B') -> Pair (Conv A A') (Conv B B')
Pi-inj c =
let mkSigma cA cB = Pi-inj-BConv c
in mkSigma (BConv-Conv cA) (BConv-Conv cB)
NF-U : {n : Nat} -> NF {n} U
NF-U _ ()
U-not-Pi : {n : Nat} {A : Expr n} {B : Expr (suc n)} -> Eq (U {n}) (Pi A B) -> Empty
U-not-Pi ()
Conv-U-Pi : {n : Nat} {A : Expr n} {B : Expr (suc n)} ->
Conv (U {n}) (Pi A B) -> Empty
Conv-U-Pi c =
let mkSigma Z (mkSigma z1 z2) = church-rosser c
mkSigma A2 (mkSigma B2 (mkSigma e _)) = Beta-Pi-inv z2
in U-not-Pi (Eq-trans (NF-Beta-refl NF-U z1) e)