Theory Denotational_Semantics
theory "Denotational_Semantics"
imports
Ordinary_Differential_Equations.ODE_Analysis
"Lib"
"Ids"
"Syntax"
begin
subsection ‹Denotational Semantics›
text ‹
The canonical dynamic semantics of dL are given as a denotational semantics.
The important definitions for the denotational semantics are states $\nu$,
interpretations I and the semantic functions $[[\psi]]I$, $[[\theta]]I\nu$,
$[[\alpha]]I$, which are represented by the Isabelle functions \verb|fml_sem|,
\verb|dterm_sem| and \verb|prog_sem|, respectively.
›
subsection ‹States›
text ‹We formalize a state S as a pair $(S_V, S_V') : R^n \times R^n $, where $S_V$ assigns
values to the program variables and $S_V$' assigns values to their
differentials. Function constants are also formalized as having a fixed arity
m \verb|(Rvec_dim)| which may differ from n. If a function does not need to
have m arguments, any remaining arguments can be uniformly set to 0,
which simulates the affect of having functions of less arguments.
Most semantic proofs need to reason about states agreeing on variables.
We say Vagree A B V if states A and B have the same values on all variables in V,
similarly with VSagree A B V for simple states A and B and Iagree I J V for interpretations
I and J.
›
type_synonym 'a Rvec = "real^('a::finite)"
type_synonym 'a state = "'a Rvec × 'a Rvec"
type_synonym 'a simple_state = "'a Rvec"
definition Vagree :: "'c::finite state ⇒ 'c state ⇒ ('c + 'c) set ⇒ bool"
where "Vagree ν ν' V ≡
(∀i. Inl i ∈ V ⟶ fst ν $ i = fst ν' $ i)
∧ (∀i. Inr i ∈ V ⟶ snd ν $ i = snd ν' $ i)"
definition VSagree :: "'c::finite simple_state ⇒ 'c simple_state ⇒ 'c set ⇒ bool"
where "VSagree ν ν' V ⟷ (∀i ∈ V. (ν $ i) = (ν' $ i))"
lemma agree_nil:"Vagree ν ω {}"
by (auto simp add: Vagree_def)
lemma agree_supset:"A ⊇ B ⟹ Vagree ν ν' A ⟹ Vagree ν ν' B"
by (auto simp add: Vagree_def)
lemma VSagree_nil:"VSagree ν ω {}"
by (auto simp add: VSagree_def)
lemma VSagree_supset:"A ⊇ B ⟹ VSagree ν ν' A ⟹ VSagree ν ν' B"
by (auto simp add: VSagree_def)
lemma VSagree_UNIV_eq:"VSagree A B UNIV ⟹ A = B"
unfolding VSagree_def by (auto simp add: vec_eq_iff)
lemma agree_comm:"⋀A B V. Vagree A B V ⟹ Vagree B A V" unfolding Vagree_def by auto
lemma agree_sub:"⋀ν ω A B . A ⊆ B ⟹ Vagree ν ω B ⟹ Vagree ν ω A"
unfolding Vagree_def by auto
lemma agree_UNIV_eq:"⋀ν ω. Vagree ν ω UNIV ⟹ ν = ω"
unfolding Vagree_def by (auto simp add: vec_eq_iff)
lemma agree_UNIV_fst:"⋀ν ω. Vagree ν ω (Inl ` UNIV) ⟹ (fst ν) = (fst ω)"
unfolding Vagree_def by (auto simp add: vec_eq_iff)
lemma agree_UNIV_snd:"⋀ν ω. Vagree ν ω (Inr ` UNIV) ⟹ (snd ν) = (snd ω)"
unfolding Vagree_def by (auto simp add: vec_eq_iff)
lemma Vagree_univ:"⋀a b c d. Vagree (a,b) (c,d) UNIV ⟹ a = c ∧ b = d"
by (auto simp add: Vagree_def vec_eq_iff)
lemma agree_union:"⋀ν ω A B. Vagree ν ω A ⟹ Vagree ν ω B ⟹ Vagree ν ω (A ∪ B)"
unfolding Vagree_def by (auto simp add: vec_eq_iff)
lemma agree_trans:"Vagree ν μ A ⟹ Vagree μ ω B ⟹ Vagree ν ω (A ∩ B)"
by (auto simp add: Vagree_def)
lemma agree_refl:"Vagree ν ν A"
by (auto simp add: Vagree_def)
lemma VSagree_sub:"⋀ν ω A B . A ⊆ B ⟹ VSagree ν ω B ⟹ VSagree ν ω A"
unfolding VSagree_def by auto
lemma VSagree_refl:"VSagree ν ν A"
by (auto simp add: VSagree_def)
subsection Interpretations
text‹
For convenience we pretend interpretations contain an extra field called
FunctionFrechet specifying the Frechet derivative \verb|(FunctionFrechet f ν)| : $R^m \rightarrow R$
for every function in every state. The proposition \verb|(is_interp I)| says that such a
derivative actually exists and is continuous (i.e. all functions are C1-continuous)
without saying what the exact derivative is.
The type parameters 'a, 'b, 'c are finite types whose cardinalities indicate the maximum number
of functions, contexts, and <everything else defined by the interpretation>, respectively.
›
record ('a, 'b, 'c) interp =
Functions :: "'a ⇒ 'c Rvec ⇒ real"
Predicates :: "'c ⇒ 'c Rvec ⇒ bool"
Contexts :: "'b ⇒ 'c state set ⇒ 'c state set"
Programs :: "'c ⇒ ('c state * 'c state) set"
ODEs :: "'c ⇒ 'c simple_state ⇒ 'c simple_state"
ODEBV :: "'c ⇒ 'c set"
fun FunctionFrechet :: "('a::finite, 'b::finite, 'c::finite) interp ⇒ 'a ⇒ 'c Rvec ⇒ 'c Rvec ⇒ real"
where "FunctionFrechet I i = (THE f'. ∀ x. (Functions I i has_derivative f' x) (at x))"
definition is_interp :: "('a::finite, 'b::finite, 'c::finite) interp ⇒ bool"
where "is_interp I ≡
∀x. ∀i. ((FDERIV (Functions I i) x :> (FunctionFrechet I i x)) ∧ continuous_on UNIV (λx. Blinfun (FunctionFrechet I i x)))"
lemma is_interpD:"is_interp I ⟹ ∀x. ∀i. (FDERIV (Functions I i) x :> (FunctionFrechet I i x))"
unfolding is_interp_def by auto
definition Iagree :: "('a::finite, 'b::finite, 'c::finite) interp ⇒ ('a::finite, 'b::finite, 'c::finite) interp ⇒ ('a + 'b + 'c) set ⇒ bool"
where "Iagree I J V ≡
(∀i∈V.
(∀x. i = Inl x ⟶ Functions I x = Functions J x) ∧
(∀x. i = Inr (Inl x) ⟶ Contexts I x = Contexts J x) ∧
(∀x. i = Inr (Inr x) ⟶ Predicates I x = Predicates J x) ∧
(∀x. i = Inr (Inr x) ⟶ Programs I x = Programs J x) ∧
(∀x. i = Inr (Inr x) ⟶ ODEs I x = ODEs J x) ∧
(∀x. i = Inr (Inr x) ⟶ ODEBV I x = ODEBV J x))"
lemma Iagree_Func:"Iagree I J V ⟹ Inl f ∈ V ⟹ Functions I f = Functions J f"
unfolding Iagree_def by auto
lemma Iagree_Contexts:"Iagree I J V ⟹ Inr (Inl C) ∈ V ⟹ Contexts I C = Contexts J C"
unfolding Iagree_def by auto
lemma Iagree_Pred:"Iagree I J V ⟹ Inr (Inr p) ∈ V ⟹ Predicates I p = Predicates J p"
unfolding Iagree_def by auto
lemma Iagree_Prog:"Iagree I J V ⟹ Inr (Inr a) ∈ V ⟹ Programs I a = Programs J a"
unfolding Iagree_def by auto
lemma Iagree_ODE:"Iagree I J V ⟹ Inr (Inr a) ∈ V ⟹ ODEs I a = ODEs J a"
unfolding Iagree_def by auto
lemma Iagree_comm:"⋀A B V. Iagree A B V ⟹ Iagree B A V"
unfolding Iagree_def by auto
lemma Iagree_sub:"⋀I J A B . A ⊆ B ⟹ Iagree I J B ⟹ Iagree I J A"
unfolding Iagree_def by auto
lemma Iagree_refl:"Iagree I I A"
by (auto simp add: Iagree_def)
primrec sterm_sem :: "('a::finite, 'b::finite, 'c::finite) interp ⇒ ('a, 'c) trm ⇒ 'c simple_state ⇒ real"
where
"sterm_sem I (Var x) v = v $ x"
| "sterm_sem I (Function f args) v = Functions I f (χ i. sterm_sem I (args i) v)"
| "sterm_sem I (Plus t1 t2) v = sterm_sem I t1 v + sterm_sem I t2 v"
| "sterm_sem I (Times t1 t2) v = sterm_sem I t1 v * sterm_sem I t2 v"
| "sterm_sem I (Const r) v = r"
| "sterm_sem I ($' c) v = undefined"
| "sterm_sem I (Differential d) v = undefined"
primrec frechet :: "('a::finite, 'b::finite, 'c::finite) interp ⇒ ('a, 'c) trm ⇒ 'c simple_state ⇒ 'c simple_state ⇒ real"
where
"frechet I (Var x) v = (λv'. v' ∙ axis x 1)"
| "frechet I (Function f args) v =
(λv'. FunctionFrechet I f (χ i. sterm_sem I (args i) v) (χ i. frechet I (args i) v v'))"
| "frechet I (Plus t1 t2) v = (λv'. frechet I t1 v v' + frechet I t2 v v')"
| "frechet I (Times t1 t2) v =
(λv'. sterm_sem I t1 v * frechet I t2 v v' + frechet I t1 v v' * sterm_sem I t2 v)"
| "frechet I (Const r) v = (λv'. 0)"
| "frechet I ($' c) v = undefined"
| "frechet I (Differential d) v = undefined"
definition directional_derivative :: "('a::finite, 'b::finite, 'c::finite) interp ⇒ ('a, 'c) trm ⇒ 'c state ⇒ real"
where "directional_derivative I t = (λv. frechet I t (fst v) (snd v))"
primrec dterm_sem :: "('a::finite, 'b::finite, 'c::finite) interp ⇒ ('a, 'c) trm ⇒ 'c state ⇒ real"
where
"dterm_sem I (Var x) = (λv. fst v $ x)"
| "dterm_sem I (DiffVar x) = (λv. snd v $ x)"
| "dterm_sem I (Function f args) = (λv. Functions I f (χ i. dterm_sem I (args i) v))"
| "dterm_sem I (Plus t1 t2) = (λv. (dterm_sem I t1 v) + (dterm_sem I t2 v))"
| "dterm_sem I (Times t1 t2) = (λv. (dterm_sem I t1 v) * (dterm_sem I t2 v))"
| "dterm_sem I (Differential t) = (λv. directional_derivative I t v)"
| "dterm_sem I (Const c) = (λv. c)"
text‹ The semantics of an ODE is the vector field at a given point. ODE's are all time-independent
so no time variable is necessary. Terms on the RHS of an ODE must be differential-free, so
depends only on the xs.
The safety predicate \texttt{osafe} ensures the domains of ODE1 and ODE2 are disjoint, so vector addition
is equivalent to saying "take things defined from ODE1 from ODE1, take things defined
by ODE2 from ODE2"›
fun ODE_sem:: "('a::finite, 'b::finite, 'c::finite) interp ⇒ ('a, 'c) ODE ⇒ 'c Rvec ⇒ 'c Rvec"
where
ODE_sem_OVar:"ODE_sem I (OVar x) = ODEs I x"
| ODE_sem_OSing:"ODE_sem I (OSing x θ) = (λν. (χ i. if i = x then sterm_sem I θ ν else 0))"
| ODE_sem_OProd:"ODE_sem I (OProd ODE1 ODE2) = (λν. ODE_sem I ODE1 ν + ODE_sem I ODE2 ν)"
fun ODE_vars :: "('a,'b,'c) interp ⇒ ('a, 'c) ODE ⇒ 'c set"
where
"ODE_vars I (OVar c) = ODEBV I c"
| "ODE_vars I (OSing x θ) = {x}"
| "ODE_vars I (OProd ODE1 ODE2) = ODE_vars I ODE1 ∪ ODE_vars I ODE2"
fun semBV ::"('a, 'b,'c) interp ⇒ ('a, 'c) ODE ⇒ ('c + 'c) set"
where "semBV I ODE = Inl ` (ODE_vars I ODE) ∪ Inr ` (ODE_vars I ODE)"
lemma ODE_vars_lr:
fixes x::"'sz" and ODE::"('sf,'sz) ODE" and I::"('sf,'sc,'sz) interp"
shows "Inl x ∈ semBV I ODE ⟷ Inr x ∈ semBV I ODE"
by (induction "ODE", auto)
fun mk_xode::"('a::finite, 'b::finite, 'c::finite) interp ⇒ ('a::finite, 'c::finite) ODE ⇒ 'c::finite simple_state ⇒ 'c::finite state"
where "mk_xode I ODE sol = (sol, ODE_sem I ODE sol)"
text‹ Given an initial state $\nu$ and solution to an ODE at some point, construct the resulting state $\omega$.
This is defined using the SOME operator because the concrete definition is unwieldy. ›
definition mk_v::"('a::finite, 'b::finite, 'c::finite) interp ⇒ ('a::finite, 'c::finite) ODE ⇒ 'c::finite state ⇒ 'c::finite simple_state ⇒ 'c::finite state"
where "mk_v I ODE ν sol = (THE ω.
Vagree ω ν (- semBV I ODE)
∧ Vagree ω (mk_xode I ODE sol) (semBV I ODE))"
fun repv :: "'c::finite state ⇒ 'c ⇒ real ⇒ 'c state"
where "repv v x r = ((χ y. if x = y then r else vec_nth (fst v) y), snd v)"
fun repd :: "'c::finite state ⇒ 'c ⇒ real ⇒ 'c state"
where "repd v x r = (fst v, (χ y. if x = y then r else vec_nth (snd v) y))"
fun fml_sem :: "('a::finite, 'b::finite, 'c::finite) interp ⇒ ('a::finite, 'b::finite, 'c::finite) formula ⇒ 'c::finite state set" and
prog_sem :: "('a::finite, 'b::finite, 'c::finite) interp ⇒ ('a::finite, 'b::finite, 'c::finite) hp ⇒ ('c::finite state * 'c::finite state) set"
where
"fml_sem I (Geq t1 t2) = {v. dterm_sem I t1 v ≥ dterm_sem I t2 v}"
| "fml_sem I (Prop P terms) = {ν. Predicates I P (χ i. dterm_sem I (terms i) ν)}"
| "fml_sem I (Not φ) = {v. v ∉ fml_sem I φ}"
| "fml_sem I (And φ ψ) = fml_sem I φ ∩ fml_sem I ψ"
| "fml_sem I (Exists x φ) = {v | v r. (repv v x r) ∈ fml_sem I φ}"
| "fml_sem I (Diamond α φ) = {ν | ν ω. (ν, ω) ∈ prog_sem I α ∧ ω ∈ fml_sem I φ}"
| "fml_sem I (InContext c φ) = Contexts I c (fml_sem I φ)"
| "prog_sem I (Pvar p) = Programs I p"
| "prog_sem I (Assign x t) = {(ν, ω). ω = repv ν x (dterm_sem I t ν)}"
| "prog_sem I (DiffAssign x t) = {(ν, ω). ω = repd ν x (dterm_sem I t ν)}"
| "prog_sem I (Test φ) = {(ν, ν) | ν. ν ∈ fml_sem I φ}"
| "prog_sem I (Choice α β) = prog_sem I α ∪ prog_sem I β"
| "prog_sem I (Sequence α β) = prog_sem I α O prog_sem I β"
| "prog_sem I (Loop α) = (prog_sem I α)⇧*"
| "prog_sem I (EvolveODE ODE φ) =
({(ν, mk_v I ODE ν (sol t)) | ν sol t.
t ≥ 0 ∧
(sol solves_ode (λ_. ODE_sem I ODE)) {0..t} {x. mk_v I ODE ν x ∈ fml_sem I φ} ∧
sol 0 = fst ν})"
context ids begin
definition valid :: "('sf, 'sc, 'sz) formula ⇒ bool"
where "valid φ ≡ (∀ I. ∀ ν. is_interp I ⟶ ν ∈ fml_sem I φ)"
end
text‹ Because mk\_v is defined with the SOME operator, need to construct a state that satisfies
${\tt Vagree} \omega \nu (- {\tt ODE\_vars\ ODE})
\wedge {\tt Vagree} \omega {\tt (mk\_xode\ I\ ODE\ sol)\ (ODE\_vars\ ODE)})$
to do anything useful ›
fun concrete_v::"('a::finite, 'b::finite, 'c::finite) interp ⇒ ('a::finite, 'c::finite) ODE ⇒ 'c::finite state ⇒ 'c::finite simple_state ⇒ 'c::finite state"
where "concrete_v I ODE ν sol =
((χ i. (if Inl i ∈ semBV I ODE then sol else (fst ν)) $ i),
(χ i. (if Inr i ∈ semBV I ODE then ODE_sem I ODE sol else (snd ν)) $ i))"
lemma mk_v_exists:"∃ω. Vagree ω ν (- semBV I ODE)
∧ Vagree ω (mk_xode I ODE sol) (semBV I ODE)"
by(rule exI[where x="(concrete_v I ODE ν sol)"], auto simp add: Vagree_def)
lemma mk_v_agree:"Vagree (mk_v I ODE ν sol) ν (- semBV I ODE)
∧ Vagree (mk_v I ODE ν sol) (mk_xode I ODE sol) (semBV I ODE)"
unfolding mk_v_def
apply(rule theI[where a= "((χ i. (if Inl i ∈ semBV I ODE then sol else (fst ν)) $ i),
(χ i. (if Inr i ∈ semBV I ODE then ODE_sem I ODE sol else (snd ν)) $ i))"])
using exE[OF mk_v_exists, of ν I ODE sol]
by (auto simp add: Vagree_def vec_eq_iff)
lemma mk_v_concrete:"mk_v I ODE ν sol = ((χ i. (if Inl i ∈ semBV I ODE then sol else (fst ν)) $ i),
(χ i. (if Inr i ∈ semBV I ODE then ODE_sem I ODE sol else (snd ν)) $ i))"
apply(rule agree_UNIV_eq)
using mk_v_agree[of I ODE ν sol]
unfolding Vagree_def by auto
subsection ‹Trivial Simplification Lemmas›
text ‹
We often want to pretend the definitions in the semantics are written slightly
differently than they are. Since the simplifier has some trouble guessing that
these are the right simplifications to do, we write them all out explicitly as
lemmas, even though they prove trivially.
›
lemma svar_case:
"sterm_sem I (Var x) = (λv. v $ x)"
by auto
lemma sconst_case:
"sterm_sem I (Const r) = (λv. r)"
by auto
lemma sfunction_case:
"sterm_sem I (Function f args) = (λv. Functions I f (χ i. sterm_sem I (args i) v))"
by auto
lemma splus_case:
"sterm_sem I (Plus t1 t2) = (λv. (sterm_sem I t1 v) + (sterm_sem I t2 v))"
by auto
lemma stimes_case:
"sterm_sem I (Times t1 t2) = (λv. (sterm_sem I t1 v) * (sterm_sem I t2 v))"
by auto
lemma or_sem [simp]:
"fml_sem I (Or φ ψ) = fml_sem I φ ∪ fml_sem I ψ"
by (auto simp add: Or_def)
lemma iff_sem [simp]: "(ν ∈ fml_sem I (A ↔ B))
⟷ ((ν ∈ fml_sem I A) ⟷ (ν ∈ fml_sem I B))"
by (auto simp add: Equiv_def)
lemma box_sem [simp]:"fml_sem I (Box α φ) = {ν. ∀ ω. (ν, ω) ∈ prog_sem I α ⟶ ω ∈ fml_sem I φ}"
unfolding Box_def fml_sem.simps
using Collect_cong by (auto)
lemma forall_sem [simp]:"fml_sem I (Forall x φ) = {v. ∀r. (repv v x r) ∈ fml_sem I φ}"
unfolding Forall_def fml_sem.simps
using Collect_cong by (auto)
lemma greater_sem[simp]:"fml_sem I (Greater θ θ') = {v. dterm_sem I θ v > dterm_sem I θ' v}"
unfolding Greater_def by auto
lemma loop_sem:"prog_sem I (Loop α) = (prog_sem I α)⇧*"
by (auto)
lemma impl_sem [simp]: "(ν ∈ fml_sem I (A → B))
= ((ν ∈ fml_sem I A) ⟶ (ν ∈ fml_sem I B))"
by (auto simp add: Implies_def)
lemma equals_sem [simp]: "(ν ∈ fml_sem I (Equals θ θ'))
= (dterm_sem I θ ν = dterm_sem I θ' ν)"
by (auto simp add: Equals_def)
lemma diamond_sem [simp]: "fml_sem I (Diamond α φ)
= {ν. ∃ ω. (ν, ω) ∈ prog_sem I α ∧ ω ∈ fml_sem I φ}"
by auto
lemma tt_sem [simp]:"fml_sem I TT = UNIV" unfolding TT_def by auto
lemma ff_sem [simp]:"fml_sem I FF = {}" unfolding FF_def by auto
lemma iff_to_impl: "((ν ∈ fml_sem I A) ⟷ (ν ∈ fml_sem I B))
⟷ (((ν ∈ fml_sem I A) ⟶ (ν ∈ fml_sem I B))
∧ ((ν ∈ fml_sem I B) ⟶ (ν ∈ fml_sem I A)))"
by (auto)
fun seq2fml :: "('a,'b,'c) sequent ⇒ ('a,'b,'c) formula"
where
"seq2fml (ante,succ) = Implies (foldr And ante TT) (foldr Or succ FF)"
context ids begin
fun seq_sem ::"('sf, 'sc, 'sz) interp ⇒ ('sf, 'sc, 'sz) sequent ⇒ 'sz state set"
where "seq_sem I S = fml_sem I (seq2fml S)"
lemma and_foldl_sem:"ν ∈ fml_sem I (foldr And Γ TT) ⟹ (⋀φ. List.member Γ φ ⟹ ν ∈ fml_sem I φ)"
by(induction Γ, auto simp add: member_rec)
lemma and_foldl_sem_conv:"(⋀φ. List.member Γ φ ⟹ ν ∈ fml_sem I φ) ⟹ ν ∈ fml_sem I (foldr And Γ TT)"
by(induction Γ, auto simp add: member_rec)
lemma or_foldl_sem:"List.member Γ φ ⟹ ν ∈ fml_sem I φ ⟹ ν ∈ fml_sem I (foldr Or Γ FF)"
by(induction Γ, auto simp add: member_rec)
lemma or_foldl_sem_conv:"ν ∈ fml_sem I (foldr Or Γ FF) ⟹ ∃ φ. ν ∈ fml_sem I φ ∧ List.member Γ φ"
by(induction Γ, auto simp add: member_rec)
lemma seq_semI':"(ν ∈ fml_sem I (foldr And Γ TT) ⟹ ν ∈ fml_sem I (foldr Or Δ FF)) ⟹ ν ∈ seq_sem I (Γ,Δ)"
by auto
lemma seq_semD':"⋀P. ν ∈ seq_sem I (Γ,Δ) ⟹ ((ν ∈ fml_sem I (foldr And Γ TT) ⟹ ν ∈ fml_sem I (foldr Or Δ FF)) ⟹ P) ⟹ P"
by simp
definition sublist::"'a list ⇒ 'a list ⇒ bool"
where "sublist A B ≡ (∀x. List.member A x ⟶ List.member B x)"
lemma sublistI:"(⋀x. List.member A x ⟹ List.member B x) ⟹ sublist A B"
unfolding sublist_def by auto
lemma Γ_sub_sem:"sublist Γ1 Γ2 ⟹ ν ∈ fml_sem I (foldr And Γ2 TT) ⟹ ν ∈ fml_sem I (foldr And Γ1 TT)"
unfolding sublist_def
by (metis and_foldl_sem and_foldl_sem_conv)
lemma seq_semI:"List.member Δ ψ ⟹((⋀φ. List.member Γ φ ⟹ ν ∈ fml_sem I φ) ⟹ ν ∈ fml_sem I ψ) ⟹ ν ∈ seq_sem I (Γ,Δ)"
apply(rule seq_semI')
using and_foldl_sem[of ν I Γ] or_foldl_sem by blast
lemma seq_semD:"ν ∈ seq_sem I (Γ,Δ) ⟹ (⋀φ. List.member Γ φ ⟹ ν ∈ fml_sem I φ) ⟹ ∃φ. (List.member Δ φ) ∧ν ∈ fml_sem I φ "
apply(rule seq_semD')
using and_foldl_sem_conv or_foldl_sem_conv
by blast+
lemma seq_MP:"ν ∈ seq_sem I (Γ,Δ) ⟹ ν ∈ fml_sem I (foldr And Γ TT) ⟹ ν ∈ fml_sem I (foldr Or Δ FF)"
by(induction Δ, auto)
definition seq_valid
where "seq_valid S ≡ ∀I. is_interp I ⟶ seq_sem I S = UNIV"
text‹ Soundness for derived rules is local soundness, i.e. if the premisses are all true in the same interpretation,
then the conclusion is also true in that same interpretation. ›
definition sound :: "('sf, 'sc, 'sz) rule ⇒ bool"
where "sound R ⟷ (∀I. is_interp I ⟶ (∀i. i ≥ 0 ⟶ i < length (fst R) ⟶ seq_sem I (nth (fst R) i) = UNIV) ⟶ seq_sem I (snd R) = UNIV)"
lemma soundI:"(⋀I. is_interp I ⟹ (⋀i. i ≥ 0 ⟹ i < length SG ⟹ seq_sem I (nth SG i) = UNIV) ⟹ seq_sem I G = UNIV) ⟹ sound (SG,G)"
unfolding sound_def by auto
lemma soundI':"(⋀I ν. is_interp I ⟹ (⋀i . i ≥ 0 ⟹ i < length SG ⟹ ν ∈ seq_sem I (nth SG i)) ⟹ ν ∈ seq_sem I G) ⟹ sound (SG,G)"
unfolding sound_def by auto
lemma soundI_mem:"(⋀I. is_interp I ⟹ (⋀φ. List.member SG φ ⟹ seq_sem I φ = UNIV) ⟹ seq_sem I C = UNIV) ⟹ sound (SG,C)"
apply (auto simp add: sound_def)
by (metis in_set_conv_nth in_set_member iso_tuple_UNIV_I seq2fml.simps)
lemma soundI_memv:"(⋀I. is_interp I ⟹ (⋀φ ν. List.member SG φ ⟹ ν ∈ seq_sem I φ) ⟹ (⋀ν. ν ∈ seq_sem I C)) ⟹ sound (SG,C)"
apply(rule soundI_mem)
using impl_sem by blast
lemma soundI_memv':"(⋀I. is_interp I ⟹ (⋀φ ν. List.member SG φ ⟹ ν ∈ seq_sem I φ) ⟹ (⋀ν. ν ∈ seq_sem I C)) ⟹ R = (SG,C) ⟹ sound R"
using soundI_mem
using impl_sem by blast
lemma soundD_mem:"sound (SG,C) ⟹ (⋀I. is_interp I ⟹ (⋀φ. List.member SG φ ⟹ seq_sem I φ = UNIV) ⟹ seq_sem I C = UNIV)"
apply (auto simp add: sound_def)
using in_set_conv_nth in_set_member iso_tuple_UNIV_I seq2fml.simps
by (metis seq2fml.elims)
lemma soundD_memv:"sound (SG,C) ⟹ (⋀I. is_interp I ⟹ (⋀φ ν. List.member SG φ ⟹ ν ∈ seq_sem I φ) ⟹ (⋀ν. ν ∈ seq_sem I C))"
using soundD_mem
by (metis UNIV_I UNIV_eq_I)
end
end