------------------------------------------------------------------------
-- The zero-one-many modality
------------------------------------------------------------------------

-- Based on Conor McBride's "I Got Plenty o’ Nuttin’".

-- It might make sense to replace some of the proofs with automated
-- proofs.

open import Tools.Bool using (Bool; true; false; if_then_else_; T)

module Graded.Modality.Instances.Zero-one-many
  -- Should πŸ™ be below 𝟘?
  (πŸ™β‰€πŸ˜ : Bool)
  where
import Tools.Algebra
open import Tools.Empty
open import Tools.Function
open import Tools.Level
open import Tools.Product
open import Tools.PropositionalEquality as PE
import Tools.Reasoning.PartialOrder
import Tools.Reasoning.PropositionalEquality
open import Tools.Relation
open import Tools.Sum using (_⊎_; inj₁; injβ‚‚)

import Graded.Modality
import Graded.Modality.Instances.LowerBounded as LowerBounded
import Graded.Modality.Properties.Addition as Addition
import Graded.Modality.Properties.Meet as Meet
import Graded.Modality.Properties.Multiplication as Multiplication
import Graded.Modality.Properties.PartialOrder as PartialOrder
import Graded.Modality.Properties.Star as Star
open import Graded.Modality.Variant lzero

------------------------------------------------------------------------
-- The type

-- Zero, one or many.

data Zero-one-many : Set where
  𝟘 πŸ™ Ο‰ : Zero-one-many

private variable
  n n₁ nβ‚‚ p p₁ pβ‚‚ q r result s s₁ sβ‚‚ z z₁ zβ‚‚ : Zero-one-many

open Graded.Modality Zero-one-many
open Tools.Algebra   Zero-one-many

-- A decision procedure for equality.

infix 10 _β‰Ÿ_

_β‰Ÿ_ : Decidable (_≑_ {A = Zero-one-many})
𝟘 β‰Ÿ 𝟘 = yes refl
𝟘 β‰Ÿ πŸ™ = no (Ξ» ())
𝟘 β‰Ÿ Ο‰ = no (Ξ» ())
πŸ™ β‰Ÿ 𝟘 = no (Ξ» ())
πŸ™ β‰Ÿ πŸ™ = yes refl
πŸ™ β‰Ÿ Ο‰ = no (Ξ» ())
Ο‰ β‰Ÿ 𝟘 = no (Ξ» ())
Ο‰ β‰Ÿ πŸ™ = no (Ξ» ())
Ο‰ β‰Ÿ Ο‰ = yes refl

------------------------------------------------------------------------
-- Meet

-- Some requirements of a meet operation.

Meet-requirements :
  (Zero-one-many β†’ Zero-one-many β†’ Zero-one-many) β†’ Set
Meet-requirements _∧_ =
  (𝟘 ∧ 𝟘 ≑ 𝟘) Γ—
  (πŸ™ ∧ πŸ™ ≑ πŸ™) Γ—
  (Ο‰ ∧ Ο‰ ≑ Ο‰) Γ—
  (𝟘 ∧ Ο‰ ≑ Ο‰) Γ—
  (Ο‰ ∧ 𝟘 ≑ Ο‰) Γ—
  (πŸ™ ∧ Ο‰ ≑ Ο‰) Γ—
  (Ο‰ ∧ πŸ™ ≑ Ο‰) Γ—
  (𝟘 ∧ πŸ™ β‰’ 𝟘) Γ—
  (πŸ™ ∧ 𝟘 β‰’ 𝟘)

-- The meet operation of a "Semiring-with-meet" for Zero-one-many for
-- which the zero is 𝟘, the one is πŸ™, ω ≀ p for all p
-- and πŸ˜Β βˆ§Β πŸ™Β β‰’Β πŸ˜ has to satisfy the Meet-requirements.

Meet-requirements-required :
  (M : Semiring-with-meet) β†’
  Semiring-with-meet.𝟘          M ≑ 𝟘 β†’
  Semiring-with-meet.πŸ™          M ≑ πŸ™ β†’
  Semiring-with-meet._∧_ M    𝟘 πŸ™ β‰’ 𝟘 β†’
  (βˆ€ p β†’ Semiring-with-meet._≀_ M Ο‰ p) β†’
  Meet-requirements (Semiring-with-meet._∧_ M)
Meet-requirements-required M refl refl πŸ˜βˆ§πŸ™β‰’πŸ˜ ω≀ =
    (𝟘 ∧ 𝟘  β‰‘βŸ¨ ∧-idem _ ⟩
     𝟘      ∎)
  , (πŸ™ ∧ πŸ™  β‰‘βŸ¨ ∧-idem _ ⟩
     πŸ™      ∎)
  , (Ο‰ ∧ Ο‰  β‰‘βŸ¨ ∧-idem _ ⟩
     Ο‰      ∎)
  , (𝟘 ∧ Ο‰  β‰‘βŸ¨ ∧-comm _ _ ⟩
     Ο‰ ∧ 𝟘  β‰‘Λ˜βŸ¨ ω≀ 𝟘 ⟩
     Ο‰      ∎)
  , (Ο‰ ∧ 𝟘  β‰‘Λ˜βŸ¨ ω≀ 𝟘 ⟩
     Ο‰      ∎)
  , (πŸ™ ∧ Ο‰  β‰‘βŸ¨ ∧-comm _ _ ⟩
     Ο‰ ∧ πŸ™  β‰‘Λ˜βŸ¨ ω≀ πŸ™ ⟩
     Ο‰      ∎)
  , (Ο‰ ∧ πŸ™  β‰‘Λ˜βŸ¨ ω≀ πŸ™ ⟩
     Ο‰      ∎)
  , πŸ˜βˆ§πŸ™β‰’πŸ˜
  , (Ξ» πŸ™βˆ§πŸ˜β‰‘πŸ˜ β†’ πŸ˜βˆ§πŸ™β‰’πŸ˜ (
       𝟘 ∧ πŸ™  β‰‘βŸ¨ ∧-comm _ _ ⟩
       πŸ™ ∧ 𝟘  β‰‘βŸ¨ πŸ™βˆ§πŸ˜β‰‘πŸ˜ ⟩
       𝟘      ∎))
  where
  open Semiring-with-meet M hiding (𝟘; πŸ™; Ο‰)
  open Meet M
  open PartialOrder M
  open Tools.Reasoning.PropositionalEquality

-- The result of πŸ˜Β βˆ§Β πŸ™ and πŸ™Β βˆ§Β πŸ˜.

πŸ˜βˆ§πŸ™ : Zero-one-many
πŸ˜βˆ§πŸ™ = if πŸ™β‰€πŸ˜ then πŸ™ else Ο‰

-- Meet.

infixr 40 _∧_

_∧_ : Zero-one-many β†’ Zero-one-many β†’ Zero-one-many
𝟘 ∧ 𝟘 = 𝟘
πŸ™ ∧ πŸ™ = πŸ™
𝟘 ∧ πŸ™ = πŸ˜βˆ§πŸ™
πŸ™ ∧ 𝟘 = πŸ˜βˆ§πŸ™
_ ∧ _ = Ο‰

-- If πŸ™β‰€πŸ˜ is true, then πŸ˜βˆ§πŸ™Β β‰‘Β πŸ™.

πŸ˜βˆ§πŸ™β‰‘πŸ™ : T πŸ™β‰€πŸ˜ β†’ πŸ˜βˆ§πŸ™ ≑ πŸ™
πŸ˜βˆ§πŸ™β‰‘πŸ™ = lemma _
  where
  lemma : βˆ€ b β†’ T b β†’ (if b then πŸ™ else Ο‰) ≑ πŸ™
  lemma true _ = refl

-- If πŸ˜βˆ§πŸ™Β β‰‘Β πŸ™, then πŸ™β‰€πŸ˜ is true.

πŸ˜βˆ§πŸ™β‰‘πŸ™β†’πŸ™β‰€πŸ˜ : πŸ˜βˆ§πŸ™ ≑ πŸ™ β†’ T πŸ™β‰€πŸ˜
πŸ˜βˆ§πŸ™β‰‘πŸ™β†’πŸ™β‰€πŸ˜ = lemma _
  where
  lemma : βˆ€ b β†’ (if b then πŸ™ else Ο‰) ≑ πŸ™ β†’ T b
  lemma true _ = _

-- If πŸ™β‰€πŸ˜ is false, then πŸ˜βˆ§πŸ™Β β‰‘Β Ο‰.

πŸ˜βˆ§πŸ™β‰‘Ο‰ : Β¬ T πŸ™β‰€πŸ˜ β†’ πŸ˜βˆ§πŸ™ ≑ Ο‰
πŸ˜βˆ§πŸ™β‰‘Ο‰ = lemma _
  where
  lemma : βˆ€ b β†’ Β¬ T b β†’ (if b then πŸ™ else Ο‰) ≑ Ο‰
  lemma false _  = refl
  lemma true  ¬⊀ = βŠ₯-elim (¬⊀ _)

-- If πŸ˜βˆ§πŸ™Β β‰’Β πŸ™, then πŸ™β‰€πŸ˜ is false.

πŸ˜βˆ§πŸ™β‰’πŸ™β†’πŸ™β‰°πŸ˜ : πŸ˜βˆ§πŸ™ β‰’ πŸ™ β†’ Β¬ T πŸ™β‰€πŸ˜
πŸ˜βˆ§πŸ™β‰’πŸ™β†’πŸ™β‰°πŸ˜ = lemma _
  where
  lemma : βˆ€ b β†’ (if b then πŸ™ else Ο‰) β‰’ πŸ™ β†’ Β¬ T b
  lemma true  πŸ™β‰’πŸ™ = Ξ» _ β†’ πŸ™β‰’πŸ™ refl
  lemma false _   = idαΆ 

-- The value of πŸ˜βˆ§πŸ™ is not 𝟘.

πŸ˜βˆ§πŸ™β‰’πŸ˜ : πŸ˜βˆ§πŸ™ β‰’ 𝟘
πŸ˜βˆ§πŸ™β‰’πŸ˜ = lemma _
  where
  lemma : βˆ€ b β†’ (if b then πŸ™ else Ο‰) β‰’ 𝟘
  lemma false ()
  lemma true  ()

-- One can prove that something holds for πŸ˜βˆ§πŸ™ by proving that it holds
-- for πŸ™ (under the assumption that πŸ˜βˆ§πŸ™ is πŸ™), and that it holds for Ο‰
-- (under the assumption that πŸ˜βˆ§πŸ™ is Ο‰).

πŸ˜βˆ§πŸ™-elim :
  βˆ€ {p} (P : Zero-one-many β†’ Set p) β†’
  (πŸ˜βˆ§πŸ™ ≑ πŸ™ β†’ P πŸ™) β†’
  (πŸ˜βˆ§πŸ™ ≑ Ο‰ β†’ P Ο‰) β†’
  P πŸ˜βˆ§πŸ™
πŸ˜βˆ§πŸ™-elim P one omega = lemma _ refl
  where
  lemma : βˆ€ p β†’ πŸ˜βˆ§πŸ™ ≑ p β†’ P p
  lemma 𝟘 πŸ˜βˆ§πŸ™β‰‘πŸ˜ = βŠ₯-elim (πŸ˜βˆ§πŸ™β‰’πŸ˜ πŸ˜βˆ§πŸ™β‰‘πŸ˜)
  lemma πŸ™ πŸ˜βˆ§πŸ™β‰‘πŸ™ = one πŸ˜βˆ§πŸ™β‰‘πŸ™
  lemma Ο‰ πŸ˜βˆ§πŸ™β‰‘Ο‰ = omega πŸ˜βˆ§πŸ™β‰‘Ο‰

-- πŸ˜Β βˆ§Β πŸ˜βˆ§πŸ™ is equal to πŸ˜βˆ§πŸ™.

𝟘∧[πŸ˜βˆ§πŸ™] : 𝟘 ∧ πŸ˜βˆ§πŸ™ ≑ πŸ˜βˆ§πŸ™
𝟘∧[πŸ˜βˆ§πŸ™] = πŸ˜βˆ§πŸ™-elim
  (Ξ» p β†’ 𝟘 ∧ p ≑ p)
  (Ξ» πŸ˜βˆ§πŸ™β‰‘πŸ™ β†’ πŸ˜βˆ§πŸ™β‰‘πŸ™)
  (Ξ» _ β†’ refl)

-- πŸ™Β βˆ§Β πŸ˜βˆ§πŸ™ is equal to πŸ˜βˆ§πŸ™.

πŸ™βˆ§[πŸ˜βˆ§πŸ™] : πŸ™ ∧ πŸ˜βˆ§πŸ™ ≑ πŸ˜βˆ§πŸ™
πŸ™βˆ§[πŸ˜βˆ§πŸ™] = πŸ˜βˆ§πŸ™-elim
  (Ξ» p β†’ πŸ™ ∧ p ≑ p)
  (Ξ» _ β†’ refl)
  (Ξ» _ β†’ refl)

-- The value Ο‰ is a right zero for _∧_.

∧-zeroΚ³ : RightZero Ο‰ _∧_
∧-zeroʳ 𝟘 = refl
∧-zeroΚ³ πŸ™ = refl
∧-zeroΚ³ Ο‰ = refl

-- The value Ο‰ is a zero for _∧_.

∧-zero : Zero Ο‰ _∧_
∧-zero = (Ξ» _ β†’ refl) , ∧-zeroΚ³

-- If p ∧ q isΒ πŸ™, then at least one of p and q isΒ πŸ™, and if the other
-- one is notΒ πŸ™, then it is 𝟘, and πŸ™Β β‰€Β πŸ˜.

βˆ§β‰‘πŸ™ :
  p ∧ q ≑ πŸ™ β†’
  p ≑ 𝟘 Γ— q ≑ πŸ™ Γ— T πŸ™β‰€πŸ˜ ⊎
  p ≑ πŸ™ Γ— q ≑ 𝟘 Γ— T πŸ™β‰€πŸ˜ ⊎
  p ≑ πŸ™ Γ— q ≑ πŸ™
βˆ§β‰‘πŸ™ {p = 𝟘} {q = πŸ™} eq = inj₁ (refl , refl , πŸ˜βˆ§πŸ™β‰‘πŸ™β†’πŸ™β‰€πŸ˜ eq)
βˆ§β‰‘πŸ™ {p = πŸ™} {q = 𝟘} eq = injβ‚‚ (inj₁ (refl , refl , πŸ˜βˆ§πŸ™β‰‘πŸ™β†’πŸ™β‰€πŸ˜ eq))
βˆ§β‰‘πŸ™ {p = πŸ™} {q = πŸ™} _  = injβ‚‚ (injβ‚‚ (refl , refl))

------------------------------------------------------------------------
-- Ordering

-- Some requirements of an ordering relation.

Order-requirements : (Zero-one-many β†’ Zero-one-many β†’ Set) β†’ Set
Order-requirements _≀_ = (Ο‰ ≀ πŸ™) Γ— (Ο‰ ≀ 𝟘) Γ— Β¬ (𝟘 ≀ πŸ™)

-- The ordering relation of a "Semiring-with-meet" for Zero-one-many for
-- which the zero is 𝟘, the one is πŸ™ and pΒ βˆ§Β Ο‰ equals Ο‰ for all p
-- has to satisfy the Order-requirements.

Order-requirements-required :
  (M : Semiring-with-meet) β†’
  Semiring-with-meet.𝟘          M ≑ 𝟘 β†’
  Semiring-with-meet.πŸ™          M ≑ πŸ™ β†’
  Semiring-with-meet._∧_ M    𝟘 πŸ™ β‰’ 𝟘 β†’
  (βˆ€ p β†’ Semiring-with-meet._≀_ M Ο‰ p) β†’
  Order-requirements (Semiring-with-meet._≀_ M)
Order-requirements-required M refl refl πŸ˜βˆ§πŸ™β‰’πŸ˜ ω≀ =
  case Meet-requirements-required M refl refl πŸ˜βˆ§πŸ™β‰’πŸ˜ ω≀ of Ξ» where
    (_ , _ , _ , _ , Ο‰βŠ“πŸ˜β‰‘Ο‰ , _ , Ο‰βŠ“πŸ™β‰‘Ο‰ , πŸ˜βŠ“πŸ™β‰’πŸ˜ , _) β†’
        (Ο‰      β‰‘Λ˜βŸ¨ Ο‰βŠ“πŸ™β‰‘Ο‰ ⟩
         Ο‰ βŠ“ πŸ™  ∎)
      , (Ο‰      β‰‘Λ˜βŸ¨ Ο‰βŠ“πŸ˜β‰‘Ο‰ ⟩
         Ο‰ βŠ“ 𝟘  ∎)
      , (Ξ» πŸ˜β‰‘πŸ˜βŠ“πŸ™ β†’ πŸ˜βŠ“πŸ™β‰’πŸ˜ (
           𝟘 βŠ“ πŸ™  β‰‘Λ˜βŸ¨ πŸ˜β‰‘πŸ˜βŠ“πŸ™ ⟩
           𝟘      ∎))
  where
  open Semiring-with-meet M using () renaming (_∧_ to _βŠ“_)
  open Tools.Reasoning.PropositionalEquality

