{-# OPTIONS --sized-types #-}

-- Basic intuitionistic propositional calculus, without ∨ or ⊥.
-- Tarski-style semantics with glueing for α and ▻, after Coquand-Dybjer.
-- Implicit closed syntax.

module A201607.BasicIPC.Semantics.TarskiGluedClosedImplicit where

open import A201607.BasicIPC.Syntax.Common public
open import A201607.Common.Semantics public


-- Tarski models.

record Model : Set₁ where
  infix 3 ⊩ᵅ_
  field
    -- Forcing for atomic propositions.
    ⊩ᵅ_ : Atom → Set

open Model {{…}} public




module ImplicitSyntax
    ([⊢]_ : Ty → Set)
  where


  -- Forcing in a particular model.

  module _ {{_ : Model}} where
    infix 3 ⊩_
    ⊩_ : Ty → Set
    ⊩ α P   = Glue ([⊢] (α P)) (⊩ᵅ P)
    ⊩ A ▻ B = Glue ([⊢] (A ▻ B)) (⊩ A → ⊩ B)
    ⊩ A ∧ B = ⊩ A × ⊩ B
    ⊩ ⊤    = 𝟙

    infix 3 ⊩⋆_
    ⊩⋆_ : Cx Ty → Set
    ⊩⋆ ∅     = 𝟙
    ⊩⋆ Ξ , A = ⊩⋆ Ξ × ⊩ A


  -- Entailment, or forcing in all models.

  infix 3 ⊨_
  ⊨_ : Ty → Set₁
  ⊨ A = ∀ {{_ : Model}} → ⊩ A


  -- Additional useful equipment.

  module _ {{_ : Model}} where
    _⟪$⟫_ : ∀ {A B} → ⊩ A ▻ B → ⊩ A → ⊩ B
    s ⟪$⟫ a = sem s a

    ⟪S⟫ : ∀ {A B C} → ⊩ A ▻ B ▻ C → ⊩ A ▻ B → ⊩ A → ⊩ C
    ⟪S⟫ s₁ s₂ a = (s₁ ⟪$⟫ a) ⟪$⟫ (s₂ ⟪$⟫ a)


  -- Forcing in a particular model, for sequents.

  module _ {{_ : Model}} where
    infix 3 ⊩_⇒_
    ⊩_⇒_ : Cx Ty → Ty → Set
    ⊩ Γ ⇒ A = ⊩⋆ Γ → ⊩ A

    infix 3 ⊩_⇒⋆_
    ⊩_⇒⋆_ : Cx Ty → Cx Ty → Set
    ⊩ Γ ⇒⋆ Ξ = ⊩⋆ Γ → ⊩⋆ Ξ


  -- Entailment, or forcing in all models, for sequents.

  infix 3 _⊨_
  _⊨_ : Cx Ty → Ty → Set₁
  Γ ⊨ A = ∀ {{_ : Model}} → ⊩ Γ ⇒ A

  infix 3 _⊨⋆_
  _⊨⋆_ : Cx Ty → Cx Ty → Set₁
  Γ ⊨⋆ Ξ = ∀ {{_ : Model}} → ⊩ Γ ⇒⋆ Ξ


  -- Additional useful equipment, for sequents.

  module _ {{_ : Model}} where
    lookup : ∀ {A Γ} → A ∈ Γ → ⊩ Γ ⇒ A
    lookup top     (γ , a) = a
    lookup (pop i) (γ , b) = lookup i γ

    ⟦λ⟧ : ∀ {A B Γ} → [⊢] (A ▻ B) → ⊩ Γ , A ⇒ B → ⊩ Γ ⇒ A ▻ B
    ⟦λ⟧ t s γ = t ⅋ λ a → s (γ , a)

    _⟦$⟧_ : ∀ {A B Γ} → ⊩ Γ ⇒ A ▻ B → ⊩ Γ ⇒ A → ⊩ Γ ⇒ B
    (s₁ ⟦$⟧ s₂) γ = s₁ γ ⟪$⟫ s₂ γ

    ⟦S⟧ : ∀ {A B C Γ} → ⊩ Γ ⇒ A ▻ B ▻ C → ⊩ Γ ⇒ A ▻ B → ⊩ Γ ⇒ A → ⊩ Γ ⇒ C
    ⟦S⟧ s₁ s₂ a γ = ⟪S⟫ (s₁ γ) (s₂ γ) (a γ)

    _⟦,⟧_ : ∀ {A B Γ} → ⊩ Γ ⇒ A → ⊩ Γ ⇒ B → ⊩ Γ ⇒ A ∧ B
    (a ⟦,⟧ b) γ = a γ , b γ

    ⟦π₁⟧ : ∀ {A B Γ} → ⊩ Γ ⇒ A ∧ B → ⊩ Γ ⇒ A
    ⟦π₁⟧ s γ = π₁ (s γ)

    ⟦π₂⟧ : ∀ {A B Γ} → ⊩ Γ ⇒ A ∧ B → ⊩ Γ ⇒ B
    ⟦π₂⟧ s γ = π₂ (s γ)