------------------------------------------------------------------------
-- An investigation of to what degree weak Ξ£-types can emulate strong
-- Ξ£-types, and vice versa
------------------------------------------------------------------------

-- This module contains parts of an investigation of to what degree
-- weak Ξ£-types can emulate strong Ξ£-types, and vice versa. This
-- investigation was prompted by a question asked by an anonymous
-- reviewer. See also Definition.Untyped.Sigma, which contains some
-- basic definitions, and
-- Definition.Typed.Consequences.DerivedRules.Sigma, which contains
-- properties related to typing. This module contains properties
-- related to usage.

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

module Graded.Derived.Sigma
  {a} {M : Set a}
  (𝕄 : Modality M)
  (UR : Usage-restrictions M)
  where

open Modality 𝕄
open Usage-restrictions UR

open import Graded.Context 𝕄
open import Graded.Context.Properties 𝕄
open import Graded.Modality.Properties 𝕄
open import Graded.Usage 𝕄 UR
open import Graded.Usage.Inversion 𝕄 UR
open import Graded.Usage.Properties 𝕄 UR
open import Graded.Usage.Weakening 𝕄 UR
open import Graded.Substitution.Properties 𝕄 UR

open import Graded.Mode 𝕄

open import Definition.Untyped M
open import Definition.Untyped.Sigma M as Sigma
  using (prodrecβ‚š; module Fstα΅£-sndα΅£)

open import Tools.Bool using (T)
open import Tools.Empty
open import Tools.Fin
open import Tools.Function
open import Tools.Nat using (Nat; 1+)
open import Tools.Nullary
open import Tools.Product
open import Tools.PropositionalEquality as PE using (_β‰’_)
import Tools.Reasoning.PartialOrder
import Tools.Reasoning.PropositionalEquality
open import Tools.Sum using (_⊎_; inj₁; injβ‚‚)

private variable
  n       : Nat
  A B t u : Term _
  p q r   : M
  Ξ³ Ξ΄     : Conβ‚˜ _
  m       : Mode

------------------------------------------------------------------------
-- Some private lemmas related to the modality

private

  -- Some lemmas used below.

  πŸ˜β‰°πŸ™β†’πŸ˜βˆ§πŸ™β‰’πŸ˜ : Β¬ 𝟘 ≀ πŸ™ β†’ 𝟘 ∧ πŸ™ β‰’ 𝟘
  πŸ˜β‰°πŸ™β†’πŸ˜βˆ§πŸ™β‰’πŸ˜ πŸ˜β‰°πŸ™ =
    𝟘 ∧ πŸ™ PE.≑ 𝟘  β†’βŸ¨ flip (PE.subst (_≀ _)) (∧-decreasingΚ³ 𝟘 πŸ™) ⟩
    𝟘 ≀ πŸ™         β†’βŸ¨ πŸ˜β‰°πŸ™ ⟩
    βŠ₯             β–‘

  πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅β†’α΅Β·[πŸ˜βˆ§πŸ™]≑ :
    βˆ€ m β†’ Β¬ 𝟘 ≀ πŸ™ ⊎ πŸ™ PE.≑ 𝟘 ⊎ m β‰’ πŸ™α΅ β†’ m ᡐ· (𝟘 ∧ πŸ™) PE.≑ m
  πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅β†’α΅Β·[πŸ˜βˆ§πŸ™]≑ = Ξ» where
    𝟘ᡐ _           β†’ PE.refl
    πŸ™α΅ πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅ β†’ case πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅ of Ξ» where
      (inj₁ πŸ˜β‰°πŸ™)        β†’ β‰’πŸ˜β†’βŒžβŒŸβ‰‘πŸ™α΅ (πŸ˜β‰°πŸ™β†’πŸ˜βˆ§πŸ™β‰’πŸ˜ πŸ˜β‰°πŸ™)
      (injβ‚‚ (inj₁ πŸ™β‰‘πŸ˜)) β†’ Mode-propositional-if-πŸ™β‰‘πŸ˜ πŸ™β‰‘πŸ˜
      (injβ‚‚ (injβ‚‚ β‰’πŸ™α΅)) β†’ βŠ₯-elim (β‰’πŸ™α΅ PE.refl)

  β‰€πŸ˜β†’πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜ : πŸ™ PE.≑ 𝟘 ⊎ πŸ™ β‰’ 𝟘 β†’ (βˆ€ p β†’ p ≀ 𝟘) β†’ Β¬ 𝟘 ≀ πŸ™ ⊎ πŸ™ PE.≑ 𝟘
  β‰€πŸ˜β†’πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜ = Ξ» where
    (inj₁ πŸ™β‰‘πŸ˜) _  β†’ injβ‚‚ πŸ™β‰‘πŸ˜
    (injβ‚‚ πŸ™β‰’πŸ˜) β‰€πŸ˜ β†’ inj₁
      (𝟘 ≀ πŸ™     β†’βŸ¨ ≀-antisym (β‰€πŸ˜ _) ⟩
       πŸ™ PE.≑ 𝟘  β†’βŸ¨ πŸ™β‰’πŸ˜ ⟩
       βŠ₯         β–‘)

  [πŸ˜βˆ§πŸ™]Β·αΆœβ‰‘πŸ˜αΆœβˆ§αΆœ : (𝟘 ∧ πŸ™) ·ᢜ Ξ³ PE.≑ 𝟘ᢜ ∧ᢜ Ξ³
  [πŸ˜βˆ§πŸ™]Β·αΆœβ‰‘πŸ˜αΆœβˆ§αΆœ {Ξ³ = Ξ³} =
    (𝟘 ∧ πŸ™) ·ᢜ Ξ³      β‰‘βŸ¨ β‰ˆαΆœβ†’β‰‘ (·ᢜ-distribΚ³-∧ᢜ _ _ _) ⟩
    𝟘 ·ᢜ Ξ³ ∧ᢜ πŸ™ ·ᢜ Ξ³  β‰‘βŸ¨ β‰ˆαΆœβ†’β‰‘ (∧ᢜ-cong (·ᢜ-zeroΛ‘ _) (·ᢜ-identityΛ‘ _)) ⟩
    𝟘ᢜ ∧ᢜ γ           ∎
    where
    open Tools.Reasoning.PropositionalEquality

  [πŸ˜βˆ§πŸ™]Β·β‰‘πŸ˜βˆ§ : (𝟘 ∧ πŸ™) Β· p PE.≑ 𝟘 ∧ p
  [πŸ˜βˆ§πŸ™]Β·β‰‘πŸ˜βˆ§ {p = p} =
    (𝟘 ∧ πŸ™) Β· p    β‰‘βŸ¨ Β·-distribΚ³-∧ _ _ _ ⟩
    𝟘 Β· p ∧ πŸ™ Β· p  β‰‘βŸ¨ ∧-cong (Β·-zeroΛ‘ _) (Β·-identityΛ‘ _) ⟩
    𝟘 ∧ p          ∎
    where
    open Tools.Reasoning.PropositionalEquality

  Β·[πŸ˜βˆ§πŸ™]β‰‘πŸ˜βˆ§ : p Β· (𝟘 ∧ πŸ™) PE.≑ 𝟘 ∧ p
  Β·[πŸ˜βˆ§πŸ™]β‰‘πŸ˜βˆ§ {p = p} =
    p Β· (𝟘 ∧ πŸ™)    β‰‘βŸ¨ Β·-distribΛ‘-∧ _ _ _ ⟩
    p Β· 𝟘 ∧ p Β· πŸ™  β‰‘βŸ¨ ∧-cong (Β·-zeroΚ³ _) (Β·-identityΚ³ _) ⟩
    𝟘 ∧ p          ∎
    where
    open Tools.Reasoning.PropositionalEquality

  Β·[πŸ˜βˆ§πŸ™]Β·β‰‘πŸ˜βˆ§Β· : p Β· (𝟘 ∧ πŸ™) Β· q PE.≑ 𝟘 ∧ p Β· q
  Β·[πŸ˜βˆ§πŸ™]Β·β‰‘πŸ˜βˆ§Β· {p = p} {q = q} =
    p Β· (𝟘 ∧ πŸ™) Β· q  β‰‘βŸ¨ Β·-congΛ‘ [πŸ˜βˆ§πŸ™]Β·β‰‘πŸ˜βˆ§ ⟩
    p Β· (𝟘 ∧ q)      β‰‘βŸ¨ Β·-distribΛ‘-∧ _ _ _ ⟩
    p Β· 𝟘 ∧ p Β· q    β‰‘βŸ¨ ∧-congΚ³ (Β·-zeroΚ³ _) ⟩
    𝟘 ∧ p · q        ∎
    where
    open Tools.Reasoning.PropositionalEquality

------------------------------------------------------------------------
-- Pair constructors

-- If _+_ is pointwise bounded by _∧_, then a usage rule like the one
-- for prodα΅£ can be derived for prodβ‚š.

prodβ‚šα΅£β‚˜ :
  (βˆ€ p q β†’ p + q ≀ p ∧ q) β†’
  Ξ³ β–Έ[ m ᡐ· p ] t β†’
  Ξ΄ β–Έ[ m ] u β†’
  p ·ᢜ Ξ³ +ᢜ Ξ΄ β–Έ[ m ] prodβ‚š p t u
prodβ‚šα΅£β‚˜ +β‰€βˆ§ β–Έt β–Έu = sub (prodβ‚šβ‚˜ β–Έt β–Έu) (+αΆœβ‰€αΆœβˆ§αΆœ +β‰€βˆ§)

-- If _∧_ is pointwise bounded by _+_, then a usage rule like the one
-- for prodβ‚š can be derived for prodα΅£.

prodα΅£β‚šβ‚˜ :
  (βˆ€ p q β†’ p ∧ q ≀ p + q) β†’
  Ξ³ β–Έ[ m ᡐ· p ] t β†’
  Ξ΄ β–Έ[ m ] u β†’
  p ·ᢜ Ξ³ ∧ᢜ Ξ΄ β–Έ[ m ] prodα΅£ p t u
prodα΅£β‚šβ‚˜ βˆ§β‰€+ β–Έt β–Έu = sub (prodα΅£β‚˜ β–Έt β–Έu) (βˆ§αΆœβ‰€αΆœ+ᢜ βˆ§β‰€+)

------------------------------------------------------------------------
-- Usage lemmas for prodrecβ‚š

-- A usage lemma for prodrecβ‚š.

prodrecβ‚šβ‚˜ :
  (m ᡐ· r Β· p PE.≑ πŸ™α΅ β†’ p ≀ πŸ™) β†’
  Ξ³ β–Έ[ m ᡐ· r ] t β†’
  Ξ΄ βˆ™ ⌜ m ⌝ Β· r Β· p βˆ™ ⌜ m ⌝ Β· r β–Έ[ m ] u β†’
  (⌜ m ⌝ Β· r Β· (πŸ™ + p)) ·ᢜ Ξ³ +ᢜ Ξ΄ β–Έ[ m ] prodrecβ‚š p t u
