------------------------------------------------------------------------
-- 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 Definition.Untyped M
open import Definition.Untyped.Identity š•„
open import Definition.Untyped.Properties M
open import Definition.Typed R
open import Definition.Typed.Consequences.Canonicity R
open import Definition.Typed.EqRelInstance 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.LogicalRelation.Hidden R
open import Definition.LogicalRelation.Substitution.Introductions R
open import Definition.LogicalRelation.Fundamental.Reducibility R

open import Tools.Empty
open import Tools.Fin
open import Tools.Function
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 using (ε)

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} =
    āˆ‡ Ā» ε ⊢ u ∷ Id ā„• zero (suc t)      ā†’āŸØ ε⊢∷Idā†’ĪµāŠ¢ā‰”āˆ· ⟩
    glassify āˆ‡ Ā» ε ⊢ zero ≔ suc t ∷ ā„•  ā†’āŸØ zero≢suc ⦃ ok = ε ⦄ ⟩
    ⊄                                  ā–”

------------------------------------------------------------------------
-- 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-wkTerm āˆ‡ā€²āŠ‡āˆ‡

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 0 ] , ε āˆ™ defn 0 , āˆ™ ⊢0 , consistent ,
    (Ī» hyp → hyp _ inconsistent₁) ,
    (Ī» hyp → hyp _ inconsistentā‚‚) ,
    _ , _ , āˆ™āŠ‡ ,
    (Ī» hyp → hyp _ inconsistentā‚ƒ)
    where
    ⊢ε : Opaque[ Empty ∷ U 0 ] »⊢ ε
    ⊢ε = ε (»Opaque ok (Emptyⱼ εε))

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

    ⊢0 : Opaque[ Empty ∷ U 0 ] » ε ⊢ defn 0
    ⊢0 = univ ⊢0∷U

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

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

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

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

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

    inconsistentā‚ƒ :
      Opaque[ Empty ∷ U 0 ]
        āˆ™āŸØ opa ones ⟩[ rfl ∷ Id (U 0) (defn 0) Empty ] Ā»
      ε āˆ™ defn 0 ⊢
      subst šŸ™ (U 0) (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 0 ] Ā» ε āˆ™ defn 0)
    consistent t =
      let ⊢ε = ε āˆ™įµ—[ ā„•ā±¼ εε ] in
      Opaque[ Empty ∷ U 0 ]      Ā» ε āˆ™ defn 0 ⊢ t ∷ Empty  ā†’āŸØ definition-irrelevant-⊢∷ ok (ā„•ā±¼ εε) ⟩
      Opaque[ ā„• ∷ U 0 ]          Ā» ε āˆ™ defn 0 ⊢ t ∷ Empty  ā†’āŸØ glassify-⊢∷ ⟩
      glassify Opaque[ ā„• ∷ U 0 ] Ā» ε āˆ™ 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 _ , _ , _ , _ , āŠ¢Ī“ , con , not-con , _ =
          consistency-is-not-preserved ok
    in
    not-con (hyp āŠ¢Ī“ con)

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 _ , _ , _ , _ , āŠ¢Ī“ , con , _ , not-con , _ =
          consistency-is-not-preserved ok
    in
    not-con (hyp āŠ¢Ī“ con)

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 _ , _ , _ , _ , āŠ¢Ī“ , con , _ , _ , _ , _ , āˆ‡ā€²āŠ‡āˆ‡ , not-con =
          consistency-is-not-preserved ok
    in
    not-con (hyp āŠ¢Ī“ āˆ‡ā€²āŠ‡āˆ‡ con)

------------------------------------------------------------------------
-- 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 (wfTerm ⊢t) _ $
       PE.substā‚ƒ _⊢_∷_
         (PE.cong (_»_ _) inline-Conᵈ-glassify) PE.refl PE.refl $
       ⊢inlineᵈ∷ ⊢t) ,
    (Ī» consistent āŠ¢Ī” _ →
       consistent _ āˆ˜ā†’
       stabilityTerm
         (PE.substā‚ƒ _»⊢_≔_
            (glassify-idem _) inline-Conᵈ-glassify PE.refl $
          ⊢inline-Conįµˆā‰” āŠ¢Ī”) āˆ˜ā†’
       defn-wkTerm (Ā»āŠ‡Īµ (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 (wfTerm ⊢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 _ , _ , _ , _ , āŠ¢Ī“ , con , _ , _ , _ , _ , āˆ‡ā€²āŠ‡āˆ‡ , not-con =
          consistency-is-not-preserved ok
    in
    not-con (hyp āŠ¢Ī“ con āˆ‡ā€²āŠ‡āˆ‡)

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 āˆ˜ā†’ ε