header {* (Infinite) Sequences *} theory Sequence imports Main begin text {* Formalises sequence for TLA. We assume all sequences are infinite, but we can extract finite segments of them. Finite sequences are postfixed with an infinite chain of stuttering steps. *} types 'a seq = "nat \ 'a" text {* A sequence @{typ "'a seq"} is a function @{typ "nat \ 'a"}. A sequence is infinite since natural numbers are infinite. The state space @{typ "'a"} is parameterized. *} section "Some general Sequence functions" text {* Some general functions on sequences are provided *} constdefs first :: "'a seq \ 'a" "first s \ s 0" second :: "('a seq) \ 'a" "second s \ s (1::nat)" suffix :: "'a seq \ nat \ 'a seq" ("_ |\<^sub>s _") "s |\<^sub>s i \ \ n. s (n+i)" prefix :: "'a seq \ nat \ 'a seq" ("_[\_]") "s[\i] \ \ n. if n \ i then s n else s i" tail :: "'a seq \ 'a seq" "tail s \ s |\<^sub>s 1" map :: "('a \ 'b) \ ('a seq) \ ('b seq)" "map f \ \ s. \ n. f (s n)" app :: "'a \ ('a seq) \ ('a seq)" (infixl "##" 60) "s ## \ \ \ n. if n=0 then s else \ (n-(1::nat))" text {* @{text "s |\<^sub>s i"} returns the suffix of sequence @{term s} starting at state @{term i}. @{term first} returns the first state of a sequence while @{term second} returns the second state. @{term tail} returns the sequence starting at the second state. @{term "s ## \"} prefixes the sequence @{term \} by state @{term s} *} subsection "Properties of @{term first} and @{term second}" lemma first_tail_second: "first(tail s) = second s" proof - have "first(tail s) = (tail s) 0" by (simp add: first_def) hence "first(tail s) = (s |\<^sub>s 1) 0" by (simp add: tail_def) hence "first(tail s) = s (0+1)" by (simp add: suffix_def) hence "first(tail s) = s 1" by auto thus ?thesis by (unfold second_def) qed subsection "Properties of @{term suffix}" lemma suffix_first: "first (s |\<^sub>s n) = s n" by (auto simp add: suffix_def first_def) lemma suffix_second: "second (s |\<^sub>s n) = s (Suc n)" by (auto simp add: suffix_def second_def) lemma suffix_plus: "s |\<^sub>s n |\<^sub>s m = s |\<^sub>s (m + n)" proof - have "s |\<^sub>s n = (\ k. s (k+n))" by (simp add: suffix_def) hence "s |\<^sub>s n |\<^sub>s m = ((\ k. s (k+n)) |\<^sub>s m)" by simp hence "s |\<^sub>s n |\<^sub>s m = (\ l. s (l+m+n))" by (simp add: suffix_def) hence "s |\<^sub>s n |\<^sub>s m = (\ l. s (l+(m+n)))" by (simp add: nat_add_assoc) thus "s |\<^sub>s n |\<^sub>s m = s |\<^sub>s (m + n)" by (simp add: suffix_def) qed lemma suffix_commute: "((s |\<^sub>s n) |\<^sub>s m) = ((s |\<^sub>s m) |\<^sub>s n)" proof - have "s |\<^sub>s n |\<^sub>s m = s |\<^sub>s n |\<^sub>s m" .. hence "s |\<^sub>s n |\<^sub>s m = s |\<^sub>s (m + n)" by (simp add: suffix_plus) hence "s |\<^sub>s n |\<^sub>s m = s |\<^sub>s (n + m)" by (simp add: nat_add_commute) thus "s |\<^sub>s n |\<^sub>s m = s |\<^sub>s m |\<^sub>s n" by (simp add: suffix_plus) qed lemma suffix_plus_com: "s |\<^sub>s m |\<^sub>s n = s |\<^sub>s (m + n)" proof - have "s |\<^sub>s n |\<^sub>s m = s |\<^sub>s (m + n)" by (rule suffix_plus) thus "s |\<^sub>s m |\<^sub>s n = s |\<^sub>s (m + n)" by (simp add: suffix_commute) qed lemma suffix_zero[simp]: "s |\<^sub>s 0 = s" proof - have "s |\<^sub>s 0 = (\ k. s (k+0))" by (simp add: suffix_def) hence "s |\<^sub>s 0 = (\ k. s k)" by simp thus ?thesis by simp qed lemma suffix_tail: "s |\<^sub>s 1 = tail s" proof - have "s |\<^sub>s 1 = (\ k. s (k+1))" by (simp add: suffix_def) thus ?thesis by (simp add: tail_def) qed lemma suffix_tail: "s |\<^sub>s 1 = tail s" proof - have "s |\<^sub>s 1 = (\ k. s (k+1))" by (simp add: suffix_def) thus ?thesis by (simp add: tail_def) qed lemma tail_suffix_suc: "s |\<^sub>s (Suc n) = tail (s |\<^sub>s n)" by (auto simp add: suffix_def tail_def) subsection "Properties of @{term map}" lemma seq_map_dist: "\ n. f (s n) = (map f s) n" proof - have "\ n. f (s n) = f (s n)" by auto thus "\ n. f (s n) = (map f s) n" by (unfold map_def) qed lemma seq_map_compose: "map (f o g) s = map f (map g s)" proof - have "f o g == \ s. f(g(s))" by (unfold comp_def) hence "map (f o g) = (\ s. \n. f (g (s n)))" by (simp add: map_def) hence "map (f o g) s = (\n. f (g (s n)))" by simp thus ?thesis by (simp add: map_def) qed subsection "Properties of @{term app}" lemma seq_app_second: "(s ## \) 1 = \ 0" by (auto simp add: app_def) lemma seq_app_first: "(s ## \) 0 = s" by (auto simp add: app_def) lemma seq_app_first_tail: "(first s) ## (tail s) = s" proof (rule ext) fix x show "(first s ## tail s) x = s x" by (auto simp add: first_def app_def suffix_def tail_def) qed lemma seq_app_tail: "tail (x ## s) = s" by (auto simp add: app_def tail_def suffix_def) lemma seq_app_greather_than_zero: "\ n > 0. (s ## \) n = \ (n-(1::nat))" by (auto simp add: app_def) section "Finite and Empty Sequences" text{* In this section we identify finite and empty sequences and prove lemmas of them. *} constdefs fin :: "('a seq) \ bool" "fin s \ \ i. \ j \ i. s j = s i" inf :: "('a seq) \ bool" "inf s \ \ i. \ j \ i. s j \ s i" last :: "('a seq) \ nat" "last s \ LEAST i. (\ j \ i. s j = s i)" laststate :: "('a seq) \ 'a" "laststate s \ s (last s)" emptyseq :: "('a seq) \ bool" "emptyseq \ \ s. \ i. s i = s 0" notemptyseq :: "('a seq) \ bool" "notemptyseq \ \ s. \ i. s i \ s 0" text {* Predicate @{term fin} holds if there is an element in the sequence such that all succeding elements are identical, i.e. the sequence is finite. @{term "last s"} returns the (first occurence of the) last element id (number) in a finite sequence @{term s}. Note that if @{text s} is not finite then an arbitrary number is returned. The @{text i} must be unique: Since we use @{text LEAST} and not @{text THE} this holds since @{text LEAST} requires the smallest number where this property holds. @{term laststate} returns the last @{typ "'a"} (i.e. state). We assume that the sequence is finite when using @{term last} and @{term laststate}. Predicate @{term emptyseq} identifies empty sequences -- i.e. all states in the sequence are identical to the initial one, while @{term notemptyseq} holds if the given sequence is not empty. *} subsection "Properties of @{term fin} and @{term inf}" lemma inf_not_fin: "(\(fin s)) = inf s" proof (rule iffI) assume a1: "\ fin s" show "inf s" proof (unfold inf_def) from a1 have "\(\ i. \ j. j \ i \ s j = s i)" by (unfold fin_def) hence "\(\ i.\(\ j. \(j \ i \ s j = s i)))" by auto hence "\(\ i.\(\ j. (j \ i \ s j \ s i)))" by auto thus "\ i. \ j. j \ i \ s j \ s i" by auto qed next assume a2: "inf s" show "\ fin s" proof (unfold fin_def) from a2 have "\ i. \ j. j \ i \ s j \ s i" by (unfold inf_def) hence "\ i. \ j. j \ i \ \(s j = s i)" by auto hence "\ i. \(\ j.\( j \ i \ \(s j = s i)))" by auto hence "\(\ i. \ j.\( j \ i \ \(s j = s i)))" by auto thus "\(\ i. \ j. j \ i \ s j = s i)" by auto qed qed lemma fin_not_inf: "(fin s) = (\(inf s))" proof (rule iffI) assume a1: "fin s" show "\ inf s" proof (unfold inf_def) from a1 have "(\ i. \ j. j \ i \ s j = s i)" by (unfold fin_def) hence "(\ i.\(\ j. \(j \ i \ s j = s i)))" by auto hence "(\ i.\(\ j. (j \ i \ s j \ s i)))" by auto thus "\(\ i. \ j. j \ i \ s j \ s i)" by auto qed next assume a2: "\ inf s" show "fin s" proof (unfold fin_def) from a2 have "\(\ i. \ j. j \ i \ s j \ s i)" by (unfold inf_def) hence "\(\ i. \ j. j \ i \ \(s j = s i))" by auto hence "\(\ i. \(\ j.\( j \ i \ \(s j = s i))))" by auto hence "\ i. \ j.\( j \ i \ \(s j = s i))" by auto thus "\ i. \ j. j \ i \ s j = s i" by auto qed qed lemma "\ s. fin s \ inf s" proof fix s show "fin s \ inf s" proof (cases "fin s") assume "fin s" show "fin s \ inf s" by (rule disjI1) next assume "\(fin s)" hence "inf s" by (auto simp add: inf_not_fin) thus "fin s \ inf s" by auto qed qed subsection "Properties of @{term emptyseq}" lemma empty_is_finite: assumes h1: "emptyseq s" shows "fin s" proof - from h1 have g1:"\ j. s j = s 0" by (unfold emptyseq_def) hence "\ i. \ j. s j = s i" by auto from g1 this have "\ i. \ j \ i. s j = s i" by auto thus ?thesis by (unfold fin_def) qed lemma empty_suffix_is_empty: assumes H: "emptyseq s" shows "\ n. emptyseq (s |\<^sub>s n)" proof (rule allI,unfold emptyseq_def,rule allI) fix i n from H have a1: "\ i. s i = s 0" by (unfold emptyseq_def) hence "s (i+n) = s 0" .. hence g1: "(s |\<^sub>s n) i = s 0" by (unfold suffix_def) from a1 have "s (0+n) = s 0" .. hence g2: "(s |\<^sub>s n) 0 = s 0" by (unfold suffix_def) with g1 show "(s |\<^sub>s n) i = (s |\<^sub>s n) 0" by auto qed lemma empty_suffix_exteq: assumes H:"emptyseq s" shows "\ m. (s |\<^sub>s n) m = s m" proof (rule allI,unfold suffix_def) fix m n from H have a1: "\ n. s n = s 0" by (unfold emptyseq_def) { from a1 have "s m = s 0" ..} moreover { from a1 have "s (m + n) = s 0" ..} ultimately show "s (m + n) = s m" by auto qed lemma empty_suffix_eq: assumes H: "emptyseq s" shows "(s |\<^sub>s n) = s" proof (rule ext) fix m from H have "\ m. (s |\<^sub>s n) m = s m" by (rule empty_suffix_exteq) thus "(s |\<^sub>s n) m = s m" .. qed lemma seq_not_empty_notempty: "(\(emptyseq s)) = notemptyseq s" proof (rule iffI) assume a1: "\(emptyseq s)" thus g1: "notemptyseq s" proof - from a1 have "\(\ i. s i = s 0)" by (unfold emptyseq_def) hence "(\ i. s i \ s 0)" by auto thus ?thesis by (unfold notemptyseq_def) qed next assume a2: "notemptyseq s" thus g2: "\(emptyseq s)" proof - from a2 have "(\ i. s i \ s 0)" by (unfold notemptyseq_def) hence "\(\ i. s i = s 0)" by auto thus ?thesis by (unfold emptyseq_def) qed qed lemma seq_notnot_empty_empty: "(emptyseq s) = (\(notemptyseq s))" proof (rule iffI) assume a1: "emptyseq s" show "\ notemptyseq s" proof - from a1 have "\ i. s i = s 0" by (unfold emptyseq_def) hence "\(\ i. s i \ s 0)" by auto thus "\ notemptyseq s" by (unfold notemptyseq_def) qed next assume a2: "\ notemptyseq s" show "emptyseq s" proof - from a2 have "\(\ i. s i \ s 0)" by (unfold notemptyseq_def) hence "\ i. s i = s 0" by blast thus ?thesis by (unfold emptyseq_def) qed qed lemma seq_empty_or_notempty: "emptyseq s \ notemptyseq s" proof - have "emptyseq s \ \(emptyseq s)" proof (cases "emptyseq s") case True thus ?thesis .. next case False thus ?thesis .. qed thus ?thesis by (auto simp add: seq_notnot_empty_empty) qed lemma suc_empty: assumes H1: "emptyseq (s |\<^sub>s m) " shows "emptyseq (s |\<^sub>s (Suc m))" proof (unfold emptyseq_def,rule allI,unfold suffix_def,simp) fix i from H1 have "\i. (s |\<^sub>s m) i = (s |\<^sub>s m) 0" by (unfold emptyseq_def) hence a1:"\i. s (i+m) = s (0+m)" by (unfold suffix_def) hence "s (1+m) = s (0+m)" .. hence g1: "s (Suc m) = s m" by auto from a1 have "s ((i+1)+m) = s (0+m)" .. hence g2: "s (Suc (i+m)) = s m" by auto with g1 show "s (Suc (i+m)) = s (Suc m)" by auto qed lemma assumes h: "\ n. s n = s 0" shows "\ n. s n = s (Suc n)" proof fix n show "s n = s (Suc n)" proof - from h have g1: "s n = s 0" .. from h have g2: "s (Suc n) = s 0" by auto with g1 show ?thesis by auto qed qed lemma seq_empty_all: assumes H: "\ i. s i = s 0" shows "\ i j. s i = s j" proof fix i show "\ j. s i = s j" proof fix j show "s i = s j" proof - from H have g1: "s i = s 0" .. from H have g2: "s j = s 0" .. with g1 show "s i = s j" by simp qed qed qed subsection "Properties of @{term last} and @{term laststate}" lemma fin_stut_after_last: assumes H: "fin s" shows "(\ j \ (last s). s j = s (last s))" proof fix j show "last s \ j \ s j = s (last s)" proof - from H have a1: "\ i. \ j \ i. s j = s i" by (unfold fin_def) from a1 obtain i where "\ j \ i. s j = s i" (is "?P i") .. hence "?P (LEAST x. ?P x)" by (rule LeastI) hence "\ j \ (last s). s j = s (last s)" by (fold last_def) thus "(last s) \ j \ s j = s (last s)" by blast qed qed section "Stuttering Invariance" text {* This section provides functions for removing stuttering steps of sequences, i.e. we formalise Lamports @{text \} operator. However, the semantics differs from Lamports, and is closer to Wahab's definition in the PVS prover. *} constdefs nonstutseq :: "('a seq) \ bool" "nonstutseq \ \ s. \ i. s i = s (Suc i) \ (\ j > i. s i = s j)" stutstep :: "('a seq) \ nat \ bool" "stutstep s n \ (s n = s (Suc n))" nextnat :: "('a seq) \ nat" "nextnat \ \ s. if emptyseq s then 0 else LEAST i. s i \ s 0" nextsuffix :: "('a seq) \ ('a seq)" "nextsuffix \ \ s. s |\<^sub>s (nextnat s)" consts "next" :: "nat \ ('a seq) \ ('a seq)" primrec "next 0 = id" "next (Suc n) = (nextsuffix) o (next n)" constdefs collapse :: "('a seq) \ ('a seq)" ("\") "\ s \ \ n. (next n s) 0" text {* Predicate @{term nonstutseq} identifies sequences without any stuttering steps -- except for an infinite empty sequence suffix. Further, @{term "stutstep s n"} is a predicate which holds if the step after @{term "s n"} is equal to @{term "s n"}, i.e. @{term "Suc n"} is a stuttering step. @{term "collapse s"} / @{term "\ s"} formalises Lamports @{term "\"} operator. It returns the first state of the result of @{term "next n s"}. @{term "next n s"} finds suffix of the $n^{th}$ change. Hence the first element, which @{term "\ s"} returns, is the state after the $n^{th}$ change. @{term "next n s"} is defined by primitive recursion on @{term "n"} using function composition of function @{term nextsuffix}. E.g. @{term "next 3 s"} equals @{term "nextsuffix (nextsuffix (nextsuffix s))"}. @{term "nextsuffix s"} returns the suffix of the sequence starting at the next changing state. It uses @{term "nextnat"} to obtain this. All the real computation is done in htis function. Firstly, an empty sequence will obviously not contain any changes, and @{text 0} is therefore returned. In this case @{term "nextsuffix"} behaves like the identify function. If the sequence is not empty then the smallest number @{term "i"} such that @{term "s i"} is different from the initial state is returned. This is achieved by @{term "Least"}. *} subsection "Properties of @{term nonstutseq}" lemma seq_empty_is_nonstut: assumes H: "emptyseq s" shows "nonstutseq s" proof (unfold nonstutseq_def) show "\i. s i = s (Suc i) \ (\j. i < j \ s i = s j)" proof fix i show "s i = s (Suc i) \ (\j. i < j \ s i = s j)" proof(rule impI,rule allI,rule impI) fix j assume a1: "s i = s (Suc i)" assume a2: "i < j" show "s i = s j" proof - from H have a3: "\ i. s i = s 0" by (unfold emptyseq_def) hence "\ i j. s i = s j" by (rule seq_empty_all) thus "s i = s j" by simp qed qed qed qed lemma notempty_exist_nonstut: assumes H: "\ emptyseq (s |\<^sub>s m)" shows "\ i. s i \ s m \ i > m" proof - from H have a1: "\(\ i. (s |\<^sub>s m) i = (s |\<^sub>s m) 0)" by (unfold emptyseq_def) hence "\ i. (s |\<^sub>s m) i \ (s |\<^sub>s m) 0" by auto hence "\ i. s (i+m) \ s (0+m)" by (auto simp add: suffix_def) hence g1: "\ i. s (i+m) \ s m" by auto from g1 obtain i where g1': "s (i+m) \ s m" .. have "(s (i+m)) \ (s m) \ (i \ 0)" proof (rule impI,rule ccontr) assume "\ i \ 0" hence a1: "i = 0" by arith assume "s (i + m) \ s m" with a1 have "s (0+m) \ s m" by auto hence "s m \ s m" by auto thus False by auto qed with g1' have "i \ 0" by auto hence g2: "i+m > m" by arith with g1' have "s (i+m) \ s m \ (i+m) > m" by auto thus "\ j. s j \ s m \ j > m" by auto qed subsection "Properties of @{term nextnat}" lemma nextnat_le_unch: assumes H: "n < nextnat s" shows "s n = s 0" proof (cases "emptyseq s") assume "emptyseq s" hence "nextnat s = 0" by (simp add: nextnat_def) with H show ?thesis by auto next assume "\ emptyseq s" hence a1: "nextnat s = (LEAST i. s i \ s 0)" by (simp add: nextnat_def) show ?thesis proof (rule ccontr) assume a2: "s n \ s 0" (is "?P n") hence "(LEAST i. s i \ s 0) \ n" by (rule Least_le) hence "\(n < (LEAST i. s i \ s 0))" by auto also from H a1 have "n < (LEAST i. s i \ s 0)" by simp ultimately show False by auto qed qed lemma stutnempty: assumes H: "\ stutstep s n" shows "\ emptyseq (s |\<^sub>s n)" proof (unfold emptyseq_def suffix_def) from H have "s (Suc n) \ s n" by (auto simp add: stutstep_def) hence "s (1+n) \ s (0+n)" by auto hence "\ i. s (i+n) \ s (0+n)" .. thus "\(\ i. s (i+n) = s (0+n))" by auto qed lemma notstutstep_nexnat1: assumes H: "\ stutstep s n" shows "nextnat (s |\<^sub>s n) = 1" proof - from H have h': "nextnat (s |\<^sub>s n) = (LEAST i. (s |\<^sub>s n) i \ (s |\<^sub>s n) 0)" by (auto simp add: nextnat_def stutnempty) from H have "s (Suc n) \ s n" by (auto simp add: stutstep_def) hence "(s |\<^sub>s n) (1::nat) \ (s |\<^sub>s n) 0" (is "?P (1::nat)") by (auto simp add: suffix_def) hence "Least ?P \ 1" by (rule Least_le) hence g1: "Least ?P = 0 \ Least ?P = 1" by auto with h' have g1': "nextnat (s |\<^sub>s n) = 0 \ nextnat (s |\<^sub>s n) = 1" by auto also have "nextnat (s |\<^sub>s n) \ 0" proof - from H have "\ emptyseq (s |\<^sub>s n)" by (rule stutnempty) hence "notemptyseq (s |\<^sub>s n)" by (simp add: seq_not_empty_notempty) hence "\ i. (s |\<^sub>s n) i \ (s |\<^sub>s n) 0" by (unfold notemptyseq_def) then obtain i where "(s |\<^sub>s n) i \ (s |\<^sub>s n) 0" .. hence "(s |\<^sub>s n) (LEAST i. (s |\<^sub>s n) i \ (s |\<^sub>s n) 0) \ (s |\<^sub>s n) 0" by (rule LeastI) with h' have g2: "(s |\<^sub>s n) (nextnat (s |\<^sub>s n)) \ (s |\<^sub>s n) 0" by auto show "(nextnat (s |\<^sub>s n)) \ 0" proof assume "(nextnat (s |\<^sub>s n)) = 0" hence "(s |\<^sub>s n) (nextnat (s |\<^sub>s n)) = (s |\<^sub>s n) 0" by auto with g2 show False .. qed qed ultimately show "nextnat (s |\<^sub>s n) = 1" by auto qed lemma stutstep_notempty_notempty: assumes h1: "notemptyseq (s |\<^sub>s n)" (is "notemptyseq ?s") and h2: "stutstep s n" shows "notemptyseq (s |\<^sub>s (Suc n))" (is "notemptyseq ?sn") proof (rule ccontr) assume a1: "\ notemptyseq (s |\<^sub>s (Suc n))" hence a1': "emptyseq ?sn" by (simp add: seq_notnot_empty_empty) hence a2: "\ i. ?sn i = ?sn 0" by (auto simp add: emptyseq_def) from h2 have h2':"s n = s (Suc n)" by (simp add: stutstep_def) from h1 have "\ i. ?s i \ ?s 0" by (simp add: notemptyseq_def) then obtain i where a3: "?s i \ ?s 0" .. hence g1: "s (i+n) \ s n" by (simp add: suffix_def) have g2:"i > 0" proof (rule ccontr) assume "\(i > 0)" hence "i=0" by arith hence "s (i+n) = s n" by auto with g1 show False by auto qed from a2 have " ?sn (i-(1::nat)) = ?sn 0" .. hence "s ((i-(1::nat))+(Suc n)) = s (Suc n)" by (auto simp add: suffix_def) hence "s (i-(1::nat)+(1::nat)+n) = s (Suc n)" by auto with g2 have "s (i+n) = s (Suc n)" by auto with h2' have "s (i+n) = s n" by simp with g1 show False by auto qed lemma stutstep_notempty_sucnextnat: assumes h1: "\ emptyseq (s |\<^sub>s n)" and h2: "stutstep s n" shows "(nextnat (s |\<^sub>s n)) = Suc (nextnat (s |\<^sub>s (Suc n)))" proof - from h2 have g1: "\(s (0+n) \ s (Suc n))" (is "\ ?P 0") by (auto simp add: stutstep_def) from h1 have "notemptyseq (s |\<^sub>s n)" by (simp add: seq_not_empty_notempty) hence "\ i. (s |\<^sub>s n) i \ (s |\<^sub>s n) 0" by (unfold notemptyseq_def) then obtain i where "(s |\<^sub>s n) i \ (s |\<^sub>s n) 0" .. hence "s (i+n) \ s n" by (simp add: suffix_def) with h2 have g2: "s (i+n) \ s (Suc n)" (is "?P i") by (simp add: stutstep_def) from g2 g1 have "(LEAST n. ?P n) = Suc (LEAST n. ?P (Suc n))" by (rule Least_Suc) from g2 g1 have "(LEAST i. s (i+n) \ s (Suc n)) = Suc (LEAST i. s ((Suc i)+n) \ s (Suc n))" by (rule Least_Suc) hence G1: "(LEAST i. s (i+n) \ s (Suc n)) = Suc (LEAST i. s (i+Suc n) \ s (Suc n))" by auto from h1 h2 have "\ emptyseq (s |\<^sub>s Suc n)" by (simp add: seq_not_empty_notempty stutstep_notempty_notempty) hence "nextnat (s |\<^sub>s Suc n) = (LEAST i. (s |\<^sub>s Suc n) i \ (s |\<^sub>s Suc n) 0)" by (auto simp add: nextnat_def) hence g1: "nextnat (s |\<^sub>s Suc n) = (LEAST i. s (i+(Suc n)) \ s (Suc n))" by (simp add: suffix_def) from h1 have "nextnat (s |\<^sub>s n) = (LEAST i. (s |\<^sub>s n) i \ (s |\<^sub>s n) 0)" by (auto simp add: nextnat_def) hence g2: "nextnat (s |\<^sub>s n) = (LEAST i. s (i+n) \ s n)" by (simp add: suffix_def) with h2 have g2': "nextnat (s |\<^sub>s n) = (LEAST i. s (i+n) \ s (Suc n))" by (auto simp add: stutstep_def) from G1 g1 g2' show ?thesis by auto qed lemma nextnat_empty_neq: assumes H: "\ emptyseq s" shows "s (nextnat s) \ s 0" proof - from H have a1: "nextnat s = (LEAST i. s i \ s 0)" by (simp add: nextnat_def) from H have a2: "\ i. s i \ s 0" by (simp add: seq_not_empty_notempty notemptyseq_def) from this obtain i where "s i \ s 0" .. hence "s (LEAST i. s i \ s 0) \ s 0" by (rule LeastI) with a1 show ?thesis by auto qed lemma nextnat_empty_gzero: assumes H: "\ emptyseq s" shows "nextnat s > 0" proof - from H have a1: "s (nextnat s) \ s 0" by (rule nextnat_empty_neq) have "nextnat s \ 0" proof (rule ccontr) assume "\ nextnat s \ 0" hence "nextnat s = 0" by auto hence "s (nextnat s) = s 0" by auto with a1 show False by simp qed thus "nextnat s > 0" by auto qed subsection "Properties of @{term nextsuffix}" lemma empty_nextsuffix: assumes H: "emptyseq s" shows "nextsuffix s = s" proof - from H have "nextnat s = 0" by (simp add: nextnat_def) thus ?thesis by (auto simp add: nextsuffix_def) qed lemma empty_nextsuffix_id: assumes H: "emptyseq s" shows "nextsuffix s = id s" proof - from H have "nextsuffix s = s" by (rule empty_nextsuffix) thus "nextsuffix s = id s" by auto qed lemma assumes H: "stutstep s n" shows "nextsuffix (s |\<^sub>s n) = nextsuffix (s |\<^sub>s (Suc n))" proof (unfold nextsuffix_def) show "(s |\<^sub>s n) |\<^sub>s nextnat (s |\<^sub>s n) = (s |\<^sub>s Suc n) |\<^sub>s nextnat (s |\<^sub>s Suc n)" proof (cases "emptyseq (s |\<^sub>s n)") assume a1: "emptyseq (s |\<^sub>s n)" hence a1': "emptyseq (s |\<^sub>s Suc n)" by (rule suc_empty) have "(s |\<^sub>s n) = (s |\<^sub>s Suc n)" proof (rule ext, unfold suffix_def) fix x thm "emptyseq_def" { from a1 have "\ i. (s |\<^sub>s n) i = (s |\<^sub>s n) 0" by (unfold emptyseq_def) hence "\ i. s (i+n) = s n" by (simp add: suffix_def) hence "s (x+n) = s n" .. } moreover { from a1' have "\ i. (s |\<^sub>s Suc n) i = (s |\<^sub>s Suc n) 0" by (unfold emptyseq_def) hence "\ i. s (i+Suc n) = s (Suc n)" by (simp add: suffix_def) hence "s (x+Suc n) = s (Suc n)" .. } moreover from H have "s (Suc n) = s n" by (simp add: stutstep_def) ultimately show "s (x + n) = s (x + Suc n)" by simp qed moreover from a1 have "(s |\<^sub>s n) |\<^sub>s nextnat (s |\<^sub>s n) = (s |\<^sub>s n)" by (simp add: nextnat_def suffix_zero) moreover from a1' have "(s |\<^sub>s Suc n) |\<^sub>s nextnat (s |\<^sub>s Suc n) = (s |\<^sub>s Suc n)" by (simp add: nextnat_def suffix_zero) ultimately show ?thesis by simp next assume a1: "\ emptyseq (s |\<^sub>s n)" with H have "(nextnat (s |\<^sub>s n)) = Suc (nextnat (s |\<^sub>s (Suc n)))" by (simp add: stutstep_notempty_sucnextnat) hence "(s |\<^sub>s n) |\<^sub>s nextnat (s |\<^sub>s n) = (s |\<^sub>s n) |\<^sub>s Suc (nextnat (s |\<^sub>s Suc n))" by auto also hence "\ = (s |\<^sub>s n) |\<^sub>s (1 + (nextnat (s |\<^sub>s Suc n)))" by auto also hence "\ = (s |\<^sub>s n) |\<^sub>s 1 |\<^sub>s (nextnat (s |\<^sub>s Suc n))" by (auto simp: suffix_plus_com) also hence "\ = (s |\<^sub>s Suc n) |\<^sub>s (nextnat (s |\<^sub>s Suc n))" by (auto simp: suffix_plus_com) finally show ?thesis by auto qed qed lemma notstutstep_nextsuffix1: assumes H: "\ stutstep s n" shows "nextsuffix (s |\<^sub>s n) = s |\<^sub>s (Suc n)" proof (unfold nextsuffix_def) show "(s |\<^sub>s n |\<^sub>s (nextnat (s |\<^sub>s n))) = s |\<^sub>s (Suc n)" proof - from H have "nextnat (s |\<^sub>s n) = 1" by (rule notstutstep_nexnat1) hence "(s |\<^sub>s n |\<^sub>s (nextnat (s |\<^sub>s n))) = s |\<^sub>s n |\<^sub>s 1" by auto thus ?thesis by (simp add: suffix_def) qed qed subsection "Properties of @{term next}" lemma next_first: "next 1 = nextsuffix" by auto lemma next_zero: "next 0 s = s" by auto lemma next_suc_suffix: "next (Suc n) s = nextsuffix (next n s)" by auto lemma next_suffix_com: "nextsuffix (next n s) = (next n (nextsuffix s))" by (induct n, auto) lemma next_plus: "next (m+n) s = next m (next n s)" by (induct m, auto) lemma next_empty: assumes H: "emptyseq s" shows "next n s = s" proof (induct n) from H show "next 0 s = s" by auto next fix n assume a1: "next n s = s" have "next (Suc n) s = nextsuffix (next n s)" by auto with a1 have "next (Suc n) s = nextsuffix s" by simp with H show "next (Suc n) s = s" by (simp add: nextsuffix_def nextnat_def) qed lemma notempty_nextnotzero: assumes H: "\emptyseq s" shows "(next (Suc 0) s) 0 \ s 0" proof - from H have g1: "s (nextnat s) \ s 0" by (rule nextnat_empty_neq) have "next (Suc 0) s = nextsuffix s" by auto also hence "\ = s |\<^sub>s (nextnat s)" by (simp add: nextsuffix_def) ultimately have "(next (Suc 0) s) 0 = s |\<^sub>s (nextnat s) 0" by simp hence "(next (Suc 0) s) 0 = s (nextnat s)" by (simp add: suffix_def) with g1 show ?thesis by simp qed lemma next_ex_id: "\ i. s i = (next m s) 0" proof - have "\ i. (s |\<^sub>s i) = (next m s)" proof (induct m) have "s |\<^sub>s 0 = next 0 s" by simp thus "\ i. (s |\<^sub>s i) = (next 0 s)" .. next fix m assume a1: "\ i. (s |\<^sub>s i) = (next m s)" then obtain i where a1': "(s |\<^sub>s i) = (next m s)" .. have "next (Suc m) s = nextsuffix (next m s)" by auto hence "next (Suc m) s = (next m s) |\<^sub>s (nextnat (next m s))" by (simp add: nextsuffix_def) hence "\ i. next (Suc m) s = (next m s) |\<^sub>s i" .. then obtain j where "next (Suc m) s = (next m s) |\<^sub>s j" .. with a1' have "next (Suc m) s = (s |\<^sub>s i) |\<^sub>s j" by simp hence "next (Suc m) s = (s |\<^sub>s (j+i))" by (simp add: suffix_plus) hence "(s |\<^sub>s (j+i)) = next (Suc m) s" by simp thus "\ i. (s |\<^sub>s i) = (next (Suc m) s)" .. qed then obtain i where "(s |\<^sub>s i) = (next m s)" .. hence "(s |\<^sub>s i) 0 = (next m s) 0" by auto hence "s i = (next m s) 0" by (auto simp add: suffix_def) thus ?thesis .. qed subsection "Properties of @{term collapse}" lemma emptyseq_collapse_eq: assumes A1: "emptyseq s" shows "\ s = s" proof (unfold collapse_def, rule ext) fix n from A1 have "next n s = s" by (rule next_empty) hence g1: "(next n s) 0 = s 0" by auto from A1 have "\ n. s n = s 0" by (auto simp add: emptyseq_def) hence g2: "s n = s 0" .. with g1 show "(next n s) 0 = s n" by auto qed lemma empty_collapse_empty: assumes H: "emptyseq s" shows "emptyseq (\ s)" proof - from H have "\ s = s" by (rule emptyseq_collapse_eq) with H show ?thesis by auto qed lemma collapse_empty_empty: assumes H: "emptyseq (\ s)" shows "emptyseq s" proof (rule ccontr) assume a1: "\emptyseq s" fix i { from H have "\ i. (\ s) i = (\ s) 0" by (unfold emptyseq_def) hence "\ i. (next i s) 0 = s 0" by (auto simp add: collapse_def)} moreover { from a1 have "(next (Suc 0) s) 0 \ s 0" by (rule notempty_nextnotzero) hence "\ i. (next i s) 0 \ s 0" .. hence "\(\ i. (next i s 0) = s 0)" by auto } ultimately show False by auto qed lemma notempty_collapse_notempty: assumes H: "notemptyseq s" shows "notemptyseq (\ s)" proof (unfold notemptyseq_def collapse_def) from H have "\emptyseq s" by (simp add: seq_not_empty_notempty) hence "(next (Suc 0) s 0) \ s 0" by (rule notempty_nextnotzero) hence "\ i. (next i s 0) \ s 0" .. thus "\ i. (next i s 0) \ (next 0 s 0)" by auto qed lemma collapse_notempty_notempty: assumes H: "notemptyseq (\ s)" shows "notemptyseq s" proof (unfold notemptyseq_def collapse_def) from H have "\ i. (\ s) i \ (\ s) 0" by (unfold notemptyseq_def) hence "\ i. (next i s) 0 \ (next 0 s) 0" by (unfold collapse_def) then obtain i where g1: "(next i s) 0 \ (next 0 s) 0" .. have "\ j. s j = (next i s) 0" by (rule next_ex_id) then obtain j where "s j = (next i s) 0" .. with g1 have "s j \ (next 0 s) 0" by simp hence "s j \ s 0" by auto thus "\ i. s i \ s 0" .. qed section "Similarity of Sequences" constdefs seqsimilar :: "('a seq) \ ('a seq) \ bool" ("_ \ _") "\ \ \ \ \ n. (\ \) n = (\ \) n" text {* To sequences @{term s} and @{term t} are \emph{similar} if they are equal up to stuttering, written @{term "s \ t"}. It requires that each changing steps are equal -- and is defined using the @{term \} operator. *} subsection "Properties of @{term seqsimilar}" lemma seqsim_refl: "s \ s" by (auto simp add: seqsimilar_def) lemma seqsim_sym: assumes H: "s \ t" shows "t \ s" proof (unfold seqsimilar_def, rule allI) fix n from H have "\ n. (\ s) n = (\ t) n" by (unfold seqsimilar_def) hence "(\ s) n = (\ t) n" .. thus "(\ t) n = (\ s) n" .. qed lemma seqeq_imp_sim: assumes H: "s = t" shows "s \ t" proof - have "s \ s" by (simp add: seqsimilar_def) with H show "s \ t" by auto qed lemma seqsim_trans: assumes h1: "s \ t" and h2: "t \ z" shows "s \ z" proof (unfold seqsimilar_def, rule allI) fix n { from h1 have "\ n. (\ s) n = (\ t) n" by (unfold seqsimilar_def) hence "(\ s) n = (\ t) n" .. } moreover { from h2 have "\ n. (\ t) n = (\ z) n" by (unfold seqsimilar_def) hence "(\ t) n = (\ z) n" .. } ultimately show "(\ s) n = (\ z) n" by auto qed theorem sim_first: assumes H: "s \ t" shows "first s = first t" proof - { have "(next 0 s) 0 = s 0" by auto hence "(\ s) 0 = s 0" by (simp add: collapse_def)} moreover { have "(next 0 t) 0 = t 0" by auto hence "(\ t) 0 = t 0" by (simp add: collapse_def)} moreover { from H have "\ n. (\ s) n = (\ t) n" by (simp add: seqsimilar_def) hence "(\ s) 0 = (\ t) 0" by auto } ultimately show ?thesis by (auto simp add: first_def) qed lemma sim_first2: assumes H: "s \ t" shows "s 0 = t 0" proof - from H have "first s = first t" by (rule sim_first) thus ?thesis by (simp add: first_def) qed lemma tail_sim_second: assumes H: "tail s \ tail t" shows "second s = second t" proof - from H have "first (tail s) = first (tail t)" by (simp add: sim_first) thus "second s = second t" by (simp add: first_tail_second) qed lemma seqsim_empty_empty: assumes H1: "s \ t" and H2: "emptyseq s" shows "emptyseq t" proof (rule collapse_empty_empty, unfold emptyseq_def,rule allI) fix n from H2 have "(next n s) = s" by (rule next_empty) hence g1: "(next n s) 0 = s 0" by simp from H1 have "\ n. (\ s) n = (\ t) n" by (unfold seqsimilar_def) hence "(\ s) n = (\ t) n" .. hence "(next n s) 0 = (next n t) 0" by (unfold collapse_def) with g1 have "s 0 = (next n t) 0" by simp hence "(next n t) 0 = s 0" .. with H1 have "(next n t) 0 = t 0" by (simp add: sim_first2) thus "(\ t) n = (\ t) 0" by (auto simp add: collapse_def) qed lemma seq_empty_eq: assumes H1: "s 0 = t 0" and H2: "emptyseq s" and H3: "emptyseq t" shows "s = t" proof - from H2 have a1: "\ i. s i = s 0" by (unfold emptyseq_def) from H3 have a2: "\ j. t j = t 0" by (unfold emptyseq_def) have "\ x. s x = t x" proof - fix x show "s x = t x" proof - fix i from a1 have a1a: "s i = s 0" .. with H1 have a1b: "s i = t 0" by simp from a2 have a2a: "t i = t 0" .. with a1b show "s i = t i" by simp qed qed thus "s = t" by (rule ext) qed lemma coleq_seqsim: "(\ s = \ t) = (s \ t)" proof (rule iffI) assume "\ s = \ t" thus "s \ t" by (auto simp add: collapse_def seqsimilar_def) next assume "s \ t" thus "\ s = \ t" by (auto simp add: collapse_def seqsimilar_def) qed lemma seqsim_notempty_notempty: assumes H1: "s \ t" and H2: "notemptyseq s" shows "notemptyseq t" proof (rule collapse_notempty_notempty, unfold notemptyseq_def) from H1 have g1: "\ s = \ t" by (simp add: coleq_seqsim) from H2 have "notemptyseq (\ s)" by (rule notempty_collapse_notempty) hence "\i. (\ s) i \ (\ s) 0" by (unfold notemptyseq_def) with g1 show "\i. (\ t) i \ (\ t) 0" by auto qed lemma seqsim_notstutstep: assumes H: "\ (stutstep s n)" shows "(s |\<^sub>s (Suc n)) \ nextsuffix (s |\<^sub>s n)" proof - have "s |\<^sub>s (Suc n) \ s |\<^sub>s (Suc n)" by (rule seqsim_refl) with H show ?thesis by (auto simp add: notstutstep_nextsuffix1) qed lemma stut_nextsuf_suc: assumes H: "stutstep s n" shows "nextsuffix (s |\<^sub>s n) = nextsuffix (s |\<^sub>s (Suc n))" proof (cases "emptyseq (s |\<^sub>s n)") assume a1: "emptyseq (s |\<^sub>s n)" have a1': "emptyseq (s |\<^sub>s Suc n)" by (rule suc_empty) from a1 have "nextnat (s |\<^sub>s n) = 0" by (simp add: nextnat_def) hence g1: "nextsuffix (s |\<^sub>s n) = (s |\<^sub>s n)" by (auto simp add: nextsuffix_def suffix_zero) from a1' have "nextnat (s |\<^sub>s Suc n) = 0" by (simp add: nextnat_def) hence g2: "nextsuffix (s |\<^sub>s Suc n) = (s |\<^sub>s Suc n)" by (auto simp add: nextsuffix_def suffix_zero) have "(s |\<^sub>s n) = (s |\<^sub>s Suc n)" proof fix x show "(s |\<^sub>s n) x = (s |\<^sub>s Suc n) x" proof (unfold suffix_def) from a1 have "\ i. (s |\<^sub>s n) i = (s |\<^sub>s n) 0" by (unfold emptyseq_def) hence a2: "\ i. s (i + n) = s n" by (auto simp add: suffix_def) from a2 have "s (x + n) = s n" .. also from a2 have "s (Suc x + n) = s n" .. hence "s (x + Suc n) = s n" by auto ultimately show "s (x + n) = s (x + Suc n)" by simp qed qed with g1 g2 show ?thesis by auto next assume a1: "\ emptyseq (s |\<^sub>s n)" hence "notemptyseq (s |\<^sub>s n)" by (simp add: seq_not_empty_notempty) with H have "notemptyseq (s |\<^sub>s Suc n)" by (simp add: stutstep_notempty_notempty) hence a1': "\ emptyseq (s |\<^sub>s Suc n)" by (simp add: seq_not_empty_notempty) show ?thesis proof (unfold nextsuffix_def) from H a1 have "(nextnat (s |\<^sub>s n)) = Suc (nextnat (s |\<^sub>s Suc n))" by (auto simp add: stutstep_notempty_sucnextnat) hence "(s |\<^sub>s n) |\<^sub>s (nextnat (s |\<^sub>s n)) = (s |\<^sub>s n) |\<^sub>s (Suc (nextnat (s |\<^sub>s Suc n)))" by auto hence "(s |\<^sub>s n) |\<^sub>s (nextnat (s |\<^sub>s n)) = (s |\<^sub>s n) |\<^sub>s (1 + (nextnat (s |\<^sub>s Suc n)))" by simp hence "(s |\<^sub>s n) |\<^sub>s (nextnat (s |\<^sub>s n)) = ((s |\<^sub>s n) |\<^sub>s 1) |\<^sub>s (nextnat (s |\<^sub>s Suc n))" by (auto simp add: suffix_plus) thus "(s |\<^sub>s n) |\<^sub>s (nextnat (s |\<^sub>s n)) = (s |\<^sub>s Suc n) |\<^sub>s (nextnat (s |\<^sub>s Suc n))" by (auto simp add: suffix_plus) qed qed lemma seqsim_suffix_seqsim: assumes H: "s \ t" shows "nextsuffix s \ nextsuffix t" proof (unfold seqsimilar_def collapse_def, rule allI) fix n { from H have "\ n. (\ s) n = (\ t) n" by (unfold seqsimilar_def) hence "\ n. (next n s) 0 = (next n t) 0" by (simp add: collapse_def) hence "(next (Suc n) s) 0 = (next (Suc n) t) 0" .. } moreover { have "nextsuffix (next n s) = next (Suc n) s" by auto hence "next n (nextsuffix s) = next (Suc n) s" by (simp add: next_suffix_com) } moreover { have "nextsuffix (next n t) = next (Suc n) t" by auto hence "next n (nextsuffix t) = next (Suc n) t" by (simp add: next_suffix_com) } ultimately show "next n (nextsuffix s) 0 = next n (nextsuffix t) 0" by auto qed lemma seqsim_stutstep: assumes H: "stutstep s n" shows "(s |\<^sub>s (Suc n)) \ (s |\<^sub>s n)" (is "?sn \ ?s") proof (unfold seqsimilar_def collapse_def,rule allI) fix m show "next m (s |\<^sub>s Suc n) 0 = next m (s |\<^sub>s n) 0" proof (cases m) assume a2: "m=0" with H have "(s |\<^sub>s Suc n) 0 = (s |\<^sub>s n) 0" by (auto simp add: suffix_def stutstep_def) with a2 show "next m (s |\<^sub>s Suc n) 0 = next m (s |\<^sub>s n) 0" by auto next fix k assume a2: "m = Suc k" { from a2 have "next m (s |\<^sub>s Suc n) = nextsuffix (next k (s |\<^sub>s Suc n))" by auto hence "next m (s |\<^sub>s Suc n) = next k (nextsuffix (s |\<^sub>s Suc n))" by (simp add: next_suffix_com) with H have "next m (s |\<^sub>s Suc n) = next k (nextsuffix (s |\<^sub>s n))" by (simp add: stut_nextsuf_suc)} moreover { from a2 have "next m (s |\<^sub>s n) = nextsuffix (next k (s |\<^sub>s n))" by auto hence "next m (s |\<^sub>s n) = next k (nextsuffix (s |\<^sub>s n))" by (simp add: next_suffix_com) } ultimately show "next m (s |\<^sub>s Suc n) 0 = next m (s |\<^sub>s n) 0" by simp qed qed lemma addfeqstut: assumes H: "s = first t" shows "stutstep (s ## t) 0" using H by (auto simp add: first_def stutstep_def app_def suffix_def) lemma addfeqsim: assumes H: "s = first t" shows "(s ## t) \ t" proof - from H have "stutstep (s ## t) 0" by (rule addfeqstut) hence "((s ## t) |\<^sub>s (Suc 0)) \ ((s ## t) |\<^sub>s 0)" by (rule seqsim_stutstep) hence "tail (s ## t) \ (s ## t)" by (auto simp add: suffix_def tail_def) hence "t \ (s ## t)" by (auto simp add: tail_def app_def suffix_def) thus ?thesis by (rule seqsim_sym) qed lemma addfirststut: assumes H: "first s = second s" shows "s \ tail s" proof - have g1: "(first s) ## (tail s) = s" by (rule seq_app_first_tail) from H have "(first s) = first (tail s)" by (auto simp add: first_def second_def tail_def suffix_def) hence "(first s) ## (tail s) \ (tail s)" by (rule addfeqsim) with g1 show ?thesis by auto qed lemma app_seqsimilar: assumes h1: "s \ t" shows "(x ## s) \ (x ## t)" proof (unfold seqsimilar_def, rule allI) fix n show "\ (x ## s) n = \ (x ## t) n" proof (cases "stutstep (x ## s) 0") assume a1: "stutstep (x ## s) 0" from h1 have "first s = first t" by (rule sim_first) with a1 have a2: "stutstep (x ## t) 0" by (auto simp add: stutstep_def first_def suffix_def app_def) from a1 have "((x ## s) |\<^sub>s (Suc 0)) \ ((x ## s) |\<^sub>s 0)" by (rule seqsim_stutstep) hence "tail (x ## s) \ (x ## s)" by (auto simp add: tail_def suffix_def) hence g1: "s \ (x ## s)" by (auto simp add: app_def tail_def suffix_def) from a2 have "((x ## t) |\<^sub>s (Suc 0)) \ ((x ## t) |\<^sub>s 0)" by (rule seqsim_stutstep) hence "tail (x ## t) \ (x ## t)" by (auto simp add: tail_def suffix_def) hence g2: "t \ (x ## t)" by (auto simp add: app_def tail_def suffix_def) from h1 g2 have "s \ (x ## t)" by (rule seqsim_trans) from this[THEN seqsim_sym] g1 have "(x ## s) \ (x ## t)" by (rule seqsim_sym[OF seqsim_trans]) hence "\ n. \ (x ## s) n = \ (x ## t) n" by (unfold seqsimilar_def) thus ?thesis .. next assume a1: "\ stutstep (x ## s) 0" from h1 have "first s = first t" by (rule sim_first) with a1 have a2: "\ stutstep (x ## t) 0" by (auto simp add: stutstep_def first_def suffix_def app_def) from a1 have "((x ## s) |\<^sub>s (Suc 0)) \ nextsuffix ((x ## s) |\<^sub>s 0)" by (rule seqsim_notstutstep) hence "(tail (x ## s)) \ nextsuffix (x ## s)" by (auto simp add: tail_def suffix_zero) hence g1: "s \ nextsuffix (x ## s)" by (auto simp add: seq_app_tail) from a2 have "((x ## t) |\<^sub>s (Suc 0)) \ nextsuffix ((x ## t) |\<^sub>s 0)" by (rule seqsim_notstutstep) hence "(tail (x ## t)) \ nextsuffix (x ## t)" by (auto simp add: tail_def suffix_zero) hence g2: "t \ nextsuffix (x ## t)" by (auto simp add: seq_app_tail) with h1 have "s \ nextsuffix (x ## t)" by (rule seqsim_trans) from this[THEN seqsim_sym] g1 have g3: "nextsuffix (x ## s) \ nextsuffix (x ## t)" by (rule seqsim_sym[OF seqsim_trans]) hence "\ n. \(nextsuffix (x ## s)) n = \(nextsuffix (x ## t)) n" by (unfold seqsimilar_def) hence g3': "\ n. next n (nextsuffix (x ## s)) 0 = next n (nextsuffix (x ## t)) 0" by (unfold collapse_def) show ?thesis proof (unfold collapse_def) show "next n (x ## s) 0 = next n (x ## t) 0" proof (induct n) show "next 0 (x ## s) 0 = next 0 (x ## t) 0" by (auto simp add: app_def) next fix m assume a1: "next m (x ## s) 0 = next m (x ## t) 0" from g3' have "next m (nextsuffix (x ## s)) 0 = next m (nextsuffix (x ## t)) 0" .. hence "nextsuffix (next m (x ## s)) 0 = nextsuffix (next m (x ## t)) 0" by (simp add: next_suffix_com) thus "next (Suc m) (x ## s) 0 = next (Suc m) (x ## t) 0" by (simp add: next_suc_suffix) qed qed qed qed lemma simstep_disj1: assumes H: "s \ t" shows "\ n. \ m. ((s |\<^sub>s n) \ (t |\<^sub>s m))" proof fix n show "\ m. ((s |\<^sub>s n) \ (t |\<^sub>s m))" proof (induct n) have "((s |\<^sub>s 0) \ (t |\<^sub>s 0))" by (auto simp add: suffix_zero) thus "\ m. ((s |\<^sub>s 0) \ (t |\<^sub>s m))" .. next fix n assume a1: "\ m. ((s |\<^sub>s n) \ (t |\<^sub>s m))" then obtain m where a1': "((s |\<^sub>s n) \ (t |\<^sub>s m))" .. show "\ m. ((s |\<^sub>s (Suc n)) \ (t |\<^sub>s m))" proof (cases "stutstep s n") assume a2: "stutstep s n" hence a2': "(s |\<^sub>s (Suc n)) \ (s |\<^sub>s n)" by (rule seqsim_stutstep) from a2' a1' have "((s |\<^sub>s (Suc n)) \ (t |\<^sub>s m))" by (rule seqsim_trans) thus ?thesis by auto next fix k assume a2: "\ stutstep s n" hence "(s |\<^sub>s (Suc n)) \ nextsuffix (s |\<^sub>s n)" by (rule seqsim_notstutstep) also from a1' have "nextsuffix (s |\<^sub>s n) \ nextsuffix (t |\<^sub>s m)" by (simp add: seqsim_suffix_seqsim) ultimately have "(s |\<^sub>s (Suc n)) \ nextsuffix (t |\<^sub>s m)" by (rule seqsim_trans) thm "nextsuffix_def" hence "(s |\<^sub>s (Suc n)) \ (t |\<^sub>s m) |\<^sub>s (nextnat (t |\<^sub>s m))" by (unfold nextsuffix_def) hence "(s |\<^sub>s (Suc n)) \ t |\<^sub>s m |\<^sub>s (nextnat (t |\<^sub>s m))" by simp hence "(s |\<^sub>s (Suc n)) \ t |\<^sub>s (m + (nextnat (t |\<^sub>s m)))" by (simp add: suffix_plus_com) thus "\ m. (s |\<^sub>s (Suc n)) \ t |\<^sub>s m" .. qed qed qed lemma nextnat_le_seqsim: "n < nextnat s \ s \ (s |\<^sub>s n)" proof (cases "emptyseq s") assume "emptyseq s" hence "nextnat s = 0" by (simp add: nextnat_def) thus ?thesis by auto next assume a1: "\ emptyseq s" show ?thesis proof (induct n) show "0 < nextnat s \ s \ (s |\<^sub>s 0)" by (simp add: suffix_zero seqsim_refl) next fix n assume a2: "n < nextnat s \ s \ (s |\<^sub>s n)" show "(Suc n) < nextnat s \ s \ (s |\<^sub>s (Suc n))" proof thm "nextnat_le_unch" assume a3: "Suc n < nextnat s" hence g1: "s (Suc n) = s 0" by (rule nextnat_le_unch) from a3 have a3': "n < nextnat s" by simp hence "s n = s 0" by (rule nextnat_le_unch) with g1 have "stutstep s n" by (simp add: stutstep_def) hence g2: "(s |\<^sub>s n) \ (s |\<^sub>s (Suc n))" by (rule seqsim_stutstep[THEN seqsim_sym]) from a3' a2 have g3: "s \ (s |\<^sub>s n)" by auto from g3 g2 show "s \ (s |\<^sub>s (Suc n))" by (rule seqsim_trans) qed qed qed lemma seqsim_prev_nextnat: "s \ s |\<^sub>s ((nextnat s)-(1::nat))" proof (cases "emptyseq s") assume a1: "emptyseq s" hence "nextnat s = 0" by (simp add: nextnat_def) hence "(nextnat s)-(1::nat) = 0" by auto hence "s |\<^sub>s ((nextnat s)-(1::nat)) = s |\<^sub>s 0" by simp thus ?thesis by (simp add: seqsim_refl) next assume a1': "\ emptyseq s" hence "nextnat s > 0" by (rule nextnat_empty_gzero) hence "(nextnat s)-(1::nat) < nextnat s" by auto thus ?thesis by (simp add: nextnat_le_seqsim) qed lemma gzero_sucpreveq: assumes H: "m > 0" shows "m = Suc (m-(1::nat))" proof - from H show ?thesis by arith qed theorem sim_step: assumes H: "s \ t" shows "\ 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)))" proof fix n show "\ 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)))" proof (induct n) show "\ m. ((s |\<^sub>s 0) \ (t |\<^sub>s m)) \ (((s |\<^sub>s Suc 0) \ (t |\<^sub>s Suc m)) \ ((s |\<^sub>s Suc 0) \ (t |\<^sub>s m)))" proof (cases "stutstep s 0") assume a1: "stutstep s 0" hence a2: "(s |\<^sub>s Suc 0) \ (s |\<^sub>s 0)" by (rule seqsim_stutstep) hence a2': "(s |\<^sub>s Suc 0) \ s" by (simp add: suffix_zero) with H have "(s |\<^sub>s 0) \ t" by simp also from a2' H have "(s |\<^sub>s Suc 0) \ t" by (rule seqsim_trans) ultimately have "((s |\<^sub>s 0) \ t) \ ((s |\<^sub>s (Suc 0)) \ t)" by auto hence "((s |\<^sub>s 0) \ (t |\<^sub>s 0)) \ ((s |\<^sub>s (Suc 0)) \ (t |\<^sub>s 0))" by (simp add: suffix_zero) hence "((s |\<^sub>s 0) \ (t |\<^sub>s 0)) \ (((s |\<^sub>s Suc 0) \ (t |\<^sub>s Suc 0)) \ ((s |\<^sub>s (Suc 0)) \ (t |\<^sub>s 0)))" by auto thus "\ m. ((s |\<^sub>s 0) \ (t |\<^sub>s m)) \ (((s |\<^sub>s Suc 0) \ (t |\<^sub>s Suc m)) \ ((s |\<^sub>s Suc 0) \ (t |\<^sub>s m)))" .. next assume a1: "\ stutstep s 0" hence "\ emptyseq (s |\<^sub>s 0)" by (rule stutnempty) hence "\ emptyseq s" by simp hence "notemptyseq s" by (simp add: seq_not_empty_notempty) with H have "notemptyseq t" by (simp add: seqsim_notempty_notempty) hence a2: "\ emptyseq t" by (simp add: seq_not_empty_notempty) hence g2': "0 < nextnat t" by (rule nextnat_empty_gzero) have g3: "t \ t |\<^sub>s ((nextnat t)-(1::nat))" by (rule seqsim_prev_nextnat) have "nextsuffix t = t |\<^sub>s (nextnat t)" by (simp add: nextsuffix_def) with g2' have g4: "nextsuffix t = t |\<^sub>s Suc ((nextnat t)-(1::nat))" by (simp add: gzero_sucpreveq) from H g3 have "s \ t |\<^sub>s ((nextnat t)-(1::nat))" by (rule seqsim_trans) hence G1: "(s |\<^sub>s 0) \ t |\<^sub>s ((nextnat t)-(1::nat))" by auto from a1 have "(s |\<^sub>s Suc 0) = nextsuffix (s |\<^sub>s 0)" by (rule notstutstep_nextsuffix1[THEN sym]) hence G1': "(s |\<^sub>s Suc 0) = nextsuffix s" by simp from H have "nextsuffix s \ nextsuffix t" by (rule seqsim_suffix_seqsim) with G1' g4 have "(s |\<^sub>s Suc 0) \ t |\<^sub>s Suc ((nextnat t)-(1::nat))" by simp with G1 have "((s |\<^sub>s 0) \ t |\<^sub>s ((nextnat t)-(1::nat))) \ ((s |\<^sub>s Suc 0) \ t |\<^sub>s Suc ((nextnat t)-(1::nat)))" by simp hence "\ m. ((s |\<^sub>s 0) \ (t |\<^sub>s m)) \ ((s |\<^sub>s Suc 0) \ (t |\<^sub>s Suc m))" .. thus "\ m. ((s |\<^sub>s 0) \ (t |\<^sub>s m)) \ (((s |\<^sub>s Suc 0) \ (t |\<^sub>s Suc m)) \ ((s |\<^sub>s Suc 0) \ (t |\<^sub>s m)))" by auto qed next fix n assume a1: "\ 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)))" .. thus "\ m. ((s |\<^sub>s Suc n) \ (t |\<^sub>s m)) \ (((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s Suc m)) \ ((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s m)))" proof assume b1: "(s |\<^sub>s n) \ (t |\<^sub>s m)" and b2: "((s |\<^sub>s Suc n) \ (t |\<^sub>s Suc m)) \ ((s |\<^sub>s Suc n) \ (t |\<^sub>s m))" from b2 show ?thesis proof assume b2: "((s |\<^sub>s Suc n) \ (t |\<^sub>s Suc m))" (is "?s \ ?t") show ?thesis proof (cases "stutstep s (Suc n)") assume "stutstep s (Suc n)" hence a2: "(s |\<^sub>s Suc (Suc n)) \ (s |\<^sub>s (Suc n))" by (rule seqsim_stutstep) from a2 b2 have "(s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s Suc m)" by (rule seqsim_trans) with b2 have "((s |\<^sub>s Suc n) \ (t |\<^sub>s Suc m)) \ ((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s Suc m))" by auto hence "\ m. ((s |\<^sub>s Suc n) \ (t |\<^sub>s m)) \ ((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s m))" .. thus ?thesis by auto next assume A1: "\stutstep s (Suc n)" hence "\ emptyseq (s |\<^sub>s Suc n)" by (rule stutnempty) hence "notemptyseq (s |\<^sub>s Suc n)" by (simp add: seq_not_empty_notempty) with b2 have "notemptyseq (t |\<^sub>s Suc m)" by (simp add: seqsim_notempty_notempty) hence a2: "\ emptyseq (t |\<^sub>s Suc m)" by (simp add: seq_not_empty_notempty) hence g2': "0 < nextnat (t |\<^sub>s Suc m)" by (rule nextnat_empty_gzero) have g3: "(t |\<^sub>s Suc m) \ (t |\<^sub>s Suc m) |\<^sub>s ((nextnat (t |\<^sub>s Suc m))-(1::nat))" by (rule seqsim_prev_nextnat) have "nextsuffix (t |\<^sub>s Suc m) = (t |\<^sub>s Suc m) |\<^sub>s (nextnat (t |\<^sub>s Suc m))" by (simp add: nextsuffix_def) with g2' have g4: "nextsuffix (t |\<^sub>s Suc m) = (t |\<^sub>s Suc m) |\<^sub>s Suc ((nextnat (t |\<^sub>s Suc m))-(1::nat))" by (simp add: gzero_sucpreveq) from b2 g3 have G1: "(s |\<^sub>s Suc n) \ ((t |\<^sub>s Suc m) |\<^sub>s ((nextnat (t |\<^sub>s Suc m))-(1::nat)))" by (rule seqsim_trans) from A1 have G1': "(s |\<^sub>s Suc (Suc n)) = nextsuffix (s |\<^sub>s Suc n)" by (rule notstutstep_nextsuffix1[THEN sym]) from b2 have "nextsuffix (s |\<^sub>s Suc n) \ nextsuffix (t |\<^sub>s Suc m)" by (rule seqsim_suffix_seqsim) with G1' g4 have "(s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s Suc m) |\<^sub>s Suc ((nextnat (t |\<^sub>s Suc m))-(1::nat))" by simp with G1 have "((s |\<^sub>s Suc n) \ (t |\<^sub>s Suc m) |\<^sub>s ((nextnat (t |\<^sub>s Suc m))-(1::nat))) \ ((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s Suc m) |\<^sub>s Suc ((nextnat (t |\<^sub>s Suc m))-(1::nat)))" by simp with G1 have "((s |\<^sub>s Suc n) \ t |\<^sub>s ((Suc m) + ((nextnat (t |\<^sub>s Suc m))-(1::nat)))) \ ((s |\<^sub>s Suc (Suc n)) \ t |\<^sub>s ((Suc m) + Suc ((nextnat (t |\<^sub>s Suc m))-(1::nat))))" by (simp add: suffix_plus_com) hence "((s |\<^sub>s Suc n) \ (t |\<^sub>s ((Suc m) + ((nextnat (t |\<^sub>s Suc m))-(1::nat))) )) \ ((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s Suc ((Suc m) + ((nextnat (t |\<^sub>s Suc m))-(1::nat)))))" by auto hence "\ m. ((s |\<^sub>s Suc n) \ (t |\<^sub>s m)) \ ((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s Suc m))" by blast thus "\ m. ((s |\<^sub>s Suc n) \ (t |\<^sub>s m)) \ (((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s Suc m)) \ ((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s m)))" by auto qed next assume b2: "((s |\<^sub>s Suc n) \ (t |\<^sub>s m))" show ?thesis proof (cases "stutstep s (Suc n)") assume "stutstep s (Suc n)" hence a2: "(s |\<^sub>s Suc (Suc n)) \ (s |\<^sub>s (Suc n))" by (rule seqsim_stutstep) from a2 b2 have "(s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s m)" by (rule seqsim_trans) with b2 have "((s |\<^sub>s Suc n) \ (t |\<^sub>s m)) \ ((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s m))" by auto hence "\ m. ((s |\<^sub>s Suc n) \ (t |\<^sub>s m)) \ ((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s m))" .. thus ?thesis by auto next assume A1: "\stutstep s (Suc n)" hence "\ emptyseq (s |\<^sub>s Suc n)" by (rule stutnempty) hence "notemptyseq (s |\<^sub>s Suc n)" by (simp add: seq_not_empty_notempty) with b2 have "notemptyseq (t |\<^sub>s m)" by (simp add: seqsim_notempty_notempty) hence a2: "\ emptyseq (t |\<^sub>s m)" by (simp add: seq_not_empty_notempty) hence g2': "0 < nextnat (t |\<^sub>s m)" by (rule nextnat_empty_gzero) have g3: "(t |\<^sub>s m) \ (t |\<^sub>s m) |\<^sub>s ((nextnat (t |\<^sub>s m))-(1::nat))" by (rule seqsim_prev_nextnat) have "nextsuffix (t |\<^sub>s m) = (t |\<^sub>s m) |\<^sub>s (nextnat (t |\<^sub>s m))" by (simp add: nextsuffix_def) with g2' have g4: "nextsuffix (t |\<^sub>s m) = (t |\<^sub>s m) |\<^sub>s Suc ((nextnat (t |\<^sub>s m))-(1::nat))" by (simp add: gzero_sucpreveq) from b2 g3 have G1: "(s |\<^sub>s Suc n) \ ((t |\<^sub>s m) |\<^sub>s ((nextnat (t |\<^sub>s m))-(1::nat)))" by (rule seqsim_trans) from A1 have G1': "(s |\<^sub>s Suc (Suc n)) = nextsuffix (s |\<^sub>s Suc n)" by (rule notstutstep_nextsuffix1[THEN sym]) from b2 have "nextsuffix (s |\<^sub>s Suc n) \ nextsuffix (t |\<^sub>s m)" by (rule seqsim_suffix_seqsim) with G1' g4 have "(s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s m) |\<^sub>s Suc ((nextnat (t |\<^sub>s m))-(1::nat))" by simp with G1 have "((s |\<^sub>s Suc n) \ (t |\<^sub>s m) |\<^sub>s ((nextnat (t |\<^sub>s m))-(1::nat))) \ ((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s m) |\<^sub>s Suc ((nextnat (t |\<^sub>s m))-(1::nat)))" by simp with G1 have "((s |\<^sub>s Suc n) \ t |\<^sub>s (m + ((nextnat (t |\<^sub>s m))-(1::nat)))) \ ((s |\<^sub>s Suc (Suc n)) \ t |\<^sub>s (m + Suc ((nextnat (t |\<^sub>s m))-(1::nat))))" by (simp add: suffix_plus_com) hence "((s |\<^sub>s Suc n) \ (t |\<^sub>s (m + ((nextnat (t |\<^sub>s m))-(1::nat))) )) \ ((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s Suc (m + ((nextnat (t |\<^sub>s m))-(1::nat)))))" by auto hence "\ m. ((s |\<^sub>s Suc n) \ (t |\<^sub>s m)) \ ((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s Suc m))" by blast thus "\ m. ((s |\<^sub>s Suc n) \ (t |\<^sub>s m)) \ (((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s Suc m)) \ ((s |\<^sub>s Suc (Suc n)) \ (t |\<^sub>s m)))" by auto qed qed qed qed qed end