------------------------------------------------------------------------
-- The fundamental lemma does not hold in general without the
-- assumption that erased matches are disallowed or the context is
-- empty
------------------------------------------------------------------------

open import Graded.Modality
open import Graded.Usage.Restrictions
open import Definition.Typed.EqualityRelation
open import Definition.Typed.Restrictions
open import Tools.Nullary
open import Tools.PropositionalEquality as PE

module Graded.Erasure.LogicalRelation.Fundamental.Counterexample
  {a} {M : Set a}
  (𝕄 : Modality M)
  (open Modality 𝕄)
  (TR : Type-restrictions M)
  (UR : Usage-restrictions M)
  (𝟘-well-behaved : Has-well-behaved-zero M semiring-with-meet)
  {{eqrel : EqRelSet TR}}
  where

open EqRelSet {{...}}
open Type-restrictions TR
open Usage-restrictions UR

open import Graded.Context 𝕄
open import Graded.Context.Properties 𝕄
open import Graded.Modality.Properties.Has-well-behaved-zero
  semiring-with-meet 𝟘-well-behaved
open import Graded.Modality.Properties.PartialOrder
  semiring-with-meet
open import Graded.Usage 𝕄 UR
open import Graded.Mode 𝕄

open import Definition.Untyped M hiding (_∷_)
open import Definition.Typed TR
open import Definition.Typed.Consequences.Canonicity TR
open import Definition.Typed.Consequences.Substitution TR
open import Definition.Typed.Properties TR
open import Definition.LogicalRelation TR
open import Definition.LogicalRelation.Substitution TR
open import Definition.LogicalRelation.Substitution.Properties TR
import Definition.LogicalRelation.Substitution.Irrelevance TR as IS

import Graded.Erasure.Target as T
import Graded.Erasure.LogicalRelation 𝕄 TR is-𝟘? as LR
import Graded.Erasure.LogicalRelation.Irrelevance 𝕄 TR is-𝟘? as LRI
import Graded.Erasure.LogicalRelation.Subsumption 𝕄 TR is-𝟘? as LRS

open import Tools.Fin
open import Tools.Function
open import Tools.Product

private variable
  p : M

-- If Prodrec-allowed 𝟘 p 𝟘 holds for some p (which means that certain
-- kinds of erased matches are allowed), and if additionally
-- Σᵣ-allowed p 𝟘 holds, then one cannot prove a variant of the
-- fundamental lemma without the assumption "erased matches are not
-- allowed or the context is empty" (assuming that Agda is
-- consistent).

negation-of-fundamental-lemma-with-erased-matches :
  Prodrec-allowed 𝟘 p 𝟘 
  Σᵣ-allowed p 𝟘 
  ¬ (∀ {k} {Δ : Con Term k} (⊢Δ :  Δ) 
     let open LR ⊢Δ in
     (∀ {t}  Δ  t  Empty  ) 
      {n} {Γ : Con Term n} {t A : Term n} {γ : Conₘ n} {m} 
     Γ  t  A  γ ▸[ m ] t 
     ∃₂ λ ([Γ] : ⊩ᵛ Γ) ([A] : Γ ⊩ᵛ⟨ ¹  A / [Γ]) 
       γ  Γ ⊩ʳ⟨ ¹  t ∷[ m ] A / [Γ] / [A])
