# Theory SemilatAlg

```(*  Title:      HOL/MicroJava/BV/SemilatAlg.thy
Author:     Gerwin Klein
*)

section ‹More on Semilattices›

theory SemilatAlg
imports Typing_Framework
begin

definition lesubstep_type :: "(nat × 's) set ⇒ 's ord ⇒ (nat × 's) set ⇒ bool"
("(_ /{⊑⇘_⇙} _)" [50, 0, 51] 50)
where "A {⊑⇘r⇙} B ≡ ∀(p,τ) ∈ A. ∃τ'. (p,τ') ∈ B ∧ τ ⊑⇩r τ'"

notation (ASCII)
lesubstep_type  ("(_ /{<='__} _)" [50, 0, 51] 50)

primrec pluslussub :: "'a list ⇒ ('a ⇒ 'a ⇒ 'a) ⇒ 'a ⇒ 'a"  ("(_ /⨆⇘_⇙ _)" [65, 0, 66] 65)
where
"pluslussub [] f y = y"
| "pluslussub (x#xs) f y = pluslussub xs f (x ⊔⇩f y)"
(*<*)
notation (ASCII)
pluslussub  ("(_ /++'__ _)" [65, 1000, 66] 65)
(*>*)

definition bounded :: "'s step_type ⇒ nat ⇒ bool"
where
"bounded step n ⟷ (∀p<n. ∀τ. ∀(q,τ') ∈ set (step p τ). q<n)"

definition pres_type :: "'s step_type ⇒ nat ⇒ 's set ⇒ bool"
where
"pres_type step n A ⟷ (∀τ∈A. ∀p<n. ∀(q,τ') ∈ set (step p τ). τ' ∈ A)"

definition mono :: "'s ord ⇒ 's step_type ⇒ nat ⇒ 's set ⇒ bool"
where
"mono r step n A ⟷
(∀τ p τ'. τ ∈ A ∧ p<n ∧ τ ⊑⇩r τ' ⟶ set (step p τ) {⊑⇘r⇙} set (step p τ'))"

lemma [iff]: "{} {⊑⇘r⇙} B"
(*<*) by (simp add: lesubstep_type_def) (*>*)

lemma [iff]: "(A {⊑⇘r⇙} {}) = (A = {})"
(*<*) by (cases "A={}") (auto simp add: lesubstep_type_def) (*>*)

lemma lesubstep_union:
"⟦ A⇩1 {⊑⇘r⇙} B⇩1; A⇩2 {⊑⇘r⇙} B⇩2 ⟧ ⟹ A⇩1 ∪ A⇩2 {⊑⇘r⇙} B⇩1 ∪ B⇩2"
(*<*) by (auto simp add: lesubstep_type_def) (*>*)

lemma pres_typeD:
"⟦ pres_type step n A; s∈A; p<n; (q,s')∈set (step p s) ⟧ ⟹ s' ∈ A"
(*<*) by (unfold pres_type_def, blast) (*>*)

lemma monoD:
"⟦ mono r step n A; p < n; s∈A; s ⊑⇩r t ⟧ ⟹ set (step p s) {⊑⇘r⇙} set (step p t)"
(*<*) by (unfold mono_def, blast) (*>*)

lemma boundedD:
"⟦ bounded step n; p < n; (q,t) ∈ set (step p xs) ⟧ ⟹ q < n"
(*<*) by (unfold bounded_def, blast) (*>*)

lemma lesubstep_type_refl [simp, intro]:
"(⋀x. x ⊑⇩r x) ⟹ A {⊑⇘r⇙} A"
(*<*) by (unfold lesubstep_type_def) auto (*>*)

lemma lesub_step_typeD:
"A {⊑⇘r⇙} B ⟹ (x,y) ∈ A ⟹ ∃y'. (x, y') ∈ B ∧ y ⊑⇩r y'"
(*<*) by (unfold lesubstep_type_def) blast (*>*)

lemma list_update_le_listI [rule_format]:
"set xs ⊆ A ⟶ set ys ⊆ A ⟶ xs [⊑⇩r] ys ⟶ p < size xs ⟶
x ⊑⇩r ys!p ⟶ semilat(A,r,f) ⟶ x∈A ⟶
xs[p := x ⊔⇩f xs!p] [⊑⇩r] ys"
(*<*)
apply (simp only: Listn.le_def lesub_def semilat_def)
done
(*>*)

lemma plusplus_closed: assumes "Semilat A r f" shows
"⋀y. ⟦ set x ⊆ A; y ∈ A⟧ ⟹ x ⨆⇘f⇙ y ∈ A"
(*<*)
proof (induct x)
interpret Semilat A r f by fact
show "⋀y. y ∈ A ⟹ [] ⨆⇘f⇙ y ∈ A" by simp
fix y x xs
assume y: "y ∈ A" and xxs: "set (x#xs) ⊆ A"
assume IH: "⋀y. ⟦ set xs ⊆ A; y ∈ A⟧ ⟹ xs ⨆⇘f⇙ y ∈ A"
from xxs obtain x: "x ∈ A" and xs: "set xs ⊆ A" by simp
from x y have "x ⊔⇘f⇙ y ∈ A" ..
with xs have "xs ⨆⇘f⇙ (x ⊔⇘f⇙ y) ∈ A" by (rule IH)
thus "x#xs ⨆⇘f⇙ y ∈ A" by simp
qed
(*>*)

lemma (in Semilat) pp_ub2:
"⋀y. ⟦ set x ⊆ A; y ∈ A⟧ ⟹ y ⊑⇘r⇙ x ⨆⇘f⇙ y"
(*<*)
proof (induct x)
from semilat show "⋀y. y ⊑⇘r⇙ [] ⨆⇘f⇙ y" by simp

fix y a l assume y:  "y ∈ A" and "set (a#l) ⊆ A"
then obtain a: "a ∈ A" and x: "set l ⊆ A" by simp
assume "⋀y. ⟦set l ⊆ A; y ∈ A⟧ ⟹ y ⊑⇘r⇙ l ⨆⇘f⇙ y"
from this and x have IH: "⋀y. y ∈ A ⟹ y ⊑⇘r⇙ l ⨆⇘f⇙ y" .

from a y have "y ⊑⇘r⇙ a ⊔⇘f⇙ y" ..
also from a y have "a ⊔⇘f⇙ y ∈ A" ..
hence "(a ⊔⇘f⇙ y) ⊑⇘r⇙ l ⨆⇘f⇙ (a ⊔⇘f⇙ y)" by (rule IH)
finally have "y ⊑⇘r⇙ l ⨆⇘f⇙ (a ⊔⇘f⇙ y)" .
thus "y ⊑⇘r⇙ (a#l) ⨆⇘f⇙ y" by simp
qed
(*>*)

lemma (in Semilat) pp_ub1:
shows "⋀y. ⟦set ls ⊆ A; y ∈ A; x ∈ set ls⟧ ⟹ x ⊑⇘r⇙ ls ⨆⇘f⇙ y"
(*<*)
proof (induct ls)
show "⋀y. x ∈ set [] ⟹ x ⊑⇘r⇙ [] ⨆⇘f⇙ y" by simp

fix y s ls
assume "set (s#ls) ⊆ A"
then obtain s: "s ∈ A" and ls: "set ls ⊆ A" by simp
assume y: "y ∈ A"

assume "⋀y. ⟦set ls ⊆ A; y ∈ A; x ∈ set ls⟧ ⟹ x ⊑⇘r⇙ ls ⨆⇘f⇙ y"
from this and ls have IH: "⋀y. x ∈ set ls ⟹ y ∈ A ⟹ x ⊑⇘r⇙ ls ⨆⇘f⇙ y" .

assume "x ∈ set (s#ls)"
then obtain xls: "x = s ∨ x ∈ set ls" by simp
moreover {
assume xs: "x = s"
from s y have "s ⊑⇘r⇙ s ⊔⇘f⇙ y" ..
also from s y have "s ⊔⇘f⇙ y ∈ A" ..
with ls have "(s ⊔⇘f⇙ y) ⊑⇘r⇙ ls ⨆⇘f⇙ (s ⊔⇘f⇙ y)" by (rule pp_ub2)
finally have "s ⊑⇘r⇙ ls ⨆⇘f⇙ (s ⊔⇘f⇙ y)" .
with xs have "x ⊑⇘r⇙ ls ⨆⇘f⇙ (s ⊔⇘f⇙ y)" by simp
}
moreover {
assume "x ∈ set ls"
hence "⋀y. y ∈ A ⟹ x ⊑⇘r⇙ ls ⨆⇘f⇙ y" by (rule IH)
moreover from s y have "s ⊔⇘f⇙ y ∈ A" ..
ultimately have "x ⊑⇘r⇙ ls ⨆⇘f⇙ (s ⊔⇘f⇙ y)" .
}
ultimately
have "x ⊑⇘r⇙ ls ⨆⇘f⇙ (s ⊔⇘f⇙ y)" by blast
thus "x ⊑⇘r⇙ (s#ls) ⨆⇘f⇙ y" by simp
qed
(*>*)

lemma (in Semilat) pp_lub:
assumes z: "z ∈ A"
shows
"⋀y. y ∈ A ⟹ set xs ⊆ A ⟹ ∀x ∈ set xs. x ⊑⇘r⇙ z ⟹ y ⊑⇘r⇙ z ⟹ xs ⨆⇘f⇙ y ⊑⇘r⇙ z"
(*<*)
proof (induct xs)
fix y assume "y ⊑⇘r⇙ z" thus "[] ⨆⇘f⇙ y ⊑⇘r⇙ z" by simp
next
fix y l ls assume y: "y ∈ A" and "set (l#ls) ⊆ A"
then obtain l: "l ∈ A" and ls: "set ls ⊆ A" by auto
assume "∀x ∈ set (l#ls). x ⊑⇘r⇙ z"
then obtain lz: "l ⊑⇘r⇙ z" and lsz: "∀x ∈ set ls. x ⊑⇘r⇙ z" by auto
assume "y ⊑⇘r⇙ z" with lz have "l ⊔⇘f⇙ y ⊑⇘r⇙ z" using l y z ..
moreover
from l y have "l ⊔⇘f⇙ y ∈ A" ..
moreover
assume "⋀y. y ∈ A ⟹ set ls ⊆ A ⟹ ∀x ∈ set ls. x ⊑⇘r⇙ z ⟹ y ⊑⇘r⇙ z
⟹ ls ⨆⇘f⇙ y ⊑⇘r⇙ z"
ultimately
have "ls ⨆⇘f⇙ (l ⊔⇘f⇙ y) ⊑⇘r⇙ z" using ls lsz by -
thus "(l#ls) ⨆⇘f⇙ y ⊑⇘r⇙ z" by simp
qed
(*>*)

lemma ub1': assumes "Semilat A r f"
shows "⟦∀(p,s) ∈ set S. s ∈ A; y ∈ A; (a,b) ∈ set S⟧
⟹ b ⊑⇘r⇙ map snd [(p', t') ← S. p' = a] ⨆⇘f⇙ y"
(*<*)
proof -
interpret Semilat A r f by fact
let "b ⊑⇘r⇙ ?map ⨆⇘f⇙ y" = ?thesis

assume "y ∈ A"
moreover
assume "∀(p,s) ∈ set S. s ∈ A"
hence "set ?map ⊆ A" by auto
moreover
assume "(a,b) ∈ set S"
hence "b ∈ set ?map" by (induct S, auto)
ultimately
show ?thesis by - (rule pp_ub1)
qed
(*>*)

lemma plusplus_empty:
"∀s'. (q, s') ∈ set S ⟶ s' ⊔⇘f⇙ ss ! q = ss ! q ⟹
(map snd [(p', t') ← S. p' = q] ⨆⇘f⇙ ss ! q) = ss ! q"
(*<*)
apply (induct S)
apply auto
done
(*>*)

end
```