{-# OPTIONS --cubical-compatible --safe #-}
open import Forcing.Base
module Forcing.Semantics (L… : ForcingNotion) where
open import Data.List
open import Data.List.Membership.Propositional renaming (_∈_ to _⋿_)
open import Data.List.Relation.Unary.All
open import Relation.Binary.PropositionalEquality
open import Data.Unit
open import Data.Empty
open import Data.Sum
open import Data.Product
import Relation.Unary
open import Forcing.Monad (L…)
open ForcingNotion L…
Ty : Set₁
Ty = Set
Cxt : Set₁
Cxt = List Set
Env : Cxt → Set₁
Env Γ = All (λ ty → ty) Γ
data Term (Γ : Cxt) (ty : Ty) : Set₁ where
var : ty ⋿ Γ → Term Γ ty
lit : ty → Term Γ ty
app : {ty' : Ty} → Term Γ (ty' → ty) → Term Γ ty' → Term Γ ty
data Fragment : Set where
coherent first-order : Fragment
data Language : Set₁ where
base : Language
with-generic-filter : Language
infixr 1 _∨_
infixr 2 _∧_
data Formula (Γ : Cxt) : Fragment → Language → Set₁ where
Rel₂ : {frag : Fragment} {lang : Language} {ty ty' : Ty} → (ty → ty' → Set) → Term Γ ty → Term Γ ty' → Formula Γ frag lang
top : {frag : Fragment} {lang : Language} → Formula Γ frag lang
bot : {frag : Fragment} {lang : Language} → Formula Γ frag lang
_∨_ : {frag : Fragment} {lang : Language} → Formula Γ frag lang → Formula Γ frag lang → Formula Γ frag lang
_∧_ : {frag : Fragment} {lang : Language} → Formula Γ frag lang → Formula Γ frag lang → Formula Γ frag lang
_⇒_ : {frag : Fragment} {lang : Language} → Formula Γ frag lang → Formula Γ frag lang → Formula Γ first-order lang
EX : {frag : Fragment} {lang : Language} {ty : Ty} → Formula (ty ∷ Γ) frag lang → Formula Γ frag lang
FA : {frag : Fragment} {lang : Language} {ty : Ty} → Formula (ty ∷ Γ) frag lang → Formula Γ first-order lang
G : {frag : Fragment} → Term Γ L → Formula Γ frag with-generic-filter
1ˢᵗ : {Γ : Cxt} {frag : Fragment} {lang : Language} → Formula Γ frag lang → Formula Γ first-order lang
1ˢᵗ (Rel₂ R s t) = Rel₂ R s t
1ˢᵗ top = top
1ˢᵗ bot = top
1ˢᵗ (φ ∨ ψ) = 1ˢᵗ φ ∨ 1ˢᵗ ψ
1ˢᵗ (φ ∧ ψ) = 1ˢᵗ φ ∧ 1ˢᵗ ψ
1ˢᵗ (φ ⇒ ψ) = 1ˢᵗ φ ⇒ 1ˢᵗ ψ
1ˢᵗ (EX φ) = EX (1ˢᵗ φ)
1ˢᵗ (FA φ) = FA (1ˢᵗ φ)
1ˢᵗ (G t) = G t
eval : {Γ : Cxt} {ty : Ty} → Env Γ → Term Γ ty → ty
eval env (var v) = Data.List.Relation.Unary.All.lookup env v
eval env (lit u) = u
eval env (app f u) = eval env f (eval env u)
exec : {frag : Fragment} {Γ : Cxt} → Env Γ → Formula Γ frag base → Set
exec env (Rel₂ R s t) = R (eval env s) (eval env t)
exec env top = ⊤
exec env bot = ⊥
exec env (φ ∨ ψ) = exec env φ ⊎ exec env ψ
exec env (φ ∧ ψ) = exec env φ × exec env ψ
exec env (φ ⇒ ψ) = exec env φ → exec env ψ
exec env (EX φ) = Σ[ x ∈ _ ] exec (x ∷ env) φ
exec env (FA φ) = (x : _) → exec (x ∷ env) φ
execP : {{x : L}} {frag : Fragment} {lang : Language} {Γ : Cxt} → Env Γ → Formula Γ frag lang → Set
execP {{x}} env (Rel₂ R s t) = R (eval env s) (eval env t)
execP {{x}} env top = ⊤
execP {{x}} env bot = ⊥
execP {{x}} env (φ ∨ ψ) = execP {{x}} env φ ⊎ execP {{x}} env ψ
execP {{x}} env (φ ∧ ψ) = execP env φ × execP env ψ
execP {{x}} env (φ ⇒ ψ) = {{y : L}} {{y≼x : y ≼ x}} → execP {{y}} env φ → execP {{y}} env ψ
execP {{x}} env (EX φ) = Σ[ u ∈ _ ] execP {{x}} (u ∷ env) φ
execP {{x}} env (FA φ) = {{y : L}} {{y≼x : y ≼ x}} (u : _) → execP {{y}} (u ∷ env) φ
execP {{x}} env (G t) = x ≼ eval env t
exec∇ : {{x : L}} {frag : Fragment} {lang : Language} {Γ : Cxt} → Env Γ → Formula Γ frag lang → Set
exec∇ {{x}} env (Rel₂ R s t) = ∇ (R (eval env s) (eval env t))
exec∇ {{x}} env top = ⊤
exec∇ {{x}} env bot = ∇ ⊥
exec∇ {{x}} env (φ ∨ ψ) = ∇ (λ {{x}} → exec∇ {{x}} env φ ⊎ exec∇ {{x}} env ψ)
exec∇ {{x}} env (φ ∧ ψ) = exec∇ env φ × exec∇ env ψ
exec∇ {{x}} env (φ ⇒ ψ) = {{y : L}} {{y≼x : y ≼ x}} → exec∇ {{y}} env φ → exec∇ {{y}} env ψ
exec∇ {{x}} env (EX φ) = ∇ (λ {{x}} → Σ[ u ∈ _ ] exec∇ {{x}} (u ∷ env) φ)
exec∇ {{x}} env (FA φ) = {{y : L}} {{y≼x : y ≼ x}} (u : _) → exec∇ {{y}} (u ∷ env) φ
exec∇ {{x}} env (G t) = ∇ (λ {{y}} → y ≼ eval env t)
weakenP
: {frag : Fragment} {lang : Language} {Γ : Cxt} {env : Env Γ}
→ (φ : Formula Γ frag lang)
→ {x y : L} → y ≼ x → execP {{x}} env φ → execP {{y}} env φ
weakenP (Rel₂ R s t) y≼x p = p
weakenP top y≼x p = p
weakenP (φ ∨ ψ) y≼x (inj₁ p) = inj₁ (weakenP φ y≼x p)
weakenP (φ ∨ ψ) y≼x (inj₂ p) = inj₂ (weakenP ψ y≼x p)
weakenP (φ ∧ ψ) y≼x (p , q) = weakenP φ y≼x p , weakenP ψ y≼x q
weakenP (φ ⇒ ψ) y≼x p {{z}} {{z≼y}} = λ q → p {{z}} {{≼-trans z≼y y≼x}} q
weakenP (EX φ) y≼x (u , p) = u , weakenP φ y≼x p
weakenP (FA φ) y≼x p {{z}} {{z≼y}} = λ u → p {{z}} {{≼-trans z≼y y≼x}} u
weakenP (G x) y≼x p = ≼-trans y≼x p
weaken
: {frag : Fragment} {lang : Language} {Γ : Cxt} {φ : Formula Γ frag lang} {env : Env Γ}
→ {x y : L} → y ≼ x → exec∇ {{x}} env φ → exec∇ {{y}} env φ
weaken {φ = Rel₂ R s t} y≼x p = weaken-ev (λ _ q → q) y≼x p
weaken {φ = top} y≼x p = tt
weaken {φ = bot} y≼x p = weaken-ev (λ _ q → q) y≼x p
weaken {φ = φ ∨ ψ} y≼x p = weaken-ev (λ z≼w → [ (λ q → inj₁ (weaken z≼w q)) , (λ q → inj₂ (weaken z≼w q)) ]′) y≼x p
weaken {φ = φ ∧ ψ} y≼x p = weaken y≼x (proj₁ p) , weaken y≼x (proj₂ p)
weaken {φ = φ ⇒ ψ} y≼x p {{z}} {{z≼y}} q = p {{z}} {{≼-trans z≼y y≼x}} q
weaken {φ = EX φ} y≼x p = weaken-ev (λ z≼w (u , q) → u , weaken z≼w q) y≼x p
weaken {φ = FA φ} y≼x p {{z}} {{z≼y}} u = p {{z}} {{≼-trans z≼y y≼x}} u
weaken {φ = G t} y≼x p = weaken-ev ≼-trans y≼x p
open import Data.List.Relation.Unary.Any
var₀ : {Γ : Cxt} {ty : Ty} → Term (ty ∷ Γ) ty
var₀ = var (here refl)
var₁ : {Γ : Cxt} {ty ty' : Ty} → Term (ty ∷ ty' ∷ Γ) ty'
var₁ = var (there (here refl))
var₂ : {Γ : Cxt} {ty ty' ty'' : Ty} → Term (ty ∷ ty' ∷ ty'' ∷ Γ) ty''
var₂ = var (there (there (here refl)))
lemma-exec-coherent₁
: {{x : L}} {lang : Language} {Γ : Cxt}
→ (env : Env Γ) (φ : Formula Γ coherent lang)
→ exec∇ env φ → ∇ (λ {{y}} → execP {{y}} env φ)
lemma-exec-coherent₁ env (Rel₂ R s t) p = p
lemma-exec-coherent₁ env top p = now tt
lemma-exec-coherent₁ env bot p = p ⟫= ⊥-elim
lemma-exec-coherent₁ env (φ ∨ ψ) p = p ⟫= λ {{y}} {{y≼x}} → [ (λ q → fmap {{y}} inj₁ (lemma-exec-coherent₁ {{y}} env φ q)), (λ q → fmap {{y}} inj₂ (lemma-exec-coherent₁ {{y}} env ψ q)) ]′
lemma-exec-coherent₁ env (φ ∧ ψ) p = lemma-exec-coherent₁ {{_}} env φ (proj₁ p) ⟫= λ {{y}} {{y≼x}} q → _⟫=_ {{y}} (lemma-exec-coherent₁ {{y}} env ψ (weaken y≼x (proj₂ p))) λ {{z}} {{z≼y}} r → now (weakenP φ z≼y q , r)
lemma-exec-coherent₁ env (EX φ) p = p ⟫= λ {{y}} {{y≼x}} (u , q) → _⟫=_ {{y}} (lemma-exec-coherent₁ {{y}} (u ∷ env) φ q) λ {{z}} {{z≼y}} r → now (u , r)
lemma-exec-coherent₁ env (G x) p = p
lemma-exec-coherent₂
: {{x : L}} {lang : Language} {Γ : Cxt}
→ (env : Env Γ) (φ : Formula Γ coherent lang)
→ ∇ (λ {{y}} → execP {{y}} env φ) → exec∇ env φ
lemma-exec-coherent₂ env (Rel₂ R s t) p = p
lemma-exec-coherent₂ env top p = tt
lemma-exec-coherent₂ env bot p = p
lemma-exec-coherent₂ env (φ ∨ ψ) p = fmap (λ {{y}} → [ (λ q → inj₁ (lemma-exec-coherent₂ {{y}} env φ (now q))) , (λ q → inj₂ (lemma-exec-coherent₂ {{y}} env ψ (now q))) ]′) p
lemma-exec-coherent₂ env (φ ∧ ψ) p = lemma-exec-coherent₂ env φ (fmap proj₁ p) , lemma-exec-coherent₂ env ψ (fmap proj₂ p)
lemma-exec-coherent₂ env (EX φ) p = p ⟫= λ {{y}} (u , q) → fmap {{y}} (u ,_) (now (lemma-exec-coherent₂ {{y}} (u ∷ env) φ (now q)))
lemma-exec-coherent₂ env (G x) p = p
lemma-exec-coherent₁'
: {{x : L}} {Γ : Cxt}
→ (env : Env Γ) (φ : Formula Γ coherent base)
→ execP env φ → exec env φ
lemma-exec-coherent₁' env (Rel₂ R s t) p = p
lemma-exec-coherent₁' env top p = p
lemma-exec-coherent₁' env (φ ∨ ψ) p = Data.Sum.map (lemma-exec-coherent₁' env φ) (lemma-exec-coherent₁' env ψ) p
lemma-exec-coherent₁' env (φ ∧ ψ) p = Data.Product.map (lemma-exec-coherent₁' env φ) (lemma-exec-coherent₁' env ψ) p
lemma-exec-coherent₁' env (EX φ) p = proj₁ p , lemma-exec-coherent₁' (proj₁ p ∷ env) φ (proj₂ p)
lemma-exec-coherent₂'
: {{x : L}} {Γ : Cxt}
→ (env : Env Γ) (φ : Formula Γ coherent base)
→ exec env φ → execP env φ
lemma-exec-coherent₂' env (Rel₂ R s t) p = p
lemma-exec-coherent₂' env top p = p
lemma-exec-coherent₂' env (φ ∨ ψ) p = Data.Sum.map (lemma-exec-coherent₂' env φ) (lemma-exec-coherent₂' env ψ) p
lemma-exec-coherent₂' env (φ ∧ ψ) p = Data.Product.map (lemma-exec-coherent₂' env φ) (lemma-exec-coherent₂' env ψ) p
lemma-exec-coherent₂' env (EX φ) p = proj₁ p , lemma-exec-coherent₂' (proj₁ p ∷ env) φ (proj₂ p)
module 1ˢᵗOrderEquivalence
(all-coverings-inhabited : {x : L} (R : Cov x) → Relation.Unary.Satisfiable (_◁ R)) where
open import Forcing.Monad.Conservative L… all-coverings-inhabited
thm₁
: {{x : L}}
→ {frag : Fragment} {Γ : Cxt}
→ (env : Env Γ) (φ : Formula Γ frag base)
→ exec env φ → exec∇ env φ
thm₂
: {{x : L}}
→ {frag : Fragment} {Γ : Cxt}
→ (env : Env Γ) (φ : Formula Γ frag base)
→ exec∇ {{x}} env φ → exec env φ
thm₁ env (Rel₂ R s t) p = now p
thm₁ env top p = p
thm₁ env (φ ∨ ψ) (inj₁ p) = now (inj₁ (thm₁ env φ p))
thm₁ env (φ ∨ ψ) (inj₂ p) = now (inj₂ (thm₁ env ψ p))
thm₁ env (φ ∧ ψ) (p , q) = thm₁ env φ p , thm₁ env ψ q
thm₁ env (φ ⇒ ψ) p {{y}} {{y≼x}} q = thm₁ {{y}} env ψ (p (thm₂ {{y}} env φ q))
thm₁ env (EX φ) (u , p) = now (u , thm₁ (u ∷ env) φ p)
thm₁ env (FA φ) p {{y}} {{y≼x}} = λ u → thm₁ {{y}} (u ∷ env) φ (p u)
thm₂ {{x}} env (Rel₂ R s t) p = escape p
thm₂ {{x}} env top p = tt
thm₂ {{x}} env bot p = escape p
thm₂ {{x}} env (φ ∨ ψ) p = escape (fmap {{x}} (λ {{y}} → [ (λ q → inj₁ (thm₂ {{y}} env φ q)) , (λ q → inj₂ (thm₂ {{y}} env ψ q)) ]′) p)
thm₂ {{x}} env (φ ∧ ψ) p = thm₂ env φ (proj₁ p) , thm₂ env ψ (proj₂ p)
thm₂ {{x}} env (φ ⇒ ψ) p = λ q → thm₂ {{x}} env ψ (p {{x}} {{≼-refl}} (thm₁ {{x}} env φ q))
thm₂ {{x}} env (EX φ) p = escape (fmap (λ {{y}} (u , q) → u , thm₂ {{y}} (u ∷ env) φ q) p)
thm₂ {{x}} env (FA φ) p = λ u → thm₂ (u ∷ env) φ (p {{x}} {{≼-refl}} u)
module CoherentEquivalence
(top : L)
(escape : {P : Set} → ∇ {{top}} P → P) where
thm₁
: {{x : L}}
→ {Γ : Cxt}
→ (env : Env Γ)
→ (φ ψ : Formula Γ coherent base)
→ exec env (φ ⇒ ψ) → exec∇ {{x}} env (φ ⇒ ψ)
thm₁ env φ ψ p {{y}} {{y≼x}} q = lemma-exec-coherent₂ {{y}} env ψ (fmap {{y}} (λ {{z}} → lemma-exec-coherent₂' {{z}} env ψ) (fmap {{y}} p (fmap {{y}} (λ {{z}} → lemma-exec-coherent₁' {{z}} env φ) (lemma-exec-coherent₁ {{y}} env φ q))))
thm₁⁺
: {ty : Ty}
→ (φ ψ : Formula (ty ∷ []) coherent base)
→ exec [] (FA (φ ⇒ ψ)) → exec∇ {{top}} [] (FA (φ ⇒ ψ))
thm₁⁺ φ ψ p {{y}} {{y≼top}} = λ u {{z}} {{z≼y}} → thm₁ {{y}} (u ∷ []) φ ψ (p u) {{z}} {{z≼y}}
thm₂
: {Γ : Cxt}
→ (env : Env Γ)
→ (φ ψ : Formula Γ coherent base)
→ exec∇ {{top}} env (φ ⇒ ψ) → exec env (φ ⇒ ψ)
thm₂ env φ ψ p q =
escape (fmap {{top}} (lemma-exec-coherent₁' env ψ) (lemma-exec-coherent₁ {{top}} env ψ (p {{top}} {{≼-refl}} (lemma-exec-coherent₂ {{top}} env φ (now (lemma-exec-coherent₂' {{top}} env φ q))))))
thm₂⁺
: {ty : Ty}
→ (φ ψ : Formula (ty ∷ []) coherent base)
→ exec∇ {{top}} [] (FA (φ ⇒ ψ)) → exec [] (FA (φ ⇒ ψ))
thm₂⁺ φ ψ p = λ u q → thm₂ (u ∷ []) φ ψ (p {{top}} {{≼-refl}} u) q