-- The inferred ordering relation.

infix 10 _≀_

_≀_ : Zero-one-many β†’ Zero-one-many β†’ Set
p ≀ q = p ≑ p ∧ q

-- The quantity Ο‰ is smaller than all others.

ω≀ : βˆ€ p β†’ Ο‰ ≀ p
ω≀ _ = refl

-- 𝟘 is maximal.

𝟘-maximal : 𝟘 ≀ p β†’ p ≑ 𝟘
𝟘-maximal {p = 𝟘} refl = refl
𝟘-maximal {p = πŸ™}      = πŸ˜βˆ§πŸ™-elim
  (Ξ» q β†’ 𝟘 ≑ q β†’ πŸ™ ≑ 𝟘)
  (Ξ» _ β†’ sym)
  (Ξ» _ ())

-- 𝟘 is not below πŸ˜βˆ§πŸ™.

πŸ˜β‰°πŸ˜βˆ§πŸ™ : Β¬ 𝟘 ≀ πŸ˜βˆ§πŸ™
πŸ˜β‰°πŸ˜βˆ§πŸ™ = πŸ˜βˆ§πŸ™β‰’πŸ˜ βˆ˜β†’ 𝟘-maximal

-- If πŸ™β‰€πŸ˜ is true, then πŸ™Β β‰€Β πŸ˜.

πŸ™β‰€πŸ˜β†’πŸ™β‰€πŸ˜ : T πŸ™β‰€πŸ˜ β†’ πŸ™ ≀ 𝟘
πŸ™β‰€πŸ˜β†’πŸ™β‰€πŸ˜ πŸ™β‰€πŸ˜ =
  πŸ™      β‰‘Λ˜βŸ¨ πŸ˜βˆ§πŸ™β‰‘πŸ™ πŸ™β‰€πŸ˜ ⟩
  πŸ™ ∧ 𝟘  ∎
  where
  open Tools.Reasoning.PropositionalEquality

-- If πŸ™β‰€πŸ˜ is false, then πŸ™ is maximal.

πŸ™-maximal : Β¬ T πŸ™β‰€πŸ˜ β†’ πŸ™ ≀ p β†’ p ≑ πŸ™
πŸ™-maximal {p = πŸ™} _   refl = refl
πŸ™-maximal {p = 𝟘} πŸ™β‰°πŸ˜ πŸ™β‰€πŸ˜  = βŠ₯-elim (
  case
    πŸ™      β‰‘βŸ¨ πŸ™β‰€πŸ˜ ⟩
    πŸ™ ∧ 𝟘  β‰‘βŸ¨ πŸ˜βˆ§πŸ™β‰‘Ο‰ πŸ™β‰°πŸ˜ ⟩
    Ο‰      ∎
  of Ξ» ())
  where
  open Tools.Reasoning.PropositionalEquality

------------------------------------------------------------------------
-- Addition

-- Addition.

infixr 40 _+_

_+_ : Zero-one-many β†’ Zero-one-many β†’ Zero-one-many
𝟘 + q = q
πŸ™ + 𝟘 = πŸ™
_ + _ = Ο‰

-- If πŸ™β‰€πŸ˜ is true, then _+_ is decreasing in its left argument.

+-decreasingΛ‘ : T πŸ™β‰€πŸ˜ β†’ βˆ€ p q β†’ p + q ≀ p
+-decreasingΛ‘ πŸ™β‰€πŸ˜ = Ξ» where
  𝟘 𝟘 β†’ refl
  𝟘 πŸ™ β†’ πŸ™β‰€πŸ˜β†’πŸ™β‰€πŸ˜ πŸ™β‰€πŸ˜
  𝟘 Ο‰ β†’ refl
  πŸ™ 𝟘 β†’ refl
  πŸ™ πŸ™ β†’ refl
  πŸ™ Ο‰ β†’ refl
  Ο‰ _ β†’ refl

-- If πŸ™β‰€πŸ˜ is not true, then _+_ is not decreasing in its left argument.

Β¬-+-decreasingΛ‘ : Β¬ T πŸ™β‰€πŸ˜ β†’ Β¬ (βˆ€ p q β†’ p + q ≀ p)
Β¬-+-decreasingΛ‘ πŸ™β‰°πŸ˜ hyp =
  case πŸ™-maximal {p = 𝟘} πŸ™β‰°πŸ˜ (hyp 𝟘 πŸ™) of Ξ» ()

-- The sum of two non-zero values is Ο‰.

β‰’πŸ˜+β‰’πŸ˜ : p β‰’ 𝟘 β†’ q β‰’ 𝟘 β†’ p + q ≑ Ο‰
β‰’πŸ˜+β‰’πŸ˜ {p = 𝟘}         πŸ˜β‰’πŸ˜ _   = βŠ₯-elim (πŸ˜β‰’πŸ˜ refl)
β‰’πŸ˜+β‰’πŸ˜ {p = πŸ™} {q = 𝟘} _   πŸ˜β‰’πŸ˜ = βŠ₯-elim (πŸ˜β‰’πŸ˜ refl)
β‰’πŸ˜+β‰’πŸ˜ {p = πŸ™} {q = πŸ™} _   _   = refl
β‰’πŸ˜+β‰’πŸ˜ {p = πŸ™} {q = Ο‰} _   _   = refl
β‰’πŸ˜+β‰’πŸ˜ {p = Ο‰}         _   _   = refl

-- If pΒ +Β q is πŸ™, then either p is πŸ™ and q is 𝟘, or q is πŸ™ and p is 𝟘.

+β‰‘πŸ™ : p + q ≑ πŸ™ β†’ p ≑ πŸ™ Γ— q ≑ 𝟘 ⊎ p ≑ 𝟘 Γ— q ≑ πŸ™
+β‰‘πŸ™ {p = 𝟘} {q = πŸ™} refl = injβ‚‚ (refl , refl)
+β‰‘πŸ™ {p = πŸ™} {q = 𝟘} refl = inj₁ (refl , refl)

-- The value Ο‰ is a right zero for _+_.

+-zeroΚ³ : RightZero Ο‰ _+_
+-zeroʳ 𝟘 = refl
+-zeroΚ³ πŸ™ = refl
+-zeroΚ³ Ο‰ = refl

-- The value Ο‰ is a zero for _+_.

+-zero : Zero Ο‰ _+_
+-zero = (Ξ» _ β†’ refl) , +-zeroΚ³

------------------------------------------------------------------------
-- Multiplication

-- Multiplication.

infixr 45 _Β·_

_Β·_ : Zero-one-many β†’ Zero-one-many β†’ Zero-one-many
𝟘 · _ = 𝟘
_ · 𝟘 = 𝟘
πŸ™ Β· πŸ™ = πŸ™
_ Β· _ = Ο‰

-- Multiplication is idempotent.

Β·-idempotent : Idempotent _Β·_
·-idempotent 𝟘 = refl
Β·-idempotent πŸ™ = refl
Β·-idempotent Ο‰ = refl

-- Multiplication is commutative.

Β·-comm : Commutative _Β·_
Β·-comm = Ξ» where
  𝟘 𝟘 β†’ refl
  𝟘 πŸ™ β†’ refl
  𝟘 Ο‰ β†’ refl
  πŸ™ 𝟘 β†’ refl
  πŸ™ πŸ™ β†’ refl
  πŸ™ Ο‰ β†’ refl
  Ο‰ 𝟘 β†’ refl
  Ο‰ πŸ™ β†’ refl
  Ο‰ Ο‰ β†’ refl

-- If p is not 𝟘, then ω · p is equal to Ο‰.

Ο‰Β·β‰’πŸ˜ : p β‰’ 𝟘 β†’ Ο‰ Β· p ≑ Ο‰
Ο‰Β·β‰’πŸ˜ {p = 𝟘} πŸ˜β‰’πŸ˜ = βŠ₯-elim (πŸ˜β‰’πŸ˜ refl)
Ο‰Β·β‰’πŸ˜ {p = πŸ™} _   = refl
Ο‰Β·β‰’πŸ˜ {p = Ο‰} _   = refl

-- If p is not 𝟘, then πŸ™Β Β·Β p is not 𝟘.

πŸ™Β·β‰’πŸ˜ : p β‰’ 𝟘 β†’ πŸ™ Β· p β‰’ 𝟘
πŸ™Β·β‰’πŸ˜ {p = 𝟘} πŸ˜β‰’πŸ˜ = πŸ˜β‰’πŸ˜
πŸ™Β·β‰’πŸ˜ {p = πŸ™} πŸ™β‰’πŸ˜ = πŸ™β‰’πŸ˜
πŸ™Β·β‰’πŸ˜ {p = Ο‰} Ο‰β‰’πŸ˜ = Ο‰β‰’πŸ˜

-- The value of ω · p is notΒ πŸ™.

Ο‰Β·β‰’πŸ™ : Ο‰ Β· p β‰’ πŸ™
Ο‰Β·β‰’πŸ™ {p = 𝟘} ()
Ο‰Β·β‰’πŸ™ {p = πŸ™} ()
Ο‰Β·β‰’πŸ™ {p = Ο‰} ()

opaque

  -- The grade ω · (pΒ +Β q) is bounded by ω · q.

  ω·+≀ω·ʳ : βˆ€ p β†’ Ο‰ Β· (p + q) ≀ Ο‰ Β· q
  ω·+≀ω·ʳ {q = 𝟘} 𝟘 = refl
  ω·+≀ω·ʳ {q = πŸ™} 𝟘 = refl
  ω·+≀ω·ʳ {q = Ο‰} 𝟘 = refl
  ω·+≀ω·ʳ {q = 𝟘} πŸ™ = refl
  ω·+≀ω·ʳ {q = πŸ™} πŸ™ = refl
  ω·+≀ω·ʳ {q = Ο‰} πŸ™ = refl
  ω·+≀ω·ʳ         Ο‰ = refl

------------------------------------------------------------------------
-- The modality without the star operation

-- The zero-one-many semiring with meet

