------------------------------------------------------------------------
-- 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
import Graded.Modality.Properties
open import Graded.FullReduction.Assumptions
import Graded.Usage.Restrictions

import Definition.Typed.Restrictions
open import Definition.Untyped

open import Tools.Empty
open import Tools.Function
open import Tools.Nat using (Sequence)
open import Tools.Product
open import Tools.PropositionalEquality
open import Tools.Relation
open import Tools.Sum

private variable
  p  : Affine
  pα΅’ : Sequence Affine

-- An "affine types" modality.

affineModality : Modality
affineModality = zero-one-many-modality variant

open Definition.Typed.Restrictions affineModality
open Graded.Modality.Properties    affineModality
open Graded.Usage.Restrictions     affineModality

private variable
  rs : Type-restrictions
  us : Usage-restrictions

-- The nr function obtained from zero-one-many-greatest-star-nr is
-- strictly greater than the one obtained from zero-one-many-has-nr.

alternative-greater :
  let nr₁ = zero-one-many-has-nr .Has-nr.nr
      nrβ‚‚ = zero-one-many-greatest-star-nr .Has-nr.nr
  in
  (βˆƒβ‚… Ξ» p r z s n β†’ Β¬ nr₁ p r z s n ≑ nrβ‚‚ p r z s n) Γ—
  (βˆ€ p r z s n β†’ nr₁ p r z s n ≀ nrβ‚‚ p r z s n)
