header {* Semantics *} theory Semantics imports Sequence Intensional begin text {* This theory provides a shallow embedding of the TLA* semantics. *} section "Types of Formulas" types ('a,'b) formfun = "'a seq \ 'b" 'a formula = "('a,bool) formfun" ('a,'b) stfun = "'a \ 'b" 'a stpred = "('a,bool) stfun" instance "*" :: (type,type) world .. instance "*" :: (world,world) world .. instance "fun" :: (type,world) world .. instance "fun" :: (type,type) world .. instance "fun" :: (world,world) world .. text {* Pair and function are instantiated to be of type class world. This allows use of the lifted intensional logic for formulas, and standard logical connectives can therefore be used. *} section "Semantics of TLA*" text {* The semantics of TLA* is defined *} constdefs always :: "'a formula \ 'a formula" "always F \ \ s. \ n. (s |\<^sub>s n) \ F" nexts :: "('a,'b) formfun \ ('a,'b) formfun" "nexts F \ \ s. (tail s) \ F" before :: "('a,'b) stfun \ ('a,'b) formfun" "before f \ \ s. (first s) \ f" after :: "('a,'b) stfun \ ('a,'b) formfun" "after f \ nexts (before f)" unch :: "('a,'b) stfun \ 'a formula" "unch v \ \ s. s \ (after v) = (before v)" action :: "'a formula \ ('a,'b) stfun \ 'a formula" "action P v \ \ s. \ i. ((s |\<^sub>s i) \ P) \ ((s |\<^sub>s i) \ unch v)" subsection "Concrete Syntax" text{* This is the concrete syntax for the (abstract) operator above *} syntax "_always" :: "lift \ lift" ("([]_)" [40] 90) "_nexts" :: "lift \ lift" ("(Next _)" [40] 90) "_action" :: "[lift,lift] \ lift" ("([][_]'_(_))" [20,1000] 90) "_before" :: "lift \ lift" ("($_)" [100] 99) "_after" :: "lift \ lift" ("(_$)" [100] 99) "_prime" :: "lift \ lift" ("(_`)" [100] 99) "_unch" :: "lift \ lift" ("(Unchanged _)" [100] 99) "TEMP" :: "lift \ 'b" ("(TEMP _)") translations "_always" \ "always" "_nexts" \ "nexts" "_action" \ "action" "_before" \ "before" "_after" \ "after" "_prime" \ "after" "_unch" \ "unch" "TEMP F" \ "(F:: (nat \ _) \ _)" syntax (xsymbols) "_always" :: "lift \ lift" ("(\_)" [40] 90) "_nexts" :: "lift \ lift" ("(\_)" [40] 90) "_action" :: "[lift,lift] \ lift" ("(\[_]'_(_))" [20,1000] 90) section "Abbreviations" text {* Some normal temporal abbreviations are given, with their concrete syntax. *} constdefs actrans :: "'a formula \ ('a,'b) stfun \ 'a formula" "actrans P v \ TEMP(P \ unch v)" eventually :: "'a formula \ 'a formula" "eventually F \ LIFT(\\\F)" angle_action :: "'a formula \ ('a,'b) stfun \ 'a formula" "angle_action P v \ LIFT(\\[\P]_v)" angle_actrans :: "'a formula \ ('a,'b) stfun \ 'a formula" "angle_actrans P v \ TEMP(\ actrans LIFT(\P) v)" leadsto :: "'a formula \ 'a formula \ 'a formula" "leadsto P Q \ LIFT \(P \ eventually Q)" subsection "Concrete Syntax" syntax "_actrans" :: "[lift,lift] \ lift" ("([_]'_(_))" [20] 90) "_eventually" :: "lift \ lift" ("(<>_)" [40] 90) "_angle_action" :: "[lift,lift] \ lift" ("(<><_>'_(_))" [20,1000] 90) "_angle_actrans" :: "[lift,lift] \ lift" ("(<_>'_(_))" [20,1000] 90) "_leadsto" :: "[lift,lift] \ lift" ("(_ ~> _)" [40,40] 90) translations "_actrans" \ "actrans" "_eventually" \ "eventually" "_angle_action" \ "angle_action" "_angle_actrans" \ "angle_actrans" "_leadsto" \ "leadsto" syntax (xsymbols) "_eventually" :: "lift \ lift" ("(\_)" [40] 90) "_angle_action" :: "[lift,lift] \ lift" ("(\\_\'_(_))" [20,1000] 90) "_angle_actrans" :: "[lift,lift] \ lift" ("(\_\'_(_))" [20,1000] 90) "_leadsto" :: "[lift,lift] \ lift" ("(_ \ _)" [40,40] 90) section "Properties of Operators" text {* The following two lemmas shows that these operators has the obvious semantics. *} lemma eventually_defs: "(w \ \ F) = (\ n. (w |\<^sub>s n) \ F)" proof assume a1: "(w \ \ F)" hence "w \ \\\F" by (unfold eventually_def) hence "\(w \ \\F)" by auto hence "\(\ n. (w |\<^sub>s n) \ \F)" by (auto simp add: always_def) hence "\(\ n. \((w |\<^sub>s n) \ F))" by auto thus "(\ n. (w |\<^sub>s n) \ F)" by auto next assume a1: "(\ n. (w |\<^sub>s n) \ F)" show "w \ \ F" by (simp add: eventually_def always_def) qed lemma angle_action_defs: "(w \ \\P\_v) = (\ i. ((w |\<^sub>s i) \ P) \ ((w |\<^sub>s i) \ v$ \ $v))" proof assume "w \ \\P\_v" hence "w \ \\[\P]_v" by (unfold angle_action_def) hence "\(w \ \[\P]_v)" by auto hence "\(\ i. ((w |\<^sub>s i) \ \P) \ ((w |\<^sub>s i) \ Unchanged v))" by (unfold action_def) hence "\ i. \(((w |\<^sub>s i) \ \P) \ ((w |\<^sub>s i) \ Unchanged v))" by auto thus "\ i. ((w |\<^sub>s i) \ P) \ ((w |\<^sub>s i) \ v$ \ $v)" by (auto simp add: unch_def) next assume a1: "\ i. ((w |\<^sub>s i) \ P) \ ((w |\<^sub>s i) \ v$ \ $v)" thus "w \ \\P\_v" by (simp add: angle_action_def action_def unch_def) qed lemma unch_defs: "(w \ Unchanged v) = (((second w) \ v) = ((first w) \ v))" by (auto simp add: unch_def before_def nexts_def after_def tail_def suffix_def first_def second_def) section "Invariance Under Stuttering" text {* This section formalises stuttering invariance for the defined operators. *} constdefs stutinv :: "('a,'b) formfun \ bool" "stutinv F \ \ \ \. \ \ \ \ (\ \ F) = (\ \ F)" nstutinv :: "('a,'b) formfun \ bool" "nstutinv P \ \ \ \. (first \ = first \) \ (tail \) \ (tail \) \ (\ \ P) = (\ \ P)" syntax "_stutinv" :: "lift \ bool" ("(STUTINV _)" [40] 40) "_nstutinv" :: "lift \ bool" ("(NSTUTINV _)" [40] 40) translations "_stutinv" \ "stutinv" "_nstutinv" \ "nstutinv" text {* Predicate @{term "stutinv F"} formalises stuttering invariance for formula @{term F}. That is if two sequences are similar @{term "s \ t"} (equal up to stuttering) then the validity of @{term F} under both @{term s} and @{term t} are equivalent. Predicate @{term "nstutinv P"} should be read as \emph{nearly stuttering invariant} -- and is required for some stuttering invariance proofs. *} lemma stutinv_strictly_stronger: assumes h: "STUTINV F" shows "NSTUTINV F" proof (unfold nstutinv_def,(rule allI)+,intro impI,elim conjE) fix s t :: "nat \ 'a" assume a1: "first s = first t" and a2: "(tail s) \ (tail t)" from h have "\ \ \. \ \ \ \ (\ \ F) = (\ \ F)" by (simp add: stutinv_def) hence g1: "s \ t \ (s \ F) = (t \ F)" by blast have "s \ t" proof - have tg1: "(first s) ## (tail s) = s" by (rule seq_app_first_tail) have tg2: "(first t) ## (tail t) = t" by (rule seq_app_first_tail) with tg2 a1 have tg2': "(first s) ## (tail t) = t" by simp from a2 have "(first s) ## (tail s) \ (first s) ## (tail t)" by (rule app_seqsimilar) with tg1 tg2' show ?thesis by auto qed with g1 show "(s \ F) = (t \ F)" by auto qed subsection "Properties of @{term stutinv}" text {* This section proof stuttering invariance, preservation of stuttering invariance and introduction of stuttering invariance for different formulas. First, state predicates are stuttering invariant. *} theorem stut_before: "STUTINV $F" proof (unfold stutinv_def,(rule allI)+,rule impI) fix s t :: "'a seq" assume a1: "s \ t" hence "(first s) = (first t)" by (rule sim_first) thus "(s \ $F) = (t \ $F)" by (auto simp add: before_def) qed text{* Invariants preserves stuttering invariance. *} theorem stut_always: assumes H:"stutinv F" shows "STUTINV \F" proof (unfold stutinv_def,(rule allI)+,rule impI) fix s t from H have h':"\ \ \. \ \ \ \ (\ \ F) = (\ \ F)" by (unfold stutinv_def) hence a1: "s \ t \ (s \ F) = (t \ F)" by simp assume a2: "s \ t" with a1 have a1': "(s \ F) = (t \ F)" by auto show "(s \ (\ F)) = (t \ (\ F))" proof assume a1: "t \ (\ F)" show "s \ (\ F)" proof (unfold always_def,rule allI) fix n from a2 have "\ n. \ m. ((s |\<^sub>s n) \ (t |\<^sub>s m)) \ (((s |\<^sub>s Suc n) \ (t |\<^sub>s Suc m)) \ ((s |\<^sub>s Suc n) \ (t |\<^sub>s m)))" by (rule sim_step) hence "\ m. ((s |\<^sub>s n) \ (t |\<^sub>s m)) \ (((s |\<^sub>s Suc n) \ (t |\<^sub>s Suc m)) \ ((s |\<^sub>s Suc n) \ (t |\<^sub>s m)))" .. then obtain m where "((s |\<^sub>s n) \ (t |\<^sub>s m)) \ (((s |\<^sub>s Suc n) \ (t |\<^sub>s Suc m)) \ ((s |\<^sub>s Suc n) \ (t |\<^sub>s m)))" .. hence "(s |\<^sub>s n \ t |\<^sub>s m)" by auto with h' have g1: "(s |\<^sub>s n \ F) = (t |\<^sub>s m \ F)" by auto from a1 have "\n. (t |\<^sub>s n) \ F" by (auto simp add: always_def) hence "(t |\<^sub>s m) \ F" .. with g1 show "(s |\<^sub>s n) \ F" by auto qed next assume a1: "s \ (\ F)" show "t \ (\ F)" proof (unfold always_def,rule allI) fix n from a2 have "\ n. \ m. ((t |\<^sub>s n) \ (s |\<^sub>s m)) \ (((t |\<^sub>s Suc n) \ (s |\<^sub>s Suc m)) \ ((t |\<^sub>s Suc n) \ (s |\<^sub>s m)))" by (rule sim_step[OF seqsim_sym]) hence "\ m. ((t |\<^sub>s n) \ (s |\<^sub>s m)) \ (((t |\<^sub>s Suc n) \ (s |\<^sub>s Suc m)) \ ((t |\<^sub>s Suc n) \ (s |\<^sub>s m)))" .. then obtain m where "((t |\<^sub>s n) \ (s |\<^sub>s m)) \ (((t |\<^sub>s Suc n) \ (s |\<^sub>s Suc m)) \ ((t |\<^sub>s Suc n) \ (s |\<^sub>s m)))" .. hence "(t |\<^sub>s n \ s |\<^sub>s m)" by auto with h' have g1: "(t |\<^sub>s n \ F) = (s |\<^sub>s m \ F)" by auto from a1 have "\n. (s |\<^sub>s n) \ F" by (auto simp add: always_def) hence "(s |\<^sub>s m) \ F" .. with g1 show "(t |\<^sub>s n) \ F" by auto qed qed qed text{* If we can assume that a formula @{term P} is nearly suttering invariant then wrapping it in @{text "\[-]_v"} will introduce stuttering invariance. *} theorem stut_action: assumes H: "NSTUTINV P" shows "STUTINV \[P]_v" proof (unfold stutinv_def,(rule allI)+,rule impI) fix s t from H have h':"\ \ \. (first \ = first \) \ (tail \) \ (tail \) \ (\ \ P) = (\ \ P)" by (simp add: nstutinv_def) hence a1:"(first s = first t) \ (tail s) \ (tail t) \ (s \ P) = (t \ P)" by simp assume a2: "s \ t" hence a2': "t \ s" by (rule seqsim_sym) show "(s \ \[P]_v) = (t \ \[P]_v)" proof assume a1: "t \ \[P]_v" show "s \ \[P]_v" proof (unfold action_def,rule allI) fix n from a2 have "\ n. \ m. ((s |\<^sub>s n) \ (t |\<^sub>s m)) \ (((s |\<^sub>s Suc n) \ (t |\<^sub>s Suc m)) \ ((s |\<^sub>s Suc n) \ (t |\<^sub>s m)))" by (rule sim_step) hence "\ m. ((s |\<^sub>s n) \ (t |\<^sub>s m)) \ (((s |\<^sub>s Suc n) \ (t |\<^sub>s Suc m)) \ ((s |\<^sub>s Suc n) \ (t |\<^sub>s m)))" .. then obtain m where a2': "((s |\<^sub>s n) \ (t |\<^sub>s m)) \ (((s |\<^sub>s Suc n) \ (t |\<^sub>s Suc m)) \ ((s |\<^sub>s Suc n) \ (t |\<^sub>s m)))" .. from a2' have g1: "(s |\<^sub>s n \ t |\<^sub>s m)" by auto hence "first (s |\<^sub>s n) = first (t |\<^sub>s m) " by (simp add: sim_first) hence g1': "s n = t m" by (simp add: suffix_def first_def) hence g1'': "first (s |\<^sub>s n) = first (t |\<^sub>s m)" by (simp add: suffix_first) from a2' have g2: "(s |\<^sub>s (Suc n) \ t |\<^sub>s (Suc m)) \ (s |\<^sub>s (Suc n) \ t |\<^sub>s m)" by auto hence "(first (s |\<^sub>s (Suc n)) = first (t |\<^sub>s (Suc m))) \ (first (s |\<^sub>s (Suc n)) = first (t |\<^sub>s m))" by (auto simp add: sim_first) hence g2':"(s (Suc n) = t (Suc m)) \ (s (Suc n) = t m)" by (simp add: suffix_def first_def) thm action_def from a1 have "\i. ((t |\<^sub>s i) \ P) \ ((t |\<^sub>s i) \ (Unchanged v))" by (simp add: action_def) hence a1': "((t |\<^sub>s m) \ P) \ ((t |\<^sub>s m) \ (Unchanged v))" .. thus "((s |\<^sub>s n) \ P) \ ((s |\<^sub>s n) \ (Unchanged v))" proof assume a3: "(t |\<^sub>s m) \ Unchanged v" hence a3': "((second (t |\<^sub>s m)) \ v) = ((first (t |\<^sub>s m)) \ v)" by (simp add: unch_defs) from g2' show ?thesis proof assume a4: "s (Suc n) = t (Suc m)" show ?thesis proof (rule disjI2) from a4 have G2: "second (s |\<^sub>s n) = second (t |\<^sub>s m)" by (simp add: suffix_second) from g1'' G2 a3' have "((second (s |\<^sub>s n)) \ v) = ((first (s |\<^sub>s n)) \ v)" by auto thus "(s |\<^sub>s n) \ (Unchanged v)" by (simp add: unch_defs) qed next assume a4: "s (Suc n) = t m" hence a4': "second (s |\<^sub>s n) = first (t |\<^sub>s m)" by (simp add: suffix_first suffix_second) show ?thesis proof (rule disjI2) from a3' g1'' a4' have "((second (s |\<^sub>s n)) \ v) = ((first (s |\<^sub>s n)) \ v)" by auto thus "(s |\<^sub>s n) \ (Unchanged v)" by (simp add: unch_defs) qed qed next assume a3: "((t |\<^sub>s m) \ P)" from g2 show ?thesis proof from H have h':"\ \ \. (first \ = first \) \ (tail \) \ (tail \) \ (\ \ P) = (\ \ P)" by (simp add: nstutinv_def) hence g3: "(first (s |\<^sub>s n) = first (t |\<^sub>s m)) \ (tail (s |\<^sub>s n) \ tail (t |\<^sub>s m)) \ (((s |\<^sub>s n) \ P) = ((t |\<^sub>s m) \ P))" by auto assume a4: "s |\<^sub>s Suc n \ t |\<^sub>s Suc m" hence g4: "tail (s |\<^sub>s n) \ tail (t |\<^sub>s m)" by (simp add: tail_suffix_suc) from g1 have "first (s |\<^sub>s n) = first (t |\<^sub>s m)" by (simp add: sim_first) with g3 g4 have "((s |\<^sub>s n) \ P) = ((t |\<^sub>s m) \ P)" by auto with a3 show ?thesis by auto next assume a3: "s |\<^sub>s Suc n \ t |\<^sub>s m" hence "first (s |\<^sub>s Suc n) = first (t |\<^sub>s m)" by (simp add: sim_first) hence "s (Suc n) = (t m)" by (simp add: suffix_def first_def) hence g3: "second (s |\<^sub>s n) = first (t |\<^sub>s m)" by (simp add: suffix_first suffix_second) have "((first (t |\<^sub>s m)) \ v) = ((first (t |\<^sub>s m)) \ v)" by auto with g1'' g3 have "((second (s |\<^sub>s n)) \ v) = ((first (s |\<^sub>s n)) \ v)" by auto thus ?thesis by (simp add: unch_defs) qed qed qed next assume a1: "s \ \[P]_v" show "t \ \[P]_v" proof (unfold action_def,rule allI) fix n from a2' have "\ n. \ m. ((t |\<^sub>s n) \ (s |\<^sub>s m)) \ (((t |\<^sub>s Suc n) \ (s |\<^sub>s Suc m)) \ ((t |\<^sub>s Suc n) \ (s |\<^sub>s m)))" by (rule sim_step) hence "\ m. ((t |\<^sub>s n) \ (s |\<^sub>s m)) \ (((t |\<^sub>s Suc n) \ (s |\<^sub>s Suc m)) \ ((t |\<^sub>s Suc n) \ (s |\<^sub>s m)))" .. then obtain m where a2'': "((t |\<^sub>s n) \ (s |\<^sub>s m)) \ (((t |\<^sub>s Suc n) \ (s |\<^sub>s Suc m)) \ ((t |\<^sub>s Suc n) \ (s |\<^sub>s m)))" .. from a2'' have g1: "(t |\<^sub>s n \ s |\<^sub>s m)" by auto hence "first (t |\<^sub>s n) = first (s |\<^sub>s m) " by (simp add: sim_first) hence g1': "t n = s m" by (simp add: suffix_def first_def) hence g1'': "first (t |\<^sub>s n) = first (s |\<^sub>s m)" by (simp add: suffix_first) from a2'' have g2: "(t |\<^sub>s (Suc n) \ s |\<^sub>s (Suc m)) \ (t |\<^sub>s (Suc n) \ s |\<^sub>s m)" by auto hence "(first (t |\<^sub>s (Suc n)) = first (s |\<^sub>s (Suc m))) \ (first (t |\<^sub>s (Suc n)) = first (s |\<^sub>s m))" by (auto simp add: sim_first) hence g2':"(t (Suc n) = s (Suc m)) \ (t (Suc n) = s m)" by (simp add: suffix_def first_def) from a1 have "\i. ((s |\<^sub>s i) \ P) \ ((s |\<^sub>s i) \ (Unchanged v))" by (simp add: action_def) hence a1': "((s |\<^sub>s m) \ P) \ ((s |\<^sub>s m) \ (Unchanged v))" .. thus "((t |\<^sub>s n) \ P) \ ((t |\<^sub>s n) \ (Unchanged v))" proof assume a3: "(s |\<^sub>s m) \ Unchanged v" hence a3': "((second (s |\<^sub>s m)) \ v) = ((first (s |\<^sub>s m)) \ v)" by (simp add: unch_defs) from g2' show ?thesis proof assume a4: "t (Suc n) = s (Suc m)" show ?thesis proof (rule disjI2) from a4 have G2: "second (t |\<^sub>s n) = second (s |\<^sub>s m)" by (simp add: suffix_second) from g1'' G2 a3' have "((second (t |\<^sub>s n)) \ v) = ((first (t |\<^sub>s n)) \ v)" by auto thus "(t |\<^sub>s n) \ (Unchanged v)" by (simp add: unch_defs) qed next assume a4: "t (Suc n) = s m" hence a4': "second (t |\<^sub>s n) = first (s |\<^sub>s m)" by (simp add: suffix_first suffix_second) show ?thesis proof (rule disjI2) from a3' g1'' a4' have "((second (t |\<^sub>s n)) \ v) = ((first (t |\<^sub>s n)) \ v)" by auto thus "(t |\<^sub>s n) \ (Unchanged v)" by (simp add: unch_defs) qed qed next assume a3: "((s |\<^sub>s m) \ P)" from g2 show ?thesis proof from H have h':"\ \ \. (first \ = first \) \ (tail \) \ (tail \) \ (\ \ P) = (\ \ P)" by (simp add: nstutinv_def) hence g3: "(first (t |\<^sub>s n) = first (s |\<^sub>s m)) \ (tail (t |\<^sub>s n) \ tail (s |\<^sub>s m)) \ (((t |\<^sub>s n) \ P) = ((s |\<^sub>s m) \ P))" by auto assume a4: "t |\<^sub>s Suc n \ s |\<^sub>s Suc m" hence g4: "tail (t |\<^sub>s n) \ tail (s |\<^sub>s m)" by (simp add: tail_suffix_suc) from g1 have "first (t |\<^sub>s n) = first (s |\<^sub>s m)" by (simp add: sim_first) with g3 g4 have "((t |\<^sub>s n) \ P) = ((s |\<^sub>s m) \ P)" by auto with a3 show ?thesis by auto next assume a3: "t |\<^sub>s Suc n \ s |\<^sub>s m" hence "first (t |\<^sub>s Suc n) = first (s |\<^sub>s m)" by (simp add: sim_first) hence "t (Suc n) = (s m)" by (simp add: suffix_def first_def) hence g3: "second (t |\<^sub>s n) = first (s |\<^sub>s m)" by (simp add: suffix_first suffix_second) have "((first (s |\<^sub>s m)) \ v) = ((first (s |\<^sub>s m)) \ v)" by auto with g1'' g3 have "((second (t |\<^sub>s n)) \ v) = ((first (t |\<^sub>s n)) \ v)" by auto thus ?thesis by (simp add: unch_defs) qed qed qed qed qed text{* The lemmas below shows that propositional and predicate operators preserves stuttering invariance. *} lemma stut_and: "\STUTINV F;STUTINV G\ \ STUTINV (F \ G)" by (auto simp add: stutinv_def) lemma stut_or: "\STUTINV F;STUTINV G\ \ STUTINV (F \ G)" by (auto simp add: stutinv_def) lemma stut_imp: "\STUTINV F;STUTINV G\ \ STUTINV (F \ G)" by (auto simp add: stutinv_def) lemma stut_eq: "\STUTINV F;STUTINV G\ \ STUTINV (F = G)" by (auto simp add: stutinv_def) lemma stut_noteq: "\STUTINV F;STUTINV G\ \ STUTINV (F \ G)" by (auto simp add: stutinv_def) lemma stut_not: "STUTINV F \ STUTINV (\ F)" by (auto simp add: stutinv_def) lemma stut_all: "STUTINV F \ STUTINV (\ x. F)" by (auto simp add: stutinv_def) lemma stut_ex: "STUTINV F \ STUTINV (\ x. F)" by (auto simp add: stutinv_def) lemma stut_const: "STUTINV #c" by (auto simp add: stutinv_def) lemma stut_fun1: "STUTINV X \ STUTINV (f )" by (auto simp add: stutinv_def) lemma stut_fun2: "\STUTINV X;STUTINV Y\ \ STUTINV (f )" by (auto simp add: stutinv_def) lemma stut_fun3: "\STUTINV X;STUTINV Y;STUTINV Z\ \ STUTINV (f )" by (auto simp add: stutinv_def) lemma stut_plus: "\STUTINV x;STUTINV y\ \ STUTINV (x+y)" by (auto simp add: stutinv_def) (* FIXME: add stut for all operators! *) subsection "Properties of @{term nstutinv}" text {* This section shows nearly stuttering invariance properties for some operators. Firstly, a transition is nearly stuttering invariant *} text{* If a formula @{term F} is stuttering invariant then @{text "\F"} is nearly stuttering invariant. *} lemma nstut_nexts: assumes H: "STUTINV F" shows "NSTUTINV \F" proof (unfold nstutinv_def,(rule allI)+,rule impI) fix s :: "nat \ 'a" fix t :: "nat \ 'a" from H have h':"\ \ \. \ \ \ \ (\ \ F) = (\ \ F)" by (unfold stutinv_def) hence a1: "(tail s) \ (tail t) \ ((tail s) \ F) = ((tail t) \ F)" by simp assume a2: "first s = first t \ tail s \ tail t" show "(s \ \F) = (t \ \F)" proof (unfold nexts_def) from a1 a2 show "((tail s) \ F) = ((tail t) \ F)" by auto qed qed text{* The @{text "[-]_v"} operator is not part of the semantics of TLA*, but is used in the axioms of it. However, it is alwasy wrapped inside @{text "\[-]_v"} so we only require that it preserves nearly stuttering invariance. I am not sure if it introduces stuttering invariance with the same assumption. It might be a problem that the formulas it wraps can be temporal, while @{text "[-]_v"} is not. *} text{* The lemmas below shows that propositional and predicate operators preserves nearly stuttering invariance. *} lemma nstut_and: "\NSTUTINV F;NSTUTINV G\ \ NSTUTINV (F \ G)" by (auto simp add: nstutinv_def) lemma nstut_or: "\NSTUTINV F;NSTUTINV G\ \ NSTUTINV (F \ G)" by (auto simp add: nstutinv_def) lemma nstut_imp: "\NSTUTINV F;NSTUTINV G\ \ NSTUTINV (F \ G)" by (auto simp add: nstutinv_def) lemma nstut_eq: assumes h1: "NSTUTINV F" and h2: "NSTUTINV G" shows "NSTUTINV (F = G)" proof (unfold nstutinv_def,(rule allI)+) fix s t from h1 have "\ \ \. (first \ = first \) \ (tail \) \ (tail \) \ (\ \ F) = (\ \ F)" by (unfold nstutinv_def) hence g1: "(first s = first t) \ (tail s) \ (tail t) \ (s \ F) = (t \ F)" by blast from h2 have "\ \ \. (first \ = first \) \ (tail \) \ (tail \) \ (\ \ G) = (\ \ G)" by (unfold nstutinv_def) hence g2: "(first s = first t) \ (tail s) \ (tail t) \ (s \ G) = (t \ G)" by blast with g1 show "(first s = first t) \ (tail s) \ (tail t) \ (s \ F = G) = (t \ F = G)" by auto qed lemma nstut_not: "NSTUTINV F \ NSTUTINV (\ F)" by (auto simp add: nstutinv_def) lemma nstut_noteq: assumes h1: "NSTUTINV F" and h2: "NSTUTINV G" shows "NSTUTINV (F \ G)" proof - from h1 h2 have "NSTUTINV (F=G)" by (rule nstut_eq) thus "NSTUTINV \(F=G)" by (rule nstut_not) qed lemma nstut_all: "NSTUTINV F \ NSTUTINV (\ x. F)" by (auto simp add: nstutinv_def) lemma nstut_ex: "NSTUTINV F \ NSTUTINV (\ x. F)" by (auto simp add: nstutinv_def) lemma nstut_const: "NSTUTINV #c" by (auto simp add: nstutinv_def) lemma nstut_fun1: assumes h1: "NSTUTINV X" shows "NSTUTINV (f )" proof (unfold nstutinv_def,(rule allI)+,rule impI) fix s t :: "nat \ 'a" assume a1: "first s = first t \ tail s \ tail t" from h1 have "\ s t. first s = first t \ tail s \ tail t \ (s \ X)=(t \ X)" by (unfold nstutinv_def) hence "first s = first t \ tail s \ tail t \ (s \ X)=(t \ X)" by blast with a1 have "(s \ X)=(t \ X)" by simp thus "(s \ f) = (t \ f)" by auto qed lemma nstut_fun2: assumes h1: "NSTUTINV X" and h2: "NSTUTINV Y" shows "NSTUTINV (f )" proof (unfold nstutinv_def,(rule allI)+,rule impI) fix s t :: "nat \ 'a" assume a1: "first s = first t \ tail s \ tail t" from h1 have "\ s t. first s = first t \ tail s \ tail t \ (s \ X)=(t \ X)" by (unfold nstutinv_def) hence "first s = first t \ tail s \ tail t \ (s \ X)=(t \ X)" by blast with a1 have g1: "(s \ X)=(t \ X)" by simp from h2 have "\ s t. first s = first t \ tail s \ tail t \ (s \ Y)=(t \ Y)" by (unfold nstutinv_def) hence "first s = first t \ tail s \ tail t \ (s \ Y)=(t \ Y)" by blast with a1 have "(s \ Y)=(t \ Y)" by simp with g1 show "(s \ f) = (t \ f)" by auto qed lemma nstut_fun3: assumes h1: "NSTUTINV X" and h2: "NSTUTINV Y" and h3: "NSTUTINV Z" shows "NSTUTINV (f )" proof (unfold nstutinv_def,(rule allI)+,rule impI) fix s t :: "nat \ 'a" assume a1: "first s = first t \ tail s \ tail t" from h1 have "\ s t. first s = first t \ tail s \ tail t \ (s \ X)=(t \ X)" by (unfold nstutinv_def) hence "first s = first t \ tail s \ tail t \ (s \ X)=(t \ X)" by blast with a1 have g1: "(s \ X)=(t \ X)" by simp from h2 have "\ s t. first s = first t \ tail s \ tail t \ (s \ Y)=(t \ Y)" by (unfold nstutinv_def) hence "first s = first t \ tail s \ tail t \ (s \ Y)=(t \ Y)" by blast with a1 have g2:"(s \ Y)=(t \ Y)" by simp from h3 have "\ s t. first s = first t \ tail s \ tail t \ (s \ Z)=(t \ Z)" by (unfold nstutinv_def) hence "first s = first t \ tail s \ tail t \ (s \ Z)=(t \ Z)" by blast with a1 have "(s \ Z)=(t \ Z)" by simp with g1 g2 show "(s \ f) = (t \ f)" by auto qed lemma nstut_plus: "\NSTUTINV x;NSTUTINV y\ \ NSTUTINV (x+y)" by (auto simp add: nstut_fun2) (* FIX ME: ADD for other operators: is it necessary? *) subsection "Abbreviations" text {* We show the obvious fact that the same properties holds for abbreviated operators. *} lemmas nstut_before = stut_before[THEN stutinv_strictly_stronger] lemma nstut_after: "NSTUTINV F$" proof (unfold after_def) have "STUTINV $F" by (rule stut_before) thus "NSTUTINV \$F" by (rule nstut_nexts) qed lemma nstut_unch: "NSTUTINV (Unchanged v)" proof (unfold unch_def) have g1: "NSTUTINV v$" by (rule nstut_after) have "NSTUTINV $v" by (rule stut_before[THEN stutinv_strictly_stronger]) with g1 show "NSTUTINV (v$ = $v)" by (rule nstut_eq) qed lemma nstut_actrans: assumes H: "NSTUTINV P" shows "NSTUTINV [P]_v" proof(unfold actrans_def) from H nstut_unch[of v] show "NSTUTINV (P \ Unchanged v)" by (rule nstut_or) qed lemma stut_eventually: assumes H: "STUTINV F" shows "STUTINV \F" proof (unfold eventually_def) from H have "STUTINV \F" by (rule stut_not) hence "STUTINV \\F" by (rule stut_always) thus "STUTINV \\\F" by (rule stut_not) qed lemma stut_angle_action: assumes H: "NSTUTINV P" shows "STUTINV \\P\_v" proof (unfold angle_action_def) from H have "NSTUTINV \P" by (rule nstut_not) hence "STUTINV \[\ P]_v" by (rule stut_action) thus "STUTINV \\[\ P]_v" by (rule stut_not) qed lemma nstut_angle_acttrans: assumes H: "NSTUTINV P" shows "NSTUTINV \P\_v" proof (unfold angle_actrans_def) from H have "NSTUTINV \P" by (rule nstut_not) hence "NSTUTINV [\ P]_v" by (rule nstut_actrans) thus "NSTUTINV (\[\ P]_v)" by (rule nstut_not) qed lemmas stutinvs = stut_before (* stut_statepred *) stut_always stut_action stut_and stut_or stut_imp stut_eq stut_noteq stut_not stut_all stut_ex stut_eventually stut_angle_action stut_const stut_fun1 stut_fun2 stut_fun3 stut_plus lemmas nstutinvs = nstut_before nstut_after nstut_nexts nstut_actrans nstut_unch nstut_and nstut_or nstut_imp nstut_eq nstut_noteq nstut_not nstut_all nstut_ex nstut_angle_acttrans stutinv_strictly_stronger nstut_const nstut_fun1 nstut_fun2 nstut_fun3 stutinvs[THEN stutinv_strictly_stronger] lemmas bothstutinvs = stutinvs nstutinvs end