zero-one-many-semiring-with-meet : Semiring-with-meet
zero-one-many-semiring-with-meet = record
  { _+_          = _+_
  ; _Β·_          = _Β·_
  ; _∧_          = _∧_
  ; 𝟘            = 𝟘
  ; πŸ™            = πŸ™
  ; Ο‰            = Ο‰
  ; Ο‰β‰€πŸ™          = refl
  ; ω·+≀ω·ʳ      = Ξ» {p = p} β†’ ω·+≀ω·ʳ p
  ; is-𝟘?        = _β‰Ÿ 𝟘
  ; +-Β·-Semiring = record
    { isSemiringWithoutAnnihilatingZero = record
      { +-isCommutativeMonoid = record
        { isMonoid = record
          { isSemigroup = record
            { isMagma = record
              { isEquivalence = PE.isEquivalence
              ; βˆ™-cong = congβ‚‚ _+_
              }
            ; assoc = Ξ» where
                𝟘 _ _ β†’ refl
                πŸ™ 𝟘 _ β†’ refl
                πŸ™ πŸ™ 𝟘 β†’ refl
                πŸ™ πŸ™ πŸ™ β†’ refl
                πŸ™ πŸ™ Ο‰ β†’ refl
                πŸ™ Ο‰ _ β†’ refl
                Ο‰ _ _ β†’ refl
            }
          ; identity =
                (Ξ» _ β†’ refl)
              , comm∧idΛ‘β‡’idΚ³ +-comm (Ξ» _ β†’ refl)
          }
        ; comm = +-comm
        }
        ; *-cong = congβ‚‚ _Β·_
        ; *-assoc = Ξ» where
              𝟘 _ _ β†’ refl
              πŸ™ 𝟘 _ β†’ refl
              πŸ™ πŸ™ 𝟘 β†’ refl
              πŸ™ πŸ™ πŸ™ β†’ refl
              πŸ™ πŸ™ Ο‰ β†’ refl
              πŸ™ Ο‰ 𝟘 β†’ refl
              πŸ™ Ο‰ πŸ™ β†’ refl
              πŸ™ Ο‰ Ο‰ β†’ refl
              Ο‰ 𝟘 _ β†’ refl
              Ο‰ πŸ™ 𝟘 β†’ refl
              Ο‰ πŸ™ πŸ™ β†’ refl
              Ο‰ πŸ™ Ο‰ β†’ refl
              Ο‰ Ο‰ 𝟘 β†’ refl
              Ο‰ Ο‰ πŸ™ β†’ refl
              Ο‰ Ο‰ Ο‰ β†’ refl
        ; *-identity =
                Β·-identityΛ‘
              , comm∧idΛ‘β‡’idΚ³ Β·-comm Β·-identityΛ‘
      ; distrib =
            Β·-distrib-+Λ‘
          , comm∧distrΛ‘β‡’distrΚ³ Β·-comm Β·-distrib-+Λ‘
      }
    ; zero =
          (Ξ» _ β†’ refl)
        , comm∧zeΛ‘β‡’zeΚ³ Β·-comm (Ξ» _ β†’ refl)
    }
  ; ∧-Semilattice = record
    { isBand = record
      { isSemigroup = record
        { isMagma = record
          { isEquivalence = PE.isEquivalence
          ; βˆ™-cong        = congβ‚‚ _∧_
          }
        ; assoc = Ξ» where
            𝟘 𝟘 𝟘 β†’ refl
            𝟘 𝟘 πŸ™ β†’
              πŸ˜βˆ§πŸ™      β‰‘Λ˜βŸ¨ 𝟘∧[πŸ˜βˆ§πŸ™] ⟩
              𝟘 ∧ πŸ˜βˆ§πŸ™  ∎
            𝟘 𝟘 Ο‰ β†’ refl
            𝟘 πŸ™ 𝟘 β†’
              πŸ˜βˆ§πŸ™ ∧ 𝟘  β‰‘βŸ¨βŸ©
              πŸ˜βˆ§πŸ™ ∧ 𝟘  β‰‘βŸ¨ ∧-comm πŸ˜βˆ§πŸ™ _ ⟩
              𝟘 ∧ πŸ˜βˆ§πŸ™  ∎
            𝟘 πŸ™ πŸ™ β†’
              πŸ˜βˆ§πŸ™ ∧ πŸ™  β‰‘βŸ¨ ∧-comm πŸ˜βˆ§πŸ™ _ ⟩
              πŸ™ ∧ πŸ˜βˆ§πŸ™  β‰‘βŸ¨ πŸ™βˆ§[πŸ˜βˆ§πŸ™] ⟩
              πŸ˜βˆ§πŸ™      ∎
            𝟘 πŸ™ Ο‰ β†’
              πŸ˜βˆ§πŸ™ ∧ Ο‰  β‰‘βŸ¨ ∧-comm πŸ˜βˆ§πŸ™ _ ⟩
              Ο‰ ∧ πŸ˜βˆ§πŸ™  β‰‘βŸ¨βŸ©
              Ο‰        ∎
            𝟘 Ο‰ _ β†’ refl
            πŸ™ 𝟘 𝟘 β†’
              πŸ˜βˆ§πŸ™ ∧ 𝟘  β‰‘βŸ¨ ∧-comm πŸ˜βˆ§πŸ™ _ ⟩
              𝟘 ∧ πŸ˜βˆ§πŸ™  β‰‘βŸ¨ 𝟘∧[πŸ˜βˆ§πŸ™] ⟩
              πŸ˜βˆ§πŸ™      ∎
            πŸ™ 𝟘 πŸ™ β†’
              πŸ˜βˆ§πŸ™ ∧ πŸ™  β‰‘βŸ¨βŸ©
              πŸ˜βˆ§πŸ™ ∧ πŸ™  β‰‘βŸ¨ ∧-comm πŸ˜βˆ§πŸ™ _ ⟩
              πŸ™ ∧ πŸ˜βˆ§πŸ™  ∎
            πŸ™ 𝟘 Ο‰ β†’
              πŸ˜βˆ§πŸ™ ∧ Ο‰  β‰‘βŸ¨ ∧-comm πŸ˜βˆ§πŸ™ _ ⟩
              Ο‰ ∧ πŸ˜βˆ§πŸ™  β‰‘βŸ¨βŸ©
              Ο‰        ∎
            πŸ™ πŸ™ 𝟘 β†’
              πŸ˜βˆ§πŸ™      β‰‘Λ˜βŸ¨ πŸ™βˆ§[πŸ˜βˆ§πŸ™] ⟩
              πŸ™ ∧ πŸ˜βˆ§πŸ™  ∎
            πŸ™ πŸ™ πŸ™ β†’ refl
            πŸ™ πŸ™ Ο‰ β†’ refl
            πŸ™ Ο‰ _ β†’ refl
            Ο‰ _ _ β†’ refl
        }
      ; idem = Ξ» where
          𝟘 β†’ refl
          πŸ™ β†’ refl
          Ο‰ β†’ refl
      }
    ; comm = ∧-comm
    }
  ; ·-distrib-∧ =
        ·-distrib-∧ˑ
      , comm∧distrΛ‘β‡’distrΚ³ Β·-comm Β·-distrib-∧ˑ
  ; +-distrib-∧ =
        +-distrib-∧ˑ
      , comm∧distrΛ‘β‡’distrΚ³ +-comm +-distrib-∧ˑ
  }
  where
  open Tools.Reasoning.PropositionalEquality

  +-comm : Commutative _+_
  +-comm = Ξ» where
    𝟘 𝟘 β†’ refl
    𝟘 πŸ™ β†’ refl
    𝟘 Ο‰ β†’ refl
    πŸ™ 𝟘 β†’ refl
    πŸ™ πŸ™ β†’ refl
    πŸ™ Ο‰ β†’ refl
    Ο‰ 𝟘 β†’ refl
    Ο‰ πŸ™ β†’ refl
    Ο‰ Ο‰ β†’ refl

  Β·-identityΛ‘ : LeftIdentity πŸ™ _Β·_
  Β·-identityΛ‘ = Ξ» where
    𝟘 β†’ refl
    πŸ™ β†’ refl
    Ο‰ β†’ refl

  Β·-distrib-+Λ‘ : _Β·_ DistributesOverΛ‘ _+_
  Β·-distrib-+Λ‘ = Ξ» where
    𝟘 _ _ β†’ refl
    πŸ™ 𝟘 _ β†’ refl
    πŸ™ πŸ™ 𝟘 β†’ refl
    πŸ™ πŸ™ πŸ™ β†’ refl
    πŸ™ πŸ™ Ο‰ β†’ refl
    πŸ™ Ο‰ _ β†’ refl
    Ο‰ 𝟘 _ β†’ refl
    Ο‰ πŸ™ 𝟘 β†’ refl
    Ο‰ πŸ™ πŸ™ β†’ refl
    Ο‰ πŸ™ Ο‰ β†’ refl
    Ο‰ Ο‰ _ β†’ refl

  ∧-comm : Commutative _∧_
  ∧-comm = λ where
    𝟘 𝟘 β†’ refl
    𝟘 πŸ™ β†’ refl
    𝟘 Ο‰ β†’ refl
    πŸ™ 𝟘 β†’ refl
    πŸ™ πŸ™ β†’ refl
    πŸ™ Ο‰ β†’ refl
    Ο‰ 𝟘 β†’ refl
    Ο‰ πŸ™ β†’ refl
    Ο‰ Ο‰ β†’ refl

  ·-distrib-∧ˑ : _·_ DistributesOverˑ _∧_
  ·-distrib-∧ˑ = λ where
    𝟘 _ _ β†’ refl
    πŸ™ 𝟘 𝟘 β†’ refl
    πŸ™ 𝟘 πŸ™ β†’
      πŸ™ Β· πŸ˜βˆ§πŸ™  β‰‘βŸ¨ Β·-identityΛ‘ _ ⟩
      πŸ˜βˆ§πŸ™      ∎
    πŸ™ 𝟘 Ο‰ β†’ refl
    πŸ™ πŸ™ 𝟘 β†’
      πŸ™ Β· πŸ˜βˆ§πŸ™  β‰‘βŸ¨ Β·-identityΛ‘ _ ⟩
      πŸ˜βˆ§πŸ™      ∎
    πŸ™ πŸ™ πŸ™ β†’ refl
    πŸ™ πŸ™ Ο‰ β†’ refl
    πŸ™ Ο‰ _ β†’ refl
    Ο‰ 𝟘 𝟘 β†’ refl
    Ο‰ 𝟘 πŸ™ β†’
      Ο‰ Β· πŸ˜βˆ§πŸ™  β‰‘βŸ¨ Ο‰Β·β‰’πŸ˜ πŸ˜βˆ§πŸ™β‰’πŸ˜ ⟩
      Ο‰        ∎
    Ο‰ 𝟘 Ο‰ β†’ refl
    Ο‰ πŸ™ 𝟘 β†’
      Ο‰ Β· πŸ˜βˆ§πŸ™  β‰‘βŸ¨ Ο‰Β·β‰’πŸ˜ πŸ˜βˆ§πŸ™β‰’πŸ˜ ⟩
      Ο‰        ∎
    Ο‰ πŸ™ πŸ™ β†’ refl
    Ο‰ πŸ™ Ο‰ β†’ refl
    Ο‰ Ο‰ _ β†’ refl

  +-distrib-∧ˑ : _+_ DistributesOverˑ _∧_
  +-distrib-∧ˑ = λ where
    𝟘 _ _ β†’ refl
    πŸ™ 𝟘 𝟘 β†’ refl
    πŸ™ 𝟘 πŸ™ β†’
      πŸ™ + πŸ˜βˆ§πŸ™  β‰‘βŸ¨ β‰’πŸ˜+β‰’πŸ˜ (Ξ» ()) πŸ˜βˆ§πŸ™β‰’πŸ˜ ⟩
      Ο‰        ∎
    πŸ™ 𝟘 Ο‰ β†’ refl
    πŸ™ πŸ™ 𝟘 β†’
      πŸ™ + πŸ˜βˆ§πŸ™  β‰‘βŸ¨ β‰’πŸ˜+β‰’πŸ˜ (Ξ» ()) πŸ˜βˆ§πŸ™β‰’πŸ˜ ⟩
      Ο‰        ∎
    πŸ™ πŸ™ πŸ™ β†’ refl
    πŸ™ πŸ™ Ο‰ β†’ refl
    πŸ™ Ο‰ _ β†’ refl
    Ο‰ _ _ β†’ refl

instance

  zero-one-many-has-well-behaved-zero :
    Has-well-behaved-zero zero-one-many-semiring-with-meet
  zero-one-many-has-well-behaved-zero = record
    { non-trivial = Ξ» ()
    ; zero-product =  Ξ» where
        {p = 𝟘} _ β†’ inj₁ refl
        {q = 𝟘} _ β†’ injβ‚‚ refl
    ; +-positiveΛ‘ =  Ξ» where
        {p = 𝟘} {q = 𝟘} _  β†’ refl
        {p = 𝟘} {q = πŸ™} ()
        {p = 𝟘} {q = Ο‰} ()
    ; ∧-positiveˑ = λ where
        {p = 𝟘} {q = 𝟘} _     β†’ refl
        {p = 𝟘} {q = πŸ™} _     β†’ refl
        {p = πŸ™} {q = 𝟘} πŸ˜βˆ§πŸ™β‰‘πŸ˜ β†’
          βŠ₯-elim (
            case
              πŸ™  β‰‘βŸ¨ 𝟘-maximal (sym πŸ˜βˆ§πŸ™β‰‘πŸ˜) ⟩
              𝟘  ∎
            of Ξ» ())
    }
    where open Tools.Reasoning.PropositionalEquality

------------------------------------------------------------------------
-- Star

-- Some requirements of a star operation and a meet operation.

Star-requirements :
  (Zero-one-many β†’ Zero-one-many β†’ Zero-one-many β†’ Zero-one-many) β†’
  (Zero-one-many β†’ Zero-one-many β†’ Zero-one-many) β†’
  Set
Star-requirements _βŠ›_β–·_ _∧_ =
  let _≀_ : Zero-one-many β†’ Zero-one-many β†’ Set
      p ≀ q = p ≑ (p ∧ q)
  in
  (βˆ€ {q r} β†’                     (Ο‰ βŠ› q β–· r) ≑ Ο‰) Γ—
  (βˆ€ {p r} β†’                     (p βŠ› Ο‰ β–· r) ≑ Ο‰) Γ—
  (βˆ€ {p q} β†’ Β¬ (p ≑ 𝟘 Γ— q ≑ 𝟘) β†’ (p βŠ› q β–· Ο‰) ≑ Ο‰) Γ—
  (βˆ€ {r} β†’                       (𝟘 βŠ› 𝟘 β–· r) ≑ 𝟘) Γ—
  (βˆ€ {p} β†’                       (p βŠ› πŸ™ β–· πŸ™) ≑ Ο‰) Γ—
                                ((𝟘 βŠ› πŸ™ β–· 𝟘) ≀ (𝟘 ∧ πŸ™)) Γ—
                                ((πŸ™ βŠ› 𝟘 β–· 𝟘) ≀ (𝟘 ∧ πŸ™)) Γ—
                                ((πŸ™ βŠ› 𝟘 β–· πŸ™) ≀ πŸ™) Γ—
                                ((πŸ™ βŠ› πŸ™ β–· 𝟘) ≀ πŸ™)

-- A star operation for a Semiring-with-meet for Zero-one-many for
-- which the zero is 𝟘, the one is πŸ™, addition is _+_, multiplication
-- is _·_, and the meet operation is _∧_ has to satisfy the
-- Star-requirements (for _∧_) if certain conditions are satisfied.

Star-requirements-requiredβ€² :
  (M : Semiring-with-meet) β†’
  Semiring-with-meet.𝟘   M ≑ 𝟘 β†’
  Semiring-with-meet.πŸ™   M ≑ πŸ™ β†’
  Semiring-with-meet._+_ M ≑ _+_ β†’
  Semiring-with-meet._Β·_ M ≑ _Β·_ β†’
  Semiring-with-meet._∧_ M ≑ _∧_ β†’
  (_βŠ›_β–·_ :
   Zero-one-many β†’ Zero-one-many β†’ Zero-one-many β†’ Zero-one-many) β†’
  (βˆ€ p q r β†’ (p βŠ› q β–· r) ≀ q + r Β· (p βŠ› q β–· r)) β†’
  (βˆ€ p q r β†’ (p βŠ› q β–· r) ≀ p) β†’
  (βˆ€ r β†’ _Β·_ SubDistributesOverΚ³ (_βŠ›_β–· r) by _≀_) β†’
  Star-requirements _βŠ›_β–·_ _∧_
Star-requirements-requiredβ€²
  M refl refl refl refl refl star βŠ›-ineq₁ βŠ›-ineqβ‚‚ Β·-sub-distribΚ³-βŠ› =
  case Meet-requirements-required M refl refl πŸ˜βˆ§πŸ™β‰’πŸ˜ ω≀ of Ξ» where
    (_ , _ , Ο‰βŠ“Ο‰β‰‘Ο‰ , _ , Ο‰βŠ“πŸ˜β‰‘Ο‰ , _ , Ο‰βŠ“πŸ™β‰‘Ο‰ , _ , _) β†’
        (Ξ» {_ _} β†’ Ο‰βŠ›β–·)
      , (Ξ» {_ _} β†’ βŠ›Ο‰β–·)
      , (Ξ» {_ _} β†’ βŠ›β–·Ο‰ _ _)
      , (Ξ» {r = r} β†’ ≀-antisym
           (begin
              𝟘 βŠ› 𝟘 β–· r  β‰€βŸ¨ βŠ›-ineqβ‚‚ _ _ _ ⟩
              𝟘          ∎)
           (begin
              𝟘              β‰‘Λ˜βŸ¨ Β·-zeroΚ³ _ ⟩
              𝟘 βŠ› 𝟘 β–· r Β· 𝟘  β‰€βŸ¨ Β·-sub-distribΚ³-βŠ› _ _ _ _ ⟩
              𝟘 βŠ› 𝟘 β–· r      ∎))
      , (Ξ» {p = p} β†’ ≀-antisym
           (begin
              p βŠ› πŸ™ β–· πŸ™          β‰€βŸ¨ βŠ›-ineq₁ _ _ _ ⟩
              πŸ™ + πŸ™ Β· p βŠ› πŸ™ β–· πŸ™  β‰ˆβŸ¨ β‰’πŸ˜+β‰’πŸ˜ (Ξ» ()) (πŸ™Β·β‰’πŸ˜ βŠ›πŸ™β–·) ⟩
              Ο‰                  ∎)
           (ω≀ (p βŠ› πŸ™ β–· πŸ™)))
      , ∧-greatest-lower-bound
          (βŠ›-ineqβ‚‚ _ _ _)
          (begin
             𝟘 βŠ› πŸ™ β–· 𝟘          β‰€βŸ¨ βŠ›-ineq₁ _ _ _ ⟩
             πŸ™ + 𝟘 Β· 𝟘 βŠ› πŸ™ β–· 𝟘  β‰‘βŸ¨βŸ©
             πŸ™                  ∎)
      , ∧-greatest-lower-bound
          (begin
             πŸ™ βŠ› 𝟘 β–· 𝟘          β‰€βŸ¨ βŠ›-ineq₁ _ _ _ ⟩
             𝟘 + 𝟘 Β· πŸ™ βŠ› 𝟘 β–· 𝟘  β‰‘βŸ¨βŸ©
             𝟘                  ∎)
          (βŠ›-ineqβ‚‚ _ _ _)
      , βŠ›-ineqβ‚‚ _ _ _
      , βŠ›-ineqβ‚‚ _ _ _
  where
  open Semiring-with-meet M hiding (𝟘; πŸ™; Ο‰; _+_; _Β·_; _∧_; _≀_)
  open PartialOrder M
  open Meet M
  open Tools.Reasoning.PartialOrder ≀-poset

  infix 50 _βŠ›_β–·_

  _βŠ›_β–·_ : Zero-one-many β†’ Zero-one-many β†’ Zero-one-many β†’ Zero-one-many
  _βŠ›_β–·_ = star

  Ο‰βŠ›β–· : Ο‰ βŠ› q β–· r ≑ Ο‰
  Ο‰βŠ›β–· {q = q} {r = r} = ≀-antisym
    (begin
       Ο‰ βŠ› q β–· r  β‰€βŸ¨ βŠ›-ineqβ‚‚ _ _ _ ⟩
       Ο‰          ∎)
    (ω≀ (Ο‰ βŠ› q β–· r))

  βŠ›Ο‰β–· : p βŠ› Ο‰ β–· r ≑ Ο‰
  βŠ›Ο‰β–· {p = p} {r = r} = ≀-antisym
    (begin
       p βŠ› Ο‰ β–· r          β‰€βŸ¨ βŠ›-ineq₁ _ _ _ ⟩
       Ο‰ + r Β· p βŠ› Ο‰ β–· r  β‰‘βŸ¨βŸ©
       Ο‰                  ∎)
    (ω≀ (p βŠ› Ο‰ β–· r))

  πŸ™βŠ›β–· : πŸ™ βŠ› q β–· r β‰’ 𝟘
  πŸ™βŠ›β–· {q = q} {r = r} πŸ™βŠ›β–·β‰‘πŸ˜ =
    case begin
      𝟘              β‰‘βŸ¨βŸ©
      𝟘 Β· Ο‰          β‰‘Λ˜βŸ¨ Β·-congΚ³ πŸ™βŠ›β–·β‰‘πŸ˜ ⟩
      πŸ™ βŠ› q β–· r Β· Ο‰  β‰€βŸ¨ Β·-sub-distribΚ³-βŠ› _ _ _ _ ⟩
      Ο‰ βŠ› q Β· Ο‰ β–· r  β‰‘βŸ¨ Ο‰βŠ›β–· ⟩
      Ο‰              ∎
    of Ξ» ()

  βŠ›πŸ™β–· : p βŠ› πŸ™ β–· r β‰’ 𝟘
  βŠ›πŸ™β–· {p = p} {r = r} βŠ›πŸ™β–·β‰‘πŸ˜ =
    case begin
      𝟘                β‰‘βŸ¨βŸ©
      𝟘 Β· Ο‰            β‰‘Λ˜βŸ¨ Β·-congΚ³ βŠ›πŸ™β–·β‰‘πŸ˜ ⟩
      p βŠ› πŸ™ β–· r Β· Ο‰    β‰€βŸ¨ Β·-sub-distribΚ³-βŠ› _ _ _ _ ⟩
      (p Β· Ο‰) βŠ› Ο‰ β–· r  β‰‘βŸ¨ βŠ›Ο‰β–· ⟩
      Ο‰                ∎
    of Ξ» ()

  βŠ›β–·Ο‰ : βˆ€ p q β†’ Β¬ (p ≑ 𝟘 Γ— q ≑ 𝟘) β†’ (p βŠ› q β–· Ο‰) ≑ Ο‰
  βŠ›β–·Ο‰ _ Ο‰ _      = βŠ›Ο‰β–·
  βŠ›β–·Ο‰ Ο‰ _ _      = Ο‰βŠ›β–·
  βŠ›β–·Ο‰ 𝟘 𝟘 Β¬β‰‘πŸ˜Γ—β‰‘πŸ˜ = βŠ₯-elim (Β¬β‰‘πŸ˜Γ—β‰‘πŸ˜ (refl , refl))
  βŠ›β–·Ο‰ p πŸ™ _      = ≀-antisym
    (begin
       p βŠ› πŸ™ β–· Ο‰          β‰€βŸ¨ βŠ›-ineq₁ _ _ _ ⟩
       πŸ™ + Ο‰ Β· p βŠ› πŸ™ β–· Ο‰  β‰ˆβŸ¨ +-congΛ‘ (Ο‰Β·β‰’πŸ˜ βŠ›πŸ™β–·) ⟩
       πŸ™ + Ο‰              β‰‘βŸ¨βŸ©
       Ο‰                  ∎)
    (ω≀ (p βŠ› πŸ™ β–· Ο‰))
  βŠ›β–·Ο‰ πŸ™ 𝟘 _ = ≀-antisym
    (begin
       πŸ™ βŠ› 𝟘 β–· Ο‰      β‰€βŸ¨ βŠ›-ineq₁ _ _ _ ⟩
       Ο‰ Β· πŸ™ βŠ› 𝟘 β–· Ο‰  β‰ˆβŸ¨ Ο‰Β·β‰’πŸ˜ πŸ™βŠ›β–· ⟩
       Ο‰              ∎)
    (ω≀ (πŸ™ βŠ› 𝟘 β–· Ο‰))