prodrecβ‚šβ‚˜ {m = m} {r = r} {p = p} {Ξ³ = Ξ³} {Ξ΄ = Ξ΄} mrpβ‰‘πŸ™β†’pβ‰€πŸ™ β–Έt β–Έu = sub
  (doubleSubstβ‚˜-lemma₁ β–Έu
     (sndβ‚˜ β–Έt)
     (fstβ‚˜ (m ᡐ· r) (β–Έ-cong (lemma m) (β–Έ-Β· β–Έt)) (ᡐ·-Β·-assoc m) mrpβ‰‘πŸ™β†’pβ‰€πŸ™))
    (begin
       (⌜ m ⌝ Β· r Β· (πŸ™ + p)) ·ᢜ Ξ³ +ᢜ Ξ΄                             β‰ˆβŸ¨ +ᢜ-comm _ _ ⟩
       Ξ΄ +ᢜ (⌜ m ⌝ Β· r Β· (πŸ™ + p)) ·ᢜ Ξ³                             β‰ˆβŸ¨ +ᢜ-congΛ‘ $
                                                                      β‰ˆαΆœ-trans
                                                                        (·ᢜ-congʳ $
                                                                         PE.trans
                                                                           (Β·-congΛ‘ $
                                                                            PE.trans (Β·-distribΛ‘-+ _ _ _) $
                                                                            +-congΚ³ $
                                                                            Β·-identityΚ³ _) $
                                                                         Β·-distribΛ‘-+ _ _ _) $
                                                                      ·ᢜ-distribʳ-+ᢜ _ _ _ ⟩
       Ξ΄ +ᢜ (⌜ m ⌝ Β· r) ·ᢜ Ξ³ +ᢜ (⌜ m ⌝ Β· r Β· p) ·ᢜ Ξ³               β‰ˆΛ˜βŸ¨ +ᢜ-congΛ‘ $ +ᢜ-congΛ‘ $
                                                                       β‰ˆαΆœ-trans (β‰ˆαΆœ-sym (·ᢜ-assoc _ _ _)) $
                                                                       ·ᢜ-congʳ $
                                                                       PE.trans (Β·-assoc _ _ _) $
                                                                       Β·-congΛ‘ $
                                                                       PE.trans (Β·-assoc _ _ _) $
                                                                       Β·-congΛ‘ $
                                                                       ·⌜⌞⌟⌝ ⟩
       δ +ᢜ (⌜ m ⌝ · r) ·ᢜ γ +ᢜ (⌜ m ⌝ · r · p) ·ᢜ ⌜ ⌞ p ⌟ ⌝ ·ᢜ γ  ∎)
  where
  lemma : βˆ€ m β†’ ⌞ p ⌟ ·ᡐ m ᡐ· r PE.≑ (m ᡐ· r) ᡐ· p
  lemma 𝟘ᡐ =
    ⌞ p ⌟ ·ᡐ 𝟘ᡐ  β‰‘βŸ¨ ·ᡐ-zeroΚ³-𝟘ᡐ ⟩
    𝟘ᡐ           ∎
    where
    open Tools.Reasoning.PropositionalEquality
  lemma πŸ™α΅ =
    ⌞ p ⌟ ·ᡐ ⌞ r ⌟  β‰‘βŸ¨ ·ᡐ-comm ⌞ _ ⌟ _ ⟩
    ⌞ r ⌟ ·ᡐ ⌞ p ⌟  β‰‘βŸ¨ ⌞⌟·ᡐ ⟩
    ⌞ r Β· p ⌟       β‰‘Λ˜βŸ¨ ⌞⌟ᡐ· ⟩
    ⌞ r ⌟ ᡐ· p      ∎
    where
    open Tools.Reasoning.PropositionalEquality

  open Tools.Reasoning.PartialOrder β‰€αΆœ-poset

-- A variant of the main usage lemma for prodrecβ‚š with the mode set
-- to 𝟘ᡐ.

prodrecβ‚šβ‚˜-𝟘ᡐ :
  ⦃ ok : T 𝟘ᡐ-allowed ⦄ β†’
  Ξ³ β–Έ[ 𝟘ᡐ ] t β†’
  Ξ΄ βˆ™ 𝟘 βˆ™ 𝟘 β–Έ[ 𝟘ᡐ ] u β†’
  Ξ΄ β–Έ[ 𝟘ᡐ ] prodrecβ‚š p t u
prodrecβ‚šβ‚˜-𝟘ᡐ {Ξ³ = Ξ³} {Ξ΄ = Ξ΄} {p = p} ⦃ ok = ok ⦄ β–Έt β–Έu = sub
  (prodrecβ‚šβ‚˜
     (Ξ» ())
     β–Έt
     (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in
      sub β–Έu $ begin
        Ξ΄ βˆ™ 𝟘 Β· 𝟘 Β· p βˆ™ 𝟘 Β· 𝟘  β‰ˆβŸ¨ β‰ˆαΆœ-refl βˆ™ Β·-zeroΛ‘ _ βˆ™ Β·-zeroΛ‘ _ ⟩
        Ξ΄ βˆ™ 𝟘 βˆ™ 𝟘              ∎))
  (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in begin
     Ξ΄                            β‰ˆΛ˜βŸ¨ +ᢜ-identityΛ‘ _ ⟩
     𝟘ᢜ +ᢜ Ξ΄                      β‰ˆΛ˜βŸ¨ +ᢜ-congΚ³ (·ᢜ-zeroΛ‘ _) ⟩
     𝟘 ·ᢜ Ξ³ +ᢜ Ξ΄                  β‰ˆΛ˜βŸ¨ +ᢜ-congΚ³ (·ᢜ-congΚ³ (Β·-zeroΛ‘ _)) ⟩
     (𝟘 Β· 𝟘 Β· (πŸ™ + p)) ·ᢜ Ξ³ +ᢜ Ξ΄  ∎)

-- A variant of the main usage lemma for prodrecβ‚š with the mode set to
-- πŸ™α΅ and the quantity p to 𝟘.

prodrecβ‚šβ‚˜-πŸ™α΅-𝟘 :
  𝟘 ≀ πŸ™ ⊎ T 𝟘ᡐ-allowed β†’
  Ξ³ β–Έ[ ⌞ r ⌟ ] t β†’
  Ξ΄ βˆ™ 𝟘 βˆ™ r β–Έ[ πŸ™α΅ ] u β†’
  r ·ᢜ Ξ³ +ᢜ Ξ΄ β–Έ[ πŸ™α΅ ] prodrecβ‚š 𝟘 t u
prodrecβ‚šβ‚˜-πŸ™α΅-𝟘 {Ξ³ = Ξ³} {r = r} {Ξ΄ = Ξ΄} ok β–Έt β–Έu = sub
  (prodrecβ‚šβ‚˜
     (Ξ» ⌞rπŸ˜βŒŸβ‰‘πŸ™ β†’ case ok of Ξ» where
       (inj₁ πŸ˜β‰€πŸ™) β†’ πŸ˜β‰€πŸ™
       (injβ‚‚ 𝟘ᡐ-ok) β†’ let open Tools.Reasoning.PropositionalEquality in
         case begin
           𝟘ᡐ[ 𝟘ᡐ-ok ] β‰‘Λ˜βŸ¨ 𝟘ᡐ?β‰‘πŸ˜α΅ ⟩
           𝟘ᡐ?         β‰‘Λ˜βŸ¨ βŒžπŸ˜βŒŸβ‰‘πŸ˜α΅? ⟩
           ⌞ 𝟘 ⌟       β‰‘Λ˜βŸ¨ ⌞⌟-cong (Β·-zeroΚ³ r) ⟩
           ⌞ r Β· 𝟘 ⌟   β‰‘βŸ¨ ⌞rπŸ˜βŒŸβ‰‘πŸ™ ⟩
           πŸ™α΅          ∎
         of Ξ» ())
     β–Έt
     (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in
      sub β–Έu $ begin
        Ξ΄ βˆ™ πŸ™ Β· r Β· 𝟘 βˆ™ πŸ™ Β· r  β‰ˆβŸ¨ β‰ˆαΆœ-refl βˆ™ PE.trans (Β·-congΛ‘ (Β·-zeroΚ³ _)) (Β·-zeroΚ³ _) βˆ™ Β·-identityΛ‘ _ ⟩
        Ξ΄ βˆ™ 𝟘 βˆ™ r              ∎))
  (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in begin
     r ·ᢜ Ξ³ +ᢜ Ξ΄                  β‰ˆΛ˜βŸ¨ +ᢜ-congΚ³ $ ·ᢜ-congΚ³ $
                                      PE.trans (Β·-identityΛ‘ _) $
                                      PE.trans (Β·-congΛ‘ (+-identityΚ³ _)) $
                                      ·-identityʳ _ ⟩
     (πŸ™ Β· r Β· (πŸ™ + 𝟘)) ·ᢜ Ξ³ +ᢜ Ξ΄  ∎)

-- A variant of the main usage lemma for prodrecβ‚š with the mode set to
-- πŸ™α΅ and the quantity p to πŸ™. Note that the context in the conclusion
-- is (r + r) ·ᢜ γ +ᢜ δ, while the corresponding context in the usage
-- rule for prodrec is r ·ᢜ γ +ᢜ δ.

prodrecβ‚šβ‚˜-πŸ™α΅-πŸ™ :
  Ξ³ β–Έ[ ⌞ r ⌟ ] t β†’
  Ξ΄ βˆ™ r βˆ™ r β–Έ[ πŸ™α΅ ] u β†’
  (r + r) ·ᢜ Ξ³ +ᢜ Ξ΄ β–Έ[ πŸ™α΅ ] prodrecβ‚š πŸ™ t u
prodrecβ‚šβ‚˜-πŸ™α΅-πŸ™ {Ξ³ = Ξ³} {r = r} {Ξ΄ = Ξ΄} β–Έt β–Έu = sub
  (prodrecβ‚šβ‚˜
     (Ξ» _ β†’ ≀-refl)
     β–Έt
     (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in
      sub β–Έu $ begin
        Ξ΄ βˆ™ πŸ™ Β· r Β· πŸ™ βˆ™ πŸ™ Β· r  β‰ˆβŸ¨ β‰ˆαΆœ-refl βˆ™ PE.trans (Β·-identityΛ‘ _) (Β·-identityΚ³ _) βˆ™ Β·-identityΛ‘ _ ⟩
        Ξ΄ βˆ™ r βˆ™ r              ∎))
  (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in begin
     (r + r) ·ᢜ Ξ³ +ᢜ Ξ΄            β‰ˆΛ˜βŸ¨ +ᢜ-congΚ³ $ ·ᢜ-congΚ³ $
                                      PE.trans (Β·-identityΛ‘ _) $
                                      PE.trans (Β·-distribΛ‘-+ _ _ _) $
                                      +-cong (·-identityʳ _) (·-identityʳ _) ⟩
     (πŸ™ Β· r Β· (πŸ™ + πŸ™)) ·ᢜ Ξ³ +ᢜ Ξ΄  ∎)

