------------------------------------------------------------------------
-- Consistency of equality of natural numbers.
------------------------------------------------------------------------

open import Definition.Typed.Restrictions
open import Graded.Modality

module Definition.Typed.Consequences.Consistency
  {a} {M : Set a}
  {š•„ : Modality M}
  (R : Type-restrictions š•„)
  where

open Modality š•„
open Type-restrictions R

open import Graded.Mode.Instances.Trivial š•„

open import Definition.Untyped M
open import Definition.Untyped.Identity š•„ as Id
open import Definition.Untyped.Properties M
open import Definition.Typed R
open import Definition.Typed.Consequences.Canonicity R
open import Definition.Typed.Decidable.Internal trivial R
import Definition.Typed.Decidable.Internal.Context trivial R as IC
import Definition.Typed.Decidable.Internal.Term trivial R as I
open import Definition.Typed.EqRelInstance R
open import Definition.Typed.Inversion R
open import Definition.Typed.Properties R
open import Definition.Typed.Stability R
open import Definition.Typed.Substitution R
open import Definition.Typed.Weakening.Definition R
open import Definition.Typed.Well-formed R
open import Definition.LogicalRelation.Hidden R
open import Definition.LogicalRelation.Substitution.Introductions R
open import Definition.LogicalRelation.Fundamental.Reducibility R

open import Tools.Bool
open import Tools.Empty
open import Tools.Fin
open import Tools.Function
import Tools.List as L
open import Tools.Maybe
open import Tools.Nat
open import Tools.Product
import Tools.PropositionalEquality as PE
open import Tools.Reasoning.PropositionalEquality
open import Tools.Relation
open import Tools.Vec as V using (ε)

open Id.Internal trivial R

private
  variable
    m n  : Nat
    āˆ‡ āˆ‡ā€² : DCon (Term 0) m
    Ī” Ī•  : Con Term n
    Ī“    : Cons m n
    σ    : Subst _ _
    t u  : Term n
    p q  : M

opaque

  -- If āˆ‡Ā Ā»Ā Ī• is consistent and there is a substitution from Ī” to Ī•
  -- under āˆ‡, then āˆ‡Ā Ā»Ā Ī” is consistent.

  subst-Consistent :
    āˆ‡ Ā» Ī• ⊢ˢʷ σ ∷ Ī” → Consistent (āˆ‡ Ā» Ī•) → Consistent (āˆ‡ Ā» Ī”)
  subst-Consistent ⊢σ consistent _ ⊢t = consistent _ (subst-⊢ ⊢t ⊢σ)

opaque

  -- If there is some way to instantiate all the types inĀ Ī”, then Ī” is
  -- consistent.

  inhabited-consistent : āˆ‡ Ā» ε ⊢ˢʷ σ ∷ Ī” → Consistent (āˆ‡ Ā» Ī”)
  inhabited-consistent = flip subst-Consistent (Ī» _ → ¬Empty)

opaque

  -- If equality reflection is not allowed or the context is empty,
  -- then zero is not definitionally equal to sucĀ t.

  zero≢suc :
    ⦃ ok : No-equality-reflection or-empty (Ī“ .vars) ⦄ →
    ¬ Ī“ ⊢ zero ≔ suc t ∷ ā„•
  zero≢suc {Ī“} {t} =
    Ī“ ⊢ zero ≔ suc t ∷ ā„•                 ā†’āŸØ reducible-āŠ©ā‰”āˆ· ⟩
    (∃ Ī» l → Ī“ ⊩⟨ l ⟩ zero ≔ suc t ∷ ā„•)  ā†’āŸØ ⊩zero≔sucāˆ·ā„•ā‡” .proj₁ āˆ˜ā†’ projā‚‚ ⟩
    ⊄                                    ā–”

