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

open import Tools.Bool
open import Tools.Level

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

module Graded.Modality.Instances.Affine where

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

open import Graded.Modality Affine
import Graded.Mode.Instances.Zero-one.Variant
import Graded.Mode.Instances.Zero-one
import Graded.Modality.Properties
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

open Graded.Mode.Instances.Zero-one.Variant affineModality
open Graded.Modality.Properties             affineModality


-- 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 affineModality
  affine-has-well-behaved-zero = zero-one-many-has-well-behaved-zero

-- 𝟘 is the largest element.

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

opaque

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

  πŸ™-GLB-inv :
    Modality.Greatest-lower-bound zero-one-many-modality πŸ™ 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-modality in
    βˆ€ r z s β†’
    Modality.Greatest-lower-bound 𝕄 𝟘 (Modality.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-modality in
    βˆ€ r z s β†’
    Modality.Greatest-lower-bound 𝕄 πŸ™ (Modality.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-modality in
      βˆ€ p r β†’
    Modality.Greatest-lower-bound 𝕄 πŸ™ (Modality.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β‰‘πŸ˜))

------------------------------------------------------------------------
-- Properties relating to the Zero-one mode structure

module _ {𝟘ᡐ-allowed : Bool} where

  private
    variant : Mode-variant
    variant = record
      { 𝟘ᡐ-allowed = 𝟘ᡐ-allowed
      ; 𝟘-well-behaved = Ξ» _ β†’ affine-has-well-behaved-zero
      }

  open Graded.Mode.Instances.Zero-one   variant
  open Definition.Typed.Restrictions    affineModality
  open Graded.Usage.Restrictions        affineModality Zero-one-isMode
  open Graded.FullReduction.Assumptions variant

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

  -- 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 ⦃ affine-has-well-behaved-zero ⦄
        }
    , (Ξ» _ β†’ (_$ (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