-- Every natrec-star operator for zero-one-many-semiring-with-meet has
-- to satisfy the Star-requirements (for _∧_).

Star-requirements-required :
  (has-star : Has-star zero-one-many-semiring-with-meet) β†’
  Star-requirements (Has-star._βŠ›_β–·_ has-star) _∧_
Star-requirements-required has-star =
  Star-requirements-requiredβ€²
    zero-one-many-semiring-with-meet refl refl refl refl refl
    _βŠ›_β–·_
    βŠ›-ineq₁
    βŠ›-ineqβ‚‚
    Β·-sub-distribΚ³-βŠ›
  where
  open Has-star has-star

------------------------------------------------------------------------
-- One variant of the modality

-- A natrec-star operator defined using the construction in
-- Graded.Modality.Instances.LowerBounded.

zero-one-many-lower-bounded-star :
  Has-star zero-one-many-semiring-with-meet
zero-one-many-lower-bounded-star =
  LowerBounded.has-star zero-one-many-semiring-with-meet Ο‰ ω≀

-- With this definition the result of pΒ βŠ›Β qΒ β–·Β r is 𝟘 when p and q are
-- 𝟘, and Ο‰ otherwise.

zero-one-many-lower-bounded-βŠ› :
  let open Has-star zero-one-many-lower-bounded-star in
  (βˆ€ r β†’ 𝟘 βŠ› 𝟘 β–· r ≑ 𝟘) Γ—
  (βˆ€ p q r β†’ Β¬ (p ≑ 𝟘 Γ— q ≑ 𝟘) β†’ p βŠ› q β–· r ≑ Ο‰)
zero-one-many-lower-bounded-βŠ› =
    (Ξ» _ β†’ refl)
  , (Ξ» where
       𝟘 𝟘 _ Β¬β‰‘πŸ˜Γ—β‰‘πŸ˜ β†’ βŠ₯-elim (Β¬β‰‘πŸ˜Γ—β‰‘πŸ˜ (refl , refl))
       𝟘 πŸ™ _ _      β†’
         Ο‰ Β· πŸ˜βˆ§πŸ™  β‰‘βŸ¨ Ο‰Β·β‰’πŸ˜ πŸ˜βˆ§πŸ™β‰’πŸ˜ ⟩
         Ο‰        ∎
       𝟘 Ο‰ _ _ β†’ refl
       πŸ™ 𝟘 _ _ β†’
         Ο‰ Β· πŸ˜βˆ§πŸ™  β‰‘βŸ¨ Ο‰Β·β‰’πŸ˜ πŸ˜βˆ§πŸ™β‰’πŸ˜ ⟩
         Ο‰        ∎
       πŸ™ πŸ™ _ _ β†’ refl
       πŸ™ Ο‰ _ _ β†’ refl
       Ο‰ _ _ _ β†’ refl)
  where
  open Has-star zero-one-many-lower-bounded-star
  open Tools.Reasoning.PropositionalEquality

-- A zero-one-many modality. The dedicated nr function, if any, is
-- defined using the construction in
-- Graded.Modality.Instances.LowerBounded.

zero-one-many-lower-bounded : Modality-variant β†’ Modality
zero-one-many-lower-bounded variant = LowerBounded.isModality
  zero-one-many-semiring-with-meet Ο‰ ω≀
  variant
  (Ξ» _ β†’ zero-one-many-has-well-behaved-zero)

------------------------------------------------------------------------
-- A variant of the modality with a "greatest" star operation

-- A "greatest" definition of the star operation.

infix 50 _βŠ›_β–·_

_βŠ›_β–·_ : Zero-one-many β†’ Zero-one-many β†’ Zero-one-many β†’ Zero-one-many
p βŠ› q β–· 𝟘 = p ∧ q
p βŠ› q β–· πŸ™ = p + Ο‰ Β· q
p βŠ› q β–· Ο‰ = Ο‰ Β· (p ∧ q)

-- This definition is not equal to the one obtained from
-- zero-one-many-lower-bounded-star.

lower-bounded≒greatest :
  Has-star._βŠ›_β–·_ zero-one-many-lower-bounded-star β‰’ _βŠ›_β–·_
lower-bounded≒greatest hyp =
  case cong (Ξ» f β†’ f πŸ™ πŸ™ 𝟘) hyp of Ξ» ()

-- A simplification lemma for the star operation.

Ο‰βŠ›β–· : βˆ€ r β†’ Ο‰ βŠ› q β–· r ≑ Ο‰
Ο‰βŠ›β–· 𝟘 = refl
Ο‰βŠ›β–· πŸ™ = refl
Ο‰βŠ›β–· Ο‰ = refl

-- A simplification lemma for the star operation.

βŠ›Ο‰β–· : βˆ€ r β†’ p βŠ› Ο‰ β–· r ≑ Ο‰
βŠ›Ο‰β–· {p = p} = Ξ» where
    𝟘 β†’
      p ∧ Ο‰  β‰‘βŸ¨ M.∧-comm p _ ⟩
      Ο‰ ∧ p  β‰‘βŸ¨βŸ©
      Ο‰      ∎
    πŸ™ β†’
      p + Ο‰  β‰‘βŸ¨ M.+-comm p _ ⟩
      Ο‰ + p  β‰‘βŸ¨βŸ©
      Ο‰      ∎
    Ο‰ β†’
      Ο‰ Β· (p ∧ Ο‰)  β‰‘βŸ¨ cong (_ Β·_) (M.∧-comm p _) ⟩
      Ο‰ Β· (Ο‰ ∧ p)  β‰‘βŸ¨βŸ©
      Ο‰            ∎
  where
  open Tools.Reasoning.PropositionalEquality
  module M = Semiring-with-meet zero-one-many-semiring-with-meet

-- A simplification lemma for the star operation.

πŸ˜βŠ›πŸ˜β–· : βˆ€ r β†’ 𝟘 βŠ› 𝟘 β–· r ≑ 𝟘
πŸ˜βŠ›πŸ˜β–· 𝟘 = refl
πŸ˜βŠ›πŸ˜β–· πŸ™ = refl
πŸ˜βŠ›πŸ˜β–· Ο‰ = refl

-- A simplification lemma for the star operation.

βŠ›β–·Ο‰ : βˆ€ p q β†’ Β¬ (p ≑ 𝟘 Γ— q ≑ 𝟘) β†’ (p βŠ› q β–· Ο‰) ≑ Ο‰
βŠ›β–·Ο‰ p Ο‰ _      = βŠ›Ο‰β–· {p = p} Ο‰
βŠ›β–·Ο‰ Ο‰ _ _      = refl
βŠ›β–·Ο‰ 𝟘 𝟘 Β¬β‰‘πŸ˜Γ—β‰‘πŸ˜ = βŠ₯-elim (Β¬β‰‘πŸ˜Γ—β‰‘πŸ˜ (refl , refl))
βŠ›β–·Ο‰ 𝟘 πŸ™ _      = Ο‰Β·β‰’πŸ˜ πŸ˜βˆ§πŸ™β‰’πŸ˜
βŠ›β–·Ο‰ πŸ™ πŸ™ _      = refl
βŠ›β–·Ο‰ πŸ™ 𝟘 _      = Ο‰Β·β‰’πŸ˜ πŸ˜βˆ§πŸ™β‰’πŸ˜

-- A simplification lemma for the star operation.

βŠ›πŸ™β–·πŸ™ : βˆ€ p β†’ p βŠ› πŸ™ β–· πŸ™ ≑ Ο‰
βŠ›πŸ™β–·πŸ™ 𝟘 = refl
βŠ›πŸ™β–·πŸ™ πŸ™ = refl
βŠ›πŸ™β–·πŸ™ Ο‰ = refl

-- A simplification lemma for the star operation.

βŠ›πŸ˜βˆ§πŸ™β–·πŸ™ : βˆ€ p β†’ p βŠ› πŸ˜βˆ§πŸ™ β–· πŸ™ ≑ Ο‰
βŠ›πŸ˜βˆ§πŸ™β–·πŸ™ 𝟘 = πŸ˜βˆ§πŸ™-elim (Ξ» q β†’ 𝟘 βŠ› q β–· πŸ™ ≑ Ο‰) (Ξ» _ β†’ refl) (Ξ» _ β†’ refl)
βŠ›πŸ˜βˆ§πŸ™β–·πŸ™ πŸ™ = πŸ˜βˆ§πŸ™-elim (Ξ» q β†’ πŸ™ βŠ› q β–· πŸ™ ≑ Ο‰) (Ξ» _ β†’ refl) (Ξ» _ β†’ refl)
βŠ›πŸ˜βˆ§πŸ™β–·πŸ™ Ο‰ = refl

-- A simplification lemma for the star operation.

πŸ˜βŠ›πŸ˜βˆ§πŸ™β–·πŸ˜ : 𝟘 βŠ› πŸ˜βˆ§πŸ™ β–· 𝟘 ≑ πŸ˜βˆ§πŸ™
πŸ˜βŠ›πŸ˜βˆ§πŸ™β–·πŸ˜ = πŸ˜βˆ§πŸ™-elim
  (Ξ» q β†’ 𝟘 βŠ› q β–· 𝟘 ≑ q)
  (Ξ» πŸ˜βˆ§πŸ™β‰‘πŸ™ β†’ πŸ˜βˆ§πŸ™β‰‘πŸ™)
  (Ξ» _ β†’ refl)

-- A simplification lemma for the star operation.

πŸ™βŠ›πŸ˜βˆ§πŸ™β–·πŸ˜ : πŸ™ βŠ› πŸ˜βˆ§πŸ™ β–· 𝟘 ≑ πŸ˜βˆ§πŸ™
πŸ™βŠ›πŸ˜βˆ§πŸ™β–·πŸ˜ = πŸ˜βˆ§πŸ™-elim
  (Ξ» q β†’ πŸ™ βŠ› q β–· 𝟘 ≑ q)
  (Ξ» _ β†’ refl)
  (Ξ» _ β†’ refl)

-- The natrec-star operator returns results that are at least as large
-- as those of any other natrec-star operator for
-- zero-one-many-semiring-with-meet.

βŠ›-greatest :
  (has-star : Has-star zero-one-many-semiring-with-meet) β†’
  βˆ€ p q r β†’ Has-star._βŠ›_β–·_ has-star p q r ≀ p βŠ› q β–· r
βŠ›-greatest has-star =
  case Star-requirements-required has-star of Ξ» where
    (Ο‰βŠ›β–·β€² , βŠ›Ο‰β–·β€² , βŠ›β–·β€²Ο‰ ,
     πŸ˜βŠ›πŸ˜β–·β€² , βŠ›πŸ™β–·β€²πŸ™ , πŸ˜βŠ›πŸ™β–·β€²πŸ˜ , πŸ™βŠ›πŸ˜β–·β€²πŸ˜ , πŸ™βŠ›πŸ˜β–·β€²πŸ™ , πŸ™βŠ›πŸ™β–·β€²πŸ˜) β†’ Ξ» where
      Ο‰ q r β†’ begin
        Ο‰ βŠ› q β–·β€² r  β‰ˆβŸ¨ Ο‰βŠ›β–·β€² ⟩
        Ο‰           β‰ˆΛ˜βŸ¨ Ο‰βŠ›β–· r ⟩
        Ο‰ βŠ› q β–· r   ∎
      p Ο‰ r β†’ begin
        p βŠ› Ο‰ β–·β€² r  β‰ˆβŸ¨ βŠ›Ο‰β–·β€² ⟩
        Ο‰           β‰ˆΛ˜βŸ¨ βŠ›Ο‰β–· r ⟩
        p βŠ› Ο‰ β–· r   ∎
      𝟘 𝟘 r β†’ begin
        𝟘 βŠ› 𝟘 β–·β€² r  β‰ˆβŸ¨ πŸ˜βŠ›πŸ˜β–·β€² ⟩
        𝟘           β‰ˆΛ˜βŸ¨ πŸ˜βŠ›πŸ˜β–· r ⟩
        𝟘 βŠ› 𝟘 β–· r   ∎
      𝟘 πŸ™ Ο‰ β†’ begin
        𝟘 βŠ› πŸ™ β–·β€² Ο‰  β‰ˆβŸ¨ βŠ›β–·β€²Ο‰ (Ξ» { (_ , ()) }) ⟩
        Ο‰           β‰ˆΛ˜βŸ¨ βŠ›β–·Ο‰ 𝟘 πŸ™ (Ξ» { (_ , ()) }) ⟩
        𝟘 βŠ› πŸ™ β–· Ο‰   ∎
      πŸ™ q Ο‰ β†’ begin
        πŸ™ βŠ› q β–·β€² Ο‰  β‰ˆβŸ¨ βŠ›β–·β€²Ο‰ (Ξ» { (() , _) }) ⟩
        Ο‰           β‰ˆΛ˜βŸ¨ βŠ›β–·Ο‰ πŸ™ q (Ξ» { (() , _) }) ⟩
        πŸ™ βŠ› q β–· Ο‰   ∎
      p πŸ™ πŸ™ β†’ begin
        p βŠ› πŸ™ β–·β€² πŸ™  β‰ˆβŸ¨ βŠ›πŸ™β–·β€²πŸ™ ⟩
        Ο‰           β‰ˆΛ˜βŸ¨ βŠ›πŸ™β–·πŸ™ p ⟩
        p βŠ› πŸ™ β–· πŸ™   ∎
      𝟘 πŸ™ 𝟘 β†’ begin
        𝟘 βŠ› πŸ™ β–·β€² 𝟘  β‰€βŸ¨ πŸ˜βŠ›πŸ™β–·β€²πŸ˜ ⟩
        𝟘 ∧ πŸ™       ∎
      πŸ™ 𝟘 𝟘 β†’ begin
        πŸ™ βŠ› 𝟘 β–·β€² 𝟘  β‰€βŸ¨ πŸ™βŠ›πŸ˜β–·β€²πŸ˜ ⟩
        𝟘 ∧ πŸ™       ∎
      πŸ™ 𝟘 πŸ™ β†’ begin
        πŸ™ βŠ› 𝟘 β–·β€² πŸ™  β‰€βŸ¨ πŸ™βŠ›πŸ˜β–·β€²πŸ™ ⟩
        πŸ™           ∎
      πŸ™ πŸ™ 𝟘 β†’ begin
        πŸ™ βŠ› πŸ™ β–·β€² 𝟘  β‰€βŸ¨ πŸ™βŠ›πŸ™β–·β€²πŸ˜ ⟩
        πŸ™           ∎
  where
  open Has-star has-star renaming (_βŠ›_β–·_ to _βŠ›_β–·β€²_)
  open PartialOrder zero-one-many-semiring-with-meet
  open Tools.Reasoning.PartialOrder ≀-poset

