import Mathlib.Order.Basic
import Logic.Syntax
universe u
namespace Kripke
class Frame (W : Type u) extends Preorder W where
val : W → ℕ → Prop
le_val : ∀ {w w' : W}{i : ℕ}, w ≤ w' → val w i → val w' i
open Frame
open Syntax
open Tm
def at_world {W : Type u} [Frame W] (w : W) (tm : Tm) : Prop :=
match tm with
| var v => val w v
| Tm.and p q => at_world w p ∧ at_world w q
| Tm.or p q => at_world w p ∨ at_world w q
| imp p q => ∀ (w' : W), w ≤ w' → at_world w' p → at_world w' q
| tt => True
| ff => False
attribute [simp] at_world
def mono_at {W : Type u} [Frame W] {w w' : W} {t : Tm} (le : w ≤ w') (t_at_w : at_world w t)
: at_world w' t :=
match t with
| var _n => le_val le t_at_w
| Tm.and _p _q => ⟨mono_at le t_at_w.1, mono_at le t_at_w.2⟩
| Tm.or _p _q => match t_at_w with
| Or.inl l => Or.inl (mono_at le l)
| Or.inr r => Or.inr (mono_at le r)
| Tm.imp _p _q => fun w'' w'_le_w'' p_at_w'' => t_at_w w'' (le_trans le w'_le_w'') p_at_w''
| tt => trivial
| ff => False.elim t_at_w
def all_at_world {W : Type u} [Frame W] (w : W) : Ctxt → Prop
| [] => True
| (t :: ts) => at_world w t ∧ all_at_world w ts
attribute [simp] all_at_world
lemma all_at_append_left {W : Type u} [Frame W] {w : W} (Δ Γ : Ctxt) :
all_at_world w (Δ ++ Γ) → all_at_world w Γ := by
induction Δ with
| nil =>
simp
| cons t Δ ih =>consW : Type uw : W
intro hconsW : Type uw : W
simp [all_at_world] at hconsW : Type uw : W
exact ih h.2
lemma all_at_of_suffix {W : Type u} [Frame W] {w : W} {Γ Δ : Ctxt} (h : Γ ≤ Δ) :
all_at_world w Δ → all_at_world w Γ := by
rcases h with ⟨xs, rfl⟩
exact all_at_append_left xs Γ
def mono_all {W : Type u} [Frame W] {w w' : W} {Γ : Ctxt} (w_le_w' : w ≤ w')
(Γ_at_w : all_at_world w Γ) : all_at_world w' Γ :=
match Γ, Γ_at_w with
| [], _ => trivial
| _ :: _, ⟨h, t⟩ => ⟨mono_at w_le_w' h, mono_all w_le_w' t⟩
def Entails (W : Type u) [Frame W] (Γ : Ctxt) (t : Tm) : Prop :=
∀ (w : W), all_at_world w Γ → at_world w t
def SemEntails (Γ : Ctxt) (t : Tm) : Prop :=
∀ (W : Type u) [Frame W] (w : W), all_at_world w Γ → at_world w t
namespace Semantics
section ProofRules
def assumption : Entails W (p :: Γ) p := fun _w all => all.1
def wk : Γ ≤ Δ → Entails W Γ t → Entails W Δ t :=
fun hΓΔ Γ_to_t w all => Γ_to_t w (all_at_of_suffix hΓΔ all)
def and_I : Entails W Γ p → Entails W Γ q → Entails W Γ (p ∧ q) :=
fun p_holds q_holds w all => ⟨p_holds w all, q_holds w all⟩
def or_E : Entails W Γ (p ∨ q) → Entails W (p :: Γ) c → Entails W (q :: Γ) c → Entails W Γ c :=
fun p_or_q c_ass_p c_ass_q w all => match p_or_q w all with
| Or.inl p_at_w => c_ass_p w ⟨p_at_w, all⟩
| Or.inr q_at_w => c_ass_q w ⟨q_at_w, all⟩
def imp_I : Entails W (p :: Γ) q → Entails W Γ (p ⇒ q) :=
fun q_ass_p _w all w' w_le_w' p_at_w' =>
q_ass_p w' ⟨p_at_w', mono_all w_le_w' all⟩
def imp_E : Entails W Γ (p ⇒ q) → Entails W Γ p → Entails W Γ q :=
fun q_if_p p_holds w all =>
q_if_p w all w (le_refl w) (p_holds w all)
end ProofRules
end Semantics