opaque

  -- If equality reflection is not allowed or the context is empty,
  -- then zero is not definitionally equal to one.

  zero≢one :
    ⦃ ok : No-equality-reflection or-empty (Ī“ .vars) ⦄ →
    ¬ Ī“ ⊢ zero ≔ suc zero ∷ ā„•
  zero≢one = zero≢suc

opaque

  -- If equality reflection is allowed, then there is a context for
  -- which zero is definitionally equal to one.

  zero≔one :
    Equality-reflection →
    Ā» āˆ‡ →
    ∃ Ī» (Ī“ : Con Term 1) → āˆ‡ Ā» Ī“ ⊢ zero ≔ suc zero ∷ ā„•
  zero≔one ok Ā»āˆ‡ =
    ε āˆ™ Id ā„• zero (suc zero) ,
    equality-reflection′ ok (varā‚€ (Idⱼ′ (zeroā±¼ (ε Ā»āˆ‡)) (sucā±¼ (zeroā±¼ (ε Ā»āˆ‡)))))

opaque

  -- A variant of zero≢suc: the identity type IdĀ ā„•Ā zeroĀ (sucĀ t) is not
  -- inhabited in the empty context.

  ¬-Id-ā„•-zero-suc : ¬ āˆ‡ Ā» ε ⊢ u ∷ Id ā„• zero (suc t)
  ¬-Id-ā„•-zero-suc {āˆ‡} {u} {t} zero≔suc = ¬Empty ⊢v
    where
    c : I.Constants
    c = Ī» where
      .I.gs                 → 0
      .I.ss                 → 0
      .I.bms                → 0
      .I.ms                 → 2
      .I.meta-con-size      → 0 V.∷ 0 V.∷ ε
      .I.meta-con-term-kind → tm V.∷ tm V.∷ ε
      .I.base-dcon-size     → _
      .I.base-con-allowed   → true
      .I.base-con-size      → 0

    xt xu : I.Term c 0
    xt = I.varᵐ x0
    xu = I.varᵐ x1

    γ : I.Contexts c
    γ .I.grades              = ε
    γ .I.strengths           = ε
    γ .I.binder-modes        = ε
    γ .I.constraints⁰        = I.emptyᶜ⁰
    γ .I.constraints⁺        = L.[]
    γ .I.⌜baseāŒ              = āˆ‡ Ā» ε
    γ .I.metas .I.equalities = L.[]
    γ .I.metas .I.bindings   = λ where
      (I.var! x0)     → I.base , I.term t I.ā„•
      (I.var! x1)     → I.base , I.term u (I.Id I.ā„• I.zero (I.suc xt))
      (I.var! not-x2)

    v : I.Term c 0
    v =
      substįµ¢ I.šŸ˜ I.Uā‚€ (I.var x0) I.ā„• I.Empty
        (congįµ¢ I.šŸ˜ I.ā„• I.zero (I.suc xt) I.Uā‚€
           (I.natrec I.šŸ˜ I.šŸ˜ I.šŸ˜ I.Uā‚€ I.ā„• I.Empty (I.var x0)) xu)
        I.zero

    ⊢t : āˆ‡ Ā» ε ⊢ t ∷ ā„•
    ⊢t =
      inversion-suc (inversion-Id (wf-⊢ zero≔suc) .projā‚‚ .projā‚‚) .proj₁

    ⊢v : āˆ‡ Ā» ε ⊢ I.⌜ v āŒ γ ∷ Empty
    ⊢v = check-type-and-term-sound
      γ
      (I.base nothing I.Ā» I.base)
      v
      I.Empty
      12
      PE.refl
      (Ī» where
         .IC.constraints-wf             → L.[]
         .IC.metas-wf .IC.equalities-wf → L.[]
         .IC.metas-wf .IC.bindings-wf   → Ī» where
           (I.var! x0)         → ⊢t
           (I.var! x1)         → zero≔suc
           (I.var  not-x2 _ _))
      (wf zero≔suc)

------------------------------------------------------------------------
-- Consistency, glassification, inlining and context extensions

opaque

  -- If glassifyĀ āˆ‡ and Ī” are consistent, then āˆ‡ and Ī” are consistent.

  Consistent-glassify→Consistent :
    Consistent (glassify āˆ‡ Ā» Ī”) →
    Consistent (āˆ‡ Ā» Ī”)
  Consistent-glassify→Consistent consistent _ =
    consistent _ āˆ˜ā†’ glassify-⊢

opaque
  unfolding inlineᵈ

  -- If ε and inline-ConįµˆĀ āˆ‡Ā Ī” are consistent, then āˆ‡ and Ī” are
  -- consistent.

  Consistent-inline-Con→Consistent :
    Consistent (ε Ā» inline-Conᵈ āˆ‡ Ī”) →
    Consistent (āˆ‡ Ā» Ī”)
  Consistent-inline-Con→Consistent consistent _ =
    consistent _ āˆ˜ā†’ ⊢inlineᵈ

opaque

  -- If āˆ‡ā€²Ā Ā»Ā Ī” is consistent, where āˆ‡ā€² is a well-formed extension of
  -- āˆ‡, then āˆ‡Ā Ā»Ā Ī” is consistent.

  Consistent-āŠ‡ā†’Consistent :
    Ā» āˆ‡ā€² āŠ‡ āˆ‡ →
    Consistent (āˆ‡ā€² Ā» Ī”) →
    Consistent (āˆ‡ Ā» Ī”)
  Consistent-āŠ‡ā†’Consistent āˆ‡ā€²āŠ‡āˆ‡ consistent _ =
    consistent _ āˆ˜ā†’ defn-wk āˆ‡ā€²āŠ‡āˆ‡

opaque
  unfolding Trans ones inlineᵈ

  -- If opacity is allowed, then consistency is not preserved by
  -- glassification, inlining or context extension: there is a
  -- definition context āˆ‡ and well-formed context Ī“ that are
  -- consistent, but for which glassifyĀ āˆ‡Ā Ā»Ā Ī“ and ε » inline-ConįµˆĀ āˆ‡Ā Ī“
  -- are not consistent, and for which there is an extended context āˆ‡ā€²
  -- such that āˆ‡ā€²Ā Ā»Ā Ī“ is not consistent.

  consistency-is-not-preserved :
    Opacity-allowed →
    āˆƒā‚„ Ī» m n (āˆ‡ : DCon (Term 0) m) (Ī“ : Con Term n) →
       āˆ‡ »⊢ Ī“ Ɨ
       Consistent (āˆ‡ Ā» Ī“) Ɨ
       ¬ Consistent (glassify āˆ‡ Ā» Ī“) Ɨ
       ¬ Consistent (ε Ā» inline-Conᵈ āˆ‡ Ī“) Ɨ
       āˆƒā‚‚ Ī» m′ (āˆ‡ā€² : DCon (Term 0) m′) →
         Ā» āˆ‡ā€² āŠ‡ āˆ‡ Ɨ ¬ Consistent (āˆ‡ā€² Ā» Ī“)
  consistency-is-not-preserved ok =
    _ , _ , Opaque[ Empty ∷ Uā‚€ ] , ε āˆ™ defn 0 , āˆ™ ⊢0 , consistent ,
    (Ī» hyp → hyp _ inconsistent₁) ,
    (Ī» hyp → hyp _ inconsistentā‚‚) ,
    _ , _ , āˆ™āŠ‡ ,
    (Ī» hyp → hyp _ inconsistentā‚ƒ)
    where
    ⊢ε : Opaque[ Empty ∷ Uā‚€ ] »⊢ ε
    ⊢ε = ε (»Opaque ok (Emptyⱼ εε))

    ⊢0∷U : Opaque[ Empty ∷ Uā‚€ ] Ā» ε ⊢ defn 0 ∷ Uā‚€
    ⊢0∷U = defn ⊢ε here PE.refl

    ⊢0 : Opaque[ Empty ∷ Uā‚€ ] Ā» ε ⊢ defn 0
    ⊢0 = univ ⊢0∷U

    ⊢0′ : glassify Opaque[ Empty ∷ Uā‚€ ] Ā» ε ⊢ defn 0
    ⊢0′ = glassify-⊢ ⊢0

    inconsistent₁ :
      glassify Opaque[ Empty ∷ Uā‚€ ] Ā» ε āˆ™ defn 0 ⊢ var x0 ∷ Empty
    inconsistent₁ =
      conv (varā‚€ ⊢0′) (univ (Ī“-red (āˆ™ ⊢0′) here PE.refl PE.refl))

    inconsistentā‚‚ :
      ε Ā» inline-Conᵈ Opaque[ Empty ∷ Uā‚€ ] (ε āˆ™ defn 0) ⊢ var x0 ∷ Empty
    inconsistentā‚‚ =
      varā‚€ (⊢Empty εε)

    āˆ™āŠ‡ :
      Ā» Opaque[ Empty ∷ Uā‚€ ]
          āˆ™āŸØ opa (ε ¹) ⟩[ rfl ∷ Id (Uā‚€) (defn 0) Empty ] āŠ‡
        Opaque[ Empty ∷ Uā‚€ ]
    āˆ™āŠ‡ =
      stepᵒ₁ ok (Idⱼ′ ⊢0∷U (Emptyā±¼ ⊢ε))
        (rflⱼ′ (Ī“-red (glassify-⊢ ⊢ε) here PE.refl PE.refl))

    ⊢0″ :
      Opaque[ Empty ∷ Uā‚€ ] āˆ™āŸØ opa ones ⟩[ rfl ∷ Id Uā‚€ (defn 0) Empty ] Ā»
      ε ⊢ defn 0
    ⊢0″ = defn-wk āˆ™āŠ‡ ⊢0

    inconsistentā‚ƒ :
      Opaque[ Empty ∷ Uā‚€ ] āˆ™āŸØ opa ones ⟩[ rfl ∷ Id Uā‚€ (defn 0) Empty ] Ā»
      ε āˆ™ defn 0 ⊢
      subst šŸ™ Uā‚€ (var x0) (defn 0) Empty (defn 1) (var x0) ∷ Empty
    inconsistentā‚ƒ =
      ⊢subst (univ (varā‚€ (⊢Uā‚€ (āˆ™ ⊢0″)))) (defn (āˆ™ ⊢0″) here PE.refl)
        (varā‚€ ⊢0″)

    consistent : Consistent (Opaque[ Empty ∷ Uā‚€ ] Ā» ε āˆ™ defn 0)
    consistent t =
      let ⊢ε = ε āˆ™įµ—[ ā„•ā±¼ εε ] in
      Opaque[ Empty ∷ Uā‚€ ]      Ā» ε āˆ™ defn 0 ⊢ t ∷ Empty  ā†’āŸØ definition-irrelevant-⊢∷ ok (ā„•ā±¼ εε) ⟩
      Opaque[ ā„• ∷ Uā‚€ ]          Ā» ε āˆ™ defn 0 ⊢ t ∷ Empty  ā†’āŸØ glassify-⊢ ⟩
      glassify Opaque[ ā„• ∷ Uā‚€ ] Ā» ε āˆ™ defn 0 ⊢ t ∷ Empty  ā†’āŸØ inhabited-consistent {σ = sgSubst _}
                                                               (ā†’āŠ¢Ė¢Ź·āˆ·āˆ™ (āŠ¢Ė¢Ź·āˆ·Īµā‡” .projā‚‚ ⊢ε)
                                                                  (conv (zeroā±¼ ⊢ε) (univ (sym′ (Ī“-red ⊢ε here PE.refl PE.refl))))) _ ⟩
      ⊄                                                   ā–”