-- The "greatest" star operator defined above is a proper natrec-star
-- operator.

zero-one-many-greatest-star : Has-star zero-one-many-semiring-with-meet
zero-one-many-greatest-star = record
  { _βŠ›_β–·_                   = _βŠ›_β–·_
  ; βŠ›-ineq                  = βŠ›-ineq₁ , βŠ›-ineqβ‚‚
  ; +-sub-interchangeable-βŠ› = +-sub-interchangeable-βŠ›
  ; Β·-sub-distribΚ³-βŠ›        = Ξ» r _ _ _ β†’
                                ≀-reflexive (Β·-distribΚ³-βŠ› r _ _ _)
  ; βŠ›-sub-distrib-∧         = Ξ» r β†’
      (Ξ» _ _ _ β†’ ≀-reflexive (βŠ›-distribΛ‘-∧ r _ _ _))
    , (Ξ» _ _ _ β†’ ≀-reflexive (βŠ›-distribΚ³-∧ r _ _ _))
  }
  where
  semiring-with-meet = zero-one-many-semiring-with-meet

  open Semiring-with-meet semiring-with-meet
    hiding (𝟘; πŸ™; Ο‰; _+_; _Β·_; _∧_; _≀_)
  open PartialOrder semiring-with-meet
  open Addition semiring-with-meet
  open Meet semiring-with-meet
  open Multiplication semiring-with-meet

  βŠ›-ineq₁ : βˆ€ p q r β†’ p βŠ› q β–· r ≀ q + r Β· p βŠ› q β–· r
  βŠ›-ineq₁ p = Ξ» where
      q 𝟘 β†’ begin
        p ∧ q  β‰€βŸ¨ ∧-decreasingΚ³ p _ ⟩
        q      β‰ˆΛ˜βŸ¨ +-identityΚ³ _ ⟩
        q + 𝟘  ∎
      𝟘 πŸ™ β†’ begin
        p βŠ› 𝟘 β–· πŸ™      β‰ˆΛ˜βŸ¨ Β·-identityΛ‘ _ ⟩
        πŸ™ Β· p βŠ› 𝟘 β–· πŸ™  ∎
      πŸ™ πŸ™ β†’ begin
        p + Ο‰            β‰ˆβŸ¨ +-zeroΚ³ _ ⟩
        Ο‰                β‰‘βŸ¨βŸ©
        πŸ™ + πŸ™ Β· Ο‰        β‰ˆΛ˜βŸ¨ cong (Ξ» p β†’ πŸ™ + πŸ™ Β· p) (+-zeroΚ³ p) ⟩
        πŸ™ + πŸ™ Β· (p + Ο‰)  ∎
      Ο‰ πŸ™ β†’ begin
        p + Ο‰  β‰ˆβŸ¨ +-zeroΚ³ _ ⟩
        Ο‰      ∎
      𝟘 Ο‰ β†’ begin
        Ο‰ Β· (p ∧ 𝟘)        β‰‘βŸ¨βŸ©
        (Ο‰ Β· Ο‰) Β· (p ∧ 𝟘)  β‰ˆβŸ¨ Β·-assoc _ _ _ ⟩
        Ο‰ Β· Ο‰ Β· (p ∧ 𝟘)    ∎
      πŸ™ Ο‰ β†’ begin
        Ο‰ Β· (p ∧ πŸ™)          β‰ˆβŸ¨ Β·-distribΛ‘-∧ _ p _ ⟩
        Ο‰ Β· p ∧ Ο‰            β‰ˆβŸ¨ ∧-comm (Ο‰ Β· p) _ ⟩
        Ο‰ ∧ Ο‰ Β· p            β‰‘βŸ¨βŸ©
        Ο‰                    β‰‘βŸ¨βŸ©
        πŸ™ + Ο‰ Β· Ο‰            β‰ˆβŸ¨ cong (Ξ» p β†’ _ + Ο‰ Β· p) (∧-comm _ (Ο‰ Β· p)) ⟩
        πŸ™ + Ο‰ Β· (Ο‰ Β· p ∧ Ο‰)  β‰ˆΛ˜βŸ¨ cong (Ξ» p β†’ _ + Ο‰ Β· p) (Β·-distribΛ‘-∧ Ο‰ p _) ⟩
        πŸ™ + Ο‰ Β· Ο‰ Β· (p ∧ πŸ™)  ∎
      Ο‰ Ο‰ β†’ begin
        Ο‰ Β· (p ∧ Ο‰)  β‰ˆβŸ¨ Β·-distribΛ‘-∧ _ p _ ⟩
        Ο‰ Β· p ∧ Ο‰    β‰€βŸ¨ ∧-decreasingΚ³ (Ο‰ Β· p) _ ⟩
        Ο‰            ∎
    where
    open Tools.Reasoning.PartialOrder ≀-poset

  βŠ›-ineqβ‚‚ : βˆ€ p q r β†’ (p βŠ› q β–· r) ≀ p
  βŠ›-ineqβ‚‚ p = Ξ» where
      q 𝟘 β†’ begin
        p ∧ q  β‰€βŸ¨ ∧-decreasingΛ‘ p _ ⟩
        p      ∎
      𝟘 πŸ™ β†’ begin
        p + 𝟘  β‰ˆβŸ¨ +-identityΚ³ _ ⟩
        p      ∎
      πŸ™ πŸ™ β†’ begin
        p + Ο‰  β‰ˆβŸ¨ +-zeroΚ³ _ ⟩
        Ο‰      β‰€βŸ¨ ω≀ p ⟩
        p      ∎
      Ο‰ πŸ™ β†’ begin
        p + Ο‰  β‰ˆβŸ¨ +-zeroΚ³ _ ⟩
        Ο‰      β‰€βŸ¨ ω≀ p ⟩
        p      ∎
      q Ο‰ β†’ begin
        Ο‰ Β· (p ∧ q)    β‰ˆβŸ¨ Β·-distribΛ‘-∧ _ p _ ⟩
        Ο‰ Β· p ∧ Ο‰ Β· q  β‰€βŸ¨ ∧-decreasingΛ‘ (Ο‰ Β· p) _ ⟩
        Ο‰ Β· p          β‰€βŸ¨ Β·-monotoneΛ‘ (ω≀ πŸ™) ⟩
        πŸ™ Β· p          β‰ˆβŸ¨ Β·-identityΛ‘ _ ⟩
        p              ∎
    where
    open Tools.Reasoning.PartialOrder ≀-poset

  +-sub-interchangeable-βŠ› : βˆ€ r β†’ _+_ SubInterchangeable (_βŠ›_β–· r) by _≀_
  +-sub-interchangeable-βŠ› = Ξ» where
      𝟘 p q pβ€² qβ€² β†’ begin
        (p ∧ q) + (pβ€² ∧ qβ€²)  β‰€βŸ¨ +-sub-interchangeable-∧ p _ _ _ ⟩
        (p + pβ€²) ∧ (q + qβ€²)  ∎
      πŸ™ p q pβ€² qβ€² β†’ begin
        (p + Ο‰ Β· q) + (pβ€² + Ο‰ Β· qβ€²)  β‰ˆβŸ¨ +-assoc p _ _ ⟩
        p + (Ο‰ Β· q + (pβ€² + Ο‰ Β· qβ€²))  β‰ˆΛ˜βŸ¨ cong (p +_) (+-assoc (Ο‰ Β· q) _ _) ⟩
        p + ((Ο‰ Β· q + pβ€²) + Ο‰ Β· qβ€²)  β‰ˆβŸ¨ cong (Ξ» q β†’ p + (q + _)) (+-comm _ pβ€²) ⟩
        p + ((pβ€² + Ο‰ Β· q) + Ο‰ Β· qβ€²)  β‰ˆβŸ¨ cong (p +_) (+-assoc pβ€² _ _) ⟩
        p + (pβ€² + (Ο‰ Β· q + Ο‰ Β· qβ€²))  β‰ˆΛ˜βŸ¨ +-assoc p _ _ ⟩
        (p + pβ€²) + (Ο‰ Β· q + Ο‰ Β· qβ€²)  β‰ˆΛ˜βŸ¨ cong (_ +_) (Β·-distribΛ‘-+ Ο‰ q _) ⟩
        (p + pβ€²) + Ο‰ Β· (q + qβ€²)      ∎
      Ο‰ p q pβ€² qβ€² β†’ begin
        Ο‰ Β· (p ∧ q) + Ο‰ Β· (pβ€² ∧ qβ€²)  β‰ˆΛ˜βŸ¨ Β·-distribΛ‘-+ Ο‰ (p ∧ q) (pβ€² ∧ qβ€²) ⟩
        Ο‰ Β· ((p ∧ q) + (pβ€² ∧ qβ€²))    β‰€βŸ¨ Β·-monotoneΚ³ (+-sub-interchangeable-∧ p q pβ€² qβ€²) ⟩
        Ο‰ Β· ((p + pβ€²) ∧ (q + qβ€²))    ∎
    where
    open Tools.Reasoning.PartialOrder ≀-poset

  Β·-distribΚ³-βŠ› : βˆ€ r β†’ _Β·_ DistributesOverΚ³ (_βŠ›_β–· r)
  Β·-distribΚ³-βŠ› = Ξ» where
      𝟘 q p pβ€² β†’
        (p ∧ pβ€²) Β· q    β‰‘βŸ¨ Β·-distribΚ³-∧ _ p _ ⟩
        p Β· q ∧ pβ€² Β· q  ∎
      πŸ™ q p pβ€² β†’
        (p + Ο‰ Β· pβ€²) Β· q      β‰‘βŸ¨ Β·-distribΚ³-+ _ p _ ⟩
        p Β· q + (Ο‰ Β· pβ€²) Β· q  β‰‘βŸ¨ cong (_ +_) (Β·-assoc Ο‰ pβ€² _) ⟩
        p Β· q + Ο‰ Β· pβ€² Β· q    ∎
      Ο‰ q p pβ€² β†’
        (Ο‰ Β· (p ∧ pβ€²)) Β· q    β‰‘βŸ¨ Β·-assoc _ _ _ ⟩
        Ο‰ Β· (p ∧ pβ€²) Β· q      β‰‘βŸ¨ cong (_ Β·_) (Β·-distribΚ³-∧ _ p _) ⟩
        Ο‰ Β· (p Β· q ∧ pβ€² Β· q)  ∎
    where
    open Tools.Reasoning.PropositionalEquality

  βŠ›-distribΛ‘-∧ : βˆ€ r β†’ (_βŠ›_β–· r) DistributesOverΛ‘ _∧_
  βŠ›-distribΛ‘-∧ = Ξ» where
      𝟘 p _ _ β†’
        lemma p _ _
      πŸ™ p q qβ€² β†’
        p + Ο‰ Β· (q ∧ qβ€²)          β‰‘βŸ¨ cong (_ +_) (Β·-distribΛ‘-∧ Ο‰ q _) ⟩
        p + (Ο‰ Β· q ∧ Ο‰ Β· qβ€²)      β‰‘βŸ¨ +-distribΛ‘-∧ p _ _ ⟩
        (p + Ο‰ Β· q) ∧ p + Ο‰ Β· qβ€²  ∎
      Ο‰ p q qβ€² β†’
        Ο‰ Β· (p ∧ q ∧ qβ€²)            β‰‘βŸ¨ cong (_ Β·_) (lemma p _ _) ⟩
        Ο‰ Β· ((p ∧ q) ∧ (p ∧ qβ€²))    β‰‘βŸ¨ Β·-distribΛ‘-∧ Ο‰ (p ∧ _) _ ⟩
        Ο‰ Β· (p ∧ q) ∧ Ο‰ Β· (p ∧ qβ€²)  ∎
    where
    open Tools.Reasoning.PropositionalEquality

    lemma = Ξ» p q qβ€² β†’
      p ∧ (q ∧ qβ€²)        β‰‘Λ˜βŸ¨ cong (_∧ _) (∧-idem p) ⟩
      (p ∧ p) ∧ (q ∧ qβ€²)  β‰‘βŸ¨ ∧-assoc p _ _ ⟩
      p ∧ (p ∧ (q ∧ qβ€²))  β‰‘Λ˜βŸ¨ cong (p ∧_) (∧-assoc p _ _) ⟩
      p ∧ ((p ∧ q) ∧ qβ€²)  β‰‘βŸ¨ cong (Ξ» q β†’ p ∧ (q ∧ _)) (∧-comm p _) ⟩
      p ∧ ((q ∧ p) ∧ qβ€²)  β‰‘βŸ¨ cong (p ∧_) (∧-assoc q _ _) ⟩
      p ∧ (q ∧ (p ∧ qβ€²))  β‰‘Λ˜βŸ¨ ∧-assoc p _ _ ⟩
      (p ∧ q) ∧ (p ∧ qβ€²)  ∎

  βŠ›-distribΚ³-∧ : βˆ€ r β†’ (_βŠ›_β–· r) DistributesOverΚ³ _∧_
  βŠ›-distribΚ³-∧ = Ξ» where
      𝟘 q p pβ€² β†’
        lemma _ p _
      πŸ™ q p pβ€² β†’
        (p ∧ pβ€²) + Ο‰ Β· q            β‰‘βŸ¨ +-distribΚ³-∧ _ p _ ⟩
        (p + Ο‰ Β· q) ∧ (pβ€² + Ο‰ Β· q)  ∎
      Ο‰ q p pβ€² β†’
        Ο‰ Β· ((p ∧ pβ€²) ∧ q)          β‰‘βŸ¨ cong (_ Β·_) (lemma _ p _) ⟩
        Ο‰ Β· ((p ∧ q) ∧ (pβ€² ∧ q))    β‰‘βŸ¨ Β·-distribΛ‘-∧ Ο‰ (p ∧ _) _ ⟩
        Ο‰ Β· (p ∧ q) ∧ Ο‰ Β· (pβ€² ∧ q)  ∎
    where
    open Tools.Reasoning.PropositionalEquality

    lemma = Ξ» q p pβ€² β†’
      (p ∧ pβ€²) ∧ q        β‰‘βŸ¨ ∧-comm _ q ⟩
      q ∧ (p ∧ pβ€²)        β‰‘βŸ¨ βŠ›-distribΛ‘-∧ 𝟘 q _ _ ⟩
      (q ∧ p) ∧ (q ∧ pβ€²)  β‰‘βŸ¨ congβ‚‚ _∧_ (∧-comm q _) (∧-comm q _) ⟩
      (p ∧ q) ∧ (pβ€² ∧ q)  ∎

-- The natrec-star operator obtained from
-- zero-one-many-lower-bounded-star is not the (pointwise) greatest
-- one.

Β¬-lower-bounded-greatest :
  Β¬ ((has-star : Has-star zero-one-many-semiring-with-meet) β†’
     βˆ€ p q r β†’
     Has-star._βŠ›_β–·_ has-star                         p q r ≀
     Has-star._βŠ›_β–·_ zero-one-many-lower-bounded-star p q r)
Β¬-lower-bounded-greatest hyp =
  case hyp zero-one-many-greatest-star πŸ™ πŸ™ 𝟘 of Ξ» ()

-- A zero-one-many modality (with arbitrary "restrictions").
--
-- The dedicated nr function, if any, is the "greatest" one defined
-- above.

zero-one-many-greatest : Modality-variant β†’ Modality
zero-one-many-greatest variant = record
  { variant            = variant
  ; semiring-with-meet = zero-one-many-semiring-with-meet
  ; 𝟘-well-behaved     = Ξ» _ β†’ zero-one-many-has-well-behaved-zero
  ; has-nr             = Ξ» _ β†’
                           Star.has-nr _
                             ⦃ has-star = zero-one-many-greatest-star ⦄
  }

------------------------------------------------------------------------
-- A variant of the modality with a custom nr function