-- A variant of the previous lemma with the assumption that _∧_ is
-- pointwise bounded by _+_.

prodrecβ‚šβ‚˜-πŸ™α΅-πŸ™-βˆ§β‰€+ :
  (βˆ€ p q β†’ p ∧ q ≀ p + q) β†’
  Ξ³ β–Έ[ ⌞ r ⌟ ] t β†’
  Ξ΄ βˆ™ r βˆ™ r β–Έ[ πŸ™α΅ ] u β†’
  r ·ᢜ Ξ³ +ᢜ Ξ΄ β–Έ[ πŸ™α΅ ] prodrecβ‚š πŸ™ t u
prodrecβ‚šβ‚˜-πŸ™α΅-πŸ™-βˆ§β‰€+ {Ξ³ = Ξ³} {r = r} {Ξ΄ = Ξ΄} βˆ§β‰€+ β–Έt β–Έu = sub
  (prodrecβ‚šβ‚˜-πŸ™α΅-πŸ™ β–Έt β–Έu)
  (begin
     r ·ᢜ Ξ³ +ᢜ Ξ΄        β‰ˆΛ˜βŸ¨ +ᢜ-congΚ³ (·ᢜ-congΚ³ (∧-idem _)) ⟩
     (r ∧ r) ·ᢜ Ξ³ +ᢜ Ξ΄  β‰€βŸ¨ +ᢜ-monotoneΛ‘ (·ᢜ-monotoneΛ‘ (βˆ§β‰€+ _ _)) ⟩
     (r + r) ·ᢜ γ +ᢜ δ  ∎)
  where
  open Tools.Reasoning.PartialOrder β‰€αΆœ-poset

-- One cannot in general derive the usage rule of prodrec for
-- prodrecβ‚š.
--
-- Note that the assumption πŸ™Β β‰°Β πŸ™Β +Β πŸ™ is satisfied by, for instance,
-- the linearity modality, see
-- Graded.Modality.Instances.Linearity.Properties.Β¬prodrecβ‚˜-Linearity.

Β¬prodrecβ‚˜ : Prodrec-allowed πŸ™ πŸ™ 𝟘
          β†’ Β¬ (πŸ™ ≀ πŸ™ + πŸ™)
          β†’ Β¬ (βˆ€ {n} {Ξ³ Ξ· : Conβ‚˜ n} {Ξ΄ m r p q t u A}
               β†’ Ξ³ β–Έ[ m ᡐ· r ] t
               β†’ Ξ΄ βˆ™ ⌜ m ⌝ Β· r  Β· p βˆ™ ⌜ m ⌝ Β· r β–Έ[ m ] u
               β†’ Ξ· βˆ™ ⌜ 𝟘ᡐ? ⌝ Β· q β–Έ[ 𝟘ᡐ? ] A
               β†’ Prodrec-allowed r p q
               β†’ r ·ᢜ Ξ³ +ᢜ Ξ΄ β–Έ[ m ] prodrecβ‚š p t u)
Β¬prodrecβ‚˜ ok πŸ™β‰°πŸš prodrecβ‚šβ‚˜β€² =
  let t = prod Ξ£β‚š πŸ™ (var x0) (var x0)
      u = prod Ξ£α΅£ πŸ™ (var x1) (var x0)
      Ξ³β–Έtβ€² = prodβ‚šβ‚˜ {Ξ³ = Ξ΅ βˆ™ πŸ™} {m = πŸ™α΅} {p = πŸ™} {Ξ΄ = Ξ΅ βˆ™ πŸ™}
                      (PE.subst (Ξ» x β†’ _ β–Έ[ x ] var x0) (PE.sym ᡐ·-identityΚ³) var)
                      (var {x = x0})

      Ξ³β–Έt = PE.substβ‚‚ (Ξ» x y β†’ x β–Έ[ y ] t)
                      (PE.cong (Ξ΅ βˆ™_) (PE.trans (PE.cong (_∧ πŸ™) (Β·-identityΛ‘ πŸ™))
                                                (∧-idem πŸ™)))
                      (PE.sym ᡐ·-identityΚ³) Ξ³β–Έtβ€²
      Ξ΄β–Έuβ€² : _ β–Έ[ πŸ™α΅ ] u
      Ξ΄β–Έuβ€² = prodα΅£β‚˜ var var
      Ξ΄β–Έu = let open Tools.Reasoning.PropositionalEquality
            in  PE.subst₃ (Ξ» x y z β†’ Ξ΅ βˆ™ x βˆ™ y βˆ™ z β–Έ[ πŸ™α΅ ] u)
                      (PE.trans (+-identityʳ _) (·-identityˑ 𝟘))
                      (πŸ™ Β· ⌜ πŸ™α΅ ᡐ· πŸ™ ⌝ + 𝟘  β‰‘βŸ¨ +-identityΚ³ _ ⟩
                       πŸ™ Β· ⌜ πŸ™α΅ ᡐ· πŸ™ ⌝      β‰‘βŸ¨ Β·-identityΛ‘ _ ⟩
                       ⌜ πŸ™α΅ ᡐ· πŸ™ ⌝          β‰‘βŸ¨ PE.cong ⌜_⌝ (ᡐ·-identityΚ³ {m = πŸ™α΅}) ⟩
                       ⌜ πŸ™α΅ ⌝               β‰‘Λ˜βŸ¨ Β·-identityΛ‘ _ ⟩
                       ⌜ πŸ™α΅ ⌝ Β· πŸ™           β‰‘Λ˜βŸ¨ Β·-identityΛ‘ _ ⟩
                       ⌜ πŸ™α΅ ⌝ Β· πŸ™ Β· πŸ™       ∎)
                      (πŸ™ Β· 𝟘 + ⌜ πŸ™α΅ ⌝  β‰‘βŸ¨ PE.cong (_+ _) (Β·-identityΛ‘ 𝟘) ⟩
                       𝟘 + ⌜ πŸ™α΅ ⌝      β‰‘βŸ¨ +-identityΛ‘ _ ⟩
                       ⌜ πŸ™α΅ ⌝          β‰‘Λ˜βŸ¨ Β·-identityΚ³ _ ⟩
                       ⌜ πŸ™α΅ ⌝ Β· πŸ™      ∎)
                      Ξ΄β–Έuβ€²
      Ξ·β–ΈAβ€² = Ξ Ξ£β‚˜ {Ξ³ = 𝟘ᢜ} {p = 𝟘} {Ξ΄ = 𝟘ᢜ} {b = BMΞ£ Ξ£α΅£}
                 β„•β‚˜ (sub β„•β‚˜ (β‰€αΆœ-refl βˆ™ ≀-reflexive (Β·-zeroΚ³ _)))
      Ξ·β–ΈA = sub Ξ·β–ΈAβ€² (β‰€αΆœ-reflexive (β‰ˆαΆœ-sym (+ᢜ-identityΛ‘ 𝟘ᢜ) βˆ™
                                   PE.trans (·-zeroʳ _) (PE.sym (+-identityˑ 𝟘))))
  in  case prodrecβ‚šβ‚˜β€² {Ξ· = 𝟘ᢜ} Ξ³β–Έt Ξ΄β–Έu Ξ·β–ΈA ok of Ξ» β–Έprβ€² β†’
      case inv-usage-prodα΅£ β–Έprβ€² of Ξ» {
        (invUsageProdα΅£ {Ξ΄ = Ξ΅ βˆ™ a} {Ξ΅ βˆ™ b} aβ–Έfstt bβ–Έsndt πŸ™β‰€a+b) β†’ case inv-usage-fst aβ–Έfstt of Ξ» {
        (invUsageFst {Ξ΄ = Ξ΅ βˆ™ c} mβ€² eq cβ–Έt a≀c _) β†’ case inv-usage-snd bβ–Έsndt of Ξ» {
        (invUsageSnd {Ξ΄ = Ξ΅ βˆ™ d} dβ–Έt b≀d) β†’ case inv-usage-prodβ‚š cβ–Έt of Ξ» {
        (invUsageProdβ‚š {Ξ΄ = Ξ΅ βˆ™ e} {Ξ· = Ξ΅ βˆ™ f} eβ–Έxβ‚€ fβ–Έxβ‚€ c≀e∧f) β†’ case inv-usage-prodβ‚š dβ–Έt of Ξ» {
        (invUsageProdβ‚š {Ξ΄ = Ξ΅ βˆ™ g} {Ξ· = Ξ΅ βˆ™ h} gβ–Έxβ‚€ hβ–Έxβ‚€ d≀g∧h) β†’
          let i = ⌜ (πŸ™α΅ ᡐ· πŸ™) ᡐ· πŸ™ ⌝
              j = ⌜ πŸ™α΅ ᡐ· πŸ™ ⌝
              open Tools.Reasoning.PartialOrder ≀-poset
          in  case begin
                πŸ™ β‰‘Λ˜βŸ¨ Β·-identityΛ‘ πŸ™ ⟩
                πŸ™ Β· πŸ™ β‰‘Λ˜βŸ¨ +-identityΚ³ _ ⟩
                πŸ™ Β· πŸ™ + 𝟘 β‰€βŸ¨ β¦… πŸ™β‰€a+b ⦆ ⟩
                πŸ™ Β· a + b β‰‘βŸ¨ PE.cong (_+ b) (Β·-identityΛ‘ a) ⟩
                a + b β‰€βŸ¨ +-monotone β¦… a≀c ⦆ β¦… b≀d ⦆ ⟩
                c + d β‰€βŸ¨ +-monotone β¦… c≀e∧f ⦆ β¦… d≀g∧h ⦆ ⟩
                (πŸ™ Β· e ∧ f) + (πŸ™ Β· g ∧ h) β‰‘βŸ¨ +-cong (∧-congΚ³ (Β·-identityΛ‘ e)) (∧-congΚ³ (Β·-identityΛ‘ g)) ⟩
                (e ∧ f) + (g ∧ h) β‰€βŸ¨ +-monotone (∧-monotone β¦… inv-usage-var eβ–Έxβ‚€ ⦆ β¦… inv-usage-var fβ–Έxβ‚€ ⦆)
                                                (∧-monotone β¦… inv-usage-var gβ–Έxβ‚€ ⦆ β¦… inv-usage-var hβ–Έxβ‚€ ⦆)
                                   ⟩
                (i ∧ j) + (j ∧ πŸ™) β‰‘βŸ¨ +-congΚ³ (∧-congΚ³ (PE.cong ⌜_⌝ ⌞⌟·ᡐ-idem)) ⟩
                (j ∧ j) + (j ∧ πŸ™) β‰‘βŸ¨ +-cong (∧-cong (PE.cong ⌜_⌝ βŒžπŸ™βŒŸ) (PE.cong ⌜_⌝ βŒžπŸ™βŒŸ))
                                            (∧-congΚ³ (PE.cong ⌜_⌝ βŒžπŸ™βŒŸ))
                                   ⟩
                (πŸ™ ∧ πŸ™) + (πŸ™ ∧ πŸ™) β‰‘βŸ¨ +-cong (∧-idem πŸ™) (∧-idem πŸ™) ⟩
                πŸ™ + πŸ™ ∎
                of πŸ™β‰°πŸš
            }}}}}
  where
  β¦…_⦆ : {p q : M} β†’ Ξ΅ βˆ™ p β‰€αΆœ Ξ΅ βˆ™ q β†’ p ≀ q
  β¦…_⦆ = headβ‚˜-monotone