opaque

  -- If opacity is allowed then it is not in general the case that, if
  -- āˆ‡Ā Ā»āŠ¢Ā Ī“, and āˆ‡ and Ī“ are consistent, then glassifyĀ āˆ‡ and Ī“ are
  -- consistent.

  ¬Consistent→Consistent-glassify :
    Opacity-allowed →
    ¬ (āˆ€ {m n} {āˆ‡ : DCon (Term 0) m} {Ī“ : Con Term n} →
       āˆ‡ »⊢ Ī“ →
       Consistent (āˆ‡ Ā» Ī“) →
       Consistent (glassify āˆ‡ Ā» Ī“))
  ¬Consistent→Consistent-glassify ok hyp =
    let _ , _ , _ , _ , āŠ¢Ī“ , cons , not-cons , _ =
          consistency-is-not-preserved ok
    in
    not-cons (hyp āŠ¢Ī“ cons)

opaque

  -- If opacity is allowed then it is not in general the case that, if
  -- āˆ‡Ā Ā»āŠ¢Ā Ī“, and āˆ‡ and Ī“ are consistent, then ε and inline-ConįµˆĀ āˆ‡Ā Ī“
  -- are consistent.

  ¬Consistent→Consistent-inline-Con :
    Opacity-allowed →
    ¬ (āˆ€ {m n} {āˆ‡ : DCon (Term 0) m} {Ī“ : Con Term n} →
       āˆ‡ »⊢ Ī“ →
       Consistent (āˆ‡ Ā» Ī“) →
       Consistent (ε Ā» inline-Conᵈ āˆ‡ Ī“))
  ¬Consistent→Consistent-inline-Con ok hyp =
    let _ , _ , _ , _ , āŠ¢Ī“ , cons , _ , not-cons , _ =
          consistency-is-not-preserved ok
    in
    not-cons (hyp āŠ¢Ī“ cons)

opaque

  -- If opacity is allowed then it is not in general the case that, if
  -- āˆ‡Ā Ā»āŠ¢Ā Ī“, and āˆ‡ and Ī“ are consistent, then āˆ‡ā€² and Ī“ are consistent
  -- for every well-formed extension āˆ‡ā€² of āˆ‡.

  ¬Consistent→Consistent-āŠ‡ :
    Opacity-allowed →
    ¬ (āˆ€ {m m′ n} {āˆ‡ : DCon (Term 0) m} {āˆ‡ā€² : DCon (Term 0) m′}
         {Ī“ : Con Term n} →
       āˆ‡ »⊢ Ī“ → Ā» āˆ‡ā€² āŠ‡ āˆ‡ →
       Consistent (āˆ‡ Ā» Ī“) →
       Consistent (āˆ‡ā€² Ā» Ī“))
  ¬Consistent→Consistent-āŠ‡ ok hyp =
    let _ , _ , _ , _ , āŠ¢Ī“ , cons , _ , _ , _ , _ , āˆ‡ā€²āŠ‡āˆ‡ , not-cons =
          consistency-is-not-preserved ok
    in
    not-cons (hyp āŠ¢Ī“ āˆ‡ā€²āŠ‡āˆ‡ cons)

------------------------------------------------------------------------
-- An alternative notion of consistency

opaque

  -- An alternative notion of consistency, defined in response to
  -- ¬Consistent→Consistent-glassify,
  -- ¬Consistent→Consistent-inline-Con and ¬Consistent→Consistent-āŠ‡.

  Consistentįµ : Cons m n → Set a
  Consistentįµ (āˆ‡ Ā» Ī“) = Consistent (glassify āˆ‡ Ā» Ī“)

opaque
  unfolding Consistentįµ

  -- ConsistentįµĀ Ī“ implies ConsistentĀ Ī“.

  Consistentįµā†’Consistent :
    Consistentįµ Ī“ → Consistent Ī“
  Consistentįµā†’Consistent = Consistent-glassify→Consistent

