{-# OPTIONS --without-K --safe #-}
open import Definition.Typed.EqualityRelation
open import Tools.Relation
module Definition.LogicalRelation.Properties.Transitivity {a ℓ} (M′ : Setoid a ℓ)
{{eqrel : EqRelSet M′}} where
open EqRelSet {{...}}
open Setoid M′ using () renaming (Carrier to M)
open import Definition.Untyped M hiding (_∷_)
import Definition.Untyped.BindingType M′ as BT
open import Definition.Typed M′
open import Definition.Typed.Properties M′
import Definition.Typed.Weakening M′ as Weak
open import Definition.LogicalRelation M′
open import Definition.LogicalRelation.ShapeView M′
open import Definition.LogicalRelation.Irrelevance M′
open import Definition.LogicalRelation.Properties.Conversion M′
open import Tools.Nat
open import Tools.Product
import Tools.PropositionalEquality as PE
private
variable
n : Nat
Γ : Con Term n
mutual
transEqT : ∀ {n} {Γ : Con Term n} {A B C l l′ l″}
{[A] : Γ ⊩⟨ l ⟩ A} {[B] : Γ ⊩⟨ l′ ⟩ B} {[C] : Γ ⊩⟨ l″ ⟩ C}
→ ShapeView₃ Γ l l′ l″ A B C [A] [B] [C]
→ Γ ⊩⟨ l ⟩ A ≡ B / [A]
→ Γ ⊩⟨ l′ ⟩ B ≡ C / [B]
→ Γ ⊩⟨ l ⟩ A ≡ C / [A]
transEqT (ℕᵥ D D′ D″) A≡B B≡C = B≡C
transEqT (Emptyᵥ D D′ D″) A≡B B≡C = B≡C
transEqT (Unitᵥ D D′ D″) A≡B B≡C = B≡C
transEqT (ne (ne K [ ⊢A , ⊢B , D ] neK K≡K) (ne K₁ D₁ neK₁ _)
(ne K₂ D₂ neK₂ _))
(ne₌ M D′ neM K≡M) (ne₌ M₁ D″ neM₁ K≡M₁)
rewrite whrDet* (red D₁ , ne neK₁) (red D′ , ne neM)
| whrDet* (red D₂ , ne neK₂) (red D″ , ne neM₁) =
ne₌ M₁ D″ neM₁
(~-trans K≡M K≡M₁)
transEqT {n = n} {Γ = Γ} {l = l} {l′ = l′} {l″ = l″}
(Bᵥ W W′ W″ (Bᵣ F G D ⊢F ⊢G A≡A [F] [G] G-ext)
(Bᵣ F₁ G₁ D₁ ⊢F₁ ⊢G₁ A≡A₁ [F]₁ [G]₁ G-ext₁)
(Bᵣ F₂ G₂ D₂ ⊢F₂ ⊢G₂ A≡A₂ [F]₂ [G]₂ G-ext₂))
(B₌ F′ G′ W‴ D′ W≋W′ A≡B [F≡F′] [G≡G′])
(B₌ F″ G″ W⁗ D″ W′≋W″ A≡B₁ [F≡F′]₁ [G≡G′]₁) =
let ΠF₁G₁≡ΠF′G′ = whrDet* (red D₁ , ⟦ W′ ⟧ₙ) (D′ , ⟦ W‴ ⟧ₙ)
F₁≡F′ , G₁≡G′ , W′≡W‴ = B-PE-injectivity W′ W‴ ΠF₁G₁≡ΠF′G′
F₂≡F″ , G₂≡G″ , _ = B-PE-injectivity W″ W⁗ (whrDet* (red D₂ , ⟦ W″ ⟧ₙ) (D″ , ⟦ W⁗ ⟧ₙ))
substLift : ∀ {m n Δ l a} (ρ : Wk m n) x → Set _
substLift {_} {_} {Δ} {l} {a} ρ x = Δ ⊩⟨ l ⟩ wk (lift ρ) x [ a ]
[F′] : ∀ {m} {ρ : Wk m n} {Δ} [ρ] ⊢Δ → Δ ⊩⟨ l′ ⟩ wk ρ F′
[F′] {_} {ρ} [ρ] ⊢Δ = PE.subst (λ x → _ ⊩⟨ _ ⟩ wk ρ x) F₁≡F′ ([F]₁ [ρ] ⊢Δ)
[F″] : ∀ {m} {ρ : Wk m n} {Δ} [ρ] ⊢Δ → Δ ⊩⟨ l″ ⟩ wk ρ F″
[F″] {_} {ρ} [ρ] ⊢Δ = PE.subst (λ x → _ ⊩⟨ _ ⟩ wk ρ x) F₂≡F″ ([F]₂ [ρ] ⊢Δ)
[F′≡F″] : ∀ {m} {ρ : Wk m n} {Δ} [ρ] ⊢Δ → Δ ⊩⟨ l′ ⟩ wk ρ F′ ≡ wk ρ F″ / [F′] [ρ] ⊢Δ
[F′≡F″] {_} {ρ} [ρ] ⊢Δ = irrelevanceEq′ (PE.cong (wk ρ) F₁≡F′)
([F]₁ [ρ] ⊢Δ) ([F′] [ρ] ⊢Δ) ([F≡F′]₁ [ρ] ⊢Δ)
[G′] : ∀ {m} {ρ : Wk m n} {Δ a} [ρ] ⊢Δ
→ Δ ⊩⟨ l′ ⟩ a ∷ wk ρ F′ / [F′] [ρ] ⊢Δ
→ Δ ⊩⟨ l′ ⟩ wk (lift ρ) G′ [ a ]
[G′] {m} {ρ} [ρ] ⊢Δ [a] =
let [a′] = irrelevanceTerm′ (PE.cong (wk ρ) (PE.sym F₁≡F′))
([F′] [ρ] ⊢Δ) ([F]₁ [ρ] ⊢Δ) [a]
in PE.subst (substLift ρ) G₁≡G′ ([G]₁ [ρ] ⊢Δ [a′])
[G″] : ∀ {m} {ρ : Wk m n} {Δ a} [ρ] ⊢Δ
→ Δ ⊩⟨ l″ ⟩ a ∷ wk ρ F″ / [F″] [ρ] ⊢Δ
→ Δ ⊩⟨ l″ ⟩ wk (lift ρ) G″ [ a ]
[G″] {_} {ρ} [ρ] ⊢Δ [a] =
let [a″] = irrelevanceTerm′ (PE.cong (wk ρ) (PE.sym F₂≡F″))
([F″] [ρ] ⊢Δ) ([F]₂ [ρ] ⊢Δ) [a]
in PE.subst (substLift ρ) G₂≡G″ ([G]₂ [ρ] ⊢Δ [a″])
[G′≡G″] : ∀ {m} {ρ : Wk m n} {Δ a} [ρ] ⊢Δ
([a] : Δ ⊩⟨ l′ ⟩ a ∷ wk ρ F′ / [F′] [ρ] ⊢Δ)
→ Δ ⊩⟨ l′ ⟩ wk (lift ρ) G′ [ a ]
≡ wk (lift ρ) G″ [ a ] / [G′] [ρ] ⊢Δ [a]
[G′≡G″] {_} {ρ} [ρ] ⊢Δ [a′] =
let [a]₁ = irrelevanceTerm′ (PE.cong (wk ρ) (PE.sym F₁≡F′))
([F′] [ρ] ⊢Δ) ([F]₁ [ρ] ⊢Δ) [a′]
in irrelevanceEq′ (PE.cong (λ x → wk (lift ρ) x [ _ ]) G₁≡G′)
([G]₁ [ρ] ⊢Δ [a]₁) ([G′] [ρ] ⊢Δ [a′])
([G≡G′]₁ [ρ] ⊢Δ [a]₁)
in B₌ F″ G″ W⁗ D″ (BT.trans W≋W′ (PE.subst (λ W → W BT.≋ W⁗) W′≡W‴ W′≋W″))
(≅-trans A≡B (PE.subst (λ x → Γ ⊢ x ≅ ⟦ W⁗ ⟧ F″ ▹ G″) ΠF₁G₁≡ΠF′G′ A≡B₁))
(λ ρ ⊢Δ → transEq ([F] ρ ⊢Δ) ([F′] ρ ⊢Δ) ([F″] ρ ⊢Δ)
([F≡F′] ρ ⊢Δ) ([F′≡F″] ρ ⊢Δ))
λ ρ ⊢Δ [a] →
let [a′] = convTerm₁ ([F] ρ ⊢Δ) ([F′] ρ ⊢Δ) ([F≡F′] ρ ⊢Δ) [a]
[a″] = convTerm₁ ([F′] ρ ⊢Δ) ([F″] ρ ⊢Δ) ([F′≡F″] ρ ⊢Δ) [a′]
in transEq ([G] ρ ⊢Δ [a]) ([G′] ρ ⊢Δ [a′]) ([G″] ρ ⊢Δ [a″])
([G≡G′] ρ ⊢Δ [a]) ([G′≡G″] ρ ⊢Δ [a′])
transEqT (Uᵥ ⊢Γ ⊢Γ₁ ⊢Γ₂) A≡B B≡C = A≡B
transEqT (emb⁰¹¹ AB) A≡B B≡C = transEqT AB A≡B B≡C
transEqT (emb¹⁰¹ AB) A≡B B≡C = transEqT AB A≡B B≡C
transEqT (emb¹¹⁰ AB) A≡B B≡C = transEqT AB A≡B B≡C
transEq : ∀ {A B C l l′ l″}
([A] : Γ ⊩⟨ l ⟩ A) ([B] : Γ ⊩⟨ l′ ⟩ B) ([C] : Γ ⊩⟨ l″ ⟩ C)
→ Γ ⊩⟨ l ⟩ A ≡ B / [A]
→ Γ ⊩⟨ l′ ⟩ B ≡ C / [B]
→ Γ ⊩⟨ l ⟩ A ≡ C / [A]
transEq [A] [B] [C] A≡B B≡C =
transEqT (combine (goodCases [A] [B] A≡B) (goodCases [B] [C] B≡C)) A≡B B≡C
transEq′ : ∀ {A B B′ C C′ l l′ l″} → B PE.≡ B′ → C PE.≡ C′
→ ([A] : Γ ⊩⟨ l ⟩ A) ([B] : Γ ⊩⟨ l′ ⟩ B) ([C] : Γ ⊩⟨ l″ ⟩ C)
→ Γ ⊩⟨ l ⟩ A ≡ B′ / [A]
→ Γ ⊩⟨ l′ ⟩ B ≡ C′ / [B]
→ Γ ⊩⟨ l ⟩ A ≡ C / [A]
transEq′ PE.refl PE.refl [A] [B] [C] A≡B B≡C = transEq [A] [B] [C] A≡B B≡C
transEqTermNe : ∀ {n n′ n″ A}
→ Γ ⊩neNf n ≡ n′ ∷ A
→ Γ ⊩neNf n′ ≡ n″ ∷ A
→ Γ ⊩neNf n ≡ n″ ∷ A
transEqTermNe (neNfₜ₌ neK neM k≡m) (neNfₜ₌ neK₁ neM₁ k≡m₁) =
neNfₜ₌ neK neM₁ (~-trans k≡m k≡m₁)
mutual
transEqTermℕ : ∀ {n n′ n″}
→ Γ ⊩ℕ n ≡ n′ ∷ℕ
→ Γ ⊩ℕ n′ ≡ n″ ∷ℕ
→ Γ ⊩ℕ n ≡ n″ ∷ℕ
transEqTermℕ (ℕₜ₌ k k′ d d′ t≡u prop)
(ℕₜ₌ k₁ k″ d₁ d″ t≡u₁ prop₁) =
let k₁Whnf = naturalWhnf (proj₁ (split prop₁))
k′Whnf = naturalWhnf (proj₂ (split prop))
k₁≡k′ = whrDet*Term (redₜ d₁ , k₁Whnf) (redₜ d′ , k′Whnf)
prop′ = PE.subst (λ x → [Natural]-prop _ x _) k₁≡k′ prop₁
in ℕₜ₌ k k″ d d″ (≅ₜ-trans t≡u (PE.subst (λ x → _ ⊢ x ≅ _ ∷ _) k₁≡k′ t≡u₁))
(transNatural-prop prop prop′)
transNatural-prop : ∀ {k k′ k″}
→ [Natural]-prop Γ k k′
→ [Natural]-prop Γ k′ k″
→ [Natural]-prop Γ k k″
transNatural-prop (sucᵣ x) (sucᵣ x₁) = sucᵣ (transEqTermℕ x x₁)
transNatural-prop (sucᵣ x) (ne (neNfₜ₌ () neM k≡m))
transNatural-prop zeroᵣ prop₁ = prop₁
transNatural-prop prop zeroᵣ = prop
transNatural-prop (ne (neNfₜ₌ neK () k≡m)) (sucᵣ x₃)
transNatural-prop (ne [k≡k′]) (ne [k′≡k″]) =
ne (transEqTermNe [k≡k′] [k′≡k″])
transEmpty-prop : ∀ {k k′ k″}
→ [Empty]-prop Γ k k′
→ [Empty]-prop Γ k′ k″
→ [Empty]-prop Γ k k″
transEmpty-prop (ne [k≡k′]) (ne [k′≡k″]) =
ne (transEqTermNe [k≡k′] [k′≡k″])
transEqTermEmpty : ∀ {n n′ n″}
→ Γ ⊩Empty n ≡ n′ ∷Empty
→ Γ ⊩Empty n′ ≡ n″ ∷Empty
→ Γ ⊩Empty n ≡ n″ ∷Empty
transEqTermEmpty (Emptyₜ₌ k k′ d d′ t≡u prop)
(Emptyₜ₌ k₁ k″ d₁ d″ t≡u₁ prop₁) =
let k₁Whnf = ne (proj₁ (esplit prop₁))
k′Whnf = ne (proj₂ (esplit prop))
k₁≡k′ = whrDet*Term (redₜ d₁ , k₁Whnf) (redₜ d′ , k′Whnf)
prop′ = PE.subst (λ x → [Empty]-prop _ x _) k₁≡k′ prop₁
in Emptyₜ₌ k k″ d d″ (≅ₜ-trans t≡u (PE.subst (λ x → _ ⊢ x ≅ _ ∷ _) k₁≡k′ t≡u₁))
(transEmpty-prop prop prop′)
transEqTerm : ∀ {l A t u v}
([A] : Γ ⊩⟨ l ⟩ A)
→ Γ ⊩⟨ l ⟩ t ≡ u ∷ A / [A]
→ Γ ⊩⟨ l ⟩ u ≡ v ∷ A / [A]
→ Γ ⊩⟨ l ⟩ t ≡ v ∷ A / [A]
transEqTerm (Uᵣ′ .⁰ 0<1 ⊢Γ)
(Uₜ₌ A B d d′ typeA typeB t≡u [t] [u] [t≡u])
(Uₜ₌ A₁ B₁ d₁ d₁′ typeA₁ typeB₁ t≡u₁ [t]₁ [u]₁ [t≡u]₁)
rewrite whrDet*Term (redₜ d′ , typeWhnf typeB) (redₜ d₁ , typeWhnf typeA₁) =
Uₜ₌ A B₁ d d₁′ typeA typeB₁ (≅ₜ-trans t≡u t≡u₁) [t] [u]₁
(transEq [t] [u] [u]₁ [t≡u] (irrelevanceEq [t]₁ [u] [t≡u]₁))
transEqTerm (ℕᵣ D) [t≡u] [u≡v] = transEqTermℕ [t≡u] [u≡v]
transEqTerm (Emptyᵣ D) [t≡u] [u≡v] = transEqTermEmpty [t≡u] [u≡v]
transEqTerm (Unitᵣ D) (Unitₜ₌ ⊢t _) (Unitₜ₌ _ ⊢v) = Unitₜ₌ ⊢t ⊢v
transEqTerm (ne′ K D neK K≡K) (neₜ₌ k m d d′ (neNfₜ₌ neK₁ neM k≡m))
(neₜ₌ k₁ m₁ d₁ d″ (neNfₜ₌ neK₂ neM₁ k≡m₁)) =
let k₁≡m = whrDet*Term (redₜ d₁ , ne neK₂) (redₜ d′ , ne neM)
in neₜ₌ k m₁ d d″
(neNfₜ₌ neK₁ neM₁
(~-trans k≡m (PE.subst (λ x → _ ⊢ x ~ _ ∷ _) k₁≡m k≡m₁)))
transEqTerm (Bᵣ′ BΠ! F G D ⊢F ⊢G A≡A [F] [G] G-ext)
(Πₜ₌ f g d d′ funcF funcG f≡g [f] [g] [f≡g])
(Πₜ₌ f₁ g₁ d₁ d₁′ funcF₁ funcG₁ f≡g₁ [f]₁ [g]₁ [f≡g]₁)
rewrite whrDet*Term (redₜ d′ , functionWhnf funcG)
(redₜ d₁ , functionWhnf funcF₁) =
Πₜ₌ f g₁ d d₁′ funcF funcG₁ (≅ₜ-trans f≡g f≡g₁) [f] [g]₁
(λ ρ ⊢Δ [a] p≈p₁ p≈p₂ → transEqTerm ([G] ρ ⊢Δ [a])
([f≡g] ρ ⊢Δ [a] p≈p₁ p≈p₁)
([f≡g]₁ ρ ⊢Δ [a] p≈p₁ p≈p₂))
transEqTerm (Bᵣ′ (BΣ _ m) F G D ⊢F ⊢G A≡A [F] [G] G-ext) (Σₜ₌ p r d d′ pProd rProd p≅r [t] [u] prop) (Σₜ₌ p₁ r₁ d₁ d₁′ pProd₁ rProd₁ p≅r₁ [t]₁ [u]₁ prop₁)
with whrDet*Term (redₜ d′ , productWhnf rProd) (redₜ d₁ , productWhnf pProd₁)
transEqTerm (Bᵣ′ BΣₚ F G D ⊢F ⊢G A≡A [F] [G] G-ext)
(Σₜ₌ p r d d′ pProd rProd p≅r [t] [u] ([fstp] , [fstr] , [fst≡] , [snd≡]))
(Σₜ₌ r r₁ d₁ d₁′ pProd₁ rProd₁ p≅r₁ [t]₁ [u]₁ ([fstp]₁ , [fstr]₁ , [fst≡]₁ , [snd≡]₁))
| PE.refl =
let ⊢Γ = wf ⊢F
p≅r₁ = ≅ₜ-trans p≅r p≅r₁
[F]′ = [F] Weak.id ⊢Γ
[fst≡]′ = transEqTerm [F]′ [fst≡] [fst≡]₁
[Gfstp≡Gfstp₁] = G-ext Weak.id ⊢Γ [fstp] [fstr] [fst≡]
[Gfstp] = [G] Weak.id ⊢Γ [fstp]
[Gfstp₁] = [G] Weak.id ⊢Γ [fstp]₁
[snd≡]₁′ = convEqTerm₂ [Gfstp] [Gfstp₁] [Gfstp≡Gfstp₁] [snd≡]₁
[snd≡]′ = transEqTerm [Gfstp] [snd≡] [snd≡]₁′
in Σₜ₌ p r₁ d d₁′ pProd rProd₁ p≅r₁ [t] [u]₁ ([fstp] , [fstr]₁ , [fst≡]′ , [snd≡]′)
transEqTerm (Bᵣ′ BΣᵣ F G D ⊢F ⊢G A≡A [F] [G] G-ext)
(Σₜ₌ p r d d′ prodₙ prodₙ p≅r [t] [u] ([p₁] , [r₁] , [p₂] , [r₂] , [p₁≡r₁] , [p₂≡r₂]))
(Σₜ₌ r r₁ d₁ d₁′ prodₙ prodₙ p≅r₁ [t]₁ [u]₁ ([p₁]₁ , [r₁]₁ , [p₂]₁ , [r₂]₁ , [p₁≡r₁]₁ , [p₂≡r₂]₁))
| PE.refl =
let ⊢Γ = wf ⊢F
p≅r₁ = ≅ₜ-trans p≅r p≅r₁
[F]′ = [F] Weak.id ⊢Γ
[p₁≡r₁]′ = transEqTerm [F]′ [p₁≡r₁] [p₁≡r₁]₁
[Gp≡Gp₁] = G-ext Weak.id ⊢Γ [p₁] [p₁]₁ [p₁≡r₁]
[Gp] = [G] Weak.id ⊢Γ [p₁]
[Gp]₁ = [G] Weak.id ⊢Γ [p₁]₁
[p₂≡r₂]₁′ = convEqTerm₂ [Gp] [Gp]₁ [Gp≡Gp₁] [p₂≡r₂]₁
[p₂≡r₂]′ = transEqTerm [Gp] [p₂≡r₂] [p₂≡r₂]₁′
in Σₜ₌ p r₁ d d₁′ prodₙ prodₙ p≅r₁ [t] [u]₁ ([p₁] , [r₁]₁ , [p₂] , [r₂]₁ , [p₁≡r₁]′ , [p₂≡r₂]′)
transEqTerm (Bᵣ′ BΣᵣ F G D ⊢F ⊢G A≡A [F] [G] G-ext)
(Σₜ₌ p r d d′ (ne x) (ne y) p≅r [t] [u] p~r)
(Σₜ₌ r r₁ d₁ d₁′ (ne x₁) (ne y₁) p≅r₁ [t]₁ [u]₁ p₁~r₁)
| PE.refl =
Σₜ₌ p r₁ d d₁′ (ne x) (ne y₁) (≅ₜ-trans p≅r p≅r₁) [t] [u]₁ (~-trans p~r p₁~r₁)
transEqTerm (emb 0<1 x) t≡u u≡v = transEqTerm x t≡u u≡v