------------------------------------------------------------------------
-- 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.Function
open import Tools.Level
open import Tools.Nullary
open import Tools.Product
open import Tools.PropositionalEquality as PE
import Tools.Reasoning.PartialOrder
import Tools.Reasoning.PropositionalEquality
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
  p p₁ pβ‚‚ q r : Zero-one-many

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

------------------------------------------------------------------------
-- 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 πŸ™β‰€πŸ˜ is false, then πŸ˜βˆ§πŸ™Β β‰‘Β Ο‰.

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

-- 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)

------------------------------------------------------------------------
-- 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

-- 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 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
  { _+_          = _+_
  ; _Β·_          = _Β·_
  ; _∧_          = _∧_
  ; 𝟘            = 𝟘
  ; πŸ™            = πŸ™
  ; +-Β·-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
        }
      ; *-isMonoid = record
        { isSemigroup = record
          { isMagma = record
            { isEquivalence = PE.isEquivalence
            ; βˆ™-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

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
  { πŸ™β‰’πŸ˜ = Ξ» ()
  ; is-𝟘? = λ where
      𝟘 β†’ yes refl
      πŸ™ β†’ no (Ξ» ())
      Ο‰ β†’ no (Ξ» ())
  ; 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 = 𝟘} πŸ˜βˆ§πŸ™β‰‘πŸ˜ β†’
        PE.βŠ₯-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 variant where 𝟘ᡐ is allowed and a
-- dedicated natrec-star operator is *not* available is only defined
-- if πŸ™Β β‰€Β πŸ˜. The dedicated natrec-star operator, if any, is defined
-- using the construction in Graded.Modality.Instances.LowerBounded.

zero-one-many-lower-bounded :
  (variant : Modality-variant) β†’
  let open Modality-variant variant in
  (T 𝟘ᡐ-allowed β†’ Β¬ βŠ›-available β†’ T πŸ™β‰€πŸ˜) β†’
  Modality
zero-one-many-lower-bounded variant hyp = record
  { variant            = variant
  ; semiring-with-meet = zero-one-many-semiring-with-meet
  ; 𝟘-well-behaved     = Ξ» _ β†’ zero-one-many-has-well-behaved-zero
  ; has-star           = Ξ» _ β†’ zero-one-many-lower-bounded-star
  ; +-decreasingΛ‘      = Ξ» ok no-star β†’ +-decreasingΛ‘ (hyp ok no-star)
  }

------------------------------------------------------------------------
-- 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 Ξ» ()

-- The zero-one-many modality (with arbitrary "restrictions").
--
-- The variant where 𝟘ᡐ is allowed and a dedicated natrec-star
-- operator is *not* available is only defined if πŸ™Β β‰€Β πŸ˜. The dedicated
-- natrec-star operator, if any, is the "greatest" one defined above.

zero-one-many-greatest :
  (variant : Modality-variant) β†’
  let open Modality-variant variant in
  (T 𝟘ᡐ-allowed β†’ Β¬ βŠ›-available β†’ T πŸ™β‰€πŸ˜) β†’
  Modality
zero-one-many-greatest variant hyp = record
  { variant            = variant
  ; semiring-with-meet = zero-one-many-semiring-with-meet
  ; 𝟘-well-behaved     = Ξ» _ β†’ zero-one-many-has-well-behaved-zero
  ; has-star           = Ξ» _ β†’ zero-one-many-greatest-star
  ; +-decreasingΛ‘      = Ξ» ok no-star β†’ +-decreasingΛ‘ (hyp ok no-star)
  }