opaque
  unfolding Consistentįµ

  -- If opacity is allowed, then it is not necessarily the case that
  -- ConsistentĀ Ī“ implies ConsistentįµĀ Ī“ for every well-formed context
  -- pair Ī“.

  ¬Consistent→Consistentįµ :
    Opacity-allowed →
    ¬ (āˆ€ {m n} {Ī“ : Cons m n} →
       ⊢ Ī“ → Consistent Ī“ → Consistentįµ Ī“)
  ¬Consistent→Consistentįµ ok hyp =
    ¬Consistent→Consistent-glassify ok hyp

opaque
  unfolding Consistentįµ

  -- If ConsistentįµĀ (āˆ‡Ā Ā»Ā Ī•) holds and there is a substitution from Ī”
  -- to Ī• under āˆ‡, then ConsistentįµĀ (āˆ‡Ā Ā»Ā Ī”) holds.

  subst-Consistentįµ :
    āˆ‡ Ā» Ī• ⊢ˢʷ σ ∷ Ī” → Consistentįµ (āˆ‡ Ā» Ī•) →
    Consistentįµ (āˆ‡ Ā» Ī”)
  subst-Consistentįµ = subst-Consistent āˆ˜ā†’ glassify-⊢ˢʷ∷

opaque
  unfolding Consistentįµ

  -- If there is some way to instantiate all the types inĀ Ī” (under āˆ‡),
  -- then ConsistentįµĀ (āˆ‡Ā Ā»Ā Ī”) holds.

  āŠ¢Ė¢Ź·āˆ·ā†’Consistentįµ :
    āˆ‡ Ā» ε ⊢ˢʷ σ ∷ Ī” → Consistentįµ (āˆ‡ Ā» Ī”)
  āŠ¢Ė¢Ź·āˆ·ā†’Consistentįµ =
    flip subst-Consistentįµ (Ī» _ → ¬Empty)

opaque

  -- If āˆ‡ is well-formed, then ConsistentįµĀ (āˆ‡Ā Ā»Ā Īµ) holds.

  Consistentįµ-ε : Ā» āˆ‡ → Consistentįµ (āˆ‡ Ā» ε)
  Consistentįµ-ε =
    āŠ¢Ė¢Ź·āˆ·ā†’Consistentįµ āˆ˜ā†’ ⊢ˢʷ∷-idSubst āˆ˜ā†’ ε

------------------------------------------------------------------------
-- Consistentįµ, glassification, inlining and context extensions

opaque
  unfolding Consistentįµ

  -- ConsistentįµĀ (glassifyĀ āˆ‡Ā Ā»Ā Ī”) is logically equivalent to
  -- ConsistentįµĀ (āˆ‡Ā Ā»Ā Ī”).

  Consistentįµ-glassify⇔Consistentįµ :
    Consistentįµ (glassify āˆ‡ Ā» Ī”) ⇔
    Consistentįµ (āˆ‡ Ā» Ī”)
  Consistentįµ-glassify⇔Consistentįµ {āˆ‡} {Ī”} =
    Ī -cong-⇔ Ī» t →
      (glassify (glassify āˆ‡) Ā» Ī” ⊢ t ∷ Empty  ā‰”āŸØ PE.congā‚ƒ _⊢_∷_ (PE.cong (_Ā» _) (glassify-idem _)) PE.refl PE.refl āŸ©ā‡”
                 glassify āˆ‡  Ā» Ī” ⊢ t ∷ Empty  ▔⇔)
      →-cong-⇔ id⇔