alternative-greater =
    (𝟘 , πŸ™ , πŸ™ , 𝟘 , πŸ™ , (Ξ» ()))
  , Ξ» where
      𝟘 𝟘 𝟘 𝟘 𝟘 β†’ refl
      𝟘 𝟘 𝟘 𝟘 πŸ™ β†’ refl
      𝟘 𝟘 𝟘 𝟘 Ο‰ β†’ refl
      𝟘 𝟘 𝟘 πŸ™ 𝟘 β†’ refl
      𝟘 𝟘 𝟘 πŸ™ πŸ™ β†’ refl
      𝟘 𝟘 𝟘 πŸ™ Ο‰ β†’ refl
      𝟘 𝟘 𝟘 Ο‰ 𝟘 β†’ refl
      𝟘 𝟘 𝟘 Ο‰ πŸ™ β†’ refl
      𝟘 𝟘 𝟘 Ο‰ Ο‰ β†’ refl
      𝟘 𝟘 πŸ™ 𝟘 𝟘 β†’ refl
      𝟘 𝟘 πŸ™ 𝟘 πŸ™ β†’ refl
      𝟘 𝟘 πŸ™ 𝟘 Ο‰ β†’ refl
      𝟘 𝟘 πŸ™ πŸ™ 𝟘 β†’ refl
      𝟘 𝟘 πŸ™ πŸ™ πŸ™ β†’ refl
      𝟘 𝟘 πŸ™ πŸ™ Ο‰ β†’ refl
      𝟘 𝟘 πŸ™ Ο‰ 𝟘 β†’ refl
      𝟘 𝟘 πŸ™ Ο‰ πŸ™ β†’ refl
      𝟘 𝟘 πŸ™ Ο‰ Ο‰ β†’ refl
      𝟘 𝟘 Ο‰ 𝟘 𝟘 β†’ refl
      𝟘 𝟘 Ο‰ 𝟘 πŸ™ β†’ refl
      𝟘 𝟘 Ο‰ 𝟘 Ο‰ β†’ refl
      𝟘 𝟘 Ο‰ πŸ™ 𝟘 β†’ refl
      𝟘 𝟘 Ο‰ πŸ™ πŸ™ β†’ refl
      𝟘 𝟘 Ο‰ πŸ™ Ο‰ β†’ refl
      𝟘 𝟘 Ο‰ Ο‰ 𝟘 β†’ refl
      𝟘 𝟘 Ο‰ Ο‰ πŸ™ β†’ refl
      𝟘 𝟘 Ο‰ Ο‰ Ο‰ β†’ refl
      𝟘 πŸ™ 𝟘 𝟘 𝟘 β†’ refl
      𝟘 πŸ™ 𝟘 𝟘 πŸ™ β†’ refl
      𝟘 πŸ™ 𝟘 𝟘 Ο‰ β†’ refl
      𝟘 πŸ™ 𝟘 πŸ™ 𝟘 β†’ refl
      𝟘 πŸ™ 𝟘 πŸ™ πŸ™ β†’ refl
      𝟘 πŸ™ 𝟘 πŸ™ Ο‰ β†’ refl
      𝟘 πŸ™ 𝟘 Ο‰ 𝟘 β†’ refl
      𝟘 πŸ™ 𝟘 Ο‰ πŸ™ β†’ refl
      𝟘 πŸ™ 𝟘 Ο‰ Ο‰ β†’ refl
      𝟘 πŸ™ πŸ™ 𝟘 𝟘 β†’ refl
      𝟘 πŸ™ πŸ™ 𝟘 πŸ™ β†’ refl
      𝟘 πŸ™ πŸ™ 𝟘 Ο‰ β†’ refl
      𝟘 πŸ™ πŸ™ πŸ™ 𝟘 β†’ refl
      𝟘 πŸ™ πŸ™ πŸ™ πŸ™ β†’ refl
      𝟘 πŸ™ πŸ™ πŸ™ Ο‰ β†’ refl
      𝟘 πŸ™ πŸ™ Ο‰ 𝟘 β†’ refl
      𝟘 πŸ™ πŸ™ Ο‰ πŸ™ β†’ refl
      𝟘 πŸ™ πŸ™ Ο‰ Ο‰ β†’ refl
      𝟘 πŸ™ Ο‰ 𝟘 𝟘 β†’ refl
      𝟘 πŸ™ Ο‰ 𝟘 πŸ™ β†’ refl
      𝟘 πŸ™ Ο‰ 𝟘 Ο‰ β†’ refl
      𝟘 πŸ™ Ο‰ πŸ™ 𝟘 β†’ refl
      𝟘 πŸ™ Ο‰ πŸ™ πŸ™ β†’ refl
      𝟘 πŸ™ Ο‰ πŸ™ Ο‰ β†’ refl
      𝟘 πŸ™ Ο‰ Ο‰ 𝟘 β†’ refl
      𝟘 πŸ™ Ο‰ Ο‰ πŸ™ β†’ refl
      𝟘 πŸ™ Ο‰ Ο‰ Ο‰ β†’ refl
      𝟘 Ο‰ 𝟘 𝟘 𝟘 β†’ refl
      𝟘 Ο‰ 𝟘 𝟘 πŸ™ β†’ refl
      𝟘 Ο‰ 𝟘 𝟘 Ο‰ β†’ refl
      𝟘 Ο‰ 𝟘 πŸ™ 𝟘 β†’ refl
      𝟘 Ο‰ 𝟘 πŸ™ πŸ™ β†’ refl
      𝟘 Ο‰ 𝟘 πŸ™ Ο‰ β†’ refl
      𝟘 Ο‰ 𝟘 Ο‰ 𝟘 β†’ refl
      𝟘 Ο‰ 𝟘 Ο‰ πŸ™ β†’ refl
      𝟘 Ο‰ 𝟘 Ο‰ Ο‰ β†’ refl
      𝟘 Ο‰ πŸ™ 𝟘 𝟘 β†’ refl
      𝟘 Ο‰ πŸ™ 𝟘 πŸ™ β†’ refl
      𝟘 Ο‰ πŸ™ 𝟘 Ο‰ β†’ refl
      𝟘 Ο‰ πŸ™ πŸ™ 𝟘 β†’ refl
      𝟘 Ο‰ πŸ™ πŸ™ πŸ™ β†’ refl
      𝟘 Ο‰ πŸ™ πŸ™ Ο‰ β†’ refl
      𝟘 Ο‰ πŸ™ Ο‰ 𝟘 β†’ refl
      𝟘 Ο‰ πŸ™ Ο‰ πŸ™ β†’ refl
      𝟘 Ο‰ πŸ™ Ο‰ Ο‰ β†’ refl
      𝟘 Ο‰ Ο‰ 𝟘 𝟘 β†’ refl
      𝟘 Ο‰ Ο‰ 𝟘 πŸ™ β†’ refl
      𝟘 Ο‰ Ο‰ 𝟘 Ο‰ β†’ refl
      𝟘 Ο‰ Ο‰ πŸ™ 𝟘 β†’ refl
      𝟘 Ο‰ Ο‰ πŸ™ πŸ™ β†’ refl
      𝟘 Ο‰ Ο‰ πŸ™ Ο‰ β†’ refl
      𝟘 Ο‰ Ο‰ Ο‰ 𝟘 β†’ refl
      𝟘 Ο‰ Ο‰ Ο‰ πŸ™ β†’ refl
      𝟘 Ο‰ Ο‰ Ο‰ Ο‰ β†’ refl
      πŸ™ 𝟘 𝟘 𝟘 𝟘 β†’ refl
      πŸ™ 𝟘 𝟘 𝟘 πŸ™ β†’ refl
      πŸ™ 𝟘 𝟘 𝟘 Ο‰ β†’ refl
      πŸ™ 𝟘 𝟘 πŸ™ 𝟘 β†’ refl
      πŸ™ 𝟘 𝟘 πŸ™ πŸ™ β†’ refl
      πŸ™ 𝟘 𝟘 πŸ™ Ο‰ β†’ refl
      πŸ™ 𝟘 𝟘 Ο‰ 𝟘 β†’ refl
      πŸ™ 𝟘 𝟘 Ο‰ πŸ™ β†’ refl
      πŸ™ 𝟘 𝟘 Ο‰ Ο‰ β†’ refl
      πŸ™ 𝟘 πŸ™ 𝟘 𝟘 β†’ refl
      πŸ™ 𝟘 πŸ™ 𝟘 πŸ™ β†’ refl
      πŸ™ 𝟘 πŸ™ 𝟘 Ο‰ β†’ refl
      πŸ™ 𝟘 πŸ™ πŸ™ 𝟘 β†’ refl
      πŸ™ 𝟘 πŸ™ πŸ™ πŸ™ β†’ refl
      πŸ™ 𝟘 πŸ™ πŸ™ Ο‰ β†’ refl
      πŸ™ 𝟘 πŸ™ Ο‰ 𝟘 β†’ refl
      πŸ™ 𝟘 πŸ™ Ο‰ πŸ™ β†’ refl
      πŸ™ 𝟘 πŸ™ Ο‰ Ο‰ β†’ refl
      πŸ™ 𝟘 Ο‰ 𝟘 𝟘 β†’ refl
      πŸ™ 𝟘 Ο‰ 𝟘 πŸ™ β†’ refl
      πŸ™ 𝟘 Ο‰ 𝟘 Ο‰ β†’ refl
      πŸ™ 𝟘 Ο‰ πŸ™ 𝟘 β†’ refl
      πŸ™ 𝟘 Ο‰ πŸ™ πŸ™ β†’ refl
      πŸ™ 𝟘 Ο‰ πŸ™ Ο‰ β†’ refl
      πŸ™ 𝟘 Ο‰ Ο‰ 𝟘 β†’ refl
      πŸ™ 𝟘 Ο‰ Ο‰ πŸ™ β†’ refl
      πŸ™ 𝟘 Ο‰ Ο‰ Ο‰ β†’ refl
      πŸ™ πŸ™ 𝟘 𝟘 𝟘 β†’ refl
      πŸ™ πŸ™ 𝟘 𝟘 πŸ™ β†’ refl
      πŸ™ πŸ™ 𝟘 𝟘 Ο‰ β†’ refl
      πŸ™ πŸ™ 𝟘 πŸ™ 𝟘 β†’ refl
      πŸ™ πŸ™ 𝟘 πŸ™ πŸ™ β†’ refl
      πŸ™ πŸ™ 𝟘 πŸ™ Ο‰ β†’ refl
      πŸ™ πŸ™ 𝟘 Ο‰ 𝟘 β†’ refl
      πŸ™ πŸ™ 𝟘 Ο‰ πŸ™ β†’ refl
      πŸ™ πŸ™ 𝟘 Ο‰ Ο‰ β†’ refl
      πŸ™ πŸ™ πŸ™ 𝟘 𝟘 β†’ refl
      πŸ™ πŸ™ πŸ™ 𝟘 πŸ™ β†’ refl
      πŸ™ πŸ™ πŸ™ 𝟘 Ο‰ β†’ refl
      πŸ™ πŸ™ πŸ™ πŸ™ 𝟘 β†’ refl
      πŸ™ πŸ™ πŸ™ πŸ™ πŸ™ β†’ refl
      πŸ™ πŸ™ πŸ™ πŸ™ Ο‰ β†’ refl
      πŸ™ πŸ™ πŸ™ Ο‰ 𝟘 β†’ refl
      πŸ™ πŸ™ πŸ™ Ο‰ πŸ™ β†’ refl
      πŸ™ πŸ™ πŸ™ Ο‰ Ο‰ β†’ refl
      πŸ™ πŸ™ Ο‰ 𝟘 𝟘 β†’ refl
      πŸ™ πŸ™ Ο‰ 𝟘 πŸ™ β†’ refl
      πŸ™ πŸ™ Ο‰ 𝟘 Ο‰ β†’ refl
      πŸ™ πŸ™ Ο‰ πŸ™ 𝟘 β†’ refl
      πŸ™ πŸ™ Ο‰ πŸ™ πŸ™ β†’ refl
      πŸ™ πŸ™ Ο‰ πŸ™ Ο‰ β†’ refl
      πŸ™ πŸ™ Ο‰ Ο‰ 𝟘 β†’ refl
      πŸ™ πŸ™ Ο‰ Ο‰ πŸ™ β†’ refl
      πŸ™ πŸ™ Ο‰ Ο‰ Ο‰ β†’ refl
      πŸ™ Ο‰ 𝟘 𝟘 𝟘 β†’ refl
      πŸ™ Ο‰ 𝟘 𝟘 πŸ™ β†’ refl
      πŸ™ Ο‰ 𝟘 𝟘 Ο‰ β†’ refl
      πŸ™ Ο‰ 𝟘 πŸ™ 𝟘 β†’ refl
      πŸ™ Ο‰ 𝟘 πŸ™ πŸ™ β†’ refl
      πŸ™ Ο‰ 𝟘 πŸ™ Ο‰ β†’ refl
      πŸ™ Ο‰ 𝟘 Ο‰ 𝟘 β†’ refl
      πŸ™ Ο‰ 𝟘 Ο‰ πŸ™ β†’ refl
      πŸ™ Ο‰ 𝟘 Ο‰ Ο‰ β†’ refl
      πŸ™ Ο‰ πŸ™ 𝟘 𝟘 β†’ refl
      πŸ™ Ο‰ πŸ™ 𝟘 πŸ™ β†’ refl
      πŸ™ Ο‰ πŸ™ 𝟘 Ο‰ β†’ refl
      πŸ™ Ο‰ πŸ™ πŸ™ 𝟘 β†’ refl
      πŸ™ Ο‰ πŸ™ πŸ™ πŸ™ β†’ refl
      πŸ™ Ο‰ πŸ™ πŸ™ Ο‰ β†’ refl
      πŸ™ Ο‰ πŸ™ Ο‰ 𝟘 β†’ refl
      πŸ™ Ο‰ πŸ™ Ο‰ πŸ™ β†’ refl
      πŸ™ Ο‰ πŸ™ Ο‰ Ο‰ β†’ refl
      πŸ™ Ο‰ Ο‰ 𝟘 𝟘 β†’ refl
      πŸ™ Ο‰ Ο‰ 𝟘 πŸ™ β†’ refl
      πŸ™ Ο‰ Ο‰ 𝟘 Ο‰ β†’ refl
      πŸ™ Ο‰ Ο‰ πŸ™ 𝟘 β†’ refl
      πŸ™ Ο‰ Ο‰ πŸ™ πŸ™ β†’ refl
      πŸ™ Ο‰ Ο‰ πŸ™ Ο‰ β†’ refl
      πŸ™ Ο‰ Ο‰ Ο‰ 𝟘 β†’ refl
      πŸ™ Ο‰ Ο‰ Ο‰ πŸ™ β†’ refl
      πŸ™ Ο‰ Ο‰ Ο‰ Ο‰ β†’ refl
      Ο‰ 𝟘 𝟘 𝟘 𝟘 β†’ refl
      Ο‰ 𝟘 𝟘 𝟘 πŸ™ β†’ refl
      Ο‰ 𝟘 𝟘 𝟘 Ο‰ β†’ refl
      Ο‰ 𝟘 𝟘 πŸ™ 𝟘 β†’ refl
      Ο‰ 𝟘 𝟘 πŸ™ πŸ™ β†’ refl
      Ο‰ 𝟘 𝟘 πŸ™ Ο‰ β†’ refl
      Ο‰ 𝟘 𝟘 Ο‰ 𝟘 β†’ refl
      Ο‰ 𝟘 𝟘 Ο‰ πŸ™ β†’ refl
      Ο‰ 𝟘 𝟘 Ο‰ Ο‰ β†’ refl
      Ο‰ 𝟘 πŸ™ 𝟘 𝟘 β†’ refl
      Ο‰ 𝟘 πŸ™ 𝟘 πŸ™ β†’ refl
      Ο‰ 𝟘 πŸ™ 𝟘 Ο‰ β†’ refl
      Ο‰ 𝟘 πŸ™ πŸ™ 𝟘 β†’ refl
      Ο‰ 𝟘 πŸ™ πŸ™ πŸ™ β†’ refl
      Ο‰ 𝟘 πŸ™ πŸ™ Ο‰ β†’ refl
      Ο‰ 𝟘 πŸ™ Ο‰ 𝟘 β†’ refl
      Ο‰ 𝟘 πŸ™ Ο‰ πŸ™ β†’ refl
      Ο‰ 𝟘 πŸ™ Ο‰ Ο‰ β†’ refl
      Ο‰ 𝟘 Ο‰ 𝟘 𝟘 β†’ refl
      Ο‰ 𝟘 Ο‰ 𝟘 πŸ™ β†’ refl
      Ο‰ 𝟘 Ο‰ 𝟘 Ο‰ β†’ refl
      Ο‰ 𝟘 Ο‰ πŸ™ 𝟘 β†’ refl
      Ο‰ 𝟘 Ο‰ πŸ™ πŸ™ β†’ refl
      Ο‰ 𝟘 Ο‰ πŸ™ Ο‰ β†’ refl
      Ο‰ 𝟘 Ο‰ Ο‰ 𝟘 β†’ refl
      Ο‰ 𝟘 Ο‰ Ο‰ πŸ™ β†’ refl
      Ο‰ 𝟘 Ο‰ Ο‰ Ο‰ β†’ refl
      Ο‰ πŸ™ 𝟘 𝟘 𝟘 β†’ refl
      Ο‰ πŸ™ 𝟘 𝟘 πŸ™ β†’ refl
      Ο‰ πŸ™ 𝟘 𝟘 Ο‰ β†’ refl
      Ο‰ πŸ™ 𝟘 πŸ™ 𝟘 β†’ refl
      Ο‰ πŸ™ 𝟘 πŸ™ πŸ™ β†’ refl
      Ο‰ πŸ™ 𝟘 πŸ™ Ο‰ β†’ refl
      Ο‰ πŸ™ 𝟘 Ο‰ 𝟘 β†’ refl
      Ο‰ πŸ™ 𝟘 Ο‰ πŸ™ β†’ refl
      Ο‰ πŸ™ 𝟘 Ο‰ Ο‰ β†’ refl
      Ο‰ πŸ™ πŸ™ 𝟘 𝟘 β†’ refl
      Ο‰ πŸ™ πŸ™ 𝟘 πŸ™ β†’ refl
      Ο‰ πŸ™ πŸ™ 𝟘 Ο‰ β†’ refl
      Ο‰ πŸ™ πŸ™ πŸ™ 𝟘 β†’ refl
      Ο‰ πŸ™ πŸ™ πŸ™ πŸ™ β†’ refl
      Ο‰ πŸ™ πŸ™ πŸ™ Ο‰ β†’ refl
      Ο‰ πŸ™ πŸ™ Ο‰ 𝟘 β†’ refl
      Ο‰ πŸ™ πŸ™ Ο‰ πŸ™ β†’ refl
      Ο‰ πŸ™ πŸ™ Ο‰ Ο‰ β†’ refl
      Ο‰ πŸ™ Ο‰ 𝟘 𝟘 β†’ refl
      Ο‰ πŸ™ Ο‰ 𝟘 πŸ™ β†’ refl
      Ο‰ πŸ™ Ο‰ 𝟘 Ο‰ β†’ refl
      Ο‰ πŸ™ Ο‰ πŸ™ 𝟘 β†’ refl
      Ο‰ πŸ™ Ο‰ πŸ™ πŸ™ β†’ refl
      Ο‰ πŸ™ Ο‰ πŸ™ Ο‰ β†’ refl
      Ο‰ πŸ™ Ο‰ Ο‰ 𝟘 β†’ refl
      Ο‰ πŸ™ Ο‰ Ο‰ πŸ™ β†’ refl
      Ο‰ πŸ™ Ο‰ Ο‰ Ο‰ β†’ refl
      Ο‰ Ο‰ 𝟘 𝟘 𝟘 β†’ refl
      Ο‰ Ο‰ 𝟘 𝟘 πŸ™ β†’ refl
      Ο‰ Ο‰ 𝟘 𝟘 Ο‰ β†’ refl
      Ο‰ Ο‰ 𝟘 πŸ™ 𝟘 β†’ refl
      Ο‰ Ο‰ 𝟘 πŸ™ πŸ™ β†’ refl
      Ο‰ Ο‰ 𝟘 πŸ™ Ο‰ β†’ refl
      Ο‰ Ο‰ 𝟘 Ο‰ 𝟘 β†’ refl
      Ο‰ Ο‰ 𝟘 Ο‰ πŸ™ β†’ refl
      Ο‰ Ο‰ 𝟘 Ο‰ Ο‰ β†’ refl
      Ο‰ Ο‰ πŸ™ 𝟘 𝟘 β†’ refl
      Ο‰ Ο‰ πŸ™ 𝟘 πŸ™ β†’ refl
      Ο‰ Ο‰ πŸ™ 𝟘 Ο‰ β†’ refl
      Ο‰ Ο‰ πŸ™ πŸ™ 𝟘 β†’ refl
      Ο‰ Ο‰ πŸ™ πŸ™ πŸ™ β†’ refl
      Ο‰ Ο‰ πŸ™ πŸ™ Ο‰ β†’ refl
      Ο‰ Ο‰ πŸ™ Ο‰ 𝟘 β†’ refl
      Ο‰ Ο‰ πŸ™ Ο‰ πŸ™ β†’ refl
      Ο‰ Ο‰ πŸ™ Ο‰ Ο‰ β†’ refl
      Ο‰ Ο‰ Ο‰ 𝟘 𝟘 β†’ refl
      Ο‰ Ο‰ Ο‰ 𝟘 πŸ™ β†’ refl
      Ο‰ Ο‰ Ο‰ 𝟘 Ο‰ β†’ refl
      Ο‰ Ο‰ Ο‰ πŸ™ 𝟘 β†’ refl
      Ο‰ Ο‰ Ο‰ πŸ™ πŸ™ β†’ refl
      Ο‰ Ο‰ Ο‰ πŸ™ Ο‰ β†’ refl
      Ο‰ Ο‰ Ο‰ Ο‰ 𝟘 β†’ refl
      Ο‰ Ο‰ Ο‰ Ο‰ πŸ™ β†’ refl
      Ο‰ Ο‰ Ο‰ Ο‰ Ο‰ β†’ refl