------------------------------------------------------------------------
-- An investigation of different potential implementations of a first
-- projection for weak Ξ£-types

-- A generalised first projection with two extra quantities.

fstα΅£β€² : M β†’ M β†’ M β†’ Term n β†’ Term n β†’ Term n
fstα΅£β€² r p q = Fstα΅£-sndα΅£.fstα΅£ r q p

-- An inversion lemma for fstα΅£β€².

inv-usage-fstα΅£β€² :
  Ξ³ β–Έ[ m ] fstα΅£β€² r p q A t β†’
  βˆƒβ‚‚ Ξ» Ξ· Ξ΄ β†’
    Ξ³ β‰€αΆœ r ·ᢜ Ξ· Γ—
    Ξ· β–Έ[ m ᡐ· r ] t Γ—
    Ξ΄ β–Έ[ 𝟘ᡐ? ] A Γ—
    ⌜ m ⌝ Β· r Β· p ≀ ⌜ m ⌝ Γ—
    ⌜ m ⌝ Β· r ≀ 𝟘 Γ—
    Prodrec-allowed r p q
inv-usage-fstα΅£β€² {Ξ³ = Ξ³} {m = m} {r = r} {p = p} {q = q} β–Έfstα΅£β€² =
  case inv-usage-prodrec β–Έfstα΅£β€² of Ξ» {
    (invUsageProdrec {Ξ΄ = Ξ΄} {Ξ· = Ξ·} {ΞΈ = ΞΈ} β–Έt β–Έvar β–ΈA ok γ≀rΞ΄+Ξ·) β†’
  case inv-usage-var β–Έvar of Ξ» {
    (Ξ·β‰€πŸ˜ βˆ™ mrp≀m βˆ™ mrβ‰€πŸ˜) β†’
    Ξ΄
  , ΞΈ
  , (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in begin
       Ξ³             β‰€βŸ¨ γ≀rΞ΄+Ξ· ⟩
       r ·ᢜ Ξ΄ +ᢜ Ξ·   β‰€βŸ¨ +ᢜ-monotoneΚ³ Ξ·β‰€πŸ˜ ⟩
       r ·ᢜ Ξ΄ +ᢜ 𝟘ᢜ  β‰ˆβŸ¨ +ᢜ-identityΚ³ _ ⟩
       r ·ᢜ δ        ∎)
  , β–Έt
  , wkUsage⁻¹ β–ΈA
  , mrp≀m
  , mrβ‰€πŸ˜
  , ok }}

-- An inversion lemma for fstα΅£β€² with the mode set toΒ πŸ™α΅.

inv-usage-fstα΅£β€²-πŸ™α΅ :
  Ξ³ β–Έ[ πŸ™α΅ ] fstα΅£β€² r p q A t β†’
  βˆƒβ‚‚ Ξ» Ξ· Ξ΄ β†’
    Ξ³ β‰€αΆœ r ·ᢜ Ξ· Γ—
    Ξ· β–Έ[ ⌞ r ⌟ ] t Γ—
    Ξ΄ β–Έ[ 𝟘ᡐ? ] A Γ—
    r Β· p ≀ πŸ™ Γ—
    r ≀ 𝟘 Γ—
    Prodrec-allowed r p q
inv-usage-fstα΅£β€²-πŸ™α΅ {r = r} {p = p} β–Έfstα΅£β€² =
  case inv-usage-fstα΅£β€² β–Έfstα΅£β€² of Ξ» {
    (_ , _ , leq₁ , β–Έt , β–ΈA , leqβ‚‚ , leq₃ , ok) β†’
  _ , _ , leq₁ , β–Έt , β–ΈA ,
  (begin
     r Β· p      β‰‘Λ˜βŸ¨ Β·-identityΛ‘ _ ⟩
     πŸ™ Β· r Β· p  β‰€βŸ¨ leqβ‚‚ ⟩
     πŸ™          ∎) ,
  (begin
     r      β‰‘Λ˜βŸ¨ Β·-identityΛ‘ _ ⟩
     πŸ™ Β· r  β‰€βŸ¨ leq₃ ⟩
     𝟘      ∎) ,
  ok }
  where
  open Tools.Reasoning.PartialOrder ≀-poset

-- If πŸ˜Β β‰°Β πŸ™ then no application of fstα΅£β€²Β πŸ˜ is well-resourced (with
-- respect to the modeΒ πŸ™α΅).

πŸ˜β‰°πŸ™β†’fstα΅£β€²-𝟘-not-ok :
  Β¬ 𝟘 ≀ πŸ™ β†’
  Β¬ Ξ³ β–Έ[ πŸ™α΅ ] fstα΅£β€² 𝟘 p q A t
πŸ˜β‰°πŸ™β†’fstα΅£β€²-𝟘-not-ok {Ξ³ = Ξ³} {p = p} {q = q} {A = A} {t = t} πŸ˜β‰°πŸ™ =
  Ξ³ β–Έ[ πŸ™α΅ ] fstα΅£β€² 𝟘 p q A t  β†’βŸ¨ proj₁ βˆ˜β†’ projβ‚‚ βˆ˜β†’ projβ‚‚ βˆ˜β†’ projβ‚‚ βˆ˜β†’ projβ‚‚ βˆ˜β†’ projβ‚‚ βˆ˜β†’ inv-usage-fstα΅£β€²-πŸ™α΅ ⟩
  𝟘 Β· p ≀ πŸ™                  β†’βŸ¨ ≀-trans (≀-reflexive (PE.sym (Β·-zeroΛ‘ _))) ⟩
  𝟘 ≀ πŸ™                      β†’βŸ¨ πŸ˜β‰°πŸ™ ⟩
  βŠ₯                          β–‘

-- If πŸ™Β β‰°Β πŸ˜ then no application of fstα΅£β€²Β πŸ™ is well-resourced (with
-- respect to the modeΒ πŸ™α΅).

πŸ™β‰°πŸ˜β†’fstα΅£β€²-πŸ™-not-ok :
  Β¬ πŸ™ ≀ 𝟘 β†’
  Β¬ Ξ³ β–Έ[ πŸ™α΅ ] fstα΅£β€² πŸ™ p q A t
πŸ™β‰°πŸ˜β†’fstα΅£β€²-πŸ™-not-ok {Ξ³ = Ξ³} {p = p} {q = q} {A = A} {t = t} πŸ™β‰°πŸ˜ =
  Ξ³ β–Έ[ πŸ™α΅ ] fstα΅£β€² πŸ™ p q A t  β†’βŸ¨ proj₁ βˆ˜β†’ projβ‚‚ βˆ˜β†’ projβ‚‚ βˆ˜β†’ projβ‚‚ βˆ˜β†’ projβ‚‚ βˆ˜β†’ projβ‚‚ βˆ˜β†’ projβ‚‚ βˆ˜β†’ inv-usage-fstα΅£β€²-πŸ™α΅ ⟩
  πŸ™ ≀ 𝟘                      β†’βŸ¨ πŸ™β‰°πŸ˜ ⟩
  βŠ₯                          β–‘

-- An inversion lemma for fstα΅£β€² with the mode set toΒ πŸ™α΅ and either
-- rΒ β‰’Β πŸ˜ or πŸ™Β β‰‘Β πŸ˜.

inv-usage-fstα΅£β€²-β‰’πŸ˜-πŸ™α΅ :
  r β‰’ 𝟘 ⊎ πŸ™ PE.≑ 𝟘 β†’
  Ξ³ β–Έ[ πŸ™α΅ ] fstα΅£β€² r p q A t β†’
  βˆƒβ‚‚ Ξ» Ξ· Ξ΄ β†’
    Ξ³ β‰€αΆœ r ·ᢜ Ξ· Γ—
    Ξ· β–Έ[ πŸ™α΅ ] t Γ—
    Ξ΄ β–Έ[ 𝟘ᡐ? ] A Γ—
    r Β· p ≀ πŸ™ Γ—
    r ≀ 𝟘 Γ—
    Prodrec-allowed r p q
inv-usage-fstα΅£β€²-β‰’πŸ˜-πŸ™α΅ rβ‰’πŸ˜βŠŽπŸ™β‰‘πŸ˜ β–Έfstα΅£β€² =
  case inv-usage-fstα΅£β€²-πŸ™α΅ β–Έfstα΅£β€² of Ξ» {
    (_ , _ , leq₁ , β–Έt , β–ΈA , leqβ‚‚ , leq₃ , ok) β†’
  _ , _ , leq₁ ,
  β–Έ-cong
    (case rβ‰’πŸ˜βŠŽπŸ™β‰‘πŸ˜ of Ξ» where
       (inj₁ rβ‰’πŸ˜) β†’ β‰’πŸ˜β†’βŒžβŒŸβ‰‘πŸ™α΅ rβ‰’πŸ˜
       (injβ‚‚ πŸ™β‰‘πŸ˜) β†’ Mode-propositional-if-πŸ™β‰‘πŸ˜ πŸ™β‰‘πŸ˜)
    β–Έt ,
  β–ΈA , leqβ‚‚ , leq₃ , ok }

-- An inversion lemma for fstα΅£β€² with the mode set toΒ πŸ™α΅, r set to
-- πŸ˜Β βˆ§Β πŸ™, and either πŸ˜Β β‰°Β πŸ™ or πŸ™Β β‰‘Β πŸ˜.

inv-usage-fstα΅£β€²-πŸ˜βˆ§πŸ™-πŸ™α΅ :
  Β¬ 𝟘 ≀ πŸ™ ⊎ πŸ™ PE.≑ 𝟘 β†’
  Ξ³ β–Έ[ πŸ™α΅ ] fstα΅£β€² (𝟘 ∧ πŸ™) p q A t β†’
  βˆƒβ‚‚ Ξ» Ξ· Ξ΄ β†’
    Ξ³ β‰€αΆœ 𝟘ᢜ ∧ᢜ Ξ· Γ— Ξ· β–Έ[ πŸ™α΅ ] t Γ—
    Ξ΄ β–Έ[ 𝟘ᡐ? ] A Γ—
    𝟘 ∧ p ≀ πŸ™ Γ—
    Prodrec-allowed (𝟘 ∧ πŸ™) p q