-- An nr function for Zero-one-many.
--
-- The value of nr p 𝟘 z s n is defined in the following way:
--
-- * If pΒ =Β πŸ™, then there are no (non-erased) recursive calls, and the
--   argument is used exactly once in the successor case (excluding
--   erased uses):
--
--     f zero    = f_z
--     f (suc m) = f_s m
--
--   Let us use nΒ +Β z for the zero case, and nΒ +Β s for the successor
--   case: the result is a conservative approximation of these two
--   values (their meet).
--
-- * If p = 𝟘, then there are no (non-erased) recursive
--   calls, and the argument is not used (in non-erased positions) in
--   the successor case:
--
--     f zero    = f_z
--     f (suc m) = f_s
--
--   Let us again use nΒ +Β z for the zero case. If affine types are
--   used, then we use nΒ +Β s for the successor case again, but if
--   linear types are used, then we use ω · nΒ +Β s: the argument is not
--   used linearly in the successor case, because it is not used at
--   all, so if n is πŸ™, then the result should be Ο‰ (not πŸ™, because
--   the function is not linear, and not 𝟘, because that would amount
--   to an erased match on a natural number).
--
-- * If pΒ =Β Ο‰, then there are no (non-erased) recursive calls. In the
--   successor case the argument is used an unlimited number of times,
--   so we use ω · nΒ +Β s. In the zero case we use nΒ +Β z, as before.
--
-- All of these cases can be expressed in the following way (note that
-- πŸ™Β βˆ§Β πŸ˜ is πŸ™ for affine types and Ο‰ for linear types):
--
--   nr p 𝟘 z s n = ((πŸ™ ∧ p) Β· n + s) ∧ (n + z)
--
-- The value of nrΒ pΒ πŸ™Β zΒ sΒ n is defined in the following way:
--
-- * If p = 𝟘, then we have linear or affine recursion: the argument
--   is used linearly or affinely (n), the successor case can occur an
--   unlimited number of times (ω · s), and the zero case occurs at
--   most once (z).
--
-- * If pΒ =Β πŸ™ or pΒ =Β Ο‰, then there is recursion (ω · s), the argument
--   can be used in each recursive call (ω · n), and the zero case
--   occurs at most once (z).
--
-- We get the following definition:
--
--   nr p πŸ™ z s n = (πŸ™ + p) Β· n + Ο‰ Β· s + z
--
-- Finally we use the following definition for nrΒ p ω zΒ sΒ n:
--
--   nr _ Ο‰ z s n = Ο‰ Β· (n + s + z)
--
-- There is recursion (ω · s), in the successor case there can be
-- multiple recursive calls (ω · n), and the zero case can occur
-- multiple times (ω · z).

nr :
  Zero-one-many β†’ Zero-one-many β†’
  Zero-one-many β†’ Zero-one-many β†’ Zero-one-many β†’ Zero-one-many
nr p 𝟘 z s n = ((πŸ™ ∧ p) Β· n + s) ∧ (n + z)
nr p πŸ™ z s n = (πŸ™ + p) Β· n + Ο‰ Β· s + z
nr _ Ο‰ z s n = Ο‰ Β· (n + s + z)

-- An alternative implementation of nr.

nrβ€² :
  Zero-one-many β†’ Zero-one-many β†’
  Zero-one-many β†’ Zero-one-many β†’ Zero-one-many β†’ Zero-one-many
nrβ€² _ _ 𝟘 𝟘 𝟘 = 𝟘
nrβ€² _ 𝟘 πŸ™ πŸ™ 𝟘 = πŸ™
nrβ€² _ 𝟘 πŸ™ 𝟘 𝟘 = πŸ™ ∧ 𝟘
nrβ€² _ πŸ™ πŸ™ 𝟘 𝟘 = πŸ™
nrβ€² _ 𝟘 𝟘 πŸ™ 𝟘 = πŸ™ ∧ 𝟘
nrβ€² πŸ™ 𝟘 𝟘 𝟘 πŸ™ = πŸ™
nrβ€² 𝟘 𝟘 𝟘 𝟘 πŸ™ = πŸ™ ∧ 𝟘
nrβ€² 𝟘 πŸ™ 𝟘 𝟘 πŸ™ = πŸ™
nrβ€² _ _ _ _ _ = Ο‰

-- A type used in the implementation of Nr.

data Nr-Ο‰ : (p r z s n : Zero-one-many) β†’ Set where
  nr≑ω₁  : Nr-Ο‰ p r Ο‰ s n
  nr≑ω₂  : Nr-Ο‰ p r z Ο‰ n
  nr≑ω₃  : Nr-Ο‰ p r z s Ο‰
  nr≑ω₄  : Nr-Ο‰ p Ο‰ πŸ™ s n
  nr≑ω₅  : Nr-Ο‰ p Ο‰ 𝟘 πŸ™ n
  nr≑ω₆  : Nr-Ο‰ p Ο‰ 𝟘 𝟘 πŸ™
  nr≑ω₇  : Nr-Ο‰ Ο‰ 𝟘 𝟘 𝟘 πŸ™
  nrβ‰‘Ο‰β‚ˆ  : Nr-Ο‰ Ο‰ πŸ™ 𝟘 𝟘 πŸ™
  nr≑ω₉  : Nr-Ο‰ πŸ™ πŸ™ 𝟘 𝟘 πŸ™
  nr≑ω₁₀ : Nr-Ο‰ p 𝟘 𝟘 πŸ™ πŸ™
  nr≑ω₁₁ : Nr-Ο‰ p πŸ™ z πŸ™ n
  nr≑ω₁₂ : Nr-Ο‰ p 𝟘 πŸ™ s πŸ™
  nr≑ω₁₃ : Nr-Ο‰ p πŸ™ πŸ™ 𝟘 πŸ™

-- Another type used in the implementation of Nr.

data Nr-πŸ™βˆ§πŸ˜ : (p r z s n : Zero-one-many) β†’ Set where
  nrβ‰‘πŸ™βˆ§πŸ˜β‚ : Nr-πŸ™βˆ§πŸ˜ p 𝟘 πŸ™ 𝟘 𝟘
  nrβ‰‘πŸ™βˆ§πŸ˜β‚‚ : Nr-πŸ™βˆ§πŸ˜ p 𝟘 𝟘 πŸ™ 𝟘
  nrβ‰‘πŸ™βˆ§πŸ˜β‚ƒ : Nr-πŸ™βˆ§πŸ˜ 𝟘 𝟘 𝟘 𝟘 πŸ™

-- A view of the functions nr and nrβ€².

data Nr : (p r z s n result : Zero-one-many) β†’ Set where
  nrβ‰‘πŸ˜   :                    result ≑ 𝟘     β†’ Nr p r 𝟘 𝟘 𝟘 result
  nrβ‰‘πŸ™β‚  :                    result ≑ πŸ™     β†’ Nr p 𝟘 πŸ™ πŸ™ 𝟘 result
  nrβ‰‘πŸ™β‚‚  :                    result ≑ πŸ™     β†’ Nr p πŸ™ πŸ™ 𝟘 𝟘 result
  nrβ‰‘πŸ™β‚ƒ  :                                     Nr πŸ™ 𝟘 𝟘 𝟘 πŸ™ πŸ™
  nrβ‰‘πŸ™β‚„  :                                     Nr 𝟘 πŸ™ 𝟘 𝟘 πŸ™ πŸ™
  nrβ‰‘πŸ™βˆ§πŸ˜ : Nr-πŸ™βˆ§πŸ˜ p r z s n β†’ result ≑ πŸ™ ∧ 𝟘 β†’ Nr p r z s n result
  nr≑ω   : Nr-Ο‰ p r z s n   β†’ result ≑ Ο‰     β†’ Nr p r z s n result

-- The view is correctly defined for nrβ€².

nrβ€²-view : βˆ€ p r z s n β†’ Nr p r z s n (nrβ€² p r z s n)
nrβ€²-view = Ξ» where
  _ _ 𝟘 𝟘 𝟘 β†’ nrβ‰‘πŸ˜ refl
  _ 𝟘 πŸ™ πŸ™ 𝟘 β†’ nrβ‰‘πŸ™β‚ refl
  _ πŸ™ πŸ™ 𝟘 𝟘 β†’ nrβ‰‘πŸ™β‚‚ refl
  πŸ™ 𝟘 𝟘 𝟘 πŸ™ β†’ nrβ‰‘πŸ™β‚ƒ
  𝟘 πŸ™ 𝟘 𝟘 πŸ™ β†’ nrβ‰‘πŸ™β‚„
  _ 𝟘 πŸ™ 𝟘 𝟘 β†’ nrβ‰‘πŸ™βˆ§πŸ˜ nrβ‰‘πŸ™βˆ§πŸ˜β‚ refl
  _ 𝟘 𝟘 πŸ™ 𝟘 β†’ nrβ‰‘πŸ™βˆ§πŸ˜ nrβ‰‘πŸ™βˆ§πŸ˜β‚‚ refl
  𝟘 𝟘 𝟘 𝟘 πŸ™ β†’ nrβ‰‘πŸ™βˆ§πŸ˜ nrβ‰‘πŸ™βˆ§πŸ˜β‚ƒ refl
  _ _ Ο‰ _ _ β†’ nr≑ω nr≑ω₁ refl
  _ _ 𝟘 Ο‰ _ β†’ nr≑ω nr≑ω₂ refl
  _ 𝟘 πŸ™ Ο‰ _ β†’ nr≑ω nr≑ω₂ refl
  _ πŸ™ πŸ™ Ο‰ _ β†’ nr≑ω nr≑ω₂ refl
  _ _ 𝟘 𝟘 Ο‰ β†’ nr≑ω nr≑ω₃ refl
  _ 𝟘 𝟘 πŸ™ Ο‰ β†’ nr≑ω nr≑ω₃ refl
  _ 𝟘 πŸ™ 𝟘 Ο‰ β†’ nr≑ω nr≑ω₃ refl
  _ πŸ™ πŸ™ 𝟘 Ο‰ β†’ nr≑ω nr≑ω₃ refl
  _ 𝟘 πŸ™ πŸ™ Ο‰ β†’ nr≑ω nr≑ω₃ refl
  _ Ο‰ πŸ™ _ _ β†’ nr≑ω nr≑ω₄ refl
  _ Ο‰ 𝟘 πŸ™ _ β†’ nr≑ω nr≑ω₅ refl
  𝟘 Ο‰ 𝟘 𝟘 πŸ™ β†’ nr≑ω nr≑ω₆ refl
  πŸ™ Ο‰ 𝟘 𝟘 πŸ™ β†’ nr≑ω nr≑ω₆ refl
  Ο‰ Ο‰ 𝟘 𝟘 πŸ™ β†’ nr≑ω nr≑ω₆ refl
  Ο‰ 𝟘 𝟘 𝟘 πŸ™ β†’ nr≑ω nr≑ω₇ refl
  Ο‰ πŸ™ 𝟘 𝟘 πŸ™ β†’ nr≑ω nrβ‰‘Ο‰β‚ˆ refl
  πŸ™ πŸ™ 𝟘 𝟘 πŸ™ β†’ nr≑ω nr≑ω₉ refl
  _ 𝟘 𝟘 πŸ™ πŸ™ β†’ nr≑ω nr≑ω₁₀ refl
  _ πŸ™ 𝟘 πŸ™ _ β†’ nr≑ω nr≑ω₁₁ refl
  _ πŸ™ πŸ™ πŸ™ _ β†’ nr≑ω nr≑ω₁₁ refl
  _ 𝟘 πŸ™ 𝟘 πŸ™ β†’ nr≑ω nr≑ω₁₂ refl
  _ 𝟘 πŸ™ πŸ™ πŸ™ β†’ nr≑ω nr≑ω₁₂ refl
  _ πŸ™ πŸ™ 𝟘 πŸ™ β†’ nr≑ω nr≑ω₁₃ refl

-- The functions nr and nrβ€² are pointwise equal.

