theory Traces
imports Main HOL.Lattices HOL.List
begin
chapter ‹Traces and Definitive Prefixes›
section ‹Traces›
typedecl Σ
type_synonym 'a finite_trace = ‹'a list›
type_synonym 'a infinite_trace = ‹nat → 'a›
datatype 'a trace = Finite ‹'a finite_trace› | Infinite ‹'a infinite_trace›
fun thead :: ‹'a trace → 'a› where
‹thead (Finite t) = t ! 0›
| ‹thead (Infinite t) = t 0›
fun append :: ‹'a trace → 'a trace → 'a trace› (infixr ‹⌢› 80) where
‹(Finite t) ⌢ (Infinite ψ) = Infinite (λn. if n < length t then t!n else ψ (n - length t))›
| ‹(Finite t) ⌢ (Finite u) = Finite (t @ u)›
| ‹(Infinite t) ⌢ u = Infinite t›
definition ε :: ‹'a trace› where
‹ε = Finite []›
definition singleton :: ‹'a → 'a trace› where
‹singleton σ = Finite [σ]›
interpretation trace: monoid_list ‹(⌢)› ‹ε›
proof unfold_locales
fix a :: ‹'a trace› show ‹ε ⌢ a = a›
by (cases ‹a›; simp add: ε_def)
next
fix a :: ‹'a trace› show ‹a ⌢ ε = a›
by (cases ‹a›; simp add: ε_def)
next
fix a b c :: ‹'a trace› show ‹(a ⌢ b) ⌢ c = a ⌢ (b ⌢ c)›
apply (cases ‹a›; simp)
apply (cases ‹b›; simp)
apply (cases ‹c›; simp)
apply (rule ext; simp)
by (smt (verit, ccfv_threshold)
add.commute add_diff_inverse_nat add_less_cancel_left
nth_append trans_less_add2)
qed
lemma finite_empty_suffix:
assumes ‹Finite xs = Finite xs ⌢ t›
shows ‹t = ε›
using assms by (cases ‹t›) (simp_all add: ε_def)
lemma finite_empty_prefix:
assumes ‹Finite xs = t ⌢ Finite xs›
shows ‹t = ε›
using assms by (cases ‹t›) (simp_all add: ε_def)
lemma finite_finite_suffix:
assumes ‹Finite xs = Finite ys ⌢ t›
obtains zs where ‹t = Finite zs›
using assms by (cases ‹t›) (simp_all)
lemma finite_finite_prefix:
assumes ‹Finite xs = t ⌢ Finite ys›
obtains zs where ‹t = Finite zs›
using assms by (cases ‹t›) (simp_all)
lemma append_is_empty:
assumes ‹t ⌢ u = ε›
shows ‹t = ε›
and ‹u = ε›
using assms by (simp add: ε_def; cases ‹t›; cases ‹u›; simp)+
fun ttake :: ‹nat → 'a trace → 'a finite_trace› where
‹ttake k (Finite xs) = take k xs›
| ‹ttake k (Infinite xs) = map xs [0..<k] ›
definition itdrop :: ‹nat → 'a infinite_trace → 'a infinite_trace› where
‹itdrop k xs = (λi. xs (i + k))›
lemma itdrop_itdrop[simp]: ‹itdrop i (itdrop j x) = itdrop (i + j) x›
by (simp add: itdrop_def add.commute add.left_commute)
lemma itdrop_zero[simp]: ‹itdrop 0 x = x›
by (simp add: itdrop_def)
fun tdrop :: ‹nat → 'a trace → 'a trace› where
‹tdrop k (Finite xs) = Finite (drop k xs)›
| ‹tdrop k (Infinite xs) = Infinite (itdrop k xs) ›
lemma ttake_simp[simp]: ‹ttake (length xs) (Finite xs ⌢ t) = xs›
by (cases ‹t›, auto intro: list_eq_iff_nth_eq[THEN iffD2])
lemma ttake_tdrop[simp]: ‹Finite (ttake k t) ⌢ tdrop k t = t›
by (cases ‹t›, auto simp: itdrop_def)
definition prefixes :: ‹'a trace → 'a trace set› (‹↓ _› [80] 80) where
‹↓ t = { u | u v. t = u ⌢ v }›
definition extensions :: ‹'a trace → 'a trace set› (‹↑ _› [80] 80) where
‹↑ t = { t ⌢ u | u. True }›
lemma prefixes_extensions: ‹t ∈ ↓ u ⟷ u ∈ ↑ t›
unfolding prefixes_def extensions_def by simp
interpretation prefixes: order ‹λ t u. t ∈ ↓ u› ‹λ t u. t ∈ ↓ u ∧ t ≠ u›
proof
(* Reflexivity *)
fix x :: ‹'a trace›
show ‹x ∈ ↓ x›
unfolding prefixes_def
by (simp, metis trace.right_neutral)
next
(* Strict Ordering *)
fix x y :: ‹'a trace›
show ‹(x ∈ ↓ y ∧ x ≠ y) = (x ∈ ↓ y ∧ ¬ y ∈ ↓ x)›
unfolding prefixes_def
by (simp, metis append.simps(3) append_is_empty(1) finite_empty_suffix
trace.assoc trace.exhaust)
next
(* Antisymmetry *)
fix x y :: ‹'a trace›
assume assms: ‹x ∈ ↓ y› ‹y ∈ ↓ x›
show ‹x = y›
proof (cases ‹y›)
case Finite note yfinite = this
show ‹?thesis›
proof (cases ‹x›)
case Finite
with assms(2) obtain z where ‹x = y ⌢ z›
unfolding prefixes_def
by auto
with assms(1) yfinite show ‹?thesis›
unfolding prefixes_def
by (force simp: trace.assoc dest: finite_empty_suffix append_is_empty)
qed (smt (verit, del_insts) CollectD append.simps(3) assms(1) prefixes_def)
qed (smt (verit, del_insts) CollectD append.simps(3) assms(2) prefixes_def)
next
(* Transitivity *)
fix x y z :: ‹'a trace›
assume ‹x ∈ ↓ y› ‹y ∈ ↓ z›
then show ‹x ∈ ↓ z›
unfolding prefixes_def by (force simp: trace.assoc)
qed
lemma prefixes_empty_least : ‹ε ∈ ↓ t›
by (simp add: prefixes_def)
lemma prefixes_infinite_greatest : ‹Infinite x ∈ ↓ t ==> t = Infinite x›
by (simp add: prefixes_def)
lemma prefixes_finite : ‹Finite xs ∈ ↓ Finite ys ⟷ (∃ zs. ys = xs @ zs)›
proof (rule iffI)
show ‹Finite xs ∈ ↓ Finite ys ==> ∃zs. ys = xs @ zs›
using finite_finite_suffix by (fastforce simp: prefixes_def)
next
show ‹∃zs. ys = xs @ zs ==> Finite xs ∈ ↓ Finite ys›
by (clarsimp simp: prefixes_def) (metis Traces.append.simps(2))
qed
lemma ttake_take : ‹take n (ttake m t) = ttake (min n m) t›
by (cases ‹t›) (simp_all add: min_def take_map)
lemma tdrop_tdrop : ‹tdrop n (tdrop m t) = tdrop (n + m) t›
by (cases ‹t›) (simp_all add: add.commute add.left_commute)
lemma tdrop_mono: ‹t ∈ ↓ u ==> tdrop k t ∈ ↓ tdrop k u›
proof -
{ fix v assume A: ‹u = t ⌢ v› then have ‹∃va. tdrop k (t ⌢ v) = tdrop k t ⌢ va ›
proof (cases ‹t›; cases ‹v›)
fix x1 x2 assume ‹t = Finite x1› and ‹v = Finite x2› with A show ‹?thesis›
by (simp, metis Traces.append.simps(2))
next
fix x1 x2 assume ‹t = Finite x1› and ‹v = Infinite x2› with A
have ‹tdrop k (t ⌢ v) = tdrop k t ⌢ Infinite (itdrop (k - length x1) x2) ›
apply simp
apply (rule ext)
apply clarsimp
apply (rule conjI)
apply (simp add: add.commute itdrop_def less_diff_conv)
by (smt (z3) add.commute add_diff_cancel_left' add_diff_inverse_nat diff_is_0_eq'
diff_right_commute itdrop_def linorder_not_less nat_less_le)
then show ‹∃va. tdrop k (t ⌢ v) = tdrop k t ⌢ va›
by auto
qed auto } note A = this
assume ‹t ∈ ↓ u› with A show ?thesis unfolding prefixes_def by clarsimp
qed
lemma ttake_finite_prefixes : ‹Finite xs ∈ ↓ t ⟷ xs = ttake (length xs) t›
proof (rule iffI)
show ‹Finite xs ∈ ↓ t ==> xs = ttake (length xs) t›
by (clarsimp simp: prefixes_def)
next
show ‹xs = ttake (length xs) t ==> Finite xs ∈ ↓ t›
unfolding prefixes_def using ttake_tdrop
by (metis (full_types) mem_Collect_eq)
qed
lemma ttake_prefixes : ‹a ≤ b ==> Finite (ttake a t) ∈ ↓ Finite (ttake b t)›
by (cases ‹t›; simp add: ttake_finite_prefixes min_def take_map)
lemma finite_directed:
assumes ‹ Finite xs ∈ ↓ t › ‹ Finite ys ∈ ↓ t ›
shows ‹ ∃zs. (xs = ys @ zs) ∨ (ys = xs @ zs) ›
proof (cases ‹length xs > length ys›)
case True
with assms show ‹?thesis›
apply (simp add: ttake_finite_prefixes)
using ttake_prefixes[simplified prefixes_finite]
by (metis less_le_not_le)
next
case False
from assms this[THEN leI] show ‹?thesis›
apply (simp add: ttake_finite_prefixes)
using ttake_prefixes[simplified prefixes_finite]
by (metis)
qed
lemma prefixes_directed: ‹u ∈ ↓ t ==> v ∈ ↓ t ==> u ∈ ↓ v ∨ v ∈ ↓ u›
proof (cases ‹v›; cases ‹u›)
{ fix a b assume ‹Finite a ∈ ↓ t› ‹Finite b ∈ ↓ t›
then have ‹Finite a ∈ ↓ Finite b ∨ Finite b ∈ ↓ Finite a›
using finite_directed prefixes_finite by blast } note X = this
fix a b show ‹u ∈ ↓ t ==> v ∈ ↓ t ==> v = Finite a ==> u = Finite b ==> u ∈ ↓ v ∨ v ∈ ↓ u›
using X by auto
qed (auto simp: prefixes_def dest: prefixes_infinite_greatest)
interpretation extensions: order ‹λ t u. t ∈ ↑ u› ‹λ t u. t ∈ ↑ u ∧ t ≠ u›
proof
qed (auto simp: prefixes_extensions[THEN sym] dest: prefixes.leD intro:prefixes.order.trans)
lemma extensions_infinite[simp]: ‹↑ Infinite xs = { Infinite xs }›
by (simp add: extensions_def)
lemma extensions_empty[simp]: ‹↑ ε = UNIV›
by (simp add: extensions_def)
lemma prefixes_empty: ‹↓ ε = {ε}›
apply (clarsimp simp add: set_eq_iff ε_def prefixes_def)
apply (rule iffI)
apply (metis ε_def append_is_empty(1))
by (metis ε_def trace.left_neutral)
section ‹Prefix Closure›
definition prefix_closure :: ‹'a trace set → 'a trace set› (‹↓s _› [80] 80) where
‹↓s X = (∪ t ∈ X. prefixes t) ›
lemma prefix_closure_subset: ‹X ⊆ ↓s X›
unfolding prefix_closure_def
by auto
lemma prefix_closure_infinite: ‹Infinite x ∈ ↓s X ⟷ Infinite x ∈ X›
proof
assume ‹Infinite x ∈ ↓s X› then show ‹Infinite x ∈ X›
by (metis UN_E prefix_closure_def prefixes_infinite_greatest)
next
assume ‹Infinite x ∈ X› then show ‹Infinite x ∈ ↓s X›
by (meson in_mono prefix_closure_subset)
qed
lemma prefix_closure_idem: ‹↓s ↓s X = ↓s X›
unfolding prefix_closure_def
using prefixes.order.trans by blast
lemma prefix_closure_mono: ‹X ⊆ Y ==> ↓s X ⊆ ↓s Y›
unfolding prefix_closure_def
by blast
lemma prefix_closure_union_distrib: ‹↓s (X ∪ Y) = ↓s X ∪ ↓s Y›
unfolding prefix_closure_def
by simp
lemma prefix_closure_Union_distrib: ‹↓s (∪ S) = ∪ (prefix_closure ` S)›
unfolding prefix_closure_def
by simp
lemma prefix_closure_Inter: ‹↓s (∩ (prefix_closure ` S)) = ∩ (prefix_closure ` S) ›
unfolding prefix_closure_def
using prefixes.dual_order.trans by fastforce
lemma prefix_closure_inter: ‹↓s (↓s X ∩ ↓s Y) = ↓s X ∩ ↓s Y›
by (rule prefix_closure_Inter[where S = ‹{X,Y}›, simplified])
lemma prefix_closure_UNIV: ‹↓s UNIV = UNIV›
unfolding prefix_closure_def by blast
lemma prefix_closure_empty: ‹↓s {} = {}›
unfolding prefix_closure_def by blast
lemma prefix_closure_extensions: ‹ ↓s (↑ t) = ↑ t ∪ ↓ t›
by (force intro: prefix_closure_subset dest: prefixes_directed
simp: prefixes_extensions[THEN sym] prefix_closure_def)
lemma prefix_closure_prefixes: ‹↓s (↓ t) = ↓ t›
unfolding prefix_closure_def
by (force intro: prefixes.dual_order.trans)
section ‹Definitive Prefixes›
definition dprefixes :: ‹'a trace set → 'a trace set› (‹↓d _› [80] 80) where
‹↓d X = { t | t. ↑ t ⊆ ↓s X }›
lemma dprefixes_are_prefixes : ‹↓d X ⊆ ↓s X›
unfolding dprefixes_def
using extensions.order.refl by blast
lemma prefix_closure_dprefixes : ‹↓s (↓d X) ⊆ ↓s X›
using dprefixes_are_prefixes prefix_closure_idem prefix_closure_mono
by blast
lemma dprefixes_idem: ‹↓d ↓d X = ↓d X›
proof
show ‹↓d ↓d X ⊆ ↓d X›
using prefix_closure_dprefixes
by (force simp: dprefixes_def)
next
show ‹↓d X ⊆ ↓d ↓d X›
using extensions.order.trans prefix_closure_subset
by (force simp: dprefixes_def)
qed
lemma dprefixes_contains_extensions: ‹t ∈ ↓d X ==> ↑ t ⊆ ↓d X›
unfolding dprefixes_def
using extensions.dual_order.trans by auto
lemma dprefixes_infinite: ‹Infinite x ∈ ↓d X ⟷ Infinite x ∈ X›
proof
show ‹Infinite x ∈ X ==> Infinite x ∈ ↓d X›
unfolding dprefixes_def
using prefix_closure_subset by fastforce
next
show ‹Infinite x ∈ ↓d X ==> Infinite x ∈ X›
unfolding dprefixes_def
by (clarsimp simp: prefix_closure_infinite)
qed
lemma dprefixes_UNIV: ‹↓d UNIV = UNIV›
unfolding dprefixes_def
using prefix_closure_UNIV by force
lemma dprefixes_empty: ‹↓d {} = {}›
unfolding dprefixes_def
using prefix_closure_empty by blast
lemma dprefixes_Inter_distrib: ‹↓d (∩ S) ⊆ ∩ (dprefixes ` S)›
unfolding dprefixes_def prefix_closure_def
by auto
lemma dprefixes_Inter: ‹↓d (∩ (dprefixes ` S)) = ∩ (dprefixes ` S)›
proof
show ‹∩ (dprefixes ` S) ⊆ ↓d ∩ (dprefixes ` S)›
unfolding dprefixes_def prefix_closure_def
using prefixes.order.refl extensions.dual_order.trans
by force
next
show ‹↓d ∩ (dprefixes ` S) ⊆ ∩ (dprefixes ` S)›
using dprefixes_idem dprefixes_Inter_distrib
by blast
qed
lemma dprefixes_mono:
assumes ‹X ⊆ Y›
shows ‹↓d X ⊆ ↓d Y›
using assms
apply (simp add: dprefixes_def)
apply (simp add: prefix_closure_def)
apply (rule subsetI)
using prefixes_extensions by blast
lemma dprefixes_inter: ‹↓d (↓d X ∩ ↓d Y) = (↓d X ∩ ↓d Y)›
by (rule dprefixes_Inter[where S = ‹{X,Y}›, simplified])
lemma dprefixes_inter_distrib: ‹↓d (X ∩ Y) ⊆ ↓d X ∩ ↓d Y›
using dprefixes_Inter_distrib[where S = ‹{X,Y}›] by auto
section ‹Definitive Sets›
definition definitive:: ‹'a trace set → bool› where
‹definitive X ⟷ ↓d X = X›
lemma definitive_image: ‹∀X ∈ S. definitive X ==> dprefixes ` S = S›
unfolding definitive_def by auto
lemma definitive_dprefixes: ‹definitive (↓d X)›
unfolding definitive_def by (rule dprefixes_idem)
lemma definitive_contains_extensions: ‹definitive X ==> t ∈ X ==> ↑ t ⊆ X›
unfolding definitive_def using dprefixes_contains_extensions by blast
lemma definitive_UNIV: ‹definitive UNIV›
unfolding definitive_def by (rule dprefixes_UNIV)
lemma definitive_empty: ‹definitive {}›
unfolding definitive_def by (rule dprefixes_empty)
lemma definitive_Inter: ‹∀X ∈ S. definitive X ==> definitive (∩ S)›
unfolding definitive_def using dprefixes_Inter definitive_image[simplified definitive_def]
by metis
lemma definitive_inter: ‹definitive X ==> definitive Y ==> definitive (X ∩ Y)›
using definitive_Inter[where S = ‹{X,Y}›, simplified] by blast
lemma definitive_infinite_extension:
assumes ‹definitive X› and ‹t ∈ X›
shows ‹∃ f. Infinite f ∈ X ∧ t ∈ ↓ Infinite f›
using assms proof (cases ‹t›)
case (Finite xs) then show ‹?thesis›
apply (intro exI[where x=‹λn. if n < length xs then xs!n else undefined›])
by (force simp: prefixes_extensions[THEN sym] prefixes_def
intro!: definitive_contains_extensions[THEN subsetD, OF assms]
intro: exI[where x=‹Infinite (λ_. undefined)›])
qed auto
lemma definitive_elemI:
assumes ‹definitive X› ‹↑ t ⊆ ↓s X›
shows ‹t ∈ X›
using assms
by (auto simp add: definitive_def dprefixes_def)
definition dUnion :: ‹'a trace set set → 'a trace set› (‹∪d›) where
‹∪d X = ↓d ∪ X›
abbreviation dunion :: ‹'a trace set → 'a trace set → 'a trace set› (infixl ‹∪d› 65) where
‹X ∪d Y ≡ ∪d {X,Y}›
lemma dprefixes_dUnion: ‹↓d ∪d S = ∪d S›
by (simp add: dUnion_def dprefixes_idem)
lemma definitive_dUnion: ‹definitive (∪d S)›
by (simp add: dprefixes_dUnion definitive_def)
lemma dUnion_contains_dprefixes: ‹t ∈ S ==> ↓d t ⊆ ∪d S›
by (auto simp: dUnion_def dprefixes_def prefix_closure_def)
lemma dUnion_contains_definitive: ‹X ∈ S ==> definitive X ==> X ⊆ ∪d S›
unfolding definitive_def
using dUnion_contains_dprefixes by blast
lemma dUnion_empty[simp]: ‹∪d {} = {}›
unfolding dUnion_def
by (simp add: dprefixes_empty)
lemma dUnion_least_dprefixes: ‹(∧X. X ∈ S ==> X ⊆ ↓d Z) ==> ↓d (∪ (dprefixes ` S)) ⊆ ↓d Z›
unfolding dprefixes_def prefix_closure_def
by (simp add: subset_iff, meson extensions.order_refl prefixes.order.trans)
lemma dUnion_least_definitive:
assumes all_defn: ‹∀X ∈ S. definitive X›
shows ‹(∧X. X ∈ S ==> X ⊆ Z) ==> definitive Z ==> ↓d ∪ S ⊆ Z›
using definitive_image[OF all_defn,THEN sym] dUnion_least_dprefixes definitive_def
by metis
section ‹A type for definitive sets›
typedef 'a dset = ‹{p :: 'a trace set. definitive p }›
using definitive_UNIV by blast
setup_lifting type_definition_dset
lift_definition Inter_dset :: ‹'a dset set → 'a dset› (‹⊓›) is ‹λ ss. ∩ ss›
by (simp add: definitive_Inter)
abbreviation inter_dset :: ‹'a dset → 'a dset → 'a dset› (infixl ‹⊓› 66) where
‹X ⊓ Y ≡ ⊓ {X,Y}›
lift_definition Union_cset :: ‹'a dset set → 'a dset› (‹⊔›) is ‹λ ss. ∪d ss›
by (rule definitive_dUnion)
abbreviation union_dset :: ‹'a dset → 'a dset → 'a dset› (infixl ‹⊔› 65) where
‹X ⊔ Y ≡ ⊔ {X,Y}›
lift_definition empty_dset :: ‹'a dset› (‹∅›) is ‹{}›
by (rule definitive_empty)
lift_definition univ_dset :: ‹'a dset› (‹Σ∞›) is ‹UNIV›
by (rule definitive_UNIV)
lift_definition subset_dset :: ‹'a dset → 'a dset → bool› (infix ‹⊑› 50) is ‹(⊆)›
done
lift_definition strict_subset_cset :: ‹'a dset → 'a dset → bool› (infix ‹⊏› 50) is ‹(⊂)›
done
lift_definition in_dset :: ‹'a trace → 'a dset → bool› is ‹(∈)›
done
lift_definition notin_dset :: ‹'a trace → 'a dset → bool› is ‹(∉)›
done
lemma in_dset_ε: ‹in_dset ε A ==> A = Σ∞›
apply (transfer)
using definitive_contains_extensions extensions_empty by blast
lemma in_dset_UNIV: ‹in_dset x Σ∞›
by (transfer, simp)
lemma in_dset_subset: ‹A ⊑ B ==> in_dset x A ==> in_dset x B›
by (transfer, auto)
lemma in_dset_inter: ‹in_dset x A ==> in_dset x B ==> in_dset x (A ⊓ B)›
by (transfer, simp)
interpretation dset: complete_lattice ‹⊓› ‹⊔› ‹(⊓)› ‹(⊑)› ‹(⊏)› ‹(⊔)› ‹∅› ‹Σ∞›
proof (unfold_locales;transfer)
fix X Y Z :: ‹'a trace set› assume ‹definitive X› ‹definitive Y› ‹definitive Z›
then show ‹ Y ⊆ X ==> Z ⊆ X ==> (Y ∪d Z) ⊆ X›
by (metis dUnion_def dUnion_least_definitive insert_iff singletonD)
next
fix A :: ‹'a trace set set› and Z :: ‹'a trace set›
assume ‹∀X∈A. definitive X› ‹definitive Z› ‹(∧X. definitive X ==> X ∈ A ==> X ⊆ Z)›
then show ‹∪d A ⊆ Z›
by (simp add: dUnion_def dUnion_least_definitive)
qed (auto simp: dUnion_contains_definitive)
section ‹Isomorphism of definitive sets and LTL properties›
definition infinites :: ‹'a trace set → 'a infinite_trace set› where
‹infinites X = (∪x ∈ X. case x of Finite xs → {} | Infinite xs → {xs})›
lemma infinites_alt: ‹Infinite ` infinites A = A ∩ range Infinite›
unfolding set_eq_iff proof
fix x { assume ‹ (x ∈ Infinite ` infinites A)› hence ‹ (x ∈ A ∩ range Infinite) ›
by (clarsimp simp: infinites_def split!: trace.split_asm)
} moreover { assume ‹ (x ∈ A ∩ range Infinite) › hence ‹ (x ∈ Infinite ` infinites A) ›
by (force simp: infinites_def split!: trace.split intro!: imageI)
} ultimately show ‹ (x ∈ Infinite ` infinites A) = (x ∈ A ∩ range Infinite)›
by blast
qed
lemma infinites_append_right: ‹t ⌢ Infinite ψ ∈ range Infinite›
by (cases ‹t›; auto)
lemma infinites_prefix_closure:
assumes ‹definitive X›
shows ‹↓s Infinite ` infinites X = ↓s X›
unfolding prefix_closure_def infinites_def
using definitive_infinite_extension[OF assms] prefixes.order.trans
by (force split: trace.split_asm)
lemma infinites_UNIV[simp]: ‹infinites UNIV = UNIV›
by (auto simp: infinites_def split: trace.split)
lemma infinites_empty[simp]: ‹infinites {} = {}›
by (auto simp: infinites_def)
lemma infinites_Inter: ‹infinites (∩ S) = ∩ (infinites ` S)›
unfolding infinites_def
apply (rule set_eqI; rule iffI)
apply (force)
apply (simp split: trace.split trace.split_asm)
by (metis InterI trace.distinct(1) trace.exhaust trace.inject(2))
lemma infinites_Union: ‹infinites (∪ S) = ∪ (infinites ` S)›
unfolding infinites_def
by auto
lemma infinites_dprefixes: ‹infinites (↓d X) = infinites X›
unfolding infinites_def
by (force simp: dprefixes_infinite split: trace.split trace.split_asm)
lemma infinites_dprefixes_Infinite: ‹infinites (↓d Infinite ` X) = X›
proof
show ‹infinites (↓d Infinite ` X) ⊆ X›
unfolding infinites_def
using prefixes_infinite_greatest
by (force split: trace.split_asm simp: dprefixes_def prefix_closure_def)
next
show ‹X ⊆ infinites (↓d Infinite ` X)›
by (force simp: infinites_def dprefixes_def prefix_closure_def split: trace.split)
qed
lift_definition property :: ‹'a dset → 'a infinite_trace set› is ‹infinites›
done
lift_definition definitives :: ‹'a infinite_trace set → 'a dset› is ‹λx. ↓d (Infinite ` x)›
by (rule definitive_dprefixes)
lemma property_inverse: ‹property (definitives X) = X›
by (transfer, simp add: infinites_dprefixes_Infinite)
lemma definitives_inverse: ‹definitives (property X) = X›
proof (rule dset.order_antisym)
show ‹definitives (property X) ⊑ X›
by (transfer, force simp: dprefixes_def infinites_prefix_closure
intro: definitive_elemI)
next
show ‹X ⊑ definitives (property X)›
apply transfer
using definitive_contains_extensions definitive_infinite_extension
by (force simp: dprefixes_def prefix_closure_def infinites_def)
qed
lemma definitives_mono: ‹A ⊆ B ==> definitives A ⊑ definitives B›
by (transfer, metis dprefixes_inter_distrib image_mono inf.order_iff le_infE)
lemma property_mono: ‹A ⊑ B ==> property A ⊆ property B›
by (transfer, auto simp: infinites_def)
lemma definitives_reflecting: ‹definitives A ⊑ definitives B ==> A ⊆ B›
using property_inverse property_mono by metis
lemma completions_reflecting: ‹property A ⊆ property B ==> A ⊑ B›
using definitives_inverse definitives_mono by metis
lemma property_Inter: ‹property (⊓ S) = ∩ (property ` S)›
by (transfer, simp add: infinites_Inter)
lemma property_Union: ‹property (⊔ S) = ∪ (property ` S)›
by (transfer, simp add: dUnion_def infinites_dprefixes infinites_Union)
interpretation dset: complete_distrib_lattice ‹⊓› ‹⊔› ‹(⊓)› ‹(⊑)› ‹(⊏)› ‹(⊔)› ‹∅› ‹Σ∞›
by (unfold_locales)
(auto intro: completions_reflecting simp add: property_Inter property_Union INF_SUP_set)
definition iprepend :: ‹'a infinite_trace set → 'a infinite_trace set› where
‹iprepend X = {t. itdrop 1 t ∈ X }›
lemma iprepend_itdrop: ‹itdrop k x ∈ iprepend B ⟷ itdrop (Suc k) x ∈ B›
by (simp add: iprepend_def)
lemmas iprepend_itdrop_0[simp] = iprepend_itdrop[where k = ‹0›,simplified]
definition prepend' :: ‹'a trace set → 'a trace set› where
‹prepend' X = {t. tdrop 1 t ∈ X }›
lemma trace_uncons_cases [case_names Cons Nil]:
assumes ‹∧σ t. x = singleton σ ⌢ t ==> P›
and ‹x = ε ==> P›
shows ‹P›
proof (cases ‹x›)
case (Finite xs)
then show ‹?thesis›
by (cases ‹xs›;
force simp: assms(2)[simplified ε_def]
intro: assms(1)[where t = ‹Finite ts› for ts,
simplified singleton_def append.simps List.append.simps])
next
case (Infinite f) note A = this
have ‹f = (λn. if n = 0 then [f 0] ! n else (f ∘ Suc) (n - length [f 0]))›
by (rule ext, simp)
with A show ‹?thesis›
using assms(1)[where σ = ‹f 0› and t = ‹Infinite (f ∘ Suc)›,
simplified singleton_def append.simps, simplified]
by simp
qed
lemma append_prefixes_left: ‹a ∈ ↓ b ==> c ⌢ a ∈ ↓ c ⌢ b›
by (simp add: prefixes_def) (metis trace.assoc)
lemma tdrop_singleton_append[simp]: ‹tdrop (Suc n) (singleton σ ⌢ t) = tdrop n t›
by (cases ‹t›, simp_all add: singleton_def itdrop_def)
lemma tdrop_zero[simp]: ‹tdrop 0 t = t›
by (cases ‹t›; simp)
lemma tdrop_ε[simp]: ‹tdrop k ε = ε›
by (simp add: ε_def)
lemma prepend'_prefix_closure: ‹↓s (prepend' X) ⊆ prepend' (↓s X)›
proof (rule subsetI)
fix x
assume A: ‹ x ∈ ↓s prepend' X›
show ‹x ∈ prepend' (↓s X) ›
proof (cases ‹x› rule: trace_uncons_cases)
case (Cons σ t)
with A show ‹?thesis›
unfolding prefix_closure_def prepend'_def prefixes_def
by (fastforce simp: trace.assoc)
next
case Nil
with A show ‹?thesis›
unfolding prefix_closure_def prepend'_def
by (force simp: prefixes_empty_least)
qed
qed
lemma prepend'_dprefixes :
assumes ‹definitive X›
shows ‹↓d prepend' X = prepend' X›
proof
show ‹↓d prepend' X ⊆ prepend' X›
proof (rule subsetI)
fix x assume A: ‹x ∈ ↓d prepend' X› show ‹x ∈ prepend' X›
proof (cases ‹x› rule: trace_uncons_cases)
case (Cons σ t)
with A show ‹?thesis›
unfolding dprefixes_def
apply (subst assms[simplified definitive_def, THEN sym])
apply (clarsimp dest!: subset_trans[OF _ prepend'_prefix_closure])
using append_prefixes_left
by (force simp: dprefixes_def prepend'_def prefix_closure_def subset_iff
prefixes_extensions[THEN sym])
next
case Nil
with A show ‹?thesis›
apply (subst assms[simplified definitive_def, THEN sym])
apply (clarsimp simp: prefixes_empty_least prefixes_def dprefixes_def
prepend'_def prefix_closure_def subset_iff
prefixes_extensions[THEN sym])
by (metis tdrop_singleton_append tdrop_zero trace.assoc)
qed
qed
next
show ‹prepend' X ⊆ ↓d prepend' X›
proof (rule subsetI)
fix x assume A: ‹x ∈ prepend' X› show ‹x ∈ ↓d prepend' X›
proof (cases ‹x› rule: trace_uncons_cases)
case (Cons σ t)
with A show ‹?thesis›
by (clarsimp simp: dprefixes_def prefixes_def prepend'_def
prefix_closure_def prefixes_extensions[THEN sym])
(metis (mono_tags, lifting) assms definitive_contains_extensions
mem_Collect_eq prefixes_def prefixes_extensions subset_eq
tdrop_singleton_append tdrop_zero trace.assoc)
next
case Nil
with A show ‹?thesis›
using assms definitive_contains_extensions
by (force simp: dprefixes_def prepend'_def prefix_closure_def)
qed
qed
qed
lemma prepend'_definitive :
assumes ‹definitive X›
shows ‹definitive (prepend' X)›
unfolding definitive_def using assms
by (rule prepend'_dprefixes)
lift_definition prepend :: ‹'a dset → 'a dset› is ‹prepend'›
by (rule prepend'_definitive)
lemma prepend_Inter: ‹⊓ (prepend ` S) = prepend (⊓ S)›
apply transfer
by (auto simp add: prepend'_def)
lemma in_dset_prependD: ‹in_dset (Finite [a] ⌢ x) (prepend A) ==> in_dset x A›
by (transfer, metis One_nat_def Traces.singleton_def mem_Collect_eq prepend'_def
tdrop_singleton_append tdrop_zero)
lemma in_dset_prependI: ‹in_dset x A ==> in_dset (Finite [a] ⌢ x) (prepend A)›
by (transfer, metis One_nat_def Traces.singleton_def mem_Collect_eq prepend'_def
tdrop_singleton_append tdrop_zero)
lemma prepend'_mono:
assumes ‹A ⊆ B›
shows ‹prepend' A ⊆ prepend' B›
using assms unfolding prepend'_def
by blast
lemma property_prepend: ‹property (prepend X) = iprepend (property X)›
apply transfer
by (clarsimp simp: definitive_def infinites_def prepend'_def
split!: trace.split_asm trace.split intro!: set_eqI;
blast)
lemma iprepend_Union: ‹∪ (iprepend ` S) = iprepend (∪ S)›
by fastforce
lemma definitives_inverse_eqI: ‹definitives (property X) = definitives (property Y) ==> X = Y›
by (simp add: definitives_inverse)
lemma prepend_Union: ‹⊔ (prepend ` S) = prepend (⊔ S)›
apply (rule definitives_inverse_eqI)
apply (simp add: property_Union property_prepend)
by (metis UN_extend_simps(10) iprepend_Union)
lemma non_empty_trace: ‹ x ≠ ε ⟷ (∃σ x'. x = Finite [σ] ⌢ x')›
apply (cases ‹x› rule: trace_uncons_cases; clarsimp)
apply (metis Traces.singleton_def ε_def append_is_empty(1) not_Cons_self2 trace.inject(1))
by (metis ε_def append_is_empty(1) list.discI trace.inject(1))
lemma thead_append: ‹x ≠ ε ==> thead (x ⌢ y) = thead x›
by (cases ‹x›; cases ‹y›; simp add: ε_def nth_append)
lemma thead_prefix: ‹ x ∈ ↓ y ==> x ≠ ε ==> thead x = thead y›
apply (simp add: prefixes_def non_empty_trace)
using thead_append [where x = ‹Finite [_]›, simplified ε_def, simplified]
by (metis append_is_empty(1) thead_append)
lemma compr'_inter_thead:
‹↓d {x. x ≠ ε ∧ P (thead x)} ∩ ↓d {x. x ≠ ε ∧ Q (thead x)}
= ↓d {x. x ≠ ε ∧ P (thead x) ∧ Q (thead x)}›
proof (rule antisym)
{ fix x t
assume ‹∀t. x ∈ ↓ t ⟶ (∃x. x ≠ ε ∧ P (thead x) ∧ t ∈ ↓ x)›
and ‹∀t. x ∈ ↓ t ⟶ (∃x. x ≠ ε ∧ Q (thead x) ∧ t ∈ ↓ x)›
and ‹x ∈ ↓ t›
then have ‹ ∃x. x ≠ ε ∧ P (thead x) ∧ Q (thead x) ∧ t ∈ ↓ x›
by (cases ‹t = ε›; fastforce dest: thead_prefix simp: prefixes_empty prefixes_empty_least)
} then show ‹↓d {x. x ≠ ε ∧ P (thead x)} ∩ ↓d {x. x ≠ ε ∧ Q (thead x)} ⊆ ↓d {x. x ≠ ε ∧ P (thead x) ∧ Q (thead x)}›
by (clarsimp simp: set_eq_iff subset_iff dprefixes_def prefix_closure_def prefixes_extensions[THEN sym])
next
{ fix x
assume ‹ ∀t. x ∈ ↓ t ⟶ (∃x. x ≠ ε ∧ P (thead x) ∧ Q (thead x) ∧ t ∈ ↓ x)›
then have ‹(∀t. x ∈ ↓ t ⟶ (∃x. x ≠ ε ∧ P (thead x) ∧ t ∈ ↓ x)) ∧
(∀t. x ∈ ↓ t ⟶ (∃x. x ≠ ε ∧ Q (thead x) ∧ t ∈ ↓ x))›
by fastforce }
then show ‹↓d {x. x ≠ ε ∧ P (thead x)} ∩ ↓d {x. x ≠ ε ∧ Q (thead x)} ⊇ ↓d {x. x ≠ ε ∧ P (thead x) ∧ Q (thead x)}›
by (clarsimp simp: set_eq_iff subset_iff dprefixes_def prefix_closure_def prefixes_extensions[THEN sym])
qed
lift_definition compr :: ‹('a trace → bool) → 'a dset› is ‹λp. ↓d {x. p x }›
by (rule definitive_dprefixes)
lift_definition complement :: ‹'a dset → 'a dset› is ‹λp. ↓d (range Infinite - p)›
by (rule definitive_dprefixes)
lemma property_complement[simp]: ‹property (complement X) = UNIV - property X›
by (transfer, force simp: infinites_dprefixes[simplified infinites_def] infinites_def
split: trace.split_asm trace.split)
end
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland