------------------------------------------------------------------------
-- A modality for affine types.
------------------------------------------------------------------------

open import Tools.Bool
open import Tools.Level

open import Graded.Modality.Instances.Zero-one-many true as πŸ˜πŸ™Ο‰
open import Graded.Modality.Variant lzero

module Graded.Modality.Instances.Affine
  -- The modality variant.
  (variant : Modality-variant)
  where

open Modality-variant variant

open πŸ˜πŸ™Ο‰ renaming (Zero-one-many to Affine) public

open import Graded.Modality Affine
open import Graded.FullReduction.Assumptions

open import Definition.Typed.Restrictions Affine

open import Tools.Empty
open import Tools.Function
open import Tools.Nullary
open import Tools.Product
open import Tools.PropositionalEquality
open import Tools.Sum
open import Tools.Unit

private variable
  p  : Affine
  rs : Type-restrictions

-- An "affine types" modality.

affineModality : Modality
affineModality = zero-one-many-greatest variant _

-- The affine types" modality has a well-behaved zero.

affine-has-well-behaved-zero : Has-well-behaved-zero (Modality.semiring-with-meet affineModality)
affine-has-well-behaved-zero = zero-one-many-has-well-behaved-zero

-- 𝟘 is the largest element.

β‰€πŸ˜ : p ≀ 𝟘
β‰€πŸ˜ {p = 𝟘} = refl
β‰€πŸ˜ {p = πŸ™} = refl
β‰€πŸ˜ {p = Ο‰} = refl

-- An instance of Type-restrictions is suitable for the full reduction
-- theorem if
-- * Ξ£β‚š-allowed 𝟘 p implies that 𝟘ᡐ is allowed, and
-- * Ξ£β‚š-allowed ω p does not hold.

Suitable-for-full-reduction :
  Type-restrictions β†’ Set
Suitable-for-full-reduction rs =
  (βˆ€ p β†’ Ξ£β‚š-allowed 𝟘 p β†’ T 𝟘ᡐ-allowed) Γ—
  (βˆ€ p β†’ Β¬ Ξ£β‚š-allowed Ο‰ p)
  where
  open Type-restrictions rs

-- Given an instance of Type-restrictions one can create a "suitable"
-- instance.

suitable-for-full-reduction :
  Type-restrictions β†’ βˆƒ Suitable-for-full-reduction
suitable-for-full-reduction rs =
    record rs
      { Ξ Ξ£-allowed = Ξ» b p q β†’
          Ξ Ξ£-allowed b p q Γ— T 𝟘ᡐ-allowed Γ— p β‰’ Ο‰
      }
  , (Ξ» _ β†’ proj₁ βˆ˜β†’ projβ‚‚)
  , (Ξ» _ β†’ (_$ refl) βˆ˜β†’ projβ‚‚ βˆ˜β†’ projβ‚‚)
  where
  open Type-restrictions rs

-- The full reduction assumptions hold for affineModality and any
-- "suitable" Type-restrictions.

full-reduction-assumptions :
  Suitable-for-full-reduction rs β†’
  Full-reduction-assumptions affineModality rs
full-reduction-assumptions (πŸ˜β†’πŸ˜α΅ , ¬ω) = record
  { πŸ™β‰€πŸ˜    = Ξ» _ β†’ refl
  ; β‰‘πŸ™βŠŽπŸ™β‰€πŸ˜ = Ξ» where
      {p = Ο‰} ok β†’ βŠ₯-elim (¬ω _ ok)
      {p = πŸ™} _  β†’ inj₁ refl
      {p = 𝟘} ok β†’ injβ‚‚ (refl , πŸ˜β†’πŸ˜α΅ _ ok , refl)
  }