Theory Transition_System
section ‹Transition Systems and System Models›
text ‹ This theory formalizes transition systems (where transitions have a separate identity)
and what we call ``simple transition systems'', where transitions are just certain pairs of states.
The latter are what in the ``Relative Security'' paper we call ``system models''.
We introduce system models as a separate locale. Basic notions such as reachability are introduced,
and basic facts about them are being proved. ›
theory Transition_System
imports Trivia
begin
subsection ‹The relevant locales›
locale Transition_System =
fixes istate :: "'state ⇒ bool"
and validTrans :: "'trans ⇒ bool"
and srcOf :: "'trans ⇒ 'state"
and tgtOf :: "'trans ⇒ 'state"
locale Simple_Transition_System =
Transition_System istate validTrans fst snd
for istate :: "'state ⇒ bool"
and validTrans :: "'state × 'state ⇒ bool"
locale System_Mod =
Simple_Transition_System istate validTrans
for istate :: "'state ⇒ bool"
and validTrans :: "'state × 'state ⇒ bool"
+
fixes final :: "'state ⇒ bool"
assumes final_def: "final s1 ⟷ (∀s2. ¬ validTrans (s1,s2))"
locale System_Mod_Deterministic =
System_Mod istate validTrans final
for istate :: "'state ⇒ bool"
and validTrans :: "'state × 'state ⇒ bool"
and final :: "'state ⇒ bool"
+
fixes "next" :: "'state ⇒ 'state"
assumes validTrans_iff_next: "validTrans (s1,s2) ⟷ ¬ final s1 ∧ next s1 = s2"
context Transition_System
begin
subsection ‹Reachability›
inductive reach :: "'state ⇒ bool" where
Istate: "istate s ⟹ reach s"
|
Step: "reach s ⟹ validTrans trn ⟹ srcOf trn = s ⟹ tgtOf trn = s' ⟹ reach s'"
definition holdsIstate :: "('state ⇒ bool) ⇒ bool" where
"holdsIstate φ ≡ ∀s. istate s ⟶ φ s"
definition invar :: "('state ⇒ bool) ⇒ bool" where
"invar φ ≡ ∀ trn. validTrans trn ∧ reach (srcOf trn) ∧ φ (srcOf trn) ⟶ φ (tgtOf trn)"
lemma holdsIstate_invar:
assumes h: "holdsIstate φ" and i: "invar φ" and a: "reach s"
shows "φ s"
using a apply (induct rule: reach.induct)
using h i unfolding holdsIstate_def invar_def by auto
inductive reachFrom :: "'state ⇒ 'state ⇒ bool"
for s :: "'state"
where
Refl[intro]: "reachFrom s s"
| Step: "⟦reachFrom s s'; validTrans trn; srcOf trn = s'; tgtOf trn = s''⟧ ⟹ reachFrom s s''"
lemma reachFrom_Step1:
"⟦validTrans trn; srcOf trn = s; tgtOf trn = s'⟧ ⟹ reachFrom s s'"
by (auto intro: reachFrom.Step)
lemma reachFrom_Step_Left:
"reachFrom s' s'' ⟹ validTrans trn ⟹ srcOf trn = s ⟹ tgtOf trn = s' ⟹ reachFrom s s''"
by (induction s'' rule: reachFrom.induct) (auto intro: reachFrom.Step)
lemma reachFrom_trans: "reachFrom s0 s1 ⟹ reachFrom s1 s2 ⟹ reachFrom s0 s2"
by (induction s1 arbitrary: s2 rule: reachFrom.induct) (auto intro: reachFrom_Step_Left)
lemma reachFrom_reach: "reachFrom s s' ⟹ reach s ⟹ reach s'"
by (induction rule: reachFrom.induct) (auto intro: reach.Step)
end
subsection ‹Finite traces in transition systems ›
type_synonym 'trans trace = "'trans list"
context Transition_System
begin
inductive valid :: "'trans trace ⇒ bool" where
Singl[simp,intro!]:
"validTrans trn
⟹
valid [trn]"
|
Cons[intro]:
"⟦validTrans trn; tgtOf trn = srcOf (hd tr); valid tr⟧
⟹
valid (trn # tr)"
inductive_cases valid_SinglE[elim!]: "valid [trn]"
inductive_cases valid_ConsE[elim]: "valid (trn # tr)"
inductive valid2 :: "'trans trace ⇒ bool" where
Singl[simp,intro!]:
"validTrans trn
⟹
valid2 [trn]"
|
Rcons[intro]:
"⟦valid2 tr; tgtOf (last tr) = srcOf trn; validTrans trn⟧
⟹
valid2 (tr ## trn)"
inductive_cases valid2_SinglE[elim!]: "valid2 [trn]"
inductive_cases valid2_RconsE[elim]: "valid2 (tr ## trn)"
lemma Nil_not_valid[simp]: "¬ valid []"
by (metis valid.simps neq_Nil_conv)
lemma Nil_not_valid2[simp]: "¬ valid2 []"
by (metis valid2.cases append_Nil butlast.simps butlast_snoc not_Cons_self2)
lemma valid_Rcons:
assumes "valid tr" and "tgtOf (last tr) = srcOf trn" and "validTrans trn"
shows "valid (tr ## trn)"
using assms proof(induct arbitrary: trn)
case (Cons trn tr trna)
thus ?case by (cases tr) auto
qed auto
lemma valid_hd_Rcons[simp]:
assumes "valid tr"
shows "hd (tr ## tran) = hd tr"
by (metis Nil_not_valid assms hd_append)
lemma valid2_hd_Rcons[simp]:
assumes "valid2 tr"
shows "hd (tr ## tran) = hd tr"
by (metis Nil_not_valid2 assms hd_append)
lemma valid2_last_Cons[simp]:
assumes "valid2 tr"
shows "last (tran # tr) = last tr"
by (metis Nil_not_valid2 assms last.simps)
lemma valid2_Cons:
assumes "valid2 tr" and "tgtOf trn = srcOf (hd tr)" and "validTrans trn"
shows "valid2 (trn # tr)"
using assms proof(induct arbitrary: trn)
case Singl show ?case
unfolding two_singl_Rcons apply(rule valid2.Rcons) using Singl
by (auto intro: valid2.Singl)
next
case Rcons show ?case
unfolding append.append_Cons[symmetric] apply(rule valid2.Rcons) using Rcons by auto
qed
lemma valid_valid2: "valid = valid2"
proof(rule ext, safe)
fix tr assume "valid tr" thus "valid2 tr"
by (induct) (auto intro: valid2.Singl valid2_Cons)
next
fix tr assume "valid2 tr" thus "valid tr"
by (induct) (auto intro: valid.Singl valid_Rcons)
qed
lemma valid_Cons_iff:
"valid (trn # tr) ⟷ validTrans trn ∧ ((tgtOf trn = srcOf (hd tr) ∧ valid tr) ∨ tr = [])"
unfolding valid.simps[of "trn # tr"] by auto
lemma valid_append:
"tr ≠ [] ⟹ tr1 ≠ [] ⟹
valid (tr @ tr1) ⟷ valid tr ∧ valid tr1 ∧ tgtOf (last tr) = srcOf (hd tr1)"
by (induct tr) (auto simp add: valid_Cons_iff)
lemmas valid2_valid = valid_valid2[symmetric]
lemma valid_nth:
"valid tr ⟷
tr ≠ [] ∧
list_all validTrans tr ∧
(∀i<length tr-1. tgtOf (tr!i) = srcOf (tr!(Suc i)))"
unfolding list_all_length proof (induct tr)
case (Cons a tr)
then show ?case
apply (subst valid.simps)
apply safe
apply simp_all
apply (metis diff_Suc_1 less_Suc_eq_0_disj nth_Cons')
using Transition_System.valid_append append_self_conv2 drop_Suc_Cons hd_drop_conv_nth id_take_nth_drop
length_Cons less_Suc_eq list.simps(3) not_less valid.Cons valid_ConsE
apply (smt (verit) drop_eq_Nil2 list.discI)
apply (metis hd_conv_nth length_greater_0_conv nth_Cons_0 zero_less_Suc)
apply (metis Suc_less_eq nth_Cons_Suc)
by (metis Suc_pred length_greater_0_conv less_Suc_eq_0_disj nth_Cons_0 nth_Cons_Suc)
qed simp_all
definition validFrom :: "'state ⇒ 'trans trace ⇒ bool" where
"validFrom s tr ≡ tr = [] ∨ (valid tr ∧ srcOf (hd tr) = s)"
lemma validFrom_Nil[simp,intro!]: "validFrom s []"
unfolding validFrom_def by auto
lemma validFrom_single:
assumes ‹validFrom s [trn]›
shows ‹srcOf trn = s›
using assms by (simp add: validFrom_def)
lemma validFrom_valid[simp,intro]: "valid tr ∧ srcOf (hd tr) = s ⟹ validFrom s tr"
unfolding validFrom_def by auto
lemma validFrom_append:
"validFrom s (tr @ tr1) ⟷ (tr = [] ∧ validFrom s tr1) ∨ (tr ≠ [] ∧ validFrom s tr ∧ validFrom (tgtOf (last tr)) tr1)"
unfolding validFrom_def using valid_append
by (cases "tr = [] ∨ tr1 = []") fastforce+
lemma validFrom_Cons:
"validFrom s (trn # tr) ⟷ validTrans trn ∧ srcOf trn = s ∧ validFrom (tgtOf trn) tr"
unfolding validFrom_def by auto
lemma validFrom_sameState: "validFrom s tr ∧ validFrom s' tr ⟹ tr = [] ∨ s = s'"
by (metis validFrom_def)
lemma validFrom_nth:
"validFrom s tr ⟷
tr = [] ∨
srcOf (hd tr) = s ∧
list_all validTrans tr ∧
(∀i<length tr-1. tgtOf (tr!i) = srcOf (tr!(Suc i)))"
unfolding validFrom_def valid_nth by auto
lemma validFrom_nth_NE:
"tr ≠ [] ⟹
validFrom s tr ⟷
srcOf (hd tr) = s ∧
list_all validTrans tr ∧
(∀i<length tr-1. tgtOf (tr!i) = srcOf (tr!(Suc i)))"
unfolding validFrom_nth by auto
lemma valid_reach_src_tgt:
assumes "valid tr" and "reach (srcOf (hd tr))"
shows "reach (tgtOf (last tr))"
using assms reach.Step apply induct by auto
lemma valid_init_reach:
assumes "valid tr" and "istate (srcOf (hd tr))"
shows "reach (tgtOf (last tr))"
using valid_reach_src_tgt assms reach.Istate by metis
lemma reach_init_valid:
assumes "reach s"
shows
"istate s
∨
(∃ tr. valid tr ∧ istate (srcOf (hd tr)) ∧ tgtOf (last tr) = s)"
using assms proof induction
case (Step s trn s')
thus ?case proof(elim disjE exE conjE)
assume s: "istate s"
show ?thesis
apply (intro disjI2 exI[of _ "[trn]"])
using s Step by auto
next
fix tr assume v: "valid tr" and s: "istate (srcOf (hd tr))" and t: "tgtOf (last tr) = s"
show ?thesis
apply (intro disjI2 exI[of _ "tr ## trn"])
using Step v t s by (auto intro: valid_Rcons)
qed
qed auto
lemma reach_validFrom:
assumes "reach s'"
shows "∃ s tr. istate s ∧ (s = s' ∨ (validFrom s tr ∧ tgtOf (last tr) = s'))"
using reach_init_valid[OF assms] unfolding validFrom_def by auto
lemma valid_validTrans_set:
assumes "valid tr" and "trn ∈∈ tr"
shows "validTrans trn"
using assms by (induct tr arbitrary: trn) auto
lemma validFrom_validTrans_set:
assumes "validFrom s tr" and "trn ∈∈ tr"
shows "validTrans trn"
by (metis assms validFrom_def empty_iff list.set valid_validTrans_set)
lemma valid_validTrans_nth:
assumes v: "valid tr" and i: "i < length tr"
shows "validTrans (tr!i)"
using valid_validTrans_set[OF v] i by auto
lemma valid_validTrans_nth_srcOf_tgtOf:
assumes v: "valid tr" and i: "Suc i < length tr"
shows "srcOf (tr!(Suc i)) = tgtOf (tr!i)"
by (metis Cons_nth_drop_Suc valid_append Suc_lessD append_self_conv2 hd_drop_conv_nth i id_take_nth_drop list.distinct(1) v valid_ConsE)
lemma validFrom_reach: "validFrom s tr ⟹ reach s ⟹ tr ≠ [] ⟹ reach (tgtOf (last tr))"
by (intro valid_reach_src_tgt) (auto simp add: validFrom_def)
end
subsection ‹Finite traces in simple transition systems ›
definition "lastt s tr ≡ if tr = [] then s else last tr"
lemma lastt_Nil[simp]: "lastt s [] = s"
unfolding lastt_def by auto
context Simple_Transition_System
begin
definition validS :: "'state list ⇒ bool" where
"validS sl ≡ ∀i<length sl-1. validTrans (sl!i, sl!(Suc i))"
definition validFromS :: "'state ⇒ 'state list ⇒ bool" where
"validFromS s sl ≡ sl = [] ∨ (hd sl = s ∧ validS sl)"
lemma validS_Nil[simp,intro!]:
"validS []"
unfolding validS_def by auto
lemma validS_singl[simp,intro!]:
"validS [s]"
unfolding validS_def by auto
lemma validFromS_Nil[simp,intro!]:
"validFromS s []"
unfolding validFromS_def by auto
lemma validFromS[simp,intro!]:
"validFromS s [s]"
unfolding validFromS_def by auto
lemma validFromS_Cons_iff:
"validFromS s (s' # sl) ⟷ s = s' ∧ (sl = [] ∨ (validTrans (s,hd sl) ∧ validFromS (hd sl) sl))"
unfolding validFromS_def validS_def apply safe
subgoal by auto
subgoal using hd_conv_nth by fastforce
subgoal by simp (metis One_nat_def add.commute less_diff_conv nth_Cons_Suc plus_1_eq_Suc)
subgoal by auto
subgoal by auto
subgoal by auto
subgoal by auto
subgoal by auto
subgoal by simp (metis One_nat_def Suc_less_eq Suc_pred diff_0_eq_0 hd_conv_nth list.size(3) not_gr_zero nth_Cons' zero_less_diff) .
lemma validFromS_Cons[intro]:
"validTrans (s,s') ⟹ validFromS s' sl ⟹ validFromS s (s # sl)"
by (cases "sl", auto simp: validFromS_Cons_iff)
lemma lastt_Cons[simp]: "validTrans (s,s') ⟹ validFromS s' tr ⟹ tr ≠ [] ⟹ lastt s (s # tr) = lastt s' tr"
unfolding lastt_def by auto
definition fromS :: "'a list ⇒ ('a × 'a) list" where
"fromS sl ≡ if sl = [] then [] else zip (butlast sl) (tl sl)"
lemma fromS_Nil[simp]: "fromS [] = []"
unfolding fromS_def by auto
lemma fromS_singl[simp]: "fromS [s] = []"
unfolding fromS_def by auto
lemma fromS_eq_Nil[simp]: "fromS sl = [] ⟷ length sl ≤ Suc 0"
unfolding fromS_def by (cases sl) (auto simp: zip_eq_Nil_iff)
lemma length_fromS_notNil[simp]:
"sl ≠ [] ⟹ length (fromS sl) = length sl - 1"
unfolding fromS_def by auto
lemma fromS_nth: "i < length sl-1 ⟹ fromS sl ! i = (sl!i, sl!(Suc i))"
unfolding fromS_def by (auto simp: nth_butlast nth_tl)
lemma length_fromS_less1: "length (fromS sl) = length sl - 1"
by (auto simp add: fromS_def)
definition toS :: "('state × 'state) list ⇒ 'state list" where
"toS tr ≡ if tr = [] then [] else (fst (hd tr)) # map snd tr"
lemma toS_Nil[simp]: "toS [] = []"
unfolding toS_def by auto
lemma toS_eq_Nil[simp]: "toS tr = [] ⟷ tr = []"
unfolding toS_def by auto
lemma length_toS[simp]:
"tr ≠ [] ⟹ length (toS tr) = Suc (length tr)"
unfolding toS_def by auto
lemma toS_nth_0: "tr ≠ [] ⟹ toS tr ! 0 = fst (tr!0)"
unfolding toS_def by (simp add: hd_conv_nth)
lemma toS_nth_Suc: "i < length tr-1 ⟹ toS tr ! (Suc i) = snd (tr!i)"
unfolding toS_def by auto
lemma toS_last: "tr ≠ [] ⟹ last (toS tr) = snd (last tr)"
unfolding toS_def by (simp add: last_map)
lemma toS_nth_valid: "valid tr ⟹ i < length tr-1 ⟹ toS tr ! i = fst (tr!i)"
unfolding toS_def by (simp add: hd_conv_nth nth_Cons' valid_nth)
lemma toS_length_gt_eq: ‹length tr ≤ length (toS tr)›
by (cases ‹tr = []›, simp_all)
lemma fromS_toS_valid[simp]: "valid tr ⟹ fromS (toS tr) = tr"
apply(rule nth_equalityI)
subgoal by (cases tr, auto)
subgoal apply (cases tr)
subgoal by simp
subgoal
by (smt (verit, best) fromS_nth length_fromS_notNil toS_eq_Nil
toS_last ‹valid tr ⟹ length (fromS (toS tr)) = length tr›
diff_Suc_1 last_conv_nth le_eq_less_or_eq le_zero_eq length_Cons
less_Suc_eq_le not_less
prod.collapse toS_nth_0 toS_nth_Suc valid_nth zero_induct) . .
lemma fromS_toS_validFrom[simp]: "validFrom s tr ⟹ fromS (toS tr) = tr"
unfolding validFrom_def by auto
lemma toS_fromS_singl[simp]: "toS (fromS [s]) = []"
by simp
lemma toS_fromS_nonSingl[simp]:
"length sl ≠ Suc 0 ⟹ toS (fromS sl) = sl"
apply(rule nth_equalityI)
subgoal by (cases sl, auto)
subgoal for i apply(cases "sl = []")
subgoal by auto
subgoal apply (cases i)
subgoal by simp (metis toS_nth_0 fromS_eq_Nil fromS_nth fst_eqD
length_fromS_notNil length_greater_0_conv)
subgoal for j apply simp
by (metis (no_types, lifting) toS_def Suc_less_eq2
‹⟦length sl ≠ Suc 0⟧ ⟹ length (toS (fromS sl)) = length sl›
diff_Suc_1 fromS_nth
length_fromS_notNil list.size(3) nth_Cons_Suc nth_map snd_conv) . . .
lemma valid_fromS[simp]:
"length sl > Suc 0 ⟹ valid (fromS sl) ⟷ validS sl"
unfolding valid_nth validS_def list_all_length apply(cases sl)
subgoal by auto
subgoal for s ssl apply(cases ssl)
subgoal by auto
subgoal by (simp add: fromS_nth) . .
lemma validFrom_fromS[simp]:
"length sl ≠ Suc 0 ⟹ validFrom s (fromS sl) ⟷ validFromS s sl"
unfolding validFrom_def validFromS_def apply(cases sl)
apply (metis Simple_Transition_System.toS_fromS_nonSingl length_0_conv
list.distinct(1) toS_def)
by (metis fromS_eq_Nil hd_conv_nth length_greater_0_conv nat_less_le
not_less not_less_eq toS_fromS_nonSingl toS_nth_0 valid_fromS)
lemma validS_toS[simp]:
"valid tr ⟹ validS (toS tr)"
by (metis fromS_eq_Nil fromS_toS_valid not_less valid_fromS valid_nth)
lemma validFromS_toS[simp]:
"validFrom s tr ⟹ validFromS s (toS tr)"
by (metis validFrom_def list.sel(1) toS_def validFromS_def validS_toS)
lemma validFromS_singl_iff[simp]: "validFromS s [s'] ⟷ s = s'"
using validFromS_def by auto
end
subsection ‹Possibly infinite traces ›
type_synonym 'trans ltrace = "'trans llist"
context Transition_System
begin
coinductive lvalid :: "'trans ltrace ⇒ bool" where
Singl[simp,intro!]:
"validTrans trn
⟹
lvalid [[trn]]"
|
Cons[intro]:
"⟦validTrans trn; tgtOf trn = srcOf (lhd tr); lvalid tr⟧
⟹
lvalid (trn $ tr)"
inductive_cases lvalid_SinglE[elim!]: "lvalid [[trn]]"
inductive_cases lvalid_ConsE[elim]: "lvalid (trn $ tr)"
lemma Nil_not_lvalid[simp]: "¬ lvalid [[]]"
using lvalid.cases by blast
lemma lvalid_LCons_iff:
"lvalid (trn $ tr) ⟷ validTrans trn ∧ ((tgtOf trn = srcOf (lhd tr) ∧ lvalid tr) ∨ tr = [[]])"
by blast
definition lvalidFrom :: "'state ⇒ 'trans ltrace ⇒ bool" where
"lvalidFrom s tr ≡ tr = [[]] ∨ (lvalid tr ∧ srcOf (lhd tr) = s)"
lemma lvalidFrom_Nil[simp,intro!]: "lvalidFrom s [[]]"
unfolding lvalidFrom_def by auto
lemma lvalidFrom_single:
assumes ‹lvalidFrom s [[trn]]›
shows ‹srcOf trn = s›
using assms by (simp add: lvalidFrom_def)
lemma lvalidFrom_lvalid[simp,intro]: "lvalid tr ∧ srcOf (lhd tr) = s ⟹ lvalidFrom s tr"
unfolding lvalidFrom_def by auto
lemma lvalidFrom_Cons:
"lvalidFrom s (trn $ tr) ⟷ validTrans trn ∧ srcOf trn = s ∧ lvalidFrom (tgtOf trn) tr"
unfolding lvalidFrom_def by auto
lemma lvalidFrom_sameState: "lvalidFrom s tr ∧ lvalidFrom s' tr ⟹ tr = [[]] ∨ s = s'"
by (metis lvalidFrom_def)
end
subsection ‹Possibly infinite traces in simple transition systems ›
context Simple_Transition_System
begin
definition lvalidS :: "'state llist ⇒ bool" where
"lvalidS sl ≡ ∀i<llength sl-1. validTrans (lnth sl i, lnth sl (Suc i))"
definition lvalidFromS :: "'state ⇒ 'state llist ⇒ bool" where
"lvalidFromS s sl ≡ sl = [[]] ∨ (lhd sl = s ∧ lvalidS sl)"
lemma lvalidS_LNil[simp,intro!]:
"lvalidS [[]]"
unfolding lvalidS_def by auto
lemma lvalidS_singl[simp,intro!]:
"lvalidS [[s]]"
unfolding lvalidS_def by auto
lemma lvalidFromS_LNil[simp,intro!]:
"lvalidFromS s [[]]"
unfolding lvalidFromS_def by auto
lemma lvalidFromS[simp,intro!]:
"lvalidFromS s [[s]]"
unfolding lvalidFromS_def by auto
lemma lvalidFromS_Cons_iff:
"lvalidFromS s (s' $ sl) ⟷ s = s' ∧ (sl = [[]] ∨ (validTrans (s,lhd sl) ∧ lvalidFromS (lhd sl) sl))"
unfolding lvalidFromS_def lvalidS_def apply safe
subgoal by auto
subgoal by simp (metis i0_less lhd_conv_lnth llength_eq_0 lnth_0 lnull_def zero_enat_def)
subgoal by simp (metis Suc_ile_eq co.enat.exhaust eSuc_minus_1 idiff_0 iless_Suc_eq lnth_Suc_LCons not_less_zero)
subgoal by auto
subgoal by auto
subgoal by auto
subgoal by auto
subgoal by auto
subgoal by simp (metis One_nat_def Suc_ile_eq Suc_pred epred_conv_minus epred_llength iless_Suc_eq less_Suc_eq
llength_LCons llength_eq_0 llist.disc(1) llist.exhaust_sel lnth_LCons' zero_less_Suc zero_order(3)) .
lemma lvalidFromS_Cons[intro]:
"validTrans (s,s') ⟹ lvalidFromS s' sl ⟹ lvalidFromS s (s $ sl)"
by (cases "sl", auto simp: lvalidFromS_Cons_iff)
coinductive lvalidFromS' :: "'state ⇒ 'state llist ⇒ bool" where
lvalidFromS: "lvalidFromS s ltr ⟹ lvalidFromS' s ltr"
|
LNil: "lvalidFromS' s [[]]"
|
Singl: "lvalidFromS' s [[s]]"
|
lappend: "validFromS s tr ⟹ tr ≠ [] ⟹ validTrans (last tr, s'') ⟹
lvalidFromS' s'' ltr ⟹
lvalidFromS' s (lappend (llist_of tr) ltr)"
lemma lvalidFromS'_lnth_validTrans:
assumes "lvalidFromS' s lltr"
and "i < llength lltr - 1"
shows "validTrans (lnth lltr i, lnth lltr (Suc i))"
using assms proof(induct i arbitrary: s lltr rule: less_induct)
case (less i s lltr)
note vltr = `lvalidFromS' s lltr`
note ii = `i < llength lltr - 1`
show ?case using `lvalidFromS' s lltr` proof cases
case lvalidFromS
then show ?thesis
by (metis Simple_Transition_System.lvalidFromS_def Simple_Transition_System.lvalidS_LNil ii lvalidS_def)
next
case LNil
then show ?thesis using less(3) by auto
next
case Singl
then show ?thesis using less(3) by auto
next
case (lappend tr s'' ltr)
note lltr = `lltr = lappend (llist_of tr) ltr`
have "i < length tr - 1 ∨ i = length tr - 1 ∨ i = length tr ∨ i ≥ Suc (length tr)" by auto
then show ?thesis proof(elim disjE)
assume i: "i < length tr - 1"
hence 0: "lnth lltr i = nth tr i" "lnth lltr (Suc i) = nth tr (Suc i)"
unfolding lltr
apply (metis Suc_diff_1 length_greater_0_conv less_SucI lnth_lappend_llist_of local.lappend(3))
by (metis Suc_diff_1 Suc_less_eq i length_greater_0_conv lnth_lappend_llist_of local.lappend(3))
show ?thesis using `validFromS s tr` i unfolding 0
by (simp add: Simple_Transition_System.validS_def local.lappend(3) validFromS_def)
next
assume i: "i = length tr - 1"
hence 0: "lnth lltr i = last tr" "lnth lltr (Suc i) = s''"
unfolding lltr
apply (simp add: last_conv_nth lnth_lappend_llist_of local.lappend(3))
apply(subst lnth_lappend) using i `tr ≠ []` apply simp
by (smt (verit, best) One_nat_def Simple_Transition_System.lvalidFromS'.cases
Simple_Transition_System.lvalidFromS_def Simple_Transition_System.validFromS_def
idiff_enat_enat ii lappend_lnull2 lhd_lappend lhd_llist_of linorder_neq_iff llength_llist_of
llist.disc(1) lltr lnth_0 lnth_0_conv_lhd lnull_llist_of local.lappend(5) one_enat_def)
show ?thesis unfolding 0 by fact
next
assume i: "i = length tr"
hence ll: "llength ltr > Suc 0"
by (metis One_nat_def Suc_ile_eq add.right_neutral
diff_le_self eSuc_minus_1 epred_conv_minus epred_enat gr_zeroI ii linorder_not_less
llength_lappend llength_llist_of lltr of_nat_eq_enat of_nat_less_iff one_enat_def order_less_le
plus_1_eSuc(2) zero_enat_def)
hence ltrne: "ltr ≠ [[]]"
using ii lltr epred_conv_minus epred_enat by fastforce
hence 0: "lnth lltr i = lnth ltr 0" "lnth lltr (Suc i) = lnth ltr (Suc 0)"
unfolding lltr i lnth_lappend by auto
thus ?thesis using ll `lvalidFromS' s'' ltr`
by (metis One_nat_def eSuc_minus_1 enat_0 enat_diff_cancel_left gr_zeroI i le_numeral_extra(4)
length_greater_0_conv less.hyps local.lappend(3) nless_le one_eSuc one_enat_def)
next
assume i: "i ≥ Suc (length tr)"
hence ltrne: "ltr ≠ [[]]"
using ii lltr epred_conv_minus epred_enat by fastforce
from i obtain j where ij: "i = length tr + j"
using less_imp_add_positive
using le_Suc_ex Suc_le_eq by auto
hence jli: "j < i" by (simp add: local.lappend(3))
hence 0: "lnth lltr i = lnth ltr j" "lnth lltr (Suc i) = lnth ltr (Suc j)"
using ij unfolding lltr by (auto simp: lnth_lappend_llist_of)
have jj: "j < llength ltr - 1" using i ltrne ii unfolding ij lltr apply simp
by (metis add_diff_assoc_enat enat_add_mono i0_less ileI1 llength_eq_0 lnull_def one_eSuc plus_enat_simps(1))
have lhdltr: "lvalidFromS' (lhd ltr) ltr"
by (smt (verit) lhd_lappend lhd_llist_of llist.exhaust_sel llist.inject lnull_llist_of
local.lappend(5) lvalidFromS'.simps lvalidFromS_def validFromS_def)
show ?thesis unfolding 0 by (rule less(1)[OF jli lhdltr jj])
qed
qed
qed
proposition lvalidFromS'_imp_lvalidFromS:
assumes "lvalidFromS' s ltr"
shows "lvalidFromS s ltr"
unfolding lvalidFromS_def lvalidS_def apply safe
subgoal using assms
by (metis Simple_Transition_System.validFromS_def lhd_LCons lhd_lappend
lhd_llist_of lnull_llist_of lvalidFromS'.simps lvalidFromS_def)
subgoal for i using assms lvalidFromS'_lnth_validTrans by blast .
lemmas lvalidFromS_imp_lvalidFromS' = lvalidFromS'.intros(1)
lemma lvalidFromS_lvalidFromS':
"lvalidFromS = lvalidFromS'"
using lvalidFromS'_imp_lvalidFromS lvalidFromS_imp_lvalidFromS' by blast
lemma lvalidFromS'_lvalidFromS:
"lvalidFromS' = lvalidFromS"
using lvalidFromS'_imp_lvalidFromS lvalidFromS_imp_lvalidFromS' by blast
coinductive llvalidFromS :: "enat ⇒ 'state ⇒ 'state llist ⇒ bool" where
Delay: "n' < n ⟹ llvalidFromS n' s ltr ⟹ llvalidFromS n s ltr"
|
lvalidFromS: "lvalidFromS s ltr ⟹ llvalidFromS n s ltr"
|
LNil: "llvalidFromS n s [[]]"
|
Singl: "llvalidFromS n s [[s]]"
|
lappend: "validFromS s tr ⟹ tr ≠ [] ⟹ validTrans (last tr, s'') ⟹
llvalidFromS n' s'' ltr ⟹
llvalidFromS n s (lappend (llist_of tr) ltr)"
lemmas llvalidFromS_selectDelay = disjI1
lemmas llvalidFromS_selectlvalidFromS = disjI2[OF disjI1]
lemmas llvalidFromS_selectLNil = disjI2[OF disjI2[OF disjI1]]
lemmas llvalidFromS_selectSingl = disjI2[OF disjI2[OF disjI2[OF disjI1]]]
lemmas llvalidFromS_selectlappend = disjI2[OF disjI2[OF disjI2[OF disjI2]]]
lemma llvalidFromS_imp_lvalidFromS:
assumes "llvalidFromS n s ltr"
shows "lvalidFromS s ltr"
proof-
have 0: "∃n. llvalidFromS n s ltr" using assms by auto
show ?thesis apply(rule lvalidFromS'_imp_lvalidFromS)
using 0 proof(coinduct rule: lvalidFromS'.coinduct)
case (lvalidFromS' s tr1)
then obtain n where 0: "llvalidFromS n s tr1" by auto
then show ?case proof(induct n rule: less_induct)
case (less n)
hence 0: "llvalidFromS n s tr1" by simp
then show ?case proof cases
case (Delay n')
show ?thesis using less(1)[OF `n' < n` `llvalidFromS n' s tr1`] .
next
case lvalidFromS
thus ?thesis by auto
next
case LNil
then show ?thesis by auto
next
case Singl
then show ?thesis by auto
next
case (lappend tr s'' n' ltr)
then show ?thesis by auto
qed
qed
qed
qed
coinductive lllvalidFromS :: "turn ⇒ enat ⇒ enat ⇒ 'state ⇒ 'state llist ⇒ bool" where
DelayLR: "lllvalidFromS L wL' wR' s ltr ⟹ lllvalidFromS R wL wR s ltr"
|
DelayL: "wL' < wL ⟹ lllvalidFromS L wL' wR' s ltr ⟹ lllvalidFromS L wL wR s ltr"
|
DelayR: "wR' < wR ⟹ lllvalidFromS R wL' wR' s ltr ⟹ lllvalidFromS R wL wR s ltr"
|
LNil: "lllvalidFromS trn wL wR s [[]]"
|
Singl: "lllvalidFromS trn wL wR s [[s]]"
|
lappend: "validFromS s tr ⟹ tr ≠ [] ⟹ validTrans (last tr, s'') ⟹
lllvalidFromS trn' wL' wR' s'' ltr ⟹
lllvalidFromS trn wL wR s (lappend (llist_of tr) ltr)"
lemmas lllvalidFromS_selectDelayLR = disjI1
lemmas lllvalidFromS_selectDelayL = disjI2[OF disjI1]
lemmas lllvalidFromS_selectDelayR = disjI2[OF disjI2[OF disjI1]]
lemmas lllvalidFromS_selectLNil = disjI2[OF disjI2[OF disjI2[OF disjI1]]]
lemmas lllvalidFromS_selectSingl = disjI2[OF disjI2[OF disjI2[OF disjI2[OF disjI1]]]]
lemmas lllvalidFromS_selectlappend = disjI2[OF disjI2[OF disjI2[OF disjI2[OF disjI2]]]]
lemma lllvalidFromS_imp_lvalidFromS:
assumes "lllvalidFromS trn wL wR s ltr"
shows "lvalidFromS s ltr"
proof-
have 0: "∃trn wL wR . lllvalidFromS trn wL wR s ltr" using assms by auto
show ?thesis apply(rule lvalidFromS'_imp_lvalidFromS)
using 0 proof(coinduct rule: lvalidFromS'.coinduct)
case (lvalidFromS' s tr1)
then obtain trn wL wR where 0: "lllvalidFromS trn wL wR s tr1" by auto
then show ?case proof(induct "(trn,wL,wR)" arbitrary: trn wL wR rule: wf_induct_rule[OF "wf_TWW"])
case (1 trn wL wR)
hence 0: "lllvalidFromS trn wL wR s tr1" by simp
then show ?case proof cases
case (DelayLR wL' wR')
show ?thesis apply(rule 1(1)[OF _ `lllvalidFromS L wL' wR' s tr1`])
using DelayLR unfolding TWW_def less_turn_def by auto
next
case (DelayL wL' wR')
show ?thesis apply(rule 1(1)[OF _ `lllvalidFromS L wL' wR' s tr1`])
using DelayL unfolding TWW_def less_turn_def by auto
next
case (DelayR wR' wL')
show ?thesis apply(rule 1(1)[OF _ `lllvalidFromS R wL' wR' s tr1`])
using DelayR unfolding TWW_def less_turn_def by auto
next
case LNil
then show ?thesis by auto
next
case Singl
then show ?thesis by auto
next
case (lappend tr s'' trn' wL' wR' ltr)
then show ?thesis by blast
qed
qed
qed
qed
definition lfromS :: "'a llist ⇒ ('a × 'a) llist" where
"lfromS sl ≡ if sl = [[]] then [[]] else lzip (lbutlast sl) (ltl sl)"
lemma lfromS_LNil[simp]: "lfromS [[]] = [[]]"
unfolding lfromS_def by auto
lemma lfromS_singl[simp]: "lfromS [[s]] = [[]]"
unfolding lfromS_def by auto
lemma lfromS_eq_LNil[simp]: "lfromS sl = [[]] ⟷ lfinite sl ∧ length (list_of sl) ≤ Suc 0"
unfolding lfromS_def apply(cases sl)
subgoal by auto
subgoal by simp (metis add_is_0 add_is_1 lbutlast_Cons le_0_eq le_Suc_eq
length_0_conv lfinite.simps list.size(4) list_of_LCons list_of_LNil
lstrict_prefix_code(1) lstrict_prefix_code(2) lzip_eq_LNil_conv n_not_Suc_n) .
lemma llength_lfromS_notLNil[simp]:
"sl ≠ [[]] ⟹ lfinite sl ⟹ llength (lfromS sl) = llength sl - 1"
unfolding lfromS_def
by simp (metis One_nat_def epred_conv_minus epred_enat epred_llength length_list_of min.idem)
lemma llength_lfromS_not_lfinite[simp]:
"¬ lfinite sl ⟹ llength (lfromS sl) = ∞"
unfolding lfromS_def by (auto simp: not_lfinite_llength)
lemma llength_lfromS_less1: "llength (lfromS sl) = llength sl - 1"
by (metis idiff_0 idiff_infinity lfromS_LNil llength_LNil llength_eq_infty_conv_lfinite
llength_lfromS_notLNil llength_lfromS_not_lfinite)
lemma lfinite_lvalidFromS_validFromS: "lfinite tr ⟹ lvalidFromS s tr ⟷ validFromS s (list_of tr)"
apply(induct arbitrary: s rule: lfinite.induct)
subgoal by simp
subgoal by simp (metis lvalidFromS_Cons_iff hd_list_of lfinite_LNil list_of_LNil llist_of_list_of
validFromS_Cons_iff) .
lemma lvalidFromS_llist_of_validFromS: "lvalidFromS s (llist_of tr) ⟷ validFromS s tr"
by (simp add: lfinite_lvalidFromS_validFromS)
lemma validS_append:
assumes tr1: "validS tr1" and tr12: "validTrans (last tr1, hd tr2)"
and tr2: "validS tr2"
shows "validS (append tr1 tr2)"
apply(cases "tr1 = [] ∨ tr2 = []")
subgoal using assms by auto
subgoal
using assms unfolding validS_def nth_append apply safe
subgoal for i apply(cases "i < length tr1 - Suc 0")
subgoal by auto
subgoal apply(cases "i = length tr1 - Suc 0")
subgoal by auto (metis One_nat_def hd_conv_nth last_conv_nth)
subgoal apply(subgoal_tac "i - length tr1 < length tr2 - Suc 0")
subgoal by auto (metis Suc_diff_le linorder_not_less)
subgoal by auto . . . . .
lemma lvalidS_lappend:
assumes tr1: "lvalidS tr1" and tr12: "validTrans (llast tr1, lhd tr2)"
and tr2: "lvalidS tr2"
shows "lvalidS (lappend tr1 tr2)"
unfolding lvalidS_def proof safe
fix i assume i: "enat i < llength (lappend tr1 tr2) - 1"
show "validTrans (lnth (lappend tr1 tr2) i, lnth (lappend tr1 tr2) (Suc i))"
proof(cases "Suc i < llength tr1")
case True
hence l: "lnth (lappend tr1 tr2) i = lnth tr1 i"
and l': "lnth (lappend tr1 tr2) (Suc i) = lnth tr1 (Suc i)"
using lnth_lappend1 by (metis Suc_ile_eq order_less_le)+
show ?thesis unfolding l l' using tr1 True unfolding lvalidS_def
by (metis Suc_ile_eq diff_Suc_1 enat_llength_ldropn llength_ldropn one_enat_def)
next
case False note s = False
show ?thesis proof(cases "i < llength tr1")
case True
have si: "Suc i = llength tr1" using s True
by (simp add: Suc_ile_eq order_less_le)
hence l: "lnth (lappend tr1 tr2) i = llast tr1"
and l': "lnth (lappend tr1 tr2) (Suc i) = lhd tr2"
apply (metis True eSuc_enat llast_conv_lnth lnth_lappend1)
by (metis diff_Suc_1 diff_self_eq_0 i idiff_enat_enat lappend_lnull2 lhd_conv_lnth
linorder_neq_iff lnth_lappend one_enat_def si the_enat.simps)
show ?thesis using tr12 unfolding l l' .
next
case False
then obtain n1 where n1: "llength tr1 = enat n1"
by fastforce
hence l: "lnth (lappend tr1 tr2) i = lnth tr2 (i - n1)"
and l': "lnth (lappend tr1 tr2) (Suc i) = lnth tr2 (Suc (i - n1))"
apply (metis False lnth_lappend the_enat.simps)
by (metis False Suc_diff_le enat_ord_simps(2) linorder_le_less_linear lnth_lappend n1 s the_enat.simps)
have nn1: "i - n1 < llength tr2 - 1" using i n1
apply(cases "llength tr2", auto simp: algebra_simps)
by (metis False add_diff_cancel_right' diff_commute diff_diff_left enat_ord_simps(2) idiff_enat_enat
linordered_semidom_class.add_diff_inverse one_enat_def zero_less_diff)
show ?thesis using tr2 nn1 unfolding l l' unfolding lvalidS_def by auto
qed
qed
qed
lemma validS_append1:
assumes "validS (append tr1 tr2)" "tr1 ≠ []"
shows "validS tr1"
using assms apply(induct tr1, auto)
by (metis Simple_Transition_System.validFromS_Cons_iff append_Cons neq_Nil_conv validFromS_def)
lemma lvalidS_lappend1:
assumes "lvalidS (lappend tr1 tr2)"
shows "lvalidS tr1"
using assms unfolding lvalidS_def apply clarify subgoal for i apply simp
apply(erule allE[of _ i])
apply(subst (asm) lnth_lappend1)
subgoal by (metis co.enat.exhaust dual_order.strict_trans1 eSuc_minus_1 enat_le_plus_same(1) idiff_0 plus_1_eSuc(2))
subgoal apply(subst (asm) lnth_lappend1)
subgoal by (metis ‹enat i < llength tr1 - 1 ⟹ enat i < llength tr1› eSuc_enat eSuc_minus_1 ileI1 order_less_le)
subgoal by (meson dual_order.strict_trans1 enat_le_plus_same(1) enat_minus_mono1) . . .
lemma validS_append2:
assumes "validS (append tr1 tr2)" "tr2 ≠ []"
shows "validS tr2"
using assms apply(induct tr1, auto)
by (metis validFromS_def validS_Nil validFromS_Cons_iff)
lemma lvalidS_lappend2:
assumes "lfinite tr1" "lvalidS (lappend tr1 tr2)"
shows "lvalidS tr2"
using assms unfolding lvalidS_def apply clarify subgoal for i apply simp
apply(cases "llength tr1")
subgoal for n1
apply(erule allE[of _ "n1+i"])
apply(subst (asm) lnth_lappend2[of _ n1])
subgoal by simp
subgoal by simp
subgoal apply(subst (asm) lnth_lappend2[of _ n1])
subgoal by simp
subgoal by simp
subgoal by simp (metis add_diff_assoc_enat enat_less_enat_plusI2 ldropn_eq_LNil
llength_LNil llength_ldropn nle_le not_less_zero one_enat_def) . .
subgoal using llength_eq_infty_conv_lfinite by blast . .
lemma validS_validTrans:
assumes tr1: "tr1 ≠ []" and tr2: "tr2 ≠ []" and v: "validS (append tr1 tr2)"
shows "validTrans (last tr1, hd tr2)"
using tr1 tr2 v[unfolded validS_def, rule_format, of "length tr1 - Suc 0"]
unfolding nth_append hd_conv_nth[OF tr2] last_conv_nth[OF tr1]
by simp (metis Suc_pred add_gr_0 add_less_cancel_left length_greater_0_conv less_add_same_cancel1 plus_1_eq_Suc)
lemma lvalidS_validTrans:
assumes "tr1 ≠ [[]]" "tr2 ≠ [[]]" "lfinite tr1" "lvalidS (lappend tr1 tr2)"
shows "validTrans (llast tr1, lhd tr2)"
apply(cases "llength tr1")
subgoal for n1
using assms unfolding lvalidS_def apply(elim allE[of _ "n1-1"])
apply(subst (asm) lnth_lappend1)
subgoal
by simp (metis diff_less llength_eq_0 lnull_def not_gr_zero zero_enat_def zero_less_Suc)
subgoal apply(subst (asm) lnth_lappend2[of _ n1])
subgoal by simp
subgoal by simp
subgoal by simp (metis One_nat_def Suc_ile_eq Suc_pred add_diff_assoc_enat
cancel_comm_monoid_add_class.diff_cancel eSuc_enat enat_le_plus_same(1)
enat_ord_simps(2) i0_less lhd_conv_lnth llast_conv_lnth llength_eq_0 lnull_def one_enat_def zero_enat_def) . .
subgoal using assms(3) llength_eq_infty_conv_lfinite by blast .
lemma validS_reach:
assumes "istate (hd tr)" "validS tr"
shows "reach (last tr)"
by (metis (no_types, lifting) Istate fromS_eq_Nil hd_Nil_eq_last
hd_conv_nth assms last_conv_nth length_fromS_less1 linorder_not_less list.size(3)
nat_neq_iff toS_fromS_nonSingl toS_last toS_nth_0 valid_fromS valid_reach_src_tgt)
lemma validFromS_reach:
assumes "istate s" "validFromS s tr" "tr ≠ []"
shows "reach (last tr)"
using assms unfolding validFromS_def using validS_reach by blast
lemma reach_validFromS_reach:
assumes "reach s" "validFromS s tr" "tr ≠ []"
shows "reach (last tr)"
by (metis (no_types, lifting) Simple_Transition_System.validFromS_reach
Transition_System.reach_init_valid assms valid_reach_src_tgt)
lemma lvalidFromS_reach:
assumes i: "istate s" and l: "lvalidFromS s tr" and s': "s' ∈ lset tr"
shows "reach s'"
proof-
obtain tr1 tr2 where tr1: "lfinite tr1" "llast tr1 = s'" "tr1 ≠ [[]]" "tr = lappend tr1 tr2"
using s'
by (metis LNil_eq_lappend_iff lappend_snocL1_conv_LCons2 lfinite_LConsI lfinite_lappend
llast_lappend_LCons llast_singleton llist.distinct(1) split_llist_first)
hence "lvalidFromS s tr1"
by (metis LNil_eq_lappend_iff l lhd_lappend lnull_def lvalidFromS_def lvalidS_lappend1)
hence "validFromS s (list_of tr1) ∧ last (list_of tr1) = s'" using tr1
by (metis lfinite_lvalidFromS_validFromS llast_llist_of llist_of_list_of)
thus ?thesis
by (metis i llist_of.simps(1) llist_of_list_of tr1(1) tr1(3) validFromS_reach)
qed
lemma validFromS_append:
"tr1 ≠ [] ⟹ tr1' ≠ [] ⟹ validFromS s1 tr1 ⟹ validFromS (lastt s1 tr1) tr1' ⟹
validFromS s1 (butlast tr1 @ tr1')"
apply(cases "butlast tr1 = []")
subgoal apply simp by(cases tr1, auto split: if_splits simp: lastt_def)
subgoal unfolding validFromS_def apply(rule disjI2)
apply(rule conjI)
subgoal by (metis append_butlast_last_id hd_append2)
subgoal by (metis validS_append append_butlast_last_id lastt_def list.sel(1) list.simps(3) validS_append1 validS_validTrans)
. .
lemma lprefix_lvalidS: "lvalidS tr ⟹ lprefix tr' tr ⟹ lvalidS tr'"
by (metis lvalidS_lappend1 lprefix_conv_lappend)
lemma lprefix_lvalidFromS: "lvalidFromS s tr ⟹ lprefix tr' tr ⟹ lvalidFromS s tr'"
by (metis lvalidFromS_def lhd_LCons llist.distinct(1) lprefix.cases lprefix_lvalidS)
lemma lprefix_lvalidFrom_validFrom: "lvalidFromS s tr ⟹ lprefix (llist_of tr') tr ⟹ validFromS s tr'"
using lprefix_lvalidFromS lvalidFromS_llist_of_validFromS by blast
lemma lsublist_lvalidS: "lvalidS tr ⟹ lsublist tr' tr ⟹ lvalidS tr'"
by (metis lvalidS_lappend1 lvalidS_lappend2 lsublist_def)
lemma lsublist_lvalidromS: "lvalidFromS s tr ⟹ lsublist tr' tr ⟹ tr' ≠ LNil ⟹ lvalidFromS (lhd tr') tr'"
using lsublist_lvalidS lvalidFromS_def by auto
lemma lvalidS_LCons_iff:
"lvalidS (s $ tr) = (validTrans (s,lhd tr) ∧ lvalidS tr ∨ tr = [[]])"
using lvalidFromS_Cons_iff lvalidFromS_def by auto
lemma lvalidS_lappend_finite:
"tr ≠ [] ⟹ tr1 ≠ [[]] ⟹
lvalidS (lappend (llist_of tr) tr1) = (validS tr ∧ lvalidS tr1 ∧ validTrans (last tr,lhd tr1))"
apply (induct tr)
apply blast
by simp (metis Simple_Transition_System.validFromS_def lappend_eq_LNil_iff lhd_lappend lhd_llist_of list.simps(3) lnull_llist_of lvalidS_LCons_iff validFromS_Cons_iff)
lemma lvalidS_llist_of[simp]: "lvalidS (llist_of tr) ⟷ validS tr"
by (metis lvalidFromS_def lvalidFromS_llist_of_validFromS
lvalidS_LNil Simple_Transition_System.validFromS_def Simple_Transition_System.validS_Nil)
lemma lvalidFromS_lappend_finite:
"lvalidFromS s (lappend (llist_of tr) tr1) ⟷
validFromS s tr ∧
(tr1 = [[]] ∨
lvalidFromS (lhd tr1) tr1 ∧
(tr = [] ∧ s = lhd tr1 ∨ (tr ≠ [] ∧ validTrans (last tr, lhd tr1))))"
apply(cases "tr ≠ [] ∧ tr1 ≠ [[]]")
subgoal unfolding validFromS_def lvalidFromS_def lastt_def
by (auto simp: lvalidS_lappend_finite lappend_eq_LNil_iff)
subgoal
by (metis lappend_LNil2 lappend_code(1) llist_of.simps(1)
lvalidFromS_def lvalidFromS_llist_of_validFromS) .
lemma lvalidFromS_lappend_finite':
"tr1 ≠ [[]] ⟹
lvalidFromS s (lappend (llist_of tr) tr1) ⟷
validFromS s tr ∧
lvalidFromS (lhd tr1) tr1 ∧
(tr = [] ∧ s = lhd tr1 ∨
tr ≠ [] ∧ validTrans (last tr, lhd tr1))"
unfolding lvalidFromS_lappend_finite by auto
lemma lvalidFromS_lappend_LCons:
"lvalidFromS s (lappend (llist_of tr) (s' $ tr1)) ⟷
validFromS s tr ∧
lvalidFromS s' ((s' $ tr1)) ∧
(tr = [] ∧ s = s' ∨
tr ≠ [] ∧ validTrans (last tr, s'))"
apply(subst lvalidFromS_lappend_finite') by auto
end
subsection ‹Completed finite and possibly infinite traces in simple transition systems ›
context System_Mod
begin
definition completedFrom :: "'state ⇒ 'state list ⇒ bool" where
"completedFrom s sl ≡ (sl = [] ∧ final s) ∨ (sl ≠ [] ∧ final (last sl))"
lemma completed_Nil[simp,intro]: "completedFrom s [] ⟷ final s"
unfolding completedFrom_def by auto
lemma completed_Cons[simp]: "completedFrom s' (s # sl) ⟷ (sl = [] ∧ final s) ∨ (sl ≠ [] ∧ completedFrom s sl)"
unfolding completedFrom_def by auto
definition lcompletedFrom :: "'state ⇒ 'state llist ⇒ bool" where
"lcompletedFrom s sl ≡
lfinite sl ⟶
(sl ≠ [[]] ∧ final (last (list_of sl)))"
lemma lcompletedFrom_LCons[simp]: "lcompletedFrom s' (s $ sl) ⟷
(lfinite sl ⟶ (sl = [[]] ∧ final s) ∨ (sl ≠ [[]] ∧ lcompletedFrom s sl))"
unfolding lcompletedFrom_def using llist_of_list_of by auto fastforce+
lemma lvalid_lappend_finite:
"tr ≠ [] ⟹ tr1 ≠ [[]] ⟹
lvalid (lappend (llist_of tr) tr1) = (valid tr ∧ lvalid tr1 ∧ snd (last tr) = fst (lhd tr1))"
apply (induct tr) by (auto simp add: lvalid_LCons_iff lappend_eq_LNil_iff)
lemma lcompletedFrom_singl: "llength tr = enat (Suc 0) ⟹
lvalidFromS s tr ⟹
lcompletedFrom s tr ⟷ tr = [[s]] ∧ final s"
apply(cases tr)
subgoal by (simp add: enat_0_iff(1))
subgoal for s' tr' unfolding lcompletedFrom_def
by simp (metis lvalidFromS_Cons_iff One_nat_def eSuc_inject
lfinite_LNil list_of_LNil llength_eq_0 lnull_def one_eSuc one_enat_def) .
end
end