opaque
  unfolding Consistentįµ inlineᵈ

  -- "ConsistentįµĀ (ε » inline-ConįµˆĀ āˆ‡Ā Ī”) if glassifyĀ āˆ‡Ā Ā»āŠ¢Ā Ī” holds" is
  -- logically equivalent to ConsistentįµĀ (āˆ‡Ā Ā»Ā Ī”).

  Consistentįµ-inline-Con⇔Consistentįµ :
    (glassify āˆ‡ »⊢ Ī” → Consistentįµ (ε Ā» inline-Conᵈ āˆ‡ Ī”)) ⇔
    Consistentįµ (āˆ‡ Ā» Ī”)
  Consistentįµ-inline-Con⇔Consistentįµ =
    (Ī» consistent _ ⊢t →
       consistent (wf ⊢t) _ $
       PE.substā‚ƒ _⊢_∷_
         (PE.cong (_»_ _) inline-Conᵈ-glassify) PE.refl PE.refl $
       ⊢inlineᵈ ⊢t) ,
    (Ī» consistent āŠ¢Ī” _ →
       consistent _ āˆ˜ā†’
       stability
         (PE.substā‚ƒ _»⊢_≔_
            (glassify-idem _) inline-Conᵈ-glassify PE.refl $
          ⊢inline-Conįµˆā‰” āŠ¢Ī”) āˆ˜ā†’
       defn-wk (Ā»āŠ‡Īµ (defn-wf āŠ¢Ī”)))

opaque
  unfolding Consistentįµ

  -- ConsistentįµĀ (āˆ‡Ā Ā»Ā Ī”) holds if and only if, given that
  -- glassifyĀ āˆ‡Ā Ā»āŠ¢Ā Ī” holds, ConsistentįµĀ (āˆ‡ā€²Ā Ā»Ā Ī”) holds for all
  -- āˆ‡ā€² for which » glassifyĀ āˆ‡ā€²Ā āŠ‡Ā glassifyĀ āˆ‡ holds.
  --
  -- See also All-extensions-consistent⇔Consistentįµ below.

  Consistentįµ-āŠ‡ā‡”Consistentįµ :
    (āˆ€ {n} {āˆ‡ā€² : DCon (Term 0) n} →
     glassify āˆ‡ »⊢ Ī” → Ā» glassify āˆ‡ā€² āŠ‡ glassify āˆ‡ →
     Consistentįµ (āˆ‡ā€² Ā» Ī”)) ⇔
    Consistentįµ (āˆ‡ Ā» Ī”)
  Consistentįµ-āŠ‡ā‡”Consistentįµ =
    (Ī» consistent _ ⊢t →
       consistent (wf ⊢t) idāŠ‡ _ ⊢t) ,
    (Ī» consistent āŠ¢Ī” āˆ‡ā€²āŠ‡āˆ‡ _ ⊢t →
       consistent _ $
       PE.substā‚ƒ _⊢_∷_
         (PE.cong (_Ā» _) $ glassify-idem _) PE.refl PE.refl $
       inhabited-under-glassified-context (⊢Empty āŠ¢Ī”) āˆ‡ā€²āŠ‡āˆ‡ ⊢t .projā‚‚)

------------------------------------------------------------------------
-- Another alternative notion of consistency

opaque

  -- Another alternative notion of consistency.
  --
  -- Below the terminology "all extensions of Ī“ are consistent" is
  -- used for All-extensions-consistentĀ Ī“, but note that it is only
  -- the definition context Γ .defs that is extended.

  All-extensions-consistent : Cons m n → Set a
  All-extensions-consistent (āˆ‡ Ā» Ī“) =
    āˆ€ {k} {āˆ‡ā€² : DCon (Term 0) k} → Ā» āˆ‡ā€² āŠ‡ āˆ‡ → Consistent (āˆ‡ā€² Ā» Ī“)