instance

  -- 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 Γ—
          (b ≑ BMΞ£ 𝕀 Γ— p ≑ 𝟘 β†’ T 𝟘ᡐ-allowed) Γ—
          Β¬ (b ≑ BMΞ£ 𝕀 Γ— p ≑ Ο‰)
      ; []-cong-allowed = Ξ» s β†’
          []-cong-allowed s Γ— T 𝟘ᡐ-allowed
      ; []-congβ†’Erased = Ξ» (ok₁ , okβ‚‚) β†’
            []-congβ†’Erased ok₁ .proj₁ , []-congβ†’Erased ok₁ .projβ‚‚
          , (Ξ» _ β†’ okβ‚‚) , Ξ» ()
      ; []-cong→¬Trivial =
          𝟘ᡐ.non-trivial βˆ˜β†’ projβ‚‚
      }
  , (Ξ» _ β†’ (_$ (refl , refl)) βˆ˜β†’ proj₁ βˆ˜β†’ projβ‚‚)
  , (Ξ» _ β†’ (_$ (refl , 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 rs us
full-reduction-assumptions (πŸ˜β†’πŸ˜α΅ , ¬ω) = record
  { sinkβŠŽπŸ™β‰€πŸ˜ = Ξ» _ _ β†’ injβ‚‚ refl
  ; β‰‘πŸ™βŠŽπŸ™β‰€πŸ˜   = Ξ» where
      {p = Ο‰} ok β†’ βŠ₯-elim (¬ω _ ok)
      {p = πŸ™} _  β†’ inj₁ refl
      {p = 𝟘} ok β†’ injβ‚‚ (refl , πŸ˜β†’πŸ˜α΅ _ ok , refl)
  }

-- Type and usage restrictions that satisfy the full reduction
-- assumptions are "suitable".

full-reduction-assumptions-suitable :
  Full-reduction-assumptions rs us β†’ Suitable-for-full-reduction rs
full-reduction-assumptions-suitable as =
    (Ξ» p Ξ£-ok β†’ case β‰‘πŸ™βŠŽπŸ™β‰€πŸ˜ Ξ£-ok of Ξ» where
      (inj₁ ())
      (injβ‚‚ (_ , 𝟘ᡐ-ok , _)) β†’ 𝟘ᡐ-ok)
  , Ξ» p Ξ£-ok β†’ case β‰‘πŸ™βŠŽπŸ™β‰€πŸ˜ Ξ£-ok of Ξ» where
      (inj₁ ())
      (injβ‚‚ (() , _))
  where
  open Full-reduction-assumptions as

opaque

  -- If πŸ™ is the greatest lower bounds of a sequence then all its entries
  -- are either 𝟘 or πŸ™

  πŸ™-GLB-inv :
    Semiring-with-meet.Greatest-lower-bound zero-one-many-semiring-with-meet πŸ™ pα΅’ β†’
    βˆ€ i β†’ pα΅’ i ≑ πŸ™ ⊎ pα΅’ i ≑ 𝟘
  πŸ™-GLB-inv πŸ™-glb i = lemma _ (πŸ™-glb .proj₁ i)
    where
    lemma : βˆ€ p β†’ πŸ™ ≀ p β†’ p ≑ πŸ™ ⊎ p ≑ 𝟘
    lemma 𝟘 _ = injβ‚‚ refl
    lemma πŸ™ _ = inj₁ refl
    lemma Ο‰ ()

opaque

  -- If the greatest lower bound of nrᡒ r z s is 𝟘 then z = s 𝟘.

  nrᡒ-GLB-𝟘-inv :
   let 𝕄 = zero-one-many-semiring-with-meet in
    βˆ€ r z s β†’
    Semiring-with-meet.Greatest-lower-bound 𝕄 𝟘 (Semiring-with-meet.nrα΅’ 𝕄 r z s) β†’
    z ≑ 𝟘 Γ— s ≑ 𝟘
  nrα΅’-GLB-𝟘-inv r 𝟘 𝟘 (πŸ˜β‰€ , _) = refl , refl
  nrα΅’-GLB-𝟘-inv 𝟘 𝟘 πŸ™ (πŸ˜β‰€ , _) = case πŸ˜β‰€ 1 of Ξ» ()
  nrα΅’-GLB-𝟘-inv πŸ™ 𝟘 πŸ™ (πŸ˜β‰€ , _) = case πŸ˜β‰€ 1 of Ξ» ()
  nrα΅’-GLB-𝟘-inv Ο‰ 𝟘 πŸ™ (πŸ˜β‰€ , _) = case πŸ˜β‰€ 1 of Ξ» ()
  nrα΅’-GLB-𝟘-inv r 𝟘 Ο‰ (πŸ˜β‰€ , _) = case πŸ˜β‰€ 1 of Ξ» ()
  nrα΅’-GLB-𝟘-inv r πŸ™ s (πŸ˜β‰€ , _) = case πŸ˜β‰€ 0 of Ξ» ()
  nrα΅’-GLB-𝟘-inv r Ο‰ s (πŸ˜β‰€ , _) = case πŸ˜β‰€ 0 of Ξ» ()

opaque

  -- If the greatest lower bound of nrα΅’Β rΒ zΒ s is πŸ™ then either
  -- r=πŸ™, z=πŸ™, sβ‰‘πŸ˜
  -- rβ‰‘πŸ˜, zβ‰‘πŸ™, sβ‰‘πŸ™
  -- rβ‰‘πŸ˜, zβ‰‘πŸ˜, sβ‰‘πŸ™
  -- rβ‰‘πŸ˜, zβ‰‘πŸ™, sβ‰‘πŸ˜

  nrα΅’-GLB-πŸ™-inv :
   let 𝕄 = zero-one-many-semiring-with-meet in
    βˆ€ r z s β†’
    Semiring-with-meet.Greatest-lower-bound 𝕄 πŸ™ (Semiring-with-meet.nrα΅’ 𝕄 r z s) β†’
    r ≑ πŸ™ Γ— z ≑ πŸ™ Γ— s ≑ 𝟘 ⊎ r ≑ 𝟘 Γ— z ≑ πŸ™ Γ— s ≑ πŸ™ ⊎
    r ≑ 𝟘 Γ— z ≑ 𝟘 Γ— s ≑ πŸ™ ⊎ r ≑ 𝟘 Γ— z ≑ πŸ™ Γ— s ≑ 𝟘
  nrα΅’-GLB-πŸ™-inv 𝟘 𝟘 𝟘 (πŸ™β‰€ , glb) = case glb 𝟘 (Ξ» i β†’ ≀-reflexive (sym (nrα΅’-𝟘 i))) of Ξ» ()
  nrα΅’-GLB-πŸ™-inv πŸ™ 𝟘 𝟘 (πŸ™β‰€ , glb) = case glb 𝟘 (Ξ» i β†’ ≀-reflexive (sym (nrα΅’-𝟘 i))) of Ξ» ()
  nrα΅’-GLB-πŸ™-inv Ο‰ 𝟘 𝟘 (πŸ™β‰€ , glb) = case glb 𝟘 (Ξ» i β†’ ≀-reflexive (sym (nrα΅’-𝟘 i))) of Ξ» ()
  nrα΅’-GLB-πŸ™-inv 𝟘 𝟘 πŸ™ (πŸ™β‰€ , _) = injβ‚‚ (injβ‚‚ (inj₁ (refl , refl , refl)))
  nrα΅’-GLB-πŸ™-inv πŸ™ 𝟘 πŸ™ (πŸ™β‰€ , _) = case πŸ™β‰€ 2 of Ξ» ()
  nrα΅’-GLB-πŸ™-inv Ο‰ 𝟘 πŸ™ (πŸ™β‰€ , _) = case πŸ™β‰€ 2 of Ξ» ()
  nrα΅’-GLB-πŸ™-inv r 𝟘 Ο‰ (πŸ™β‰€ , _) = case πŸ™β‰€ 1 of Ξ» ()
  nrα΅’-GLB-πŸ™-inv 𝟘 πŸ™ 𝟘 (πŸ™β‰€ , _) = injβ‚‚ (injβ‚‚ (injβ‚‚ (refl , refl , refl)))
  nrα΅’-GLB-πŸ™-inv πŸ™ πŸ™ 𝟘 (πŸ™β‰€ , _) = inj₁ (refl , refl , refl)
  nrα΅’-GLB-πŸ™-inv Ο‰ πŸ™ 𝟘 (πŸ™β‰€ , _) = case πŸ™β‰€ 1 of Ξ» ()
  nrα΅’-GLB-πŸ™-inv 𝟘 πŸ™ πŸ™ (πŸ™β‰€ , _) = injβ‚‚ (inj₁ (refl , refl , refl))
  nrα΅’-GLB-πŸ™-inv πŸ™ πŸ™ πŸ™ (πŸ™β‰€ , _) = case πŸ™β‰€ 1 of Ξ» ()
  nrα΅’-GLB-πŸ™-inv Ο‰ πŸ™ πŸ™ (πŸ™β‰€ , _) = case πŸ™β‰€ 1 of Ξ» ()
  nrα΅’-GLB-πŸ™-inv r πŸ™ Ο‰ (πŸ™β‰€ , _) = case πŸ™β‰€ 1 of Ξ» ()
  nrα΅’-GLB-πŸ™-inv r Ο‰ s (πŸ™β‰€ , _) = case πŸ™β‰€ 0 of Ξ» ()

opaque

  -- The greatest lower bound of nrα΅’Β rΒ πŸ™Β p is πŸ™ only if
  -- p ≑ 𝟘 and r ≑ πŸ™ or
  -- p ≑ πŸ™ and r ≑ 𝟘 or
  -- p ≑ 𝟘 and r ≑ 𝟘

  nrα΅’-rπŸ™p-GLB-πŸ™-inv :
    let 𝕄 = zero-one-many-semiring-with-meet in
      βˆ€ p r β†’
    Semiring-with-meet.Greatest-lower-bound 𝕄 πŸ™ (Semiring-with-meet.nrα΅’ 𝕄 r πŸ™ p) β†’
    p ≑ 𝟘 Γ— r ≑ πŸ™ ⊎ p ≑ πŸ™ Γ— r ≑ 𝟘 ⊎ p ≑ 𝟘 Γ— r ≑ 𝟘
  nrα΅’-rπŸ™p-GLB-πŸ™-inv p r glb =
    case nrα΅’-GLB-πŸ™-inv r πŸ™ p glb of Ξ» where
      (inj₁ (rβ‰‘πŸ™ , _ , pβ‰‘πŸ˜)) β†’ inj₁ (pβ‰‘πŸ˜ , rβ‰‘πŸ™)
      (injβ‚‚ (inj₁ (rβ‰‘πŸ˜ , _ , pβ‰‘πŸ™))) β†’ injβ‚‚ (inj₁ (pβ‰‘πŸ™ , rβ‰‘πŸ˜))
      (injβ‚‚ (injβ‚‚ (inj₁ (_ , () , _))))
      (injβ‚‚ (injβ‚‚ (injβ‚‚ (rβ‰‘πŸ˜ , _ , pβ‰‘πŸ˜)))) β†’ injβ‚‚ (injβ‚‚ (pβ‰‘πŸ˜ , rβ‰‘πŸ˜))