------------------------------------------------------------------------
-- Some properties related to usage and the strong variant of Erased
------------------------------------------------------------------------

open import Graded.Modality
open import Graded.Mode
open import Graded.Usage.Restrictions

module Graded.Derived.Erased.Usage.Eta
  {a b} {M : Set a} {Mode : Set b}
  {š•„ : Modality M}
  {šŒ : IsMode Mode š•„}
  (R : Usage-restrictions š•„ šŒ)
  where

open Modality š•„
open IsMode šŒ

open import Graded.Context š•„
open import Graded.Context.Properties š•„
open import Graded.Modality.Properties š•„
open import Graded.Usage R
open import Graded.Usage.Inversion R
open import Graded.Usage.Properties R

open import Definition.Untyped M
open import Definition.Untyped.Erased.Eta š•„

open import Tools.Bool
open import Tools.Empty
open import Tools.Function
open import Tools.Product
import Tools.PropositionalEquality as PE
import Tools.Reasoning.PartialOrder
import Tools.Reasoning.PropositionalEquality
open import Tools.Relation

private variable
  t : Term _
  γ   : Conā‚˜ _
  m   : Mode
  ok  : T _

------------------------------------------------------------------------
-- Usage rules

opaque
  unfolding erased

  -- A usage rule for erased.

  ā–øerased′ :
    (Trivialᵐ → šŸ˜ ≤ šŸ™) →
    γ ā–ø[ šŸ˜įµ ] t → šŸ˜į¶œ ā–ø[ šŸ˜įµ ] erased t
  ā–øerased′ {γ} {t} hyp ā–øt =
    sub (fstā‚˜ (ā–ø-šŸ˜ ā–øt) (≤-trans (≤-reflexive (Ā·-zeroʳ _)) šŸ˜ā‰¤āŒœšŸ˜įµāŒ)) šŸ˜ā‰¤
    where
    šŸ˜ā‰¤āŒœšŸ˜įµāŒ : šŸ˜ ≤ ⌜ šŸ˜įµ āŒ
    šŸ˜ā‰¤āŒœšŸ˜įµāŒ =
      case trivialᵐ? of λ where
        (yes šŸ™įµā‰”šŸ˜įµ) →
          ≤-trans (hyp šŸ™įµā‰”šŸ˜įµ) (≤-reflexive (PE.sym (āŒœšŸ˜įµāŒā€² šŸ™įµā‰”šŸ˜įµ)))
        (no šŸ™įµā‰¢šŸ˜įµ) →
          ≤-reflexive (PE.sym (āŒœšŸ˜įµāŒ šŸ™įµā‰¢šŸ˜įµ))
    open ā‰¤į¶œ-reasoning
    šŸ˜ā‰¤ : šŸ˜į¶œ ā‰¤į¶œ ⌜ šŸ˜įµ āŒ ·ᶜ γ
    šŸ˜ā‰¤ = case trivialᵐ? of Ī» where
          (yes šŸ™įµā‰”šŸ˜įµ) → begin
            šŸ˜į¶œ          ā‰ˆĖ˜āŸØ ·ᶜ-zeroĖ” _ ⟩
            šŸ˜ ·ᶜ γ      ā‰¤āŸØ ·ᶜ-monotoneĖ” (hyp šŸ™įµā‰”šŸ˜įµ) ⟩
            šŸ™ ·ᶜ γ      ā‰ˆĖ˜āŸØ ·ᶜ-congʳ (āŒœšŸ˜įµāŒā€² šŸ™įµā‰”šŸ˜įµ) ⟩
            ⌜ šŸ˜įµ āŒ ·ᶜ γ āˆŽ
          (no šŸ™įµā‰¢šŸ˜įµ) → begin
            šŸ˜į¶œ          ā‰ˆĖ˜āŸØ ·ᶜ-zeroĖ” _ ⟩
            šŸ˜ ·ᶜ γ      ā‰ˆĖ˜āŸØ ·ᶜ-congʳ (āŒœšŸ˜įµāŒ šŸ™įµā‰¢šŸ˜įµ) ⟩
            ⌜ šŸ˜įµ āŒ ·ᶜ γ āˆŽ

