{-# OPTIONS --rewriting #-}

-- Open/extensional modality.

module Calf.Phase.Open where

open import Calf.Prelude
open import Calf.CBPV
open import Relation.Binary.PropositionalEquality as Eq using (_≡_; refl)

open import Calf.Phase.Core


 :   
 𝕁 = (u : ext)  𝕁

postulate
  open⁺ : (ext  tp⁺)  tp⁺
  open⁺/decode :  {A}  val (open⁺ A)  ((u : ext)  val (A u))
  {-# REWRITE open⁺/decode #-}

  open⁻ : (ext  tp⁻)  tp⁻
  open⁻/decode :  {A}  val (U (open⁻ A))  ((u : ext)  cmp (A u))
  {-# REWRITE open⁻/decode #-}

infix 10 ◯⁺_ ◯⁻_
◯⁺_ : tp⁺  tp⁺
◯⁺ A = open⁺ λ _  A
◯⁻_ : tp⁻  tp⁻
◯⁻ A = open⁻ λ _  A


module _ where
  open import Algebra.Cost

  ◯-CostMonoid : CostMonoid  CostMonoid
  ◯-CostMonoid cm =
    record
      {  =  
      ; _+_ = λ c₁ c₂ u  c₁ u + c₂ u
      ; zero = λ u  zero
      ; _≤_ = λ c₁ c₂  (u : ext)  c₁ u  c₂ u
      ; isCostMonoid =
          record
            { isMonoid =
                record
                  { isSemigroup =
                      record
                        { isMagma =
                            record
                              { isEquivalence = Eq.isEquivalence
                              ; ∙-cong = Eq.cong₂ _
                              }
                        ; assoc = λ c₁ c₂ c₃  funext/Ω λ u  +-assoc (c₁ u) (c₂ u) (c₃ u)
                        }
                  ; identity =
                       c  funext/Ω λ u  +-identityˡ (c u)) ,
                       c  funext/Ω λ u  +-identityʳ (c u))
                  }
            ; isPreorder =
                record
                  { isEquivalence = Eq.isEquivalence
                  ; reflexive = λ h u  ≤-reflexive (Eq.cong  x  x u) h)
                  ; trans = λ h₁ h₂ u  ≤-trans (h₁ u) (h₂ u)
                  }
            ; isMonotone =
                record
                  { ∙-mono-≤ = λ h₁ h₂ u  +-mono-≤ (h₁ u) (h₂ u)
                  }
            }
      }
      where
        open CostMonoid cm
        open import Data.Product