inv-usage-fstα΅£β€²-πŸ˜βˆ§πŸ™-πŸ™α΅ {Ξ³ = Ξ³} {p = p} πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜ β–Έfstα΅£β€² =
  case inv-usage-fstα΅£β€²-β‰’πŸ˜-πŸ™α΅ πŸ˜βˆ§πŸ™β‰’πŸ˜βŠŽπŸ™β‰‘πŸ˜ β–Έfstα΅£β€² of Ξ» {
    (Ξ· , _ , leq₁ , β–Έt , β–ΈA , leqβ‚‚ , _ , ok) β†’
  _ , _ ,
  (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in begin
     Ξ³             β‰€βŸ¨ leq₁ ⟩
     (𝟘 ∧ πŸ™) ·ᢜ Ξ·  β‰‘βŸ¨ [πŸ˜βˆ§πŸ™]Β·αΆœβ‰‘πŸ˜αΆœβˆ§αΆœ ⟩
     𝟘ᢜ ∧ᢜ η       ∎) ,
  β–Έt , β–ΈA ,
  (let open Tools.Reasoning.PartialOrder ≀-poset in begin
     𝟘 ∧ p        β‰‘Λ˜βŸ¨ [πŸ˜βˆ§πŸ™]Β·β‰‘πŸ˜βˆ§ ⟩
     (𝟘 ∧ πŸ™) Β· p  β‰€βŸ¨ leqβ‚‚ ⟩
     πŸ™            ∎) ,
  ok }
  where
  πŸ˜βˆ§πŸ™β‰’πŸ˜βŠŽπŸ™β‰‘πŸ˜ = case πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜ of Ξ» where
    (inj₁ πŸ˜β‰°πŸ™) β†’ inj₁ (πŸ˜β‰°πŸ™β†’πŸ˜βˆ§πŸ™β‰’πŸ˜ πŸ˜β‰°πŸ™)
    (injβ‚‚ πŸ™β‰‘πŸ˜) β†’ injβ‚‚ πŸ™β‰‘πŸ˜

-- If a certain usage rule holds for fstα΅£β€²Β rΒ πŸ™Β qΒ A (where A has type
-- TermΒ 1), then r is equal to πŸ™ and πŸ™Β β‰€Β πŸ˜.

fstα΅£β€²β‚˜β†’β‰‘πŸ™β‰€πŸ˜ :
  {A : Term 1} β†’
  (βˆ€ {Ξ³ t} β†’
   Ξ³ β–Έ[ πŸ™α΅ ] t β†’
   Ξ³ β–Έ[ πŸ™α΅ ] fstα΅£β€² r πŸ™ q A t) β†’
  r PE.≑ πŸ™ Γ— πŸ™ ≀ 𝟘
fstα΅£β€²β‚˜β†’β‰‘πŸ™β‰€πŸ˜ {r = r} {q = q} {A = A} =
  (βˆ€ {Ξ³ t} β†’ Ξ³ β–Έ[ πŸ™α΅ ] t β†’ Ξ³ β–Έ[ πŸ™α΅ ] fstα΅£β€² r πŸ™ q A t)  β†’βŸ¨ _$ var ⟩
  Ξ³β€² β–Έ[ πŸ™α΅ ] fstα΅£β€² r πŸ™ q A tβ€²                          β†’βŸ¨ lemma ⟩
  r PE.≑ πŸ™ Γ— πŸ™ ≀ 𝟘                                     β–‘
  where
  Ξ³β€² = Ξ΅ βˆ™ πŸ™
  tβ€² = var x0

  lemma : Ξ³β€² β–Έ[ πŸ™α΅ ] fstα΅£β€² r πŸ™ q A tβ€² β†’ r PE.≑ πŸ™ Γ— πŸ™ ≀ 𝟘
  lemma β–Έfst-t =
    case inv-usage-fstα΅£β€² β–Έfst-t of Ξ» {
      (Ξ΅ βˆ™ p , _ , Ξ΅ βˆ™ πŸ™β‰€rp , β–Έt , _ , πŸ™rπŸ™β‰€πŸ™ , πŸ™rβ‰€πŸ˜ , _) β†’
    case inv-usage-var β–Έt of Ξ» {
      (Ξ΅ βˆ™ pβ‰€βŒœβŒžr⌟⌝) β†’
    let rβ‰€πŸ™ = begin
          r          β‰‘Λ˜βŸ¨ Β·-identityΚ³ _ ⟩
          r Β· πŸ™      β‰‘Λ˜βŸ¨ Β·-identityΛ‘ _ ⟩
          πŸ™ Β· r Β· πŸ™  β‰€βŸ¨ πŸ™rπŸ™β‰€πŸ™ ⟩
          πŸ™          ∎

        rβ‰€πŸ˜ = begin
          r      β‰‘Λ˜βŸ¨ Β·-identityΛ‘ _ ⟩
          πŸ™ Β· r  β‰€βŸ¨ πŸ™rβ‰€πŸ˜ ⟩
          𝟘      ∎
    in
      ≀-antisym
        rβ‰€πŸ™
        (begin
           πŸ™              β‰€βŸ¨ πŸ™β‰€rp ⟩
           r Β· p          β‰€βŸ¨ Β·-monotoneΚ³ pβ‰€βŒœβŒžr⌟⌝ ⟩
           r Β· ⌜ ⌞ r ⌟ ⌝  β‰‘βŸ¨ ·⌜⌞⌟⌝ ⟩
           r              ∎)
    , (begin
         πŸ™      β‰€βŸ¨ πŸ™β‰€rp ⟩
         r Β· p  β‰€βŸ¨ Β·-monotoneΛ‘ rβ‰€πŸ˜ ⟩
         𝟘 Β· p  β‰‘βŸ¨ Β·-zeroΛ‘ _ ⟩
         𝟘      ∎) }}
    where
    open Tools.Reasoning.PartialOrder ≀-poset

-- If πŸ™ is not bounded by 𝟘, then a certain usage rule for
-- fstα΅£β€²Β rΒ πŸ™Β qΒ A (where A has type TermΒ 1) does not hold.

Β¬fstα΅£β€²β‚˜β€² :
  {A : Term 1} β†’
  Β¬ πŸ™ ≀ 𝟘 β†’
  Β¬ ({Ξ³ : Conβ‚˜ 1} {t : Term 1} β†’
     Ξ³ β–Έ[ πŸ™α΅ ] t β†’
     Ξ³ β–Έ[ πŸ™α΅ ] fstα΅£β€² r πŸ™ q A t)
Β¬fstα΅£β€²β‚˜β€² πŸ™β‰°πŸ˜ hyp = πŸ™β‰°πŸ˜ (fstα΅£β€²β‚˜β†’β‰‘πŸ™β‰€πŸ˜ hyp .projβ‚‚)

-- If πŸ™ is not bounded by 𝟘, then a certain usage rule for fstα΅£β€² does
-- not hold.

Β¬fstα΅£β€²β‚˜ :
  Β¬ πŸ™ ≀ 𝟘 β†’
  Β¬ (βˆ€ {Ξ³ : Conβ‚˜ 1} {t : Term 1} {p mβ€²} m β†’
     Ξ³ β–Έ[ m ᡐ· p ] t β†’
     m ᡐ· p PE.≑ mβ€² β†’
     (mβ€² PE.≑ πŸ™α΅ β†’ p ≀ πŸ™) β†’
     Ξ³ β–Έ[ mβ€² ] fstα΅£β€² r p q A t)
Β¬fstα΅£β€²β‚˜ πŸ™β‰°πŸ˜ hyp =
  Β¬fstα΅£β€²β‚˜β€² πŸ™β‰°πŸ˜ Ξ» β–Έt β†’
    hyp πŸ™α΅ (β–Έ-cong (PE.sym βŒžπŸ™βŒŸ) β–Έt) βŒžπŸ™βŒŸ (Ξ» _ β†’ ≀-refl)

------------------------------------------------------------------------
-- The first and second projections for weak Ξ£-types

open Fstα΅£-sndα΅£ (𝟘 ∧ πŸ™) 𝟘 public using (fstα΅£; sndα΅£)

------------------------------------------------------------------------
-- Inversion lemmas for usage for fstα΅£

-- An inversion lemma for fstα΅£.

inv-usage-fstα΅£ :
  Β¬ 𝟘 ≀ πŸ™ ⊎ πŸ™ PE.≑ 𝟘 ⊎ m β‰’ πŸ™α΅ β†’
  Ξ³ β–Έ[ m ] fstα΅£ p A t β†’
  βˆƒβ‚‚ Ξ» Ξ· Ξ΄ β†’
    Ξ³ β‰€αΆœ 𝟘ᢜ ∧ᢜ Ξ· Γ— Ξ· β–Έ[ m ] t Γ—
    Ξ΄ β–Έ[ 𝟘ᡐ? ] A Γ—
    𝟘 ∧ ⌜ m ⌝ Β· p ≀ ⌜ m ⌝ Γ—
    Prodrec-allowed (𝟘 ∧ πŸ™) p 𝟘
inv-usage-fstα΅£ {m = m} {Ξ³ = Ξ³} {p = p} πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅ β–Έfstα΅£ =
  case inv-usage-fstα΅£β€² β–Έfstα΅£ of Ξ» {
    (Ξ· , Ξ΄ , leq₁ , β–Έt , β–ΈA , leqβ‚‚ , leq₃ , ok) β†’
  _ , _ ,
  (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in begin
     Ξ³             β‰€βŸ¨ leq₁ ⟩
     (𝟘 ∧ πŸ™) ·ᢜ Ξ·  β‰‘βŸ¨ [πŸ˜βˆ§πŸ™]Β·αΆœβ‰‘πŸ˜αΆœβˆ§αΆœ ⟩
     𝟘ᢜ ∧ᢜ η       ∎) ,
  β–Έ-cong (πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅β†’α΅Β·[πŸ˜βˆ§πŸ™]≑ _ πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅) β–Έt ,
  β–ΈA ,
  (let open Tools.Reasoning.PartialOrder ≀-poset in begin
     𝟘 ∧ ⌜ m ⌝ Β· p        β‰‘Λ˜βŸ¨ Β·[πŸ˜βˆ§πŸ™]Β·β‰‘πŸ˜βˆ§Β· ⟩
     ⌜ m ⌝ Β· (𝟘 ∧ πŸ™) Β· p  β‰€βŸ¨ leqβ‚‚ ⟩
     ⌜ m ⌝                ∎) ,
  ok }

-- An inversion lemma for fstᡣ with the mode set to 𝟘ᡐ.

inv-usage-fstᡣ-𝟘ᡐ :
  ⦃ ok : T 𝟘ᡐ-allowed ⦄ β†’
  Ξ³ β–Έ[ 𝟘ᡐ ] fstα΅£ p A t β†’
  βˆƒ Ξ» Ξ΄ β†’
    Ξ³ β‰€αΆœ 𝟘ᢜ Γ— 𝟘ᢜ β–Έ[ 𝟘ᡐ ] t Γ—
    Ξ΄ β–Έ[ 𝟘ᡐ ] A Γ—
    Prodrec-allowed (𝟘 ∧ πŸ™) p 𝟘