opaque

  -- Another usage rule for erased.

  ā–øerased : ¬ Trivialᵐ → γ ā–ø[ šŸ˜įµ ] t → šŸ˜į¶œ ā–ø[ šŸ˜įµ ] erased t
  ā–øerased {γ} šŸ™įµā‰¢šŸ˜įµ ā–øt = ā–øerased′ (⊄-elim āˆ˜ā†’ (šŸ™įµā‰¢šŸ˜įµ $_)) ā–øt

------------------------------------------------------------------------
-- Inversion lemmas for usage

opaque
  unfolding erased

  -- An inversion lemma for erased.

  inv-usage-erased′ :
    γ ā–ø[ m ] erased t →
    ∃ Ī» Ī“ → ⌜ šŸ˜įµ āŒ ·ᶜ Ī“ ā–ø[ šŸ˜įµ ] t Ɨ γ ā‰¤į¶œ ⌜ šŸ˜įµ āŒ ·ᶜ Ī“ Ɨ m PE.≔ šŸ˜įµ
  inv-usage-erased′ {γ} {m} ā–ø[] =
    case inv-usage-fst ā–ø[] of Ī» where
      (invUsageFst {Ī“ = Ī“} ā–øt γ≤ ok) →
          _
        , ā–ø-šŸ˜ ā–øt
         , (begin
             γ           ā‰¤āŸØ γ≤ ⟩
             Ī“           ā‰¤āŸØ ▸ᵐ ā–øt ⟩
             ⌜ m āŒ ·ᶜ Ī“  ā‰ˆāŸØ ·ᶜ-congʳ (āŒœāŒ-cong (lemma ok)) ⟩
             ⌜ šŸ˜įµ āŒ ·ᶜ Ī“ āˆŽ)
        , lemma ok
    where
    lemma : ⌜ m āŒ Ā· šŸ˜ ≤ ⌜ m āŒ → m PE.≔ šŸ˜įµ
    lemma ok =
      let open ≤ᵐ-reasoning in
        ≤ᵐ-antisym ā‰¤šŸ˜įµ $ begin
          šŸ˜įµ            ā‰ˆĖ˜āŸØ āŒžšŸ˜āŒŸ ⟩
          āŒž šŸ˜ ⌟         ā‰ˆĖ˜āŸØ āŒžāŒŸ-cong (Ā·-zeroʳ _) ⟩
          āŒž ⌜ m āŒ Ā· šŸ˜ ⌟ ā‰¤āŸØ āŒžāŒŸ-monotone ok ⟩
          āŒž ⌜ m āŒ ⌟     ā‰ˆāŸØ āŒžāŒœāŒāŒŸ _ ⟩
          m             āˆŽ
    open ā‰¤į¶œ-reasoning

opaque

  -- Another inversion lemma for erased.

  inv-usage-erased :
    ¬ Trivialᵐ →
    γ ā–ø[ m ] erased t →
    šŸ˜į¶œ ā–ø[ šŸ˜įµ ] t Ɨ γ ā‰¤į¶œ šŸ˜į¶œ Ɨ m PE.≔ šŸ˜įµ
  inv-usage-erased {γ = γ} šŸ™įµā‰¢šŸ˜įµ ā–ø[] =
    let _ , ā–øt , γ≤ , m≔ = inv-usage-erased′ ā–ø[]
        ā‰ˆį¶œšŸ˜į¶œ = ā‰ˆį¶œ-trans (·ᶜ-congʳ (āŒœšŸ˜įµāŒ šŸ™įµā‰¢šŸ˜įµ)) (·ᶜ-zeroĖ” _)
    in  sub ā–øt (ā‰¤į¶œ-reflexive (ā‰ˆį¶œ-sym ā‰ˆį¶œšŸ˜į¶œ))
      , ā‰¤į¶œ-trans γ≤ (ā‰¤į¶œ-reflexive ā‰ˆį¶œšŸ˜į¶œ)
      , m≔