nr≑nrβ€² : βˆ€ p r β†’ nr p r z s n ≑ nrβ€² p r z s n
nr≑nrβ€² p r = lemma _ _ _ _ _ (nrβ€²-view p r _ _ _)
  where
  open Semiring-with-meet zero-one-many-semiring-with-meet
    hiding (𝟘; πŸ™; Ο‰; _+_; _Β·_; _∧_)
  open Tools.Reasoning.PropositionalEquality

  lemma :
    βˆ€ p r z s n β†’ Nr p r z s n (nrβ€² p r z s n) β†’
    nr p r z s n ≑ nrβ€² p r z s n
  lemma p 𝟘 .𝟘 .𝟘 .𝟘 (nrβ‰‘πŸ˜ _) =
    ((πŸ™ ∧ p) Β· 𝟘 + 𝟘) ∧ 𝟘  β‰‘βŸ¨ cong (_∧ _) (+-identityΚ³ ((πŸ™ ∧ p) Β· _)) ⟩
    ((πŸ™ ∧ p) Β· 𝟘) ∧ 𝟘      β‰‘βŸ¨ cong (_∧ _) (Β·-zeroΚ³ (πŸ™ ∧ p)) ⟩
    𝟘 ∧ 𝟘                  β‰‘βŸ¨βŸ©
    𝟘                      ∎
  lemma p πŸ™ .𝟘 .𝟘 .𝟘 (nrβ‰‘πŸ˜ _) =
    (πŸ™ + p) Β· 𝟘 + 𝟘  β‰‘βŸ¨ +-identityΚ³ _ ⟩
    (πŸ™ + p) Β· 𝟘      β‰‘βŸ¨ Β·-zeroΚ³ _ ⟩
    𝟘                ∎
  lemma _ Ο‰ .𝟘 .𝟘 .𝟘 (nrβ‰‘πŸ˜ _) =
    𝟘  ∎
  lemma p .𝟘 .πŸ™ .πŸ™ .𝟘 (nrβ‰‘πŸ™β‚ _) =
    ((πŸ™ ∧ p) Β· 𝟘 + πŸ™) ∧ πŸ™  β‰‘βŸ¨ cong ((_∧ _) βˆ˜β†’ (_+ _)) (Β·-zeroΚ³ (πŸ™ ∧ p)) ⟩
    (𝟘 + πŸ™) ∧ πŸ™            β‰‘βŸ¨βŸ©
    πŸ™                      ∎
  lemma p .πŸ™ .πŸ™ .𝟘 .𝟘 (nrβ‰‘πŸ™β‚‚ _) =
    (πŸ™ + p) Β· 𝟘 + πŸ™  β‰‘βŸ¨ cong (_+ _) (Β·-zeroΚ³ (πŸ™ + p)) ⟩
    𝟘 + πŸ™            β‰‘βŸ¨βŸ©
    πŸ™                ∎
  lemma .πŸ™ .𝟘 .𝟘 .𝟘 .πŸ™ nrβ‰‘πŸ™β‚ƒ =
    πŸ™  ∎
  lemma .𝟘 .πŸ™ .𝟘 .𝟘 .πŸ™ nrβ‰‘πŸ™β‚„ =
    πŸ™  ∎
  lemma p .𝟘 .πŸ™ .𝟘 .𝟘 (nrβ‰‘πŸ™βˆ§πŸ˜ nrβ‰‘πŸ™βˆ§πŸ˜β‚ _) =
    ((πŸ™ ∧ p) Β· 𝟘 + 𝟘) ∧ πŸ™  β‰‘βŸ¨ cong (_∧ _) (+-identityΚ³ ((πŸ™ ∧ p) Β· _)) ⟩
    ((πŸ™ ∧ p) Β· 𝟘) ∧ πŸ™      β‰‘βŸ¨ cong (_∧ _) (Β·-zeroΚ³ (πŸ™ ∧ p)) ⟩
    𝟘 ∧ πŸ™                  ∎
  lemma p .𝟘 .𝟘 .πŸ™ .𝟘 (nrβ‰‘πŸ™βˆ§πŸ˜ nrβ‰‘πŸ™βˆ§πŸ˜β‚‚ _) =
    ((πŸ™ ∧ p) Β· 𝟘 + πŸ™) ∧ 𝟘  β‰‘βŸ¨ cong ((_∧ _) βˆ˜β†’ (_+ _)) (Β·-zeroΚ³ (πŸ™ ∧ p)) ⟩
    πŸ™ ∧ 𝟘                  β‰‘βŸ¨βŸ©
    𝟘 ∧ πŸ™                  ∎
  lemma .𝟘 .𝟘 .𝟘 .𝟘 .πŸ™ (nrβ‰‘πŸ™βˆ§πŸ˜ nrβ‰‘πŸ™βˆ§πŸ˜β‚ƒ _) =
    ((𝟘 ∧ πŸ™) Β· πŸ™ + 𝟘) ∧ πŸ™  β‰‘βŸ¨ cong (_∧ _) (+-identityΚ³ (πŸ˜βˆ§πŸ™ Β· _)) ⟩
    (𝟘 ∧ πŸ™) Β· πŸ™ ∧ πŸ™        β‰‘βŸ¨ cong (_∧ _) (Β·-identityΚ³ πŸ˜βˆ§πŸ™) ⟩
    (𝟘 ∧ πŸ™) ∧ πŸ™            β‰‘βŸ¨ ∧-assoc 𝟘 πŸ™ _ ⟩
    𝟘 ∧ (πŸ™ ∧ πŸ™)            β‰‘βŸ¨βŸ©
    𝟘 ∧ πŸ™                  ∎
  lemma p 𝟘 .Ο‰ s n (nr≑ω nr≑ω₁ _) =
    ((πŸ™ ∧ p) Β· n + s) ∧ (n + Ο‰)  β‰‘βŸ¨ cong (((πŸ™ ∧ p) Β· _ + _) ∧_) (+-zeroΚ³ _) ⟩
    ((πŸ™ ∧ p) Β· n + s) ∧ Ο‰        β‰‘βŸ¨ ∧-zeroΚ³ ((πŸ™ ∧ p) Β· _ + _) ⟩
    Ο‰                            ∎
  lemma p πŸ™ .Ο‰ s n (nr≑ω nr≑ω₁ _) =
    (πŸ™ + p) Β· n + Ο‰ Β· s + Ο‰  β‰‘βŸ¨ cong ((πŸ™ + p) Β· _ +_) (+-zeroΚ³ _) ⟩
    (πŸ™ + p) Β· n + Ο‰          β‰‘βŸ¨ +-zeroΚ³ _ ⟩
    Ο‰                        ∎
  lemma p Ο‰ .Ο‰ s n (nr≑ω nr≑ω₁ _) =
    Ο‰ Β· (n + s + Ο‰)      β‰‘βŸ¨ Β·-distribΛ‘-+ _ n _ ⟩
    Ο‰ Β· n + Ο‰ Β· (s + Ο‰)  β‰‘βŸ¨ cong (Ο‰ Β· n +_) (Β·-distribΛ‘-+ _ s _) ⟩
    Ο‰ Β· n + Ο‰ Β· s + Ο‰    β‰‘βŸ¨ cong (Ο‰ Β· n +_) (+-zeroΚ³ _) ⟩
    Ο‰ Β· n + Ο‰            β‰‘βŸ¨ +-zeroΚ³ _ ⟩
    Ο‰                    ∎
  lemma p 𝟘 z .Ο‰ n (nr≑ω nr≑ω₂ ≑ω) =
    ((πŸ™ ∧ p) Β· n + Ο‰) ∧ (n + z)  β‰‘βŸ¨ cong (_∧ _) (+-zeroΚ³ ((πŸ™ ∧ p) Β· _)) ⟩
    Ο‰ ∧ (n + z)                  β‰‘βŸ¨βŸ©
    Ο‰                            β‰‘Λ˜βŸ¨ ≑ω ⟩
    nrβ€² p 𝟘 z Ο‰ n                ∎
  lemma p πŸ™ z .Ο‰ n (nr≑ω nr≑ω₂ ≑ω) =
    (πŸ™ + p) Β· n + Ο‰  β‰‘βŸ¨ +-zeroΚ³ _ ⟩
    Ο‰                β‰‘Λ˜βŸ¨ ≑ω ⟩
    nrβ€² p πŸ™ z Ο‰ n    ∎
  lemma p Ο‰ z .Ο‰ n (nr≑ω nr≑ω₂ ≑ω) =
    Ο‰ Β· (n + Ο‰)    β‰‘βŸ¨ Β·-distribΛ‘-+ _ n _ ⟩
    Ο‰ Β· n + Ο‰      β‰‘βŸ¨ +-zeroΚ³ _ ⟩
    Ο‰              β‰‘Λ˜βŸ¨ ≑ω ⟩
    nrβ€² p Ο‰ z Ο‰ n  ∎
  lemma p 𝟘 z s .Ο‰ (nr≑ω nr≑ω₃ ≑ω) =
    ((πŸ™ ∧ p) Β· Ο‰ + s) ∧ Ο‰  β‰‘βŸ¨ ∧-zeroΚ³ ((πŸ™ ∧ p) Β· _ + _) ⟩
    Ο‰                      β‰‘Λ˜βŸ¨ ≑ω ⟩
    nrβ€² p 𝟘 z s Ο‰          ∎
  lemma p πŸ™ z s .Ο‰ (nr≑ω nr≑ω₃ ≑ω) =
    (πŸ™ + p) Β· Ο‰ + Ο‰ Β· s + z  β‰‘βŸ¨ cong (_+ _) (Β·-distribΚ³-+ _ πŸ™ p) ⟩
    (Ο‰ + p Β· Ο‰) + Ο‰ Β· s + z  β‰‘βŸ¨βŸ©
    Ο‰                        β‰‘Λ˜βŸ¨ ≑ω ⟩
    nrβ€² p πŸ™ z s Ο‰            ∎
  lemma p Ο‰ z s .Ο‰ (nr≑ω nr≑ω₃ ≑ω) =
    Ο‰              β‰‘Λ˜βŸ¨ ≑ω ⟩
    nrβ€² p Ο‰ z s Ο‰  ∎
  lemma p .Ο‰ .πŸ™ s n (nr≑ω nr≑ω₄ _) =
    Ο‰ Β· (n + s + πŸ™)    β‰‘Λ˜βŸ¨ cong (Ο‰ Β·_) (+-assoc n _ _) ⟩
    Ο‰ Β· ((n + s) + πŸ™)  β‰‘βŸ¨ Β·-distribΛ‘-+ _ (n + _) _ ⟩
    Ο‰ Β· (n + s) + Ο‰    β‰‘βŸ¨ +-zeroΚ³ _ ⟩
    Ο‰                  ∎
  lemma p .Ο‰ .𝟘 .πŸ™ n (nr≑ω nr≑ω₅ _) =
    Ο‰ Β· (n + πŸ™)  β‰‘βŸ¨ Β·-distribΛ‘-+ _ n _ ⟩
    Ο‰ Β· n + Ο‰    β‰‘βŸ¨ +-zeroΚ³ _ ⟩
    Ο‰            ∎
  lemma p .Ο‰ .𝟘 .𝟘 .πŸ™ (nr≑ω nr≑ω₆ ≑ω) =
    Ο‰              β‰‘Λ˜βŸ¨ ≑ω ⟩
    nrβ€² p Ο‰ 𝟘 𝟘 πŸ™  ∎
  lemma .Ο‰ 𝟘 .𝟘 .𝟘 .πŸ™ (nr≑ω nr≑ω₇ _) =
    Ο‰  ∎
  lemma .Ο‰ πŸ™ .𝟘 .𝟘 .πŸ™ (nr≑ω nrβ‰‘Ο‰β‚ˆ _) =
    Ο‰  ∎
  lemma .πŸ™ .πŸ™ .𝟘 .𝟘 .πŸ™ (nr≑ω nr≑ω₉ _) =
    Ο‰  ∎
  lemma p .𝟘 .𝟘 .πŸ™ .πŸ™ (nr≑ω nr≑ω₁₀ _) =
    ((πŸ™ ∧ p) Β· πŸ™ + πŸ™) ∧ πŸ™  β‰‘βŸ¨ cong ((_∧ _) βˆ˜β†’ (_+ _)) (Β·-distribΚ³-∧ _ πŸ™ p) ⟩
    ((πŸ™ ∧ p Β· πŸ™) + πŸ™) ∧ πŸ™  β‰‘βŸ¨ cong ((_∧ _) βˆ˜β†’ (_+ _) βˆ˜β†’ (πŸ™ ∧_)) (Β·-identityΚ³ p) ⟩
    ((πŸ™ ∧ p) + πŸ™) ∧ πŸ™      β‰‘βŸ¨ cong (_∧ _) (+-distribΚ³-∧ _ πŸ™ p) ⟩
    (Ο‰ ∧ (p + πŸ™)) ∧ πŸ™      β‰‘βŸ¨βŸ©
    Ο‰                      ∎
  lemma p .πŸ™ z .πŸ™ n (nr≑ω nr≑ω₁₁ ≑ω) =
    (πŸ™ + p) Β· n + Ο‰  β‰‘βŸ¨ +-zeroΚ³ _ ⟩
    Ο‰                β‰‘Λ˜βŸ¨ ≑ω ⟩
    nrβ€² p πŸ™ z πŸ™ n    ∎
  lemma p .𝟘 .πŸ™ s .πŸ™ (nr≑ω nr≑ω₁₂ ≑ω) =
    ((πŸ™ ∧ p) Β· πŸ™ + s) ∧ Ο‰  β‰‘βŸ¨ ∧-zeroΚ³ ((πŸ™ ∧ p) Β· _ + _) ⟩
    Ο‰                      β‰‘Λ˜βŸ¨ ≑ω ⟩
    nrβ€² p 𝟘 πŸ™ s πŸ™          ∎
  lemma p .πŸ™ .πŸ™ .𝟘 .πŸ™ (nr≑ω nr≑ω₁₃ _) =
    (πŸ™ + p) Β· πŸ™ + πŸ™  β‰‘βŸ¨ cong (_+ _) (Β·-distribΚ³-+ _ πŸ™ p) ⟩
    (πŸ™ + p Β· πŸ™) + πŸ™  β‰‘βŸ¨ cong (_+ _) (+-comm _ (p Β· _)) ⟩
    (p Β· πŸ™ + πŸ™) + πŸ™  β‰‘βŸ¨ +-assoc (p Β· _) _ _ ⟩
    p Β· πŸ™ + Ο‰        β‰‘βŸ¨ +-zeroΚ³ _ ⟩
    Ο‰                ∎

-- The view is correctly defined for nr.

nr-view : βˆ€ p r z s n β†’ Nr p r z s n (nr p r z s n)
nr-view p r z s n =             $⟨ nrβ€²-view _ _ _ _ _ ⟩
  Nr p r z s n (nrβ€² p r z s n)  β†’βŸ¨ subst (Nr _ _ _ _ _) (sym (nr≑nrβ€² p r)) ⟩
  Nr p r z s n (nr p r z s n)   β–‘

-- The value of nr p r z s n is 𝟘 iff z, s and n are all zero.

nr-𝟘 : βˆ€ p r β†’ nr p r z s n ≑ 𝟘 ⇔ (z ≑ 𝟘 Γ— s ≑ 𝟘 Γ— n ≑ 𝟘)
nr-𝟘 p r =
    lemma₁ (nr-view _ _ _ _ _)
  , Ξ» { (refl , refl , refl) β†’ lemmaβ‚‚ p r }
  where
  open Semiring-with-meet zero-one-many-semiring-with-meet
    hiding (𝟘; πŸ™; _+_; _Β·_; _∧_)
  open Tools.Reasoning.PropositionalEquality

  lemma₁ : Nr p r z s n result β†’ result ≑ 𝟘 β†’ z ≑ 𝟘 Γ— s ≑ 𝟘 Γ— n ≑ 𝟘
  lemma₁ (nrβ‰‘πŸ˜ _)         refl = refl , refl , refl
  lemma₁ (nrβ‰‘πŸ™βˆ§πŸ˜ _ πŸ˜β‰‘πŸ˜βˆ§πŸ™) refl = βŠ₯-elim (πŸ˜βˆ§πŸ™β‰’πŸ˜ (sym πŸ˜β‰‘πŸ˜βˆ§πŸ™))

  lemmaβ‚‚ : βˆ€ p r β†’ nr p r 𝟘 𝟘 𝟘 ≑ 𝟘
  lemmaβ‚‚ = Ξ» where
    _ Ο‰ β†’ refl
    Ο‰ πŸ™ β†’ refl
    πŸ™ πŸ™ β†’ refl
    𝟘 πŸ™ β†’ refl
    Ο‰ 𝟘 β†’ refl
    πŸ™ 𝟘 β†’ refl
    𝟘 𝟘 β†’
      ((𝟘 ∧ πŸ™) Β· 𝟘 + 𝟘) ∧ 𝟘  β‰‘βŸ¨ cong (_∧ _) (+-identityΚ³ (πŸ˜βˆ§πŸ™ Β· _)) ⟩
      ((𝟘 ∧ πŸ™) Β· 𝟘) ∧ 𝟘      β‰‘βŸ¨ cong (_∧ _) (Β·-zeroΚ³ πŸ˜βˆ§πŸ™) ⟩
      𝟘 ∧ 𝟘                  β‰‘βŸ¨βŸ©
      𝟘                      ∎

-- An nr function can be defined for zero-one-many-semiring-with-meet.