inv-usage-fstα΅£-𝟘ᡐ {Ξ³ = Ξ³} β–Έfstα΅£ =
  case inv-usage-fstα΅£ (injβ‚‚ (injβ‚‚ (Ξ» ()))) β–Έfstα΅£ of Ξ» {
    (Ξ· , _ , leq₁ , β–Έt , β–ΈA , leqβ‚‚ , ok) β†’
  _ ,
  (begin
     Ξ³        β‰€βŸ¨ leq₁ ⟩
     𝟘ᢜ ∧ᢜ Ξ·  β‰€βŸ¨ ∧ᢜ-decreasingΚ³ _ _ ⟩
     Ξ·        β‰€βŸ¨ β–Έ-𝟘ᡐ β–Έt ⟩
     𝟘ᢜ       ∎) ,
  (sub (β–Έ-Β· {mβ€² = 𝟘ᡐ} β–Έt) $ begin
     𝟘ᢜ      β‰ˆΛ˜βŸ¨ ·ᢜ-zeroΛ‘ _ ⟩
     𝟘 ·ᢜ η  ∎) ,
  β–Έ-cong 𝟘ᡐ?β‰‘πŸ˜α΅ β–ΈA , ok }
  where
  open Tools.Reasoning.PartialOrder β‰€αΆœ-poset

-- An inversion lemma for fstα΅£ with the mode set toΒ πŸ™α΅.

inv-usage-fstα΅£-πŸ™α΅ :
  Β¬ 𝟘 ≀ πŸ™ ⊎ πŸ™ PE.≑ 𝟘 β†’
  Ξ³ β–Έ[ πŸ™α΅ ] fstα΅£ p A t β†’
  βˆƒβ‚‚ Ξ» Ξ· Ξ΄ β†’
    Ξ³ β‰€αΆœ 𝟘ᢜ ∧ᢜ Ξ· Γ— Ξ· β–Έ[ πŸ™α΅ ] t Γ—
    Ξ΄ β–Έ[ 𝟘ᡐ? ] A Γ—
    𝟘 ∧ p ≀ πŸ™ Γ—
    Prodrec-allowed (𝟘 ∧ πŸ™) p 𝟘
inv-usage-fstα΅£-πŸ™α΅ {p = p} πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜ β–Έfstα΅£ =
  case inv-usage-fstα΅£ πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽπŸ™α΅β‰’πŸ™α΅ β–Έfstα΅£ of Ξ» {
    (_ , _ , leq₁ , β–Έt , β–ΈA , leqβ‚‚ , ok) β†’
  _ , _ , leq₁ , β–Έt , β–ΈA ,
  (begin
     𝟘 ∧ p      β‰‘Λ˜βŸ¨ ∧-congΛ‘ (Β·-identityΛ‘ _) ⟩
     𝟘 ∧ πŸ™ Β· p  β‰€βŸ¨ leqβ‚‚ ⟩
     πŸ™          ∎) ,
  ok }
  where
  open Tools.Reasoning.PartialOrder ≀-poset

  πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽπŸ™α΅β‰’πŸ™α΅ = case πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜ of Ξ» where
    (inj₁ πŸ˜β‰°πŸ™) β†’ inj₁ πŸ˜β‰°πŸ™
    (injβ‚‚ πŸ™β‰‘πŸ˜) β†’ injβ‚‚ (inj₁ πŸ™β‰‘πŸ˜)

------------------------------------------------------------------------
-- Usage lemmas for fstα΅£

-- A usage lemma for fstα΅£.

fstα΅£β‚˜ :
  Β¬ 𝟘 ≀ πŸ™ ⊎ πŸ™ PE.≑ 𝟘 ⊎ m β‰’ πŸ™α΅ β†’
  𝟘 ∧ ⌜ m ⌝ Β· p ≀ ⌜ m ⌝ β†’
  Prodrec-allowed (𝟘 ∧ πŸ™) p 𝟘 β†’
  Ξ³ β–Έ[ m ] t β†’
  Ξ΄ β–Έ[ 𝟘ᡐ? ] A β†’
  𝟘ᢜ ∧ᢜ Ξ³ β–Έ[ m ] fstα΅£ p A t
fstα΅£β‚˜ {m = m} {p = p} {Ξ³ = Ξ³} {Ξ΄ = Ξ΄} πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅ 𝟘∧mp≀m ok β–Έt β–ΈA = sub
  (prodrecβ‚˜
     (β–Έ-cong (PE.sym (πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅β†’α΅Β·[πŸ˜βˆ§πŸ™]≑ _ πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅)) β–Έt)
     (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in
      sub var $ begin
        𝟘ᢜ βˆ™ ⌜ m ⌝ Β· (𝟘 ∧ πŸ™) Β· p βˆ™ ⌜ m ⌝ Β· (𝟘 ∧ πŸ™)  β‰ˆβŸ¨ β‰ˆαΆœ-refl βˆ™ Β·[πŸ˜βˆ§πŸ™]Β·β‰‘πŸ˜βˆ§Β· βˆ™ Β·[πŸ˜βˆ§πŸ™]β‰‘πŸ˜βˆ§ ⟩
        𝟘ᢜ βˆ™ 𝟘 ∧ ⌜ m ⌝ Β· p βˆ™ 𝟘 ∧ ⌜ m ⌝              β‰€βŸ¨ β‰€αΆœ-refl βˆ™ 𝟘∧mp≀m βˆ™ ∧-decreasingΛ‘ _ _ ⟩
        𝟘ᢜ βˆ™ ⌜ m ⌝ βˆ™ 𝟘                              ∎)
     (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in
      sub (wkUsage (step id) β–ΈA) $ begin
        Ξ΄ βˆ™ ⌜ 𝟘ᡐ? ⌝ Β· 𝟘  β‰ˆβŸ¨ β‰ˆαΆœ-refl βˆ™ Β·-zeroΚ³ _ ⟩
        Ξ΄ βˆ™ 𝟘            ∎)
     ok)
  (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in begin
     𝟘ᢜ ∧ᢜ Ξ³             β‰‘Λ˜βŸ¨ [πŸ˜βˆ§πŸ™]Β·αΆœβ‰‘πŸ˜αΆœβˆ§αΆœ ⟩
     (𝟘 ∧ πŸ™) ·ᢜ Ξ³        β‰ˆΛ˜βŸ¨ +ᢜ-identityΚ³ _ ⟩
     (𝟘 ∧ πŸ™) ·ᢜ Ξ³ +ᢜ 𝟘ᢜ  ∎)

-- A usage lemma for fstᡣ with the mode set to 𝟘ᡐ.

fstα΅£β‚˜-𝟘ᡐ :
  ⦃ ok : T 𝟘ᡐ-allowed ⦄ β†’
  Prodrec-allowed (𝟘 ∧ πŸ™) p 𝟘 β†’
  Ξ³ β–Έ[ 𝟘ᡐ ] t β†’
  Ξ΄ β–Έ[ 𝟘ᡐ ] A β†’
  Ξ³ β–Έ[ 𝟘ᡐ ] fstα΅£ p A t
fstα΅£β‚˜-𝟘ᡐ {p = p} {Ξ³ = Ξ³} {Ξ΄ = Ξ΄} ok β–Έt β–ΈA = sub
  (fstα΅£β‚˜
     (injβ‚‚ (injβ‚‚ (Ξ» ())))
     (let open Tools.Reasoning.PartialOrder ≀-poset in begin
        𝟘 ∧ 𝟘 Β· p  β‰‘βŸ¨ ∧-congΛ‘ (Β·-zeroΛ‘ _) ⟩
        𝟘 ∧ 𝟘      β‰‘βŸ¨ ∧-idem _ ⟩
        𝟘          ∎)
     ok
     β–Έt
     (β–Έ-cong (PE.sym 𝟘ᡐ?β‰‘πŸ˜α΅) β–ΈA))
  (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in begin
     Ξ³        β‰€βŸ¨ ∧ᢜ-greatest-lower-bound (β–Έ-𝟘ᡐ β–Έt) β‰€αΆœ-refl ⟩
     𝟘ᢜ ∧ᢜ γ  ∎)

-- A usage lemma for fstα΅£ with the mode set to πŸ™α΅.

fstα΅£β‚˜-πŸ™α΅ :
  Β¬ 𝟘 ≀ πŸ™ ⊎ πŸ™ PE.≑ 𝟘 β†’
  𝟘 ∧ p ≀ πŸ™ β†’
  Prodrec-allowed (𝟘 ∧ πŸ™) p 𝟘 β†’
  Ξ³ β–Έ[ πŸ™α΅ ] t β†’
  Ξ΄ β–Έ[ 𝟘ᡐ? ] A β†’
  𝟘ᢜ ∧ᢜ Ξ³ β–Έ[ πŸ™α΅ ] fstα΅£ p A t
fstα΅£β‚˜-πŸ™α΅ {p = p} πŸ˜β‰°πŸ™βŠŽπŸ™β‰’πŸ˜ 𝟘∧pβ‰€πŸ™ = fstα΅£β‚˜
  (case πŸ˜β‰°πŸ™βŠŽπŸ™β‰’πŸ˜ of Ξ» where
     (inj₁ πŸ˜β‰°πŸ™) β†’ inj₁ πŸ˜β‰°πŸ™
     (injβ‚‚ πŸ™β‰’πŸ˜) β†’ injβ‚‚ (inj₁ πŸ™β‰’πŸ˜))
  (begin
     𝟘 ∧ πŸ™ Β· p  β‰‘βŸ¨ ∧-congΛ‘ (Β·-identityΛ‘ _) ⟩
     𝟘 ∧ p      β‰€βŸ¨ 𝟘∧pβ‰€πŸ™ ⟩
     πŸ™          ∎)
  where
  open Tools.Reasoning.PartialOrder ≀-poset

-- A usage lemma for fstα΅£ with the mode set to πŸ™α΅ and the assumption
-- that 𝟘 is the largest quantity.

fstα΅£β‚˜-πŸ™α΅-β‰€πŸ˜ :
  πŸ™ PE.≑ 𝟘 ⊎ πŸ™ β‰’ 𝟘 β†’
  (βˆ€ p β†’ p ≀ 𝟘) β†’
  p ≀ πŸ™ β†’
  Prodrec-allowed (𝟘 ∧ πŸ™) p 𝟘 β†’
  Ξ³ β–Έ[ πŸ™α΅ ] t β†’
  Ξ΄ β–Έ[ 𝟘ᡐ? ] A β†’
  Ξ³ β–Έ[ πŸ™α΅ ] fstα΅£ p A t
fstα΅£β‚˜-πŸ™α΅-β‰€πŸ˜ {p = p} {Ξ³ = Ξ³} πŸ™β‰‘πŸ˜βŠŽπŸ™β‰’πŸ˜ β‰€πŸ˜ pβ‰€πŸ™ ok β–Έt β–ΈA = sub
  (fstα΅£β‚˜-πŸ™α΅
     (β‰€πŸ˜β†’πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜ πŸ™β‰‘πŸ˜βŠŽπŸ™β‰’πŸ˜ β‰€πŸ˜)
     (let open Tools.Reasoning.PartialOrder ≀-poset in begin
        𝟘 ∧ p  β‰€βŸ¨ ∧-decreasingΚ³ _ _ ⟩
        p      β‰€βŸ¨ pβ‰€πŸ™ ⟩
        πŸ™      ∎)
     ok
     β–Έt
     β–ΈA)
  (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in begin
     Ξ³        β‰€βŸ¨ ∧ᢜ-greatest-lower-bound (β‰€αΆœπŸ˜αΆœ (β‰€πŸ˜ _)) β‰€αΆœ-refl ⟩
     𝟘ᢜ ∧ᢜ γ  ∎)

