diff -r f493a20feeb3 -r 04b5e904a220 thys3/PosixSpec.thy --- a/thys3/PosixSpec.thy Sat Apr 30 00:50:08 2022 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,380 +0,0 @@ - -theory PosixSpec - imports RegLangs -begin - -section \"Plain" Values\ - -datatype val = - Void -| Char char -| Seq val val -| Right val -| Left val -| Stars "val list" - - -section \The string behind a value\ - -fun - flat :: "val \ string" -where - "flat (Void) = []" -| "flat (Char c) = [c]" -| "flat (Left v) = flat v" -| "flat (Right v) = flat v" -| "flat (Seq v1 v2) = (flat v1) @ (flat v2)" -| "flat (Stars []) = []" -| "flat (Stars (v#vs)) = (flat v) @ (flat (Stars vs))" - -abbreviation - "flats vs \ concat (map flat vs)" - -lemma flat_Stars [simp]: - "flat (Stars vs) = flats vs" -by (induct vs) (auto) - - -section \Lexical Values\ - -inductive - Prf :: "val \ rexp \ bool" ("\ _ : _" [100, 100] 100) -where - "\\ v1 : r1; \ v2 : r2\ \ \ Seq v1 v2 : SEQ r1 r2" -| "\ v1 : r1 \ \ Left v1 : ALT r1 r2" -| "\ v2 : r2 \ \ Right v2 : ALT r1 r2" -| "\ Void : ONE" -| "\ Char c : CH c" -| "\v \ set vs. \ v : r \ flat v \ [] \ \ Stars vs : STAR r" - -inductive_cases Prf_elims: - "\ v : ZERO" - "\ v : SEQ r1 r2" - "\ v : ALT r1 r2" - "\ v : ONE" - "\ v : CH c" - "\ vs : STAR r" - -lemma Prf_Stars_appendE: - assumes "\ Stars (vs1 @ vs2) : STAR r" - shows "\ Stars vs1 : STAR r \ \ Stars vs2 : STAR r" -using assms -by (auto intro: Prf.intros elim!: Prf_elims) - - -lemma flats_Prf_value: - assumes "\s\set ss. \v. s = flat v \ \ v : r" - shows "\vs. flats vs = concat ss \ (\v\set vs. \ v : r \ flat v \ [])" -using assms -apply(induct ss) -apply(auto) -apply(rule_tac x="[]" in exI) -apply(simp) -apply(case_tac "flat v = []") -apply(rule_tac x="vs" in exI) -apply(simp) -apply(rule_tac x="v#vs" in exI) -apply(simp) -done - - -lemma L_flat_Prf1: - assumes "\ v : r" - shows "flat v \ L r" -using assms -by (induct) (auto simp add: Sequ_def Star_concat) - -lemma L_flat_Prf2: - assumes "s \ L r" - shows "\v. \ v : r \ flat v = s" -using assms -proof(induct r arbitrary: s) - case (STAR r s) - have IH: "\s. s \ L r \ \v. \ v : r \ flat v = s" by fact - have "s \ L (STAR r)" by fact - then obtain ss where "concat ss = s" "\s \ set ss. s \ L r \ s \ []" - using Star_split by auto - then obtain vs where "flats vs = s" "\v\set vs. \ v : r \ flat v \ []" - using IH flats_Prf_value by metis - then show "\v. \ v : STAR r \ flat v = s" - using Prf.intros(6) flat_Stars by blast -next - case (SEQ r1 r2 s) - then show "\v. \ v : SEQ r1 r2 \ flat v = s" - unfolding Sequ_def L.simps by (fastforce intro: Prf.intros) -next - case (ALT r1 r2 s) - then show "\v. \ v : ALT r1 r2 \ flat v = s" - unfolding L.simps by (fastforce intro: Prf.intros) -qed (auto intro: Prf.intros) - - -lemma L_flat_Prf: - shows "L(r) = {flat v | v. \ v : r}" -using L_flat_Prf1 L_flat_Prf2 by blast - - - -section \Sets of Lexical Values\ - -text \ - Shows that lexical values are finite for a given regex and string. -\ - -definition - LV :: "rexp \ string \ val set" -where "LV r s \ {v. \ v : r \ flat v = s}" - -lemma LV_simps: - shows "LV ZERO s = {}" - and "LV ONE s = (if s = [] then {Void} else {})" - and "LV (CH c) s = (if s = [c] then {Char c} else {})" - and "LV (ALT r1 r2) s = Left ` LV r1 s \ Right ` LV r2 s" -unfolding LV_def -by (auto intro: Prf.intros elim: Prf.cases) - - -abbreviation - "Prefixes s \ {s'. prefix s' s}" - -abbreviation - "Suffixes s \ {s'. suffix s' s}" - -abbreviation - "SSuffixes s \ {s'. strict_suffix s' s}" - -lemma Suffixes_cons [simp]: - shows "Suffixes (c # s) = Suffixes s \ {c # s}" -by (auto simp add: suffix_def Cons_eq_append_conv) - - -lemma finite_Suffixes: - shows "finite (Suffixes s)" -by (induct s) (simp_all) - -lemma finite_SSuffixes: - shows "finite (SSuffixes s)" -proof - - have "SSuffixes s \ Suffixes s" - unfolding strict_suffix_def suffix_def by auto - then show "finite (SSuffixes s)" - using finite_Suffixes finite_subset by blast -qed - -lemma finite_Prefixes: - shows "finite (Prefixes s)" -proof - - have "finite (Suffixes (rev s))" - by (rule finite_Suffixes) - then have "finite (rev ` Suffixes (rev s))" by simp - moreover - have "rev ` (Suffixes (rev s)) = Prefixes s" - unfolding suffix_def prefix_def image_def - by (auto)(metis rev_append rev_rev_ident)+ - ultimately show "finite (Prefixes s)" by simp -qed - -lemma LV_STAR_finite: - assumes "\s. finite (LV r s)" - shows "finite (LV (STAR r) s)" -proof(induct s rule: length_induct) - fix s::"char list" - assume "\s'. length s' < length s \ finite (LV (STAR r) s')" - then have IH: "\s' \ SSuffixes s. finite (LV (STAR r) s')" - by (force simp add: strict_suffix_def suffix_def) - define f where "f \ \(v, vs). Stars (v # vs)" - define S1 where "S1 \ \s' \ Prefixes s. LV r s'" - define S2 where "S2 \ \s2 \ SSuffixes s. Stars -` (LV (STAR r) s2)" - have "finite S1" using assms - unfolding S1_def by (simp_all add: finite_Prefixes) - moreover - with IH have "finite S2" unfolding S2_def - by (auto simp add: finite_SSuffixes inj_on_def finite_vimageI) - ultimately - have "finite ({Stars []} \ f ` (S1 \ S2))" by simp - moreover - have "LV (STAR r) s \ {Stars []} \ f ` (S1 \ S2)" - unfolding S1_def S2_def f_def - unfolding LV_def image_def prefix_def strict_suffix_def - apply(auto) - apply(case_tac x) - apply(auto elim: Prf_elims) - apply(erule Prf_elims) - apply(auto) - apply(case_tac vs) - apply(auto intro: Prf.intros) - apply(rule exI) - apply(rule conjI) - apply(rule_tac x="flat a" in exI) - apply(rule conjI) - apply(rule_tac x="flats list" in exI) - apply(simp) - apply(blast) - apply(simp add: suffix_def) - using Prf.intros(6) by blast - ultimately - show "finite (LV (STAR r) s)" by (simp add: finite_subset) -qed - - -lemma LV_finite: - shows "finite (LV r s)" -proof(induct r arbitrary: s) - case (ZERO s) - show "finite (LV ZERO s)" by (simp add: LV_simps) -next - case (ONE s) - show "finite (LV ONE s)" by (simp add: LV_simps) -next - case (CH c s) - show "finite (LV (CH c) s)" by (simp add: LV_simps) -next - case (ALT r1 r2 s) - then show "finite (LV (ALT r1 r2) s)" by (simp add: LV_simps) -next - case (SEQ r1 r2 s) - define f where "f \ \(v1, v2). Seq v1 v2" - define S1 where "S1 \ \s' \ Prefixes s. LV r1 s'" - define S2 where "S2 \ \s' \ Suffixes s. LV r2 s'" - have IHs: "\s. finite (LV r1 s)" "\s. finite (LV r2 s)" by fact+ - then have "finite S1" "finite S2" unfolding S1_def S2_def - by (simp_all add: finite_Prefixes finite_Suffixes) - moreover - have "LV (SEQ r1 r2) s \ f ` (S1 \ S2)" - unfolding f_def S1_def S2_def - unfolding LV_def image_def prefix_def suffix_def - apply (auto elim!: Prf_elims) - by (metis (mono_tags, lifting) mem_Collect_eq) - ultimately - show "finite (LV (SEQ r1 r2) s)" - by (simp add: finite_subset) -next - case (STAR r s) - then show "finite (LV (STAR r) s)" by (simp add: LV_STAR_finite) -qed - - - -section \Our inductive POSIX Definition\ - -inductive - Posix :: "string \ rexp \ val \ bool" ("_ \ _ \ _" [100, 100, 100] 100) -where - Posix_ONE: "[] \ ONE \ Void" -| Posix_CH: "[c] \ (CH c) \ (Char c)" -| Posix_ALT1: "s \ r1 \ v \ s \ (ALT r1 r2) \ (Left v)" -| Posix_ALT2: "\s \ r2 \ v; s \ L(r1)\ \ s \ (ALT r1 r2) \ (Right v)" -| Posix_SEQ: "\s1 \ r1 \ v1; s2 \ r2 \ v2; - \(\s\<^sub>3 s\<^sub>4. s\<^sub>3 \ [] \ s\<^sub>3 @ s\<^sub>4 = s2 \ (s1 @ s\<^sub>3) \ L r1 \ s\<^sub>4 \ L r2)\ \ - (s1 @ s2) \ (SEQ r1 r2) \ (Seq v1 v2)" -| Posix_STAR1: "\s1 \ r \ v; s2 \ STAR r \ Stars vs; flat v \ []; - \(\s\<^sub>3 s\<^sub>4. s\<^sub>3 \ [] \ s\<^sub>3 @ s\<^sub>4 = s2 \ (s1 @ s\<^sub>3) \ L r \ s\<^sub>4 \ L (STAR r))\ - \ (s1 @ s2) \ STAR r \ Stars (v # vs)" -| Posix_STAR2: "[] \ STAR r \ Stars []" - -inductive_cases Posix_elims: - "s \ ZERO \ v" - "s \ ONE \ v" - "s \ CH c \ v" - "s \ ALT r1 r2 \ v" - "s \ SEQ r1 r2 \ v" - "s \ STAR r \ v" - -lemma Posix1: - assumes "s \ r \ v" - shows "s \ L r" "flat v = s" -using assms - by(induct s r v rule: Posix.induct) - (auto simp add: Sequ_def) - -text \ - For a give value and string, our Posix definition - determines a unique value. -\ - -lemma Posix_determ: - assumes "s \ r \ v1" "s \ r \ v2" - shows "v1 = v2" -using assms -proof (induct s r v1 arbitrary: v2 rule: Posix.induct) - case (Posix_ONE v2) - have "[] \ ONE \ v2" by fact - then show "Void = v2" by cases auto -next - case (Posix_CH c v2) - have "[c] \ CH c \ v2" by fact - then show "Char c = v2" by cases auto -next - case (Posix_ALT1 s r1 v r2 v2) - have "s \ ALT r1 r2 \ v2" by fact - moreover - have "s \ r1 \ v" by fact - then have "s \ L r1" by (simp add: Posix1) - ultimately obtain v' where eq: "v2 = Left v'" "s \ r1 \ v'" by cases auto - moreover - have IH: "\v2. s \ r1 \ v2 \ v = v2" by fact - ultimately have "v = v'" by simp - then show "Left v = v2" using eq by simp -next - case (Posix_ALT2 s r2 v r1 v2) - have "s \ ALT r1 r2 \ v2" by fact - moreover - have "s \ L r1" by fact - ultimately obtain v' where eq: "v2 = Right v'" "s \ r2 \ v'" - by cases (auto simp add: Posix1) - moreover - have IH: "\v2. s \ r2 \ v2 \ v = v2" by fact - ultimately have "v = v'" by simp - then show "Right v = v2" using eq by simp -next - case (Posix_SEQ s1 r1 v1 s2 r2 v2 v') - have "(s1 @ s2) \ SEQ r1 r2 \ v'" - "s1 \ r1 \ v1" "s2 \ r2 \ v2" - "\ (\s\<^sub>3 s\<^sub>4. s\<^sub>3 \ [] \ s\<^sub>3 @ s\<^sub>4 = s2 \ s1 @ s\<^sub>3 \ L r1 \ s\<^sub>4 \ L r2)" by fact+ - then obtain v1' v2' where "v' = Seq v1' v2'" "s1 \ r1 \ v1'" "s2 \ r2 \ v2'" - apply(cases) apply (auto simp add: append_eq_append_conv2) - using Posix1(1) by fastforce+ - moreover - have IHs: "\v1'. s1 \ r1 \ v1' \ v1 = v1'" - "\v2'. s2 \ r2 \ v2' \ v2 = v2'" by fact+ - ultimately show "Seq v1 v2 = v'" by simp -next - case (Posix_STAR1 s1 r v s2 vs v2) - have "(s1 @ s2) \ STAR r \ v2" - "s1 \ r \ v" "s2 \ STAR r \ Stars vs" "flat v \ []" - "\ (\s\<^sub>3 s\<^sub>4. s\<^sub>3 \ [] \ s\<^sub>3 @ s\<^sub>4 = s2 \ s1 @ s\<^sub>3 \ L r \ s\<^sub>4 \ L (STAR r))" by fact+ - then obtain v' vs' where "v2 = Stars (v' # vs')" "s1 \ r \ v'" "s2 \ (STAR r) \ (Stars vs')" - apply(cases) apply (auto simp add: append_eq_append_conv2) - using Posix1(1) apply fastforce - apply (metis Posix1(1) Posix_STAR1.hyps(6) append_Nil append_Nil2) - using Posix1(2) by blast - moreover - have IHs: "\v2. s1 \ r \ v2 \ v = v2" - "\v2. s2 \ STAR r \ v2 \ Stars vs = v2" by fact+ - ultimately show "Stars (v # vs) = v2" by auto -next - case (Posix_STAR2 r v2) - have "[] \ STAR r \ v2" by fact - then show "Stars [] = v2" by cases (auto simp add: Posix1) -qed - - -text \ - Our POSIX values are lexical values. -\ - -lemma Posix_LV: - assumes "s \ r \ v" - shows "v \ LV r s" - using assms unfolding LV_def - apply(induct rule: Posix.induct) - apply(auto simp add: intro!: Prf.intros elim!: Prf_elims) - done - -lemma Posix_Prf: - assumes "s \ r \ v" - shows "\ v : r" - using assms Posix_LV LV_def - by simp - -end