negation-of-fundamental-lemma-with-erased-matches
  {p = p} P-ok Σᵣ-ok hyp =
  case cEx of λ {
    (_ , _ , _ , _ , _ , ⊢t , ▸t , not-ok) 
  not-ok (hyp ⊢Δ consistent ⊢t ▸t) }
  where
  Δ : Con Term 1
  Δ = ε  (Σᵣ p , 𝟘    )

  ⊢Δ :  Δ
  ⊢Δ = ε  ΠΣⱼ (ℕⱼ ε) (ℕⱼ (ε  ℕⱼ ε)) Σᵣ-ok

  consistent :  {t}  Δ  t  Empty  
  consistent {t = t} ⊢t = ¬Empty ∷Empty
    where
    ∷Empty : ε  t [ prodᵣ p zero zero ]₀  Empty
    ∷Empty =
      substTerm ⊢t
        (prodⱼ (ℕⱼ ε) (ℕⱼ (ε  ℕⱼ ε)) (zeroⱼ ε) (zeroⱼ ε) Σᵣ-ok)

  open LR ⊢Δ
  open LRI ⊢Δ
  open LRS ⊢Δ

  cEx″ :  {v}  prodrec 𝟘 p 𝟘  (var x0) zero ® v ∷ℕ  
  cEx″ (zeroᵣ x x₁) with whnfRed*Term x (ne (prodrecₙ (var x0)))
  ... | ()
  cEx″ (sucᵣ x x₁ t®v) with whnfRed*Term x (ne (prodrecₙ (var x0)))
  ... | ()

  cEx′ :
    ([Δ] : ⊩ᵛ Δ)
    ([A] : Δ ⊩ᵛ⟨ ¹   / [Δ]) 
    ε  𝟘  Δ ⊩ʳ⟨ ¹  prodrec 𝟘 p 𝟘  (var x0) zero
      ∷[ 𝟙ᵐ ]  / [Δ] / [A] 
    
  cEx′ [Δ] [A] ⊩ʳpr =
    let [σ]′ = idSubstS [Δ]
        ⊢Δ′ = soundContext [Δ]
        [σ] = IS.irrelevanceSubst [Δ] [Δ] ⊢Δ′ ⊢Δ [σ]′
        σ®σ′ = erasedSubst {l = ¹} {σ′ = T.idSubst} [Δ] [σ]
        pr®pr = ⊩ʳpr [σ] σ®σ′
        [σA] = proj₁ (unwrap [A] ⊢Δ [σ])
        [ℕ] = ℕᵣ {l = ¹} (idRed:*: (ℕⱼ ⊢Δ))
        pr®pr′ = irrelevanceTerm [σA] [ℕ] (pr®pr ◀≢𝟘 𝟙≢𝟘)
    in  cEx″ pr®pr′

  cEx :  λ n
       ∃₄ λ (t A : Term n) (Γ : Con Term n) (γ : Conₘ n)
       Γ  t  A
      × γ ▸[ 𝟙ᵐ ] t
      × ((∃₂ λ ([Γ] : ⊩ᵛ Γ) ([A] : Γ ⊩ᵛ⟨ ¹  A / [Γ]) 
          γ  Γ ⊩ʳ⟨ ¹  t ∷[ 𝟙ᵐ ] A / [Γ] / [A]) 
         )
  cEx = _
    , prodrec 𝟘 p 𝟘  (var x0) zero ,  , ε  (Σᵣ p , 𝟘    )
    , ε  𝟘
    , prodrecⱼ Δ⊢ℕ Δℕ⊢ℕ ΔΣ⊢ℕ (var ⊢Δ here) (zeroⱼ ⊢Δℕℕ) Σᵣ-ok
    , sub ▸pr
        (≤ᶜ-reflexive
           (≈ᶜ-refl  PE.sym (PE.trans (+-identityʳ _) (·-zeroˡ _))))
    , λ {([Γ] , [A] , ⊩ʳpr)  cEx′ [Γ] [A] ⊩ʳpr}
    where
    Δ⊢ℕ = ℕⱼ ⊢Δ
    ⊢Δℕ = ⊢Δ  Δ⊢ℕ
    Δℕ⊢ℕ = ℕⱼ ⊢Δℕ
    Δ⊢Σ = ΠΣⱼ Δ⊢ℕ Δℕ⊢ℕ Σᵣ-ok
    ⊢ΔΣ = ⊢Δ  Δ⊢Σ
    ΔΣ⊢ℕ = ℕⱼ ⊢ΔΣ
    ⊢Δℕℕ = ⊢Δ  Δ⊢ℕ  Δℕ⊢ℕ
    ▸zero =
      sub zeroₘ
        (≤ᶜ-reflexive
           (≈ᶜ-refl 
            PE.trans (·-congˡ (·-zeroˡ p)) (·-zeroʳ 𝟙)  ·-zeroʳ _))
    ▸ℕ = sub ℕₘ (≤ᶜ-refl  ≤-reflexive (·-zeroʳ _))
    ▸pr = prodrecₘ {η = 𝟘ᶜ} var ▸zero ▸ℕ P-ok