\begin{code}
module ParallelReduction where
open import Chi
open import Term renaming (_⊆_ to _⊆c_ ; _∈_ to _∈c_)
open import Substitution
open import SubstitutionLemmas
open import Alpha
open import Beta
open import Relation Λ hiding (_++_) renaming (_⊆_ to _⊆R_)
open import Function
open import Function.Inverse hiding (sym;_∘_;map;id)
open Inverse
import Function.Equality as FE
open import Data.List hiding (any) renaming (length to length')
open import Data.List.Any as Any hiding (map)
open import Data.List.Any.Membership
open import Data.List.Any.Properties
open Any.Membership-≡
open import Data.Bool hiding (_≟_;_∨_)
open import Data.Nat as Nat hiding (_*_)
open import Data.Sum hiding (map) renaming (_⊎_ to _∨_)
open import Data.Empty
open import Data.Product renaming (Σ to Σₓ;map to mapₓ)
open import Relation.Binary
open import Relation.Binary.PropositionalEquality as PropEq renaming ([_] to [_]ᵢ) hiding (trans)
open import Relation.Nullary
open import Relation.Nullary.Decidable hiding (map)
open import Algebra.Structures
open DecTotalOrder Nat.decTotalOrder using () renaming (refl to ≤-refl)
open ≤-Reasoning
renaming (begin_ to start_; _∎ to _◽; _≡⟨_⟩_ to _≤⟨_⟩'_)
infixl 3 _⇉_
infixl 3 _⇉ₛ_
\end{code}
\begin{code}
data _⇉_ : Λ → Λ → Set where
⇉v : (x : V) → v x ⇉ v x
⇉ƛ : (x : V){M M' : Λ} → M ⇉ M' → ƛ x M ⇉ ƛ x M'
⇉· : {M M' N N' : Λ} → M ⇉ M' → N ⇉ N' → M · N ⇉ M' · N'
⇉β : (x : V){M M' N N' : Λ}
→ M ⇉ M' → N ⇉ N' → ƛ x M · N ⇉ M' ∙ ι ≺+ (x , N')
⇉α : {M N N' : Λ} → M ⇉ N → N ∼α N' → M ⇉ N'
\end{code}
\begin{code}
_⇉ₛ_ : Σ → Σ → Set
σ ⇉ₛ σ' = (x : V) → σ x ⇉ σ' x
\end{code}
\begin{code}
lemma⇉s : {σ σ' : Σ}(x y : V) → σ ⇉ₛ σ' → σ ≺+ (x , v y) ⇉ₛ σ' ≺+ (x , v y)
lemma⇉s {σ} {σ'} x y σ⇉σ' z with x ≟ z
... | yes _ = ⇉v y
... | no _ = σ⇉σ' z
\end{code}
\begin{code}
⇉ρ : Reflexive _⇉_
⇉ρ {v x} = ⇉v x
⇉ρ {M · N} = ⇉· ⇉ρ ⇉ρ
⇉ρ {ƛ x M} = ⇉ƛ x ⇉ρ
\end{code}
\begin{code}
lemma→α⊆⇉ : _→α_ ⊆R _⇉_
lemma→α⊆⇉ (inj₁ (ctxinj (▹β {M} {N} {x})))
= ⇉β x ⇉ρ ⇉ρ
lemma→α⊆⇉ (inj₁ (ctx·l M→βN))
= ⇉· (lemma→α⊆⇉ (inj₁ M→βN)) ⇉ρ
lemma→α⊆⇉ (inj₁ (ctx·r M→βN))
= ⇉· ⇉ρ (lemma→α⊆⇉ (inj₁ M→βN))
lemma→α⊆⇉ (inj₁ (ctxƛ {x} M→βN))
= ⇉ƛ x (lemma→α⊆⇉ (inj₁ M→βN))
lemma→α⊆⇉ (inj₂ M~N)
= ⇉α ⇉ρ M~N
\end{code}
\begin{code}
lemma⇉⊆→α* : _⇉_ ⊆R _→α*_
lemma⇉⊆→α* (⇉v x) = refl
lemma⇉⊆→α* (⇉ƛ x M⇉N) = abs-star (lemma⇉⊆→α* M⇉N)
lemma⇉⊆→α* (⇉· {M} {M'} {N} {N'} M⇉M' N⇉N')
= begin→
M · N
→⟨ app-star-l (lemma⇉⊆→α* M⇉M') ⟩
M' · N
→⟨ app-star-r (lemma⇉⊆→α* N⇉N') ⟩
M' · N'
▣
lemma⇉⊆→α* (⇉β x {M} {M'} {N} {N'} M⇉M' N⇉N')
= begin→
(ƛ x M) · N
→⟨ app-star-l (abs-star (lemma⇉⊆→α* M⇉M')) ⟩
(ƛ x M') · N
→⟨ app-star-r (lemma⇉⊆→α* N⇉N') ⟩
(ƛ x M') · N'
→⟨ just (inj₁ ( ctxinj ▹β)) ⟩
M' ∙ ι ≺+ (x , N')
▣
lemma⇉⊆→α* (⇉α {M} {N} {P} M⇉N N∼P)
= begin→
M
→⟨ lemma⇉⊆→α* M⇉N ⟩
N
→⟨ just (inj₂ N∼P) ⟩
P
▣
\end{code}
\begin{code}
lemma⇉# : {x : V}{M N : Λ} → x # M → M ⇉ N → x # N
lemma⇉# x#M M⇉N = lemma→α*# x#M (lemma⇉⊆→α* M⇉N)
lemma⇉* : {x : V}{M N : Λ} → x * N → M ⇉ N → x * M
lemma⇉* = dual-#-* lemma⇉#
\end{code}
\begin{code}
lemma⇉#⇂ : {x x' y : V}{M M' : Λ}{σ σ' : Σ} → ƛ x M ⇉ ƛ x' M' → σ ⇉ₛ σ' → y #⇂ (σ , ƛ x M) → y #⇂ (σ' , ƛ x' M')
lemma⇉#⇂ {x} ƛxM⇉ƛx'M' σ⇉σ' y#⇂σ,ƛxM z z*ƛxM' = lemma⇉# (y#⇂σ,ƛxM z (lemma⇉* z*ƛxM' ƛxM⇉ƛx'M')) (σ⇉σ' z)
\end{code}
\begin{code}
lemma⇉ : {M M' : Λ}{σ σ' : Σ}
→ M ⇉ M' → σ ⇉ₛ σ'
→ M ∙ σ ⇉ M' ∙ σ'
\end{code}
\begin{code}
lemma⇉ (⇉v x) σ⇉σ'
= σ⇉σ' x
lemma⇉ {ƛ .x M} {ƛ .x M'} {σ} {σ'}
(⇉ƛ x M⇉M') σ⇉σ'
= ⇉α (⇉ƛ y (lemma⇉ M⇉M' (lemma⇉s x y σ⇉σ')))
(∼σ (corollary4-2 {x} {y} {M'} {σ'} (lemma⇉#⇂ (⇉ƛ x M⇉M') σ⇉σ' y#⇂σ,ƛxM)))
where
y = χ (σ , ƛ x M)
y#⇂σ,ƛxM : y #⇂ (σ , ƛ x M)
y#⇂σ,ƛxM = χ-lemma2 σ (ƛ x M)
lemma⇉ (⇉· M⇉M' N⇉N') σ⇉σ'
= ⇉· (lemma⇉ M⇉M' σ⇉σ') (lemma⇉ N⇉N' σ⇉σ')
lemma⇉ .{ƛ x M · N} .{M' ∙ ι ≺+ (x , N')} {σ} {σ'}
(⇉β x {M} {M'} {N} {N'} M⇉M' N⇉N') σ⇉σ'
= ⇉α (⇉β y (lemma⇉ M⇉M' (lemma⇉s x y σ⇉σ')) (lemma⇉ N⇉N' σ⇉σ')) lemma∼
where
y = χ (σ , ƛ x M)
y#⇂σ,ƛxM : y #⇂ (σ , ƛ x M)
y#⇂σ,ƛxM = χ-lemma2 σ (ƛ x M)
lemma∼ : (M' ∙ σ' ≺+ (x , v y)) ∙ ι ≺+ (y , N' ∙ σ') ∼α (M' ∙ ι ≺+ (x , N')) ∙ σ'
lemma∼ = begin
(M' ∙ σ' ≺+ (x , v y)) ∙ ι ≺+ (y , N' ∙ σ')
∼⟨ corollary1SubstLemma (lemma⇉#⇂ (⇉ƛ x M⇉M') σ⇉σ' y#⇂σ,ƛxM) ⟩
M' ∙ σ' ≺+ (x , N' ∙ σ')
≈⟨ corollary1Prop7 {M'} {N'} {σ'} {x} ⟩
(M' ∙ ι ≺+ (x , N')) ∙ σ'
∎
lemma⇉ (⇉α M⇉N N∼N') σ⇉σ'
= ⇉α (lemma⇉ M⇉N σ⇉σ') (lemma-subst N∼N' (λ _ _ → ∼ρ))
\end{code}
\begin{code}
lemma∼α⇂ρ : ∀ {σ M} → σ ∼α σ ⇂ M
lemma∼α⇂ρ x _ = ∼ρ
lemma⇉ₛρ : ∀ {σ} → σ ⇉ₛ σ
lemma⇉ₛρ {σ} x = ⇉ρ
lemma⇉ₛ≺+ : (x : V) {M N : Λ} {σ σ' : Σ} → M ⇉ N → σ ⇉ₛ σ' → σ ≺+ (x , M) ⇉ₛ σ' ≺+ (x , N)
lemma⇉ₛ≺+ x {M} {N} {σ} {σ'} red red' y with x ≟ y
lemma⇉ₛ≺+ x red red' .x | yes refl = red
... | no ¬p = red' y
corollary⇉ₛ≺+ : (x : V) {M N : Λ} → M ⇉ N → ι ≺+ (x , M) ⇉ₛ ι ≺+ (x , N)
corollary⇉ₛ≺+ x M⇉N = lemma⇉ₛ≺+ x M⇉N lemma⇉ₛρ
\end{code}