-- A usage lemma for fstα΅£ with the mode set to πŸ™α΅ and the assumption
-- that _+_ is pointwise bounded by _∧_.

fstα΅£β‚˜-πŸ™α΅-βˆ§β‰€+ :
  πŸ™ PE.≑ 𝟘 ⊎ πŸ™ β‰’ 𝟘 β†’
  (βˆ€ p q β†’ p + q ≀ p ∧ q) β†’
  p ≀ πŸ™ β†’
  Prodrec-allowed (𝟘 ∧ πŸ™) p 𝟘 β†’
  Ξ³ β–Έ[ πŸ™α΅ ] t β†’
  Ξ΄ β–Έ[ 𝟘ᡐ? ] A β†’
  Ξ³ β–Έ[ πŸ™α΅ ] fstα΅£ p A t
fstα΅£β‚˜-πŸ™α΅-βˆ§β‰€+ πŸ™β‰‘πŸ˜βŠŽπŸ™β‰’πŸ˜ +β‰€βˆ§ = fstα΅£β‚˜-πŸ™α΅-β‰€πŸ˜ πŸ™β‰‘πŸ˜βŠŽπŸ™β‰’πŸ˜ (+β‰€βˆ§β†’β‰€πŸ˜ +β‰€βˆ§)

-- If πŸ™ is not bounded by 𝟘, then a certain usage rule for fstα΅£Β πŸ™Β A
-- (where A has type TermΒ 1) does not hold.
--
-- Note that the assumption πŸ™Β β‰°Β πŸ˜ is satisfied by, for instance, the
-- linearity modality, see
-- Graded.Modality.Instances.Linearity.Properties.Β¬fstα΅£β‚˜β€².

Β¬fstα΅£β‚˜β€² :
  {A : Term 1} β†’
  Β¬ πŸ™ ≀ 𝟘 β†’
  Β¬ ({Ξ³ : Conβ‚˜ 1} {t : Term 1} β†’
     Ξ³ β–Έ[ πŸ™α΅ ] t β†’
     Ξ³ β–Έ[ πŸ™α΅ ] fstα΅£ πŸ™ A t)
Β¬fstα΅£β‚˜β€² = Β¬fstα΅£β€²β‚˜β€²

-- If πŸ™ is not bounded by 𝟘, then a certain usage rule for fstα΅£ does
-- not hold.
--
-- Note that the assumption πŸ™Β β‰°Β πŸ˜ is satisfied by, for instance, the
-- linearity modality, see
-- Graded.Modality.Instances.Linearity.Properties.Β¬fstα΅£β‚˜.

Β¬fstα΅£β‚˜ :
  Β¬ πŸ™ ≀ 𝟘 β†’
  Β¬ (βˆ€ {Ξ³ : Conβ‚˜ 1} {t : Term 1} {p mβ€²} m β†’
     Ξ³ β–Έ[ m ᡐ· p ] t β†’
     m ᡐ· p PE.≑ mβ€² β†’
     (mβ€² PE.≑ πŸ™α΅ β†’ p ≀ πŸ™) β†’
     Ξ³ β–Έ[ mβ€² ] fstα΅£ p A t)
Β¬fstα΅£β‚˜ = Β¬fstα΅£β€²β‚˜

------------------------------------------------------------------------
-- Inversion lemmas for usage for sndα΅£

-- An inversion lemma for sndα΅£.

inv-usage-sndα΅£ :
  Β¬ 𝟘 ≀ πŸ™ ⊎ πŸ™ PE.≑ 𝟘 ⊎ m β‰’ πŸ™α΅ β†’
  βˆ€ B β†’
  Ξ³ β–Έ[ m ] sndα΅£ p q A B t β†’
  βˆƒβ‚‚ Ξ» Ξ· Ξ΄ β†’
    Ξ³ β‰€αΆœ 𝟘ᢜ ∧ᢜ Ξ· Γ— Ξ· β–Έ[ m ] t Γ—
    Ξ΄ βˆ™ ⌜ 𝟘ᡐ? ⌝ Β· q β–Έ[ 𝟘ᡐ? ] B [ fstα΅£ p (wk1 A) (var x0) ]↑ Γ—
    Prodrec-allowed (𝟘 ∧ πŸ™) p q
inv-usage-sndα΅£ {Ξ³ = Ξ³} πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅ _ β–Έsndα΅£ =
  case inv-usage-prodrec β–Έsndα΅£ of Ξ» {
    (invUsageProdrec {Ξ΄ = Ξ΄} {Ξ· = Ξ·} {ΞΈ = ΞΈ} β–Έt β–Έvar β–ΈB ok γ≀[πŸ˜βˆ§πŸ™]Ξ΄+Ξ·) β†’
  case inv-usage-var β–Έvar of Ξ» {
    (Ξ·β‰€πŸ˜ βˆ™ _ βˆ™ _) β†’
    Ξ΄
  , ΞΈ
  , (begin
       Ξ³                   β‰€βŸ¨ γ≀[πŸ˜βˆ§πŸ™]Ξ΄+Ξ· ⟩
       (𝟘 ∧ πŸ™) ·ᢜ Ξ΄ +ᢜ Ξ·   β‰€βŸ¨ +ᢜ-monotoneΚ³ Ξ·β‰€πŸ˜ ⟩
       (𝟘 ∧ πŸ™) ·ᢜ Ξ΄ +ᢜ 𝟘ᢜ  β‰ˆβŸ¨ +ᢜ-identityΚ³ _ ⟩
       (𝟘 ∧ πŸ™) ·ᢜ Ξ΄        β‰‘βŸ¨ [πŸ˜βˆ§πŸ™]Β·αΆœβ‰‘πŸ˜αΆœβˆ§αΆœ ⟩
       𝟘ᢜ ∧ᢜ δ             ∎)
  , β–Έ-cong (πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅β†’α΅Β·[πŸ˜βˆ§πŸ™]≑ _ πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅) β–Έt
  , β–ΈB
  , ok }}
  where
  open Tools.Reasoning.PartialOrder β‰€αΆœ-poset

-- An inversion lemma for sndᡣ with the mode set to 𝟘ᡐ.

inv-usage-sndᡣ-𝟘ᡐ :
  ⦃ ok : T 𝟘ᡐ-allowed ⦄ β†’
  βˆ€ B β†’
  Ξ³ β–Έ[ 𝟘ᡐ ] sndα΅£ p q A B t β†’
  βˆƒ Ξ» Ξ΄ β†’
    Ξ³ β‰€αΆœ 𝟘ᢜ Γ— 𝟘ᢜ β–Έ[ 𝟘ᡐ ] t Γ—
    Ξ΄ βˆ™ 𝟘 β–Έ[ 𝟘ᡐ ] B [ fstα΅£ p (wk1 A) (var x0) ]↑ Γ—
    Prodrec-allowed (𝟘 ∧ πŸ™) p q
inv-usage-sndα΅£-𝟘ᡐ {Ξ³ = Ξ³} {q = q} ⦃ ok = 𝟘ᡐ-ok ⦄ B β–Έsndα΅£ =
  case inv-usage-sndα΅£ (injβ‚‚ (injβ‚‚ (Ξ» ()))) B β–Έsndα΅£ of Ξ» {
    (Ξ· , Ξ΄ , leq , β–Έt , β–ΈB , ok) β†’
    _
  , (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in begin
       Ξ³        β‰€βŸ¨ leq ⟩
       𝟘ᢜ ∧ᢜ Ξ·  β‰€βŸ¨ ∧ᢜ-decreasingΚ³ _ _ ⟩
       Ξ·        β‰€βŸ¨ β–Έ-𝟘ᡐ β–Έt ⟩
       𝟘ᢜ       ∎)
  , (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in
     sub (β–Έ-Β· {mβ€² = 𝟘ᡐ} β–Έt) $ begin
       𝟘ᢜ      β‰ˆΛ˜βŸ¨ ·ᢜ-zeroΛ‘ _ ⟩
       𝟘 ·ᢜ η  ∎)
  , (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in
     sub (β–Έ-cong 𝟘ᡐ?β‰‘πŸ˜α΅ β–ΈB) $ begin
       Ξ΄ βˆ™ 𝟘            β‰ˆΛ˜βŸ¨ β‰ˆαΆœ-refl βˆ™ Β·-zeroΛ‘ _ ⟩
       Ξ΄ βˆ™ 𝟘 Β· q        β‰ˆΛ˜βŸ¨ β‰ˆαΆœ-refl βˆ™ Β·-congΚ³ (PE.cong ⌜_⌝ (𝟘ᡐ?β‰‘πŸ˜α΅ {ok = 𝟘ᡐ-ok})) ⟩
       Ξ΄ βˆ™ ⌜ 𝟘ᡐ? ⌝ Β· q  ∎)
  , ok }

------------------------------------------------------------------------
-- Usage lemmas for sndα΅£

-- A usage lemma for sndα΅£.

sndα΅£β‚˜ :
  Β¬ 𝟘 ≀ πŸ™ ⊎ πŸ™ PE.≑ 𝟘 ⊎ m β‰’ πŸ™α΅ β†’
  Prodrec-allowed (𝟘 ∧ πŸ™) p q β†’
  βˆ€ B β†’
  Ξ³ β–Έ[ m ] t β†’
  Ξ΄ βˆ™ ⌜ 𝟘ᡐ? ⌝ Β· q β–Έ[ 𝟘ᡐ? ] B [ fstα΅£ p (wk1 A) (var x0) ]↑ β†’
  𝟘ᢜ ∧ᢜ Ξ³ β–Έ[ m ] sndα΅£ p q A B t
sndα΅£β‚˜ {m = m} {p = p} {Ξ³ = Ξ³} πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅ ok _ β–Έt β–ΈB = sub
  (prodrecβ‚˜
     (β–Έ-cong (PE.sym (πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅β†’α΅Β·[πŸ˜βˆ§πŸ™]≑ _ πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜βŠŽβ‰’πŸ™α΅)) β–Έt)
     (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in
      sub var $ begin
        𝟘ᢜ βˆ™ ⌜ m ⌝ Β· (𝟘 ∧ πŸ™) Β· p βˆ™ ⌜ m ⌝ Β· (𝟘 ∧ πŸ™)  β‰ˆβŸ¨ β‰ˆαΆœ-refl βˆ™ Β·[πŸ˜βˆ§πŸ™]Β·β‰‘πŸ˜βˆ§Β· βˆ™ Β·[πŸ˜βˆ§πŸ™]β‰‘πŸ˜βˆ§ ⟩
        𝟘ᢜ βˆ™ 𝟘 ∧ ⌜ m ⌝ Β· p βˆ™ 𝟘 ∧ ⌜ m ⌝              β‰€βŸ¨ β‰€αΆœ-refl βˆ™ ∧-decreasingΛ‘ _ _ βˆ™ ∧-decreasingΚ³ _ _ ⟩
        𝟘ᢜ βˆ™ 𝟘 βˆ™ ⌜ m ⌝                              ∎)
     β–ΈB
     ok)
  (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in begin
     𝟘ᢜ ∧ᢜ Ξ³             β‰‘Λ˜βŸ¨ [πŸ˜βˆ§πŸ™]Β·αΆœβ‰‘πŸ˜αΆœβˆ§αΆœ ⟩
     (𝟘 ∧ πŸ™) ·ᢜ Ξ³        β‰ˆΛ˜βŸ¨ +ᢜ-identityΚ³ _ ⟩
     (𝟘 ∧ πŸ™) ·ᢜ Ξ³ +ᢜ 𝟘ᢜ  ∎)

