{-# OPTIONS --without-K #-} 

-- Defines a modal separation logic for predicates over effects, based on the
-- ternary effect separation predicate defined in Effect.Separation 

open import Relation.Unary
open import Relation.Binary hiding (_⇒_)
open import Relation.Binary.PropositionalEquality

open import Effect.Base

open import Data.Product
open import Function using (_$_ ; _∘_)
open import Level

open import Core.Container using (_⇿_ ; ⇿-sym)
open import Core.Extensionality

open import Core.Ternary

module Core.Logic {c } {Carrier : Set c}  w : HasRel₃ Carrier    where

  open import Core.MonotonePredicate Carrier _≲_
  
  -- Separating conjunction
  record _✴_ (P Q : Pred Carrier ) (x : Carrier) : Set (  c) where 
    constructor _✴⟨_⟩_
    field
      {xₗ xᵣ} : Carrier
      px  : P xₗ
      sep : xₗ  xᵣ  x
      qx  : Q xᵣ  

  -- Separating implication, or, the "magic wand" 
  record _─✴_ (P Q : Pred Carrier ) (x : Carrier) : Set (  c) where
    constructor wand
    field
      _⟨_⟩_ :  {x₁ x₂}  x  x₁  x₂  P x₁  Q x₂
  
  open _✴_  public 
  open _─✴_ public 

  -- Separating implication is right-adjoint to separating conjunction, as
  -- witnessed by the following functions (which should be inverses)
  
  -- Some this I have yet to verify, and all of it is digression. But some
  -- remarks:
  --
  -- The currying/uncurring functions above witness that the category of
  -- monotone predicates over effects has a closed monoidal structure, with ✷ as
  -- the tensor product.
  --
  -- Later, we will see that this is not the only closed monoidal structure on
  -- this category. In fact, the "regular" (i.e., non-separating) conjunction of
  -- predicates also has a right adjoint: the Kripke function space!
  --
  -- One might wonder what sets these monoidal structures apart. Squinting a
  -- little, we can see that the definition of separating conjunction above is
  -- strikinly similar to how Day's convolution product is computed using
  -- coends. The immediate follow-up question is wether separating conjunction
  -- preserves the monoidal structure of its inputs. If so, it, together with
  -- the magic wand (whose definition, incidently, precisely mimics how the
  -- right adjoint of the Day convolution product is usually computed in terms
  -- of ends) defines a closed monoidal structure on the category of monotone
  -- *monoidal* predicates over effects. 
  

  {- Boxes and diamonds -} 
  
  
  -- The posibility modality. One way to think about posibility is as a unary
  -- version of separating conjunction. 
  record  (P : Pred Carrier ) (x : Carrier) : Set (c  ) where
    constructor ◇⟨_⟩_ 
    field
      {x′}    : Carrier
      i       : x′  x 
      px      : P x′ 
  
  open  public 
  
  -- The necessity modality. In a similar spirit, we can view necessity as a unary
  -- version of separating implication.
  record  (P : Pred Carrier ) (x : Carrier) : Set (c  ) where
    constructor necessary 
    field
      □⟨_⟩_ :  {x′}  x  x′  P x′
      
  open  public 

  nec :  {P x}  (∀ {x′}   x  x′   P x′)   P x 
  nec f = necessary  i  f  i ⦄)




  {- TODO: definitions below hinge on the fact that the carrier and ternary
  relation live in the same universe. This is the case for (h.o.) effects, but
  question remains how can we bring back these defs. for the current more
  general definition? -}


  -- □-extract : ∀[ □ P ⇒ P ]
  -- □-extract px = □⟨ px ⟩ ≲-refl 

  -- □-duplicate : ∀[ □ P ⇒ □ (□ P ) ]
  -- □-duplicate px = necessary (λ i → necessary (λ i′ → □⟨ px ⟩ ≲-trans i i′)) 


  -- -- All necessities are monotone by default, if the stored function space
  -- -- respects equivalence of inclusion witnesses
  -- instance □-monotone : Monotone (□ P)
  -- □-monotone .weaken i px =
  --   necessary (λ i′ → □⟨ px ⟩ ≲-trans i i′) 
  
  -- □-resp-⇿ : ε₁ ⇿ ε₂ → □ P ε₁ → □ P ε₂
  -- □-resp-⇿ eq px = necessary (λ i → □⟨ px ⟩ ≲-respects-⇿ˡ (⇿-sym eq) i)

  -- Box and diamond are adjoint functors on the category of monotone predicates



  -- mod-curry : ∀[ ◇ P ⇒ Q ] → ∀[ P ⇒ □ Q ]
  -- mod-curry f px = necessary (λ i → f $ ◇⟨ i ⟩ px)
  
  -- mod-uncurry : ∀[ P ⇒ □ Q ] → ∀[ ◇ P ⇒ Q ]
  -- mod-uncurry f (◇⟨ i ⟩ px) = □⟨ f px ⟩ i
  


  -- -- A "Kripke closed monoidal structure" on the category of monotone predicates 
  
  -- -- The "Kripke exponent" (or, Kripke function space) between two predicates is
  -- -- defined as the necessity of their implication.
  -- _⇛_ : (P Q : Pred Effect ℓ) → Pred Effect (suc 0ℓ ⊔ ℓ) 
  -- P ⇛ Q = □ (P ⇒ Q) 
  
  -- kripke-curry : ⦃ Monotone P₁ ⦄ → ∀[ (P₁ ∩ P₂) ⇒ Q ] → ∀[ P₁ ⇒ (P₂ ⇛ Q) ] 
  -- kripke-curry f px₁ = necessary (λ i px₂ → f (weaken i px₁ , px₂))
  
  -- kripke-uncurry : ∀[ P₁ ⇒ (P₂ ⇛ Q) ] → ∀[ (P₁ ∩ P₂) ⇒ Q ] 
  -- kripke-uncurry f (px₁ , px₂) = □⟨ f px₁ ⟩ ≲-refl $ px₂
  
  -- ✴-curry : ∀[ (P₁ ✴ P₂) ⇒ Q ] → ∀[ P₁ ⇒ (P₂ ─✴ Q) ]
  -- ✴-curry f px₁ = wand (λ σ px₂ → f (px₁ ✴⟨ σ ⟩ px₂))
                                                 
  -- ✴-uncurry : ∀[ P₁ ⇒ (P₂ ─✴ Q) ] → ∀[ (P₁ ✴ P₂) ⇒ Q ]
  -- ✴-uncurry f (px₁ ✴⟨ σ ⟩ px₂) = f px₁ ⟨ σ ⟩ px₂