zero-one-many-has-nr : Has-nr zero-one-many-semiring-with-meet
zero-one-many-has-nr = record
  { nr          = nr
  ; nr-monotone = Ξ» {p = p} {r = r} β†’ nr-monotone p r
  ; nr-Β·        = Ξ» {p = p} {r = r} β†’ nr-Β· p r
  ; nr-+        = Ξ» {p = p} {r = r} β†’ nr-+ p r
  ; nr-𝟘        = Ξ» {p = p} {r = r} β†’
                    nr-𝟘 p r .projβ‚‚ (refl , refl , refl)
  ; nr-positive = Ξ» {p = p} {r = r} β†’ nr-𝟘 p r .proj₁
  ; nr-zero     = Ξ» {n = _} {p = p} {r = r} nβ‰€πŸ˜ β†’ nr-zero p r nβ‰€πŸ˜
  ; nr-suc      = Ξ» {p = p} {r = r} β†’ nr-suc p r
  }
  where
  open Semiring-with-meet zero-one-many-semiring-with-meet
    hiding (𝟘; πŸ™; Ο‰; _+_; _Β·_; _∧_; _≀_)
  open Addition zero-one-many-semiring-with-meet
  open Meet zero-one-many-semiring-with-meet
  open Multiplication zero-one-many-semiring-with-meet
  open PartialOrder zero-one-many-semiring-with-meet

  nr-monotone :
    βˆ€ p r β†’
    z₁ ≀ zβ‚‚ β†’ s₁ ≀ sβ‚‚ β†’ n₁ ≀ nβ‚‚ β†’
    nr p r z₁ s₁ n₁ ≀ nr p r zβ‚‚ sβ‚‚ nβ‚‚
  nr-monotone = Ξ» where
    p 𝟘 z₁≀zβ‚‚ s₁≀sβ‚‚ n₁≀nβ‚‚ β†’
      ∧-monotone (+-monotone (Β·-monotoneΚ³ {r = πŸ™ ∧ p} n₁≀nβ‚‚) s₁≀sβ‚‚)
        (+-monotone n₁≀nβ‚‚ z₁≀zβ‚‚)
    p πŸ™ z₁≀zβ‚‚ s₁≀sβ‚‚ n₁≀nβ‚‚ β†’
      +-monotone (Β·-monotoneΚ³ {r = πŸ™ + p} n₁≀nβ‚‚)
        (+-monotone (Β·-monotoneΚ³ s₁≀sβ‚‚) z₁≀zβ‚‚)
    _ Ο‰ z₁≀zβ‚‚ s₁≀sβ‚‚ n₁≀nβ‚‚ β†’
      Β·-monotoneΚ³ (+-monotone n₁≀nβ‚‚ (+-monotone s₁≀sβ‚‚ z₁≀zβ‚‚))

  nr-Β· : βˆ€ p r β†’ nr p r z s n Β· q ≀ nr p r (z Β· q) (s Β· q) (n Β· q)
  nr-Β· {z = z} {s = s} {n = n} {q = q} p = Ξ» where
      𝟘 β†’ begin
        (((πŸ™ ∧ p) Β· n + s) ∧ (n + z)) Β· q              β‰‘βŸ¨ Β·-distribΚ³-∧ _ ((πŸ™ ∧ p) Β· _ + _) _ ⟩
        ((πŸ™ ∧ p) Β· n + s) Β· q ∧ (n + z) Β· q            β‰‘βŸ¨ ∧-cong (Β·-distribΚ³-+ _ ((πŸ™ ∧ p) Β· _) _)
                                                            (·-distribʳ-+ _ n _) ⟩
        (((πŸ™ ∧ p) Β· n) Β· q + s Β· q) ∧ (n Β· q + z Β· q)  β‰‘βŸ¨ ∧-congΚ³ (+-congΚ³ (Β·-assoc (πŸ™ ∧ p) _ _)) ⟩
        ((πŸ™ ∧ p) Β· (n Β· q) + s Β· q) ∧ (n Β· q + z Β· q)  ∎
      πŸ™ β†’ begin
        ((πŸ™ + p) Β· n + Ο‰ Β· s + z) Β· q            β‰‘βŸ¨ Β·-distribΚ³-+ _ ((πŸ™ + p) Β· _) _ ⟩
        ((πŸ™ + p) Β· n) Β· q + (Ο‰ Β· s + z) Β· q      β‰‘βŸ¨ +-congΛ‘ (Β·-distribΚ³-+ _ (Ο‰ Β· s) _) ⟩
        ((πŸ™ + p) Β· n) Β· q + (Ο‰ Β· s) Β· q + z Β· q  β‰‘βŸ¨ +-cong (Β·-assoc (πŸ™ + p) _ _)
                                                      (+-congΚ³ (Β·-assoc Ο‰ s _)) ⟩
        (πŸ™ + p) Β· (n Β· q) + Ο‰ Β· (s Β· q) + z Β· q  ∎
      Ο‰ β†’ begin
        (Ο‰ Β· (n + s + z)) Β· q        β‰‘βŸ¨ Β·-assoc _ _ _ ⟩
        Ο‰ Β· ((n + s + z) Β· q)        β‰‘βŸ¨ Β·-congΛ‘ (Β·-distribΚ³-+ _ n _) ⟩
        Ο‰ Β· (n Β· q + (s + z) Β· q)    β‰‘βŸ¨ Β·-congΛ‘ (+-congΛ‘ (Β·-distribΚ³-+ _ s _)) ⟩
        Ο‰ Β· (n Β· q + s Β· q + z Β· q)  ∎
    where
    open Tools.Reasoning.PartialOrder ≀-poset

  nr-+ :
    βˆ€ p r β†’
    nr p r z₁ s₁ n₁ + nr p r zβ‚‚ sβ‚‚ nβ‚‚ ≀
    nr p r (z₁ + zβ‚‚) (s₁ + sβ‚‚) (n₁ + nβ‚‚)
  nr-+ {z₁ = z₁} {s₁ = s₁} {n₁ = n₁} {zβ‚‚ = zβ‚‚} {sβ‚‚ = sβ‚‚} {nβ‚‚ = nβ‚‚} p =
    Ξ» where
      𝟘 β†’ begin
        (((πŸ™ ∧ p) Β· n₁ + s₁) ∧ (n₁ + z₁)) +
        (((πŸ™ ∧ p) Β· nβ‚‚ + sβ‚‚) ∧ (nβ‚‚ + zβ‚‚))                            β‰€βŸ¨ +-sub-interchangeable-∧ ((πŸ™ ∧ p) Β· _ + _) _ _ _ ⟩

        (((πŸ™ ∧ p) Β· n₁ + s₁) + ((πŸ™ ∧ p) Β· nβ‚‚ + sβ‚‚)) ∧
        ((n₁ + z₁) + (nβ‚‚ + zβ‚‚))                                      β‰‘βŸ¨ ∧-cong (+-sub-interchangeable-+ ((πŸ™ ∧ p) Β· _) _ _ _)
                                                                          (+-sub-interchangeable-+ n₁ _ _ _) ⟩
        (((πŸ™ ∧ p) Β· n₁ + (πŸ™ ∧ p) Β· nβ‚‚) + (s₁ + sβ‚‚)) ∧
        ((n₁ + nβ‚‚) + (z₁ + zβ‚‚))                                      β‰‘Λ˜βŸ¨ ∧-congΚ³ (+-congΚ³ (Β·-distribΛ‘-+ (πŸ™ ∧ p) _ _)) ⟩

        ((πŸ™ ∧ p) Β· (n₁ + nβ‚‚) + (s₁ + sβ‚‚)) ∧ ((n₁ + nβ‚‚) + (z₁ + zβ‚‚))  ∎
      πŸ™ β†’ begin
        ((πŸ™ + p) Β· n₁ + Ο‰ Β· s₁ + z₁) + ((πŸ™ + p) Β· nβ‚‚ + Ο‰ Β· sβ‚‚ + zβ‚‚)    β‰‘βŸ¨ +-sub-interchangeable-+ ((πŸ™ + p) Β· _) _ _ _ ⟩
        ((πŸ™ + p) Β· n₁ + (πŸ™ + p) Β· nβ‚‚) + (Ο‰ Β· s₁ + z₁) + (Ο‰ Β· sβ‚‚ + zβ‚‚)  β‰‘βŸ¨ +-cong (sym (Β·-distribΛ‘-+ (πŸ™ + p) _ _))
                                                                            (+-sub-interchangeable-+ (Ο‰ Β· s₁) _ _ _) ⟩
        (πŸ™ + p) Β· (n₁ + nβ‚‚) + (Ο‰ Β· s₁ + Ο‰ Β· sβ‚‚) + (z₁ + zβ‚‚)            β‰‘Λ˜βŸ¨ +-congΛ‘ {x = (πŸ™ + p) Β· _}
                                                                             (+-congΚ³ (Β·-distribΛ‘-+ Ο‰ s₁ _)) ⟩
        (πŸ™ + p) Β· (n₁ + nβ‚‚) + Ο‰ Β· (s₁ + sβ‚‚) + (z₁ + zβ‚‚)                ∎
      Ο‰ β†’ begin
        Ο‰ Β· (n₁ + s₁ + z₁) + Ο‰ Β· (nβ‚‚ + sβ‚‚ + zβ‚‚)  β‰‘Λ˜βŸ¨ Β·-distribΛ‘-+ _ (n₁ + _) _ ⟩
        Ο‰ Β· ((n₁ + s₁ + z₁) + (nβ‚‚ + sβ‚‚ + zβ‚‚))    β‰‘βŸ¨ Β·-congΛ‘ lemma ⟩
        Ο‰ Β· ((n₁ + nβ‚‚) + (s₁ + sβ‚‚) + (z₁ + zβ‚‚))  ∎
    where
    lemma =
      (n₁ + s₁ + z₁) + (nβ‚‚ + sβ‚‚ + zβ‚‚)    β‰‘βŸ¨ +-sub-interchangeable-+ n₁ _ _ _ ⟩
      (n₁ + nβ‚‚) + (s₁ + z₁) + (sβ‚‚ + zβ‚‚)  β‰‘βŸ¨ +-congΛ‘ {x = n₁ + _}
                                              (+-sub-interchangeable-+ s₁ _ _ _) ⟩
      (n₁ + nβ‚‚) + (s₁ + sβ‚‚) + (z₁ + zβ‚‚)  ∎
      where
      open Tools.Reasoning.PropositionalEquality

    open Tools.Reasoning.PartialOrder ≀-poset

  nr-zero : βˆ€ p r β†’ n ≀ 𝟘 β†’ nr p r z s n ≀ z
  nr-zero {n = n} {z = z} {s = s} p r nβ‰€πŸ˜ =
    case nr-view p r z s n of Ξ» where
      (nrβ‰‘πŸ˜ β‰‘πŸ˜) β†’ begin
        nr p r 𝟘 𝟘 𝟘  β‰‘βŸ¨ β‰‘πŸ˜ ⟩
        𝟘             ∎
      (nrβ‰‘πŸ™β‚ β‰‘πŸ™) β†’ begin
        nr p 𝟘 πŸ™ πŸ™ 𝟘  β‰‘βŸ¨ β‰‘πŸ™ ⟩
        πŸ™             ∎
      (nrβ‰‘πŸ™β‚‚ β‰‘πŸ™) β†’ begin
        nr p πŸ™ πŸ™ 𝟘 𝟘  β‰‘βŸ¨ β‰‘πŸ™ ⟩
        πŸ™             ∎
      nrβ‰‘πŸ™β‚ƒ β†’ begin
        πŸ™  β‰€βŸ¨ nβ‰€πŸ˜ ⟩
        𝟘  ∎
      nrβ‰‘πŸ™β‚„ β†’ begin
        πŸ™  β‰€βŸ¨ nβ‰€πŸ˜ ⟩
        𝟘  ∎
      (nrβ‰‘πŸ™βˆ§πŸ˜ nrβ‰‘πŸ™βˆ§πŸ˜β‚ β‰‘πŸ˜βˆ§πŸ™) β†’ begin
        ((πŸ™ ∧ p) Β· 𝟘 + 𝟘) ∧ πŸ™  β‰‘βŸ¨ β‰‘πŸ˜βˆ§πŸ™ ⟩
        𝟘 ∧ πŸ™                  β‰€βŸ¨ ∧-decreasingΚ³ 𝟘 πŸ™ ⟩
        πŸ™                      ∎
      (nrβ‰‘πŸ™βˆ§πŸ˜ nrβ‰‘πŸ™βˆ§πŸ˜β‚‚ β‰‘πŸ˜βˆ§πŸ™) β†’ begin
        ((πŸ™ ∧ p) Β· 𝟘 + πŸ™) ∧ 𝟘  β‰‘βŸ¨ β‰‘πŸ˜βˆ§πŸ™ ⟩
        𝟘 ∧ πŸ™                  β‰€βŸ¨ ∧-decreasingΛ‘ 𝟘 πŸ™ ⟩
        𝟘                      ∎
      (nrβ‰‘πŸ™βˆ§πŸ˜ nrβ‰‘πŸ™βˆ§πŸ˜β‚ƒ β‰‘πŸ˜βˆ§πŸ™) β†’ begin
        ((𝟘 ∧ πŸ™) Β· πŸ™ + 𝟘) ∧ πŸ™  β‰‘βŸ¨ β‰‘πŸ˜βˆ§πŸ™ ⟩
        𝟘 ∧ πŸ™                  β‰€βŸ¨ ∧-decreasingΛ‘ 𝟘 πŸ™ ⟩
        𝟘                      ∎
      (nr≑ω _ ≑ω) β†’ begin
        nr p r z s n  β‰‘βŸ¨ ≑ω ⟩
        Ο‰             β‰€βŸ¨ refl ⟩
        z             ∎
    where
    open Tools.Reasoning.PartialOrder ≀-poset

  nr-suc : βˆ€ p r β†’ nr p r z s n ≀ s + p Β· n + r Β· nr p r z s n
  nr-suc {z = z} {s = s} {n = n} p r =
    case nr-view p r z s n of Ξ» where
      (nrβ‰‘πŸ˜ β‰‘πŸ˜) β†’ begin
        nr p r 𝟘 𝟘 𝟘                  β‰‘βŸ¨ β‰‘πŸ˜ ⟩
        𝟘                             β‰‘Λ˜βŸ¨ Β·-zeroΚ³ _ ⟩
        r Β· 𝟘                         β‰‘Λ˜βŸ¨ +-identityΛ‘ _ ⟩
        𝟘 + r Β· 𝟘                     β‰‘Λ˜βŸ¨ +-cong (Β·-zeroΚ³ p) (Β·-congΛ‘ β‰‘πŸ˜) ⟩
        p Β· 𝟘 + r Β· nr p r 𝟘 𝟘 𝟘      β‰‘βŸ¨βŸ©
        𝟘 + p · 𝟘 + r · nr p r 𝟘 𝟘 𝟘  ∎
      (nrβ‰‘πŸ™β‚ β‰‘πŸ™) β†’ begin
        nr p 𝟘 πŸ™ πŸ™ 𝟘                  β‰‘βŸ¨ β‰‘πŸ™ ⟩
        πŸ™                             β‰‘βŸ¨βŸ©
        πŸ™ + 𝟘 + 𝟘                     β‰‘Λ˜βŸ¨ +-congΛ‘ (+-congΚ³ {x = 𝟘} (Β·-zeroΚ³ p)) ⟩
        πŸ™ + p Β· 𝟘 + 𝟘                 β‰‘βŸ¨βŸ©
        πŸ™ + p Β· 𝟘 + 𝟘 Β· nr p 𝟘 πŸ™ πŸ™ 𝟘  ∎
      (nrβ‰‘πŸ™β‚‚ _) β†’ begin
        nr p πŸ™ πŸ™ 𝟘 𝟘                  β‰‘βŸ¨βŸ©
        𝟘 + nr p πŸ™ πŸ™ 𝟘 𝟘              β‰‘Λ˜βŸ¨ +-cong (Β·-zeroΚ³ p) (Β·-identityΛ‘ _) ⟩
        p Β· 𝟘 + πŸ™ Β· nr p πŸ™ πŸ™ 𝟘 𝟘      β‰‘Λ˜βŸ¨ +-identityΛ‘ _ ⟩
        𝟘 + p Β· 𝟘 + πŸ™ Β· nr p πŸ™ πŸ™ 𝟘 𝟘  ∎
      nrβ‰‘πŸ™β‚ƒ β†’ begin
        nr πŸ™ 𝟘 𝟘 𝟘 πŸ™                  β‰‘βŸ¨βŸ©
        πŸ™                             β‰‘βŸ¨βŸ©
        𝟘 + πŸ™ Β· πŸ™ + 𝟘 Β· nr πŸ™ 𝟘 𝟘 𝟘 πŸ™  ∎
      nrβ‰‘πŸ™β‚„ β†’ begin
        nr 𝟘 πŸ™ 𝟘 𝟘 πŸ™                  β‰‘βŸ¨βŸ©
        πŸ™                             β‰‘βŸ¨βŸ©
        𝟘 + 𝟘 Β· πŸ™ + πŸ™ Β· nr πŸ™ 𝟘 𝟘 𝟘 πŸ™  ∎
      (nrβ‰‘πŸ™βˆ§πŸ˜ nrβ‰‘πŸ™βˆ§πŸ˜β‚ β‰‘πŸ˜βˆ§πŸ™) β†’ begin
        ((πŸ™ ∧ p) Β· 𝟘 + 𝟘) ∧ πŸ™  β‰‘βŸ¨ β‰‘πŸ˜βˆ§πŸ™ ⟩
        𝟘 ∧ πŸ™                  β‰€βŸ¨ ∧-decreasingΛ‘ 𝟘 πŸ™ ⟩
        𝟘                      β‰‘Λ˜βŸ¨ Β·-zeroΚ³ _ ⟩
        p Β· 𝟘                  β‰‘Λ˜βŸ¨ +-identityΚ³ _ ⟩
        p · 𝟘 + 𝟘              ∎
      (nrβ‰‘πŸ™βˆ§πŸ˜ nrβ‰‘πŸ™βˆ§πŸ˜β‚‚ β‰‘πŸ˜βˆ§πŸ™) β†’ begin
        ((πŸ™ ∧ p) Β· 𝟘 + πŸ™) ∧ 𝟘  β‰‘βŸ¨ β‰‘πŸ˜βˆ§πŸ™ ⟩
        𝟘 ∧ πŸ™                  β‰€βŸ¨ ∧-decreasingΚ³ 𝟘 πŸ™ ⟩
        πŸ™                      β‰‘Λ˜βŸ¨ +-identityΚ³ _ ⟩
        πŸ™ + 𝟘                  β‰‘Λ˜βŸ¨ cong (_ +_) (Β·-zeroΚ³ p) ⟩
        πŸ™ + p Β· 𝟘              β‰‘Λ˜βŸ¨ cong (_ +_) (+-identityΚ³ (p Β· _)) ⟩
        πŸ™ + p Β· 𝟘 + 𝟘          ∎
      (nrβ‰‘πŸ™βˆ§πŸ˜ nrβ‰‘πŸ™βˆ§πŸ˜β‚ƒ β‰‘πŸ˜βˆ§πŸ™) β†’ begin
        ((𝟘 ∧ πŸ™) Β· πŸ™ + 𝟘) ∧ πŸ™  β‰‘βŸ¨ β‰‘πŸ˜βˆ§πŸ™ ⟩
        𝟘 ∧ πŸ™                  β‰€βŸ¨ ∧-decreasingΛ‘ 𝟘 πŸ™ ⟩
        𝟘                      ∎
      (nr≑ω _ ≑ω) β†’ begin
        nr p r z s n                  β‰‘βŸ¨ ≑ω ⟩
        Ο‰                             β‰€βŸ¨ refl ⟩
        s + p · n + r · nr p r z s n  ∎
    where
    open Tools.Reasoning.PartialOrder ≀-poset

-- A modality defined using zero-one-many-has-nr.

zero-one-many-modality : Modality-variant β†’ Modality
zero-one-many-modality variant = record
  { variant            = variant
  ; semiring-with-meet = zero-one-many-semiring-with-meet
  ; 𝟘-well-behaved     = Ξ» _ β†’ zero-one-many-has-well-behaved-zero
  ; has-nr             = Ξ» _ β†’ zero-one-many-has-nr
  }