-- A usage lemma for sndᡣ with the mode set to 𝟘ᡐ.

sndα΅£β‚˜-𝟘ᡐ :
  ⦃ ok : T 𝟘ᡐ-allowed ⦄ β†’
  Prodrec-allowed (𝟘 ∧ πŸ™) p q β†’
  βˆ€ B β†’
  Ξ³ β–Έ[ 𝟘ᡐ ] t β†’
  Ξ΄ βˆ™ 𝟘 β–Έ[ 𝟘ᡐ ] B [ fstα΅£ p (wk1 A) (var x0) ]↑ β†’
  Ξ³ β–Έ[ 𝟘ᡐ ] sndα΅£ p q A B t
sndα΅£β‚˜-𝟘ᡐ {p = p} {q = q} {Ξ³ = Ξ³} {Ξ΄ = Ξ΄} ⦃ ok = 𝟘ᡐ-ok ⦄ ok B β–Έt β–ΈB = sub
  (sndα΅£β‚˜
     (injβ‚‚ (injβ‚‚ (Ξ» ())))
     ok
     B
     β–Έt
     (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in
      sub (β–Έ-cong (PE.sym 𝟘ᡐ?β‰‘πŸ˜α΅) β–ΈB) $ begin
        Ξ΄ βˆ™ ⌜ 𝟘ᡐ? ⌝ Β· q  β‰ˆβŸ¨ β‰ˆαΆœ-refl βˆ™ Β·-congΚ³ (PE.cong ⌜_⌝ (𝟘ᡐ?β‰‘πŸ˜α΅ {ok = 𝟘ᡐ-ok})) ⟩
        Ξ΄ βˆ™ 𝟘 Β· q        β‰ˆβŸ¨ β‰ˆαΆœ-refl βˆ™ Β·-zeroΛ‘ _ ⟩
        Ξ΄ βˆ™ 𝟘            ∎))
  (let open Tools.Reasoning.PartialOrder β‰€αΆœ-poset in begin
     Ξ³        β‰€βŸ¨ ∧ᢜ-greatest-lower-bound (β–Έ-𝟘ᡐ β–Έt) β‰€αΆœ-refl ⟩
     𝟘ᢜ ∧ᢜ γ  ∎)

-- A usage lemma for sndα΅£ with the mode set to πŸ™α΅ and the assumption
-- that 𝟘 is the largest quantity.

sndα΅£β‚˜-πŸ™α΅-β‰€πŸ˜ :
  πŸ™ PE.≑ 𝟘 ⊎ πŸ™ β‰’ 𝟘 β†’
  (βˆ€ p β†’ p ≀ 𝟘) β†’
  Prodrec-allowed (𝟘 ∧ πŸ™) p q β†’
  βˆ€ B β†’
  Ξ³ β–Έ[ πŸ™α΅ ] t β†’
  Ξ΄ βˆ™ ⌜ 𝟘ᡐ? ⌝ Β· q β–Έ[ 𝟘ᡐ? ] B [ fstα΅£ p (wk1 A) (var x0) ]↑ β†’
  Ξ³ β–Έ[ πŸ™α΅ ] sndα΅£ p q A B t
sndα΅£β‚˜-πŸ™α΅-β‰€πŸ˜ {Ξ³ = Ξ³} πŸ™β‰‘πŸ˜βŠŽπŸ™β‰’πŸ˜ β‰€πŸ˜ ok B β–Έt β–ΈB = sub
  (sndα΅£β‚˜
     (case β‰€πŸ˜β†’πŸ˜β‰°πŸ™βŠŽπŸ™β‰‘πŸ˜ πŸ™β‰‘πŸ˜βŠŽπŸ™β‰’πŸ˜ β‰€πŸ˜ of Ξ» where
        (inj₁ πŸ˜β‰°πŸ™) β†’ inj₁ πŸ˜β‰°πŸ™
        (injβ‚‚ πŸ™β‰‘πŸ˜) β†’ injβ‚‚ (inj₁ πŸ™β‰‘πŸ˜))
     ok
     B
     β–Έt
     β–ΈB)
  (begin
     Ξ³        β‰€βŸ¨ ∧ᢜ-greatest-lower-bound (β‰€αΆœπŸ˜αΆœ (β‰€πŸ˜ _)) β‰€αΆœ-refl ⟩
     𝟘ᢜ ∧ᢜ γ  ∎)
  where
  open Tools.Reasoning.PartialOrder β‰€αΆœ-poset

-- A usage lemma for sndα΅£ with the mode set to πŸ™α΅ and the assumption
-- that _+_ is pointwise bounded by _∧_.

sndα΅£β‚˜-πŸ™α΅-+β‰€βˆ§ :
  πŸ™ PE.≑ 𝟘 ⊎ πŸ™ β‰’ 𝟘 β†’
  (βˆ€ p q β†’ p + q ≀ p ∧ q) β†’
  Prodrec-allowed (𝟘 ∧ πŸ™) p q β†’
  βˆ€ B β†’
  Ξ³ β–Έ[ πŸ™α΅ ] t β†’
  Ξ΄ βˆ™ ⌜ 𝟘ᡐ? ⌝ Β· q β–Έ[ 𝟘ᡐ? ] B [ fstα΅£ p (wk1 A) (var x0) ]↑ β†’
  Ξ³ β–Έ[ πŸ™α΅ ] sndα΅£ p q A B t
sndα΅£β‚˜-πŸ™α΅-+β‰€βˆ§ πŸ™β‰‘πŸ˜βŠŽπŸ™β‰’πŸ˜ +β‰€βˆ§ = sndα΅£β‚˜-πŸ™α΅-β‰€πŸ˜ πŸ™β‰‘πŸ˜βŠŽπŸ™β‰’πŸ˜ (+β‰€βˆ§β†’β‰€πŸ˜ +β‰€βˆ§)

-- If a certain usage rule holds for sndα΅£Β pΒ qΒ AΒ B (where A has type
-- TermΒ 1), then πŸ™Β β‰€Β πŸ˜.

sndα΅£β‚˜β†’πŸ™β‰€πŸ˜ :
  {A : Term 1} (B : Term 2) β†’
  (βˆ€ {Ξ³ t} β†’
   Ξ³ β–Έ[ πŸ™α΅ ] t β†’
   Ξ³ β–Έ[ πŸ™α΅ ] sndα΅£ p q A B t) β†’
  πŸ™ ≀ 𝟘
sndα΅£β‚˜β†’πŸ™β‰€πŸ˜ {p = p} {q = q} {A = A} B =
  (βˆ€ {Ξ³ t} β†’ Ξ³ β–Έ[ πŸ™α΅ ] t β†’ Ξ³ β–Έ[ πŸ™α΅ ] sndα΅£ p q A B t)  β†’βŸ¨ _$ var ⟩
  Ξ³β€² β–Έ[ πŸ™α΅ ] sndα΅£ p q A B tβ€²                          β†’βŸ¨ lemma ⟩
  πŸ™ ≀ 𝟘                                               β–‘
  where
  Ξ³β€² = Ξ΅ βˆ™ πŸ™
  tβ€² = var x0

  lemma : Ξ³β€² β–Έ[ πŸ™α΅ ] sndα΅£ p q A B tβ€² β†’ πŸ™ ≀ 𝟘
  lemma β–Έsnd-t =
    case inv-usage-prodrec β–Έsnd-t of Ξ» {
      (invUsageProdrec
         {Ξ΄ = Ξ΅ βˆ™ r} {Ξ· = Ξ΅ βˆ™ s} β–Έt β–Έvar _ _ (Ξ΅ βˆ™ πŸ™β‰€[πŸ˜βˆ§πŸ™]r+s)) β†’
    case inv-usage-var β–Έvar of Ξ» {
      (Ξ΅ βˆ™ sβ‰€πŸ˜ βˆ™ _ βˆ™ _) β†’
    case inv-usage-var β–Έt of Ξ» {
      (Ξ΅ βˆ™ rβ‰€βŒœβŒžπŸ˜βˆ§πŸ™βŒŸβŒ) β†’
    begin
      πŸ™                        β‰€βŸ¨ πŸ™β‰€[πŸ˜βˆ§πŸ™]r+s ⟩
      (𝟘 ∧ πŸ™) Β· r + s          β‰€βŸ¨ +-monotoneΚ³ sβ‰€πŸ˜ ⟩
      (𝟘 ∧ πŸ™) Β· r + 𝟘          β‰‘βŸ¨ +-identityΚ³ _ ⟩
      (𝟘 ∧ πŸ™) Β· r              β‰€βŸ¨ Β·-monotoneΚ³ rβ‰€βŒœβŒžπŸ˜βˆ§πŸ™βŒŸβŒ ⟩
      (𝟘 ∧ πŸ™) Β· ⌜ ⌞ 𝟘 ∧ πŸ™ ⌟ ⌝  β‰‘βŸ¨ ·⌜⌞⌟⌝ ⟩
      𝟘 ∧ πŸ™                    β‰€βŸ¨ ∧-decreasingΛ‘ _ _ ⟩
      𝟘                        ∎ }}}
    where
    open Tools.Reasoning.PartialOrder ≀-poset

-- If πŸ™ is not bounded by 𝟘, then a certain usage rule for
-- sndα΅£Β pΒ qΒ AΒ B (where A has type TermΒ 1) does not hold.
--
-- Note that the assumption πŸ™Β β‰°Β πŸ˜ is satisfied by, for instance, the
-- linearity modality, see
-- Graded.Modality.Instances.Linearity.Properties.Β¬sndα΅£β‚˜.

Β¬sndα΅£β‚˜ :
  {A : Term 1} (B : Term 2) β†’
  Β¬ πŸ™ ≀ 𝟘 β†’
  Β¬ ({Ξ³ : Conβ‚˜ 1} {t : Term 1} β†’
     Ξ³ β–Έ[ πŸ™α΅ ] t β†’
     Ξ³ β–Έ[ πŸ™α΅ ] sndα΅£ p q A B t)
Β¬sndα΅£β‚˜ B πŸ™β‰°πŸ˜ hyp = πŸ™β‰°πŸ˜ (sndα΅£β‚˜β†’πŸ™β‰€πŸ˜ B hyp)