opaque
  unfolding All-extensions-consistent Consistentįµ

  -- If Ī“ is well-formed and either some Ī -type is allowed or Γ .vars
  -- is empty, then All-extensions-consistentĀ Ī“ is logically
  -- equivalent to ConsistentįµĀ Ī“.

  All-extensions-consistent⇔Consistentįµ :
    āˆƒā‚‚ Ī -allowed or-empty (Ī“ .vars) →
    ⊢ Ī“ →
    All-extensions-consistent Ī“ ⇔ Consistentįµ Ī“
  All-extensions-consistent⇔Consistentįµ ok āŠ¢Ī“ =
    (Ī» consistent _ ⊢t →
       let _ , _ , _ , āˆ‡ā€²āŠ‡āˆ‡ , ⊢u =
             inhabited-under-extension ok (⊢Empty āŠ¢Ī“) ⊢t
       in
       consistent āˆ‡ā€²āŠ‡āˆ‡ _ ⊢u) ,
    (Ī» consistent āˆ‡ā€²āŠ‡āˆ‡ _ ⊢t →
       consistent _ $
       inhabited-under-glassified-context (⊢Empty āŠ¢Ī“) āˆ‡ā€²āŠ‡āˆ‡ ⊢t .projā‚‚)

opaque
  unfolding All-extensions-consistent

  -- If all extensions of Ī“ are consistent, then Ī“ is consistent.

  All-extensions-consistent→Consistent :
    All-extensions-consistent Ī“ → Consistent Ī“
  All-extensions-consistent→Consistent = _$ idāŠ‡

opaque
  unfolding All-extensions-consistent

  -- If opacity is allowed, then it is not necessarily the case that
  -- all extensions of a consistent, well-formed context pair are
  -- consistent.

  ¬Consistent→All-extensions-consistent :
    Opacity-allowed →
    ¬ (āˆ€ {m n} {Ī“ : Cons m n} →
       ⊢ Ī“ → Consistent Ī“ → All-extensions-consistent Ī“)
  ¬Consistent→All-extensions-consistent ok hyp =
    let _ , _ , _ , _ , āŠ¢Ī“ , cons , _ , _ , _ , _ , āˆ‡ā€²āŠ‡āˆ‡ , not-cons =
          consistency-is-not-preserved ok
    in
    not-cons (hyp āŠ¢Ī“ cons āˆ‡ā€²āŠ‡āˆ‡)

opaque
  unfolding All-extensions-consistent

  -- If all extensions of āˆ‡Ā Ā»Ā Ī• are consistent and there is a
  -- substitution from Ī” to Ī• under āˆ‡, then all extensions of āˆ‡Ā Ā»Ā Ī”
  -- are consistent.

  subst-All-extensions-consistent :
    āˆ‡ Ā» Ī• ⊢ˢʷ σ ∷ Ī” → All-extensions-consistent (āˆ‡ Ā» Ī•) →
    All-extensions-consistent (āˆ‡ Ā» Ī”)
  subst-All-extensions-consistent ⊢σ consistent āˆ‡ā€²āŠ‡āˆ‡ =
    subst-Consistent (defn-wkSubstŹ· āˆ‡ā€²āŠ‡āˆ‡ ⊢σ) (consistent āˆ‡ā€²āŠ‡āˆ‡)

opaque
  unfolding All-extensions-consistent

  -- If there is some way to instantiate all the types inĀ Ī” (under āˆ‡),
  -- then all extensions of āˆ‡Ā Ā»Ā Ī” are consistent.

  āŠ¢Ė¢Ź·āˆ·ā†’All-extensions-consistent :
    āˆ‡ Ā» ε ⊢ˢʷ σ ∷ Ī” → All-extensions-consistent (āˆ‡ Ā» Ī”)
  āŠ¢Ė¢Ź·āˆ·ā†’All-extensions-consistent =
    flip subst-All-extensions-consistent (Ī» _ _ → ¬Empty)

opaque

  -- If āˆ‡ is well-formed, then all extensions of āˆ‡Ā Ā»Ā Īµ are consistent.

  All-extensions-consistent-ε : Ā» āˆ‡ → All-extensions-consistent (āˆ‡ Ā» ε)
  All-extensions-consistent-ε =
    āŠ¢Ė¢Ź·āˆ·ā†’All-extensions-consistent āˆ˜ā†’ ⊢ˢʷ∷-idSubst āˆ˜ā†’ ε