Theories/Regular.thy
changeset 149 e122cb146ecc
equal deleted inserted replaced
148:3b7477db3462 149:e122cb146ecc
       
     1 theory Regular
       
     2 imports Main Folds
       
     3 begin
       
     4 
       
     5 section {* Preliminary definitions *}
       
     6 
       
     7 type_synonym lang = "string set"
       
     8 
       
     9 
       
    10 text {*  Sequential composition of two languages *}
       
    11 
       
    12 definition 
       
    13   Seq :: "lang \<Rightarrow> lang \<Rightarrow> lang" (infixr ";;" 100)
       
    14 where 
       
    15   "A ;; B = {s\<^isub>1 @ s\<^isub>2 | s\<^isub>1 s\<^isub>2. s\<^isub>1 \<in> A \<and> s\<^isub>2 \<in> B}"
       
    16 
       
    17 
       
    18 text {* Some properties of operator @{text ";;"}. *}
       
    19 
       
    20 lemma seq_add_left:
       
    21   assumes a: "A = B"
       
    22   shows "C ;; A = C ;; B"
       
    23 using a by simp
       
    24 
       
    25 lemma seq_union_distrib_right:
       
    26   shows "(A \<union> B) ;; C = (A ;; C) \<union> (B ;; C)"
       
    27 unfolding Seq_def by auto
       
    28 
       
    29 lemma seq_union_distrib_left:
       
    30   shows "C ;; (A \<union> B) = (C ;; A) \<union> (C ;; B)"
       
    31 unfolding Seq_def by  auto
       
    32 
       
    33 lemma seq_intro:
       
    34   assumes a: "x \<in> A" "y \<in> B"
       
    35   shows "x @ y \<in> A ;; B "
       
    36 using a by (auto simp: Seq_def)
       
    37 
       
    38 lemma seq_assoc:
       
    39   shows "(A ;; B) ;; C = A ;; (B ;; C)"
       
    40 unfolding Seq_def
       
    41 apply(auto)
       
    42 apply(blast)
       
    43 by (metis append_assoc)
       
    44 
       
    45 lemma seq_empty [simp]:
       
    46   shows "A ;; {[]} = A"
       
    47   and   "{[]} ;; A = A"
       
    48 by (simp_all add: Seq_def)
       
    49 
       
    50 lemma seq_null [simp]:
       
    51   shows "A ;; {} = {}"
       
    52   and   "{} ;; A = {}"
       
    53 by (simp_all add: Seq_def)
       
    54 
       
    55 
       
    56 text {* Power and Star of a language *}
       
    57 
       
    58 fun 
       
    59   pow :: "lang \<Rightarrow> nat \<Rightarrow> lang" (infixl "\<up>" 100)
       
    60 where
       
    61   "A \<up> 0 = {[]}"
       
    62 | "A \<up> (Suc n) =  A ;; (A \<up> n)" 
       
    63 
       
    64 definition
       
    65   Star :: "lang \<Rightarrow> lang" ("_\<star>" [101] 102)
       
    66 where
       
    67   "A\<star> \<equiv> (\<Union>n. A \<up> n)"
       
    68 
       
    69 
       
    70 lemma star_start[intro]:
       
    71   shows "[] \<in> A\<star>"
       
    72 proof -
       
    73   have "[] \<in> A \<up> 0" by auto
       
    74   then show "[] \<in> A\<star>" unfolding Star_def by blast
       
    75 qed
       
    76 
       
    77 lemma star_step [intro]:
       
    78   assumes a: "s1 \<in> A" 
       
    79   and     b: "s2 \<in> A\<star>"
       
    80   shows "s1 @ s2 \<in> A\<star>"
       
    81 proof -
       
    82   from b obtain n where "s2 \<in> A \<up> n" unfolding Star_def by auto
       
    83   then have "s1 @ s2 \<in> A \<up> (Suc n)" using a by (auto simp add: Seq_def)
       
    84   then show "s1 @ s2 \<in> A\<star>" unfolding Star_def by blast
       
    85 qed
       
    86 
       
    87 lemma star_induct[consumes 1, case_names start step]:
       
    88   assumes a: "x \<in> A\<star>" 
       
    89   and     b: "P []"
       
    90   and     c: "\<And>s1 s2. \<lbrakk>s1 \<in> A; s2 \<in> A\<star>; P s2\<rbrakk> \<Longrightarrow> P (s1 @ s2)"
       
    91   shows "P x"
       
    92 proof -
       
    93   from a obtain n where "x \<in> A \<up> n" unfolding Star_def by auto
       
    94   then show "P x"
       
    95     by (induct n arbitrary: x)
       
    96        (auto intro!: b c simp add: Seq_def Star_def)
       
    97 qed
       
    98     
       
    99 lemma star_intro1:
       
   100   assumes a: "x \<in> A\<star>"
       
   101   and     b: "y \<in> A\<star>"
       
   102   shows "x @ y \<in> A\<star>"
       
   103 using a b
       
   104 by (induct rule: star_induct) (auto)
       
   105 
       
   106 lemma star_intro2: 
       
   107   assumes a: "y \<in> A"
       
   108   shows "y \<in> A\<star>"
       
   109 proof -
       
   110   from a have "y @ [] \<in> A\<star>" by blast
       
   111   then show "y \<in> A\<star>" by simp
       
   112 qed
       
   113 
       
   114 lemma star_intro3:
       
   115   assumes a: "x \<in> A\<star>"
       
   116   and     b: "y \<in> A"
       
   117   shows "x @ y \<in> A\<star>"
       
   118 using a b by (blast intro: star_intro1 star_intro2)
       
   119 
       
   120 lemma star_cases:
       
   121   shows "A\<star> =  {[]} \<union> A ;; A\<star>"
       
   122 proof
       
   123   { fix x
       
   124     have "x \<in> A\<star> \<Longrightarrow> x \<in> {[]} \<union> A ;; A\<star>"
       
   125       unfolding Seq_def
       
   126     by (induct rule: star_induct) (auto)
       
   127   }
       
   128   then show "A\<star> \<subseteq> {[]} \<union> A ;; A\<star>" by auto
       
   129 next
       
   130   show "{[]} \<union> A ;; A\<star> \<subseteq> A\<star>"
       
   131     unfolding Seq_def by auto
       
   132 qed
       
   133 
       
   134 lemma star_decom: 
       
   135   assumes a: "x \<in> A\<star>" "x \<noteq> []"
       
   136   shows "\<exists>a b. x = a @ b \<and> a \<noteq> [] \<and> a \<in> A \<and> b \<in> A\<star>"
       
   137 using a
       
   138 by (induct rule: star_induct) (blast)+
       
   139 
       
   140 lemma
       
   141   shows seq_Union_left:  "B ;; (\<Union>n. A \<up> n) = (\<Union>n. B ;; (A \<up> n))"
       
   142   and   seq_Union_right: "(\<Union>n. A \<up> n) ;; B = (\<Union>n. (A \<up> n) ;; B)"
       
   143 unfolding Seq_def by auto
       
   144 
       
   145 lemma seq_pow_comm:
       
   146   shows "A ;; (A \<up> n) = (A \<up> n) ;; A"
       
   147 by (induct n) (simp_all add: seq_assoc[symmetric])
       
   148 
       
   149 lemma seq_star_comm:
       
   150   shows "A ;; A\<star> = A\<star> ;; A"
       
   151 unfolding Star_def seq_Union_left
       
   152 unfolding seq_pow_comm seq_Union_right 
       
   153 by simp
       
   154 
       
   155 
       
   156 text {* Two lemmas about the length of strings in @{text "A \<up> n"} *}
       
   157 
       
   158 lemma pow_length:
       
   159   assumes a: "[] \<notin> A"
       
   160   and     b: "s \<in> A \<up> Suc n"
       
   161   shows "n < length s"
       
   162 using b
       
   163 proof (induct n arbitrary: s)
       
   164   case 0
       
   165   have "s \<in> A \<up> Suc 0" by fact
       
   166   with a have "s \<noteq> []" by auto
       
   167   then show "0 < length s" by auto
       
   168 next
       
   169   case (Suc n)
       
   170   have ih: "\<And>s. s \<in> A \<up> Suc n \<Longrightarrow> n < length s" by fact
       
   171   have "s \<in> A \<up> Suc (Suc n)" by fact
       
   172   then obtain s1 s2 where eq: "s = s1 @ s2" and *: "s1 \<in> A" and **: "s2 \<in> A \<up> Suc n"
       
   173     by (auto simp add: Seq_def)
       
   174   from ih ** have "n < length s2" by simp
       
   175   moreover have "0 < length s1" using * a by auto
       
   176   ultimately show "Suc n < length s" unfolding eq 
       
   177     by (simp only: length_append)
       
   178 qed
       
   179 
       
   180 lemma seq_pow_length:
       
   181   assumes a: "[] \<notin> A"
       
   182   and     b: "s \<in> B ;; (A \<up> Suc n)"
       
   183   shows "n < length s"
       
   184 proof -
       
   185   from b obtain s1 s2 where eq: "s = s1 @ s2" and *: "s2 \<in> A \<up> Suc n"
       
   186     unfolding Seq_def by auto
       
   187   from * have " n < length s2" by (rule pow_length[OF a])
       
   188   then show "n < length s" using eq by simp
       
   189 qed
       
   190 
       
   191 
       
   192 section {* A modified version of Arden's lemma *}
       
   193 
       
   194 text {*  A helper lemma for Arden *}
       
   195 
       
   196 lemma arden_helper:
       
   197   assumes eq: "X = X ;; A \<union> B"
       
   198   shows "X = X ;; (A \<up> Suc n) \<union> (\<Union>m\<in>{0..n}. B ;; (A \<up> m))"
       
   199 proof (induct n)
       
   200   case 0 
       
   201   show "X = X ;; (A \<up> Suc 0) \<union> (\<Union>(m::nat)\<in>{0..0}. B ;; (A \<up> m))"
       
   202     using eq by simp
       
   203 next
       
   204   case (Suc n)
       
   205   have ih: "X = X ;; (A \<up> Suc n) \<union> (\<Union>m\<in>{0..n}. B ;; (A \<up> m))" by fact
       
   206   also have "\<dots> = (X ;; A \<union> B) ;; (A \<up> Suc n) \<union> (\<Union>m\<in>{0..n}. B ;; (A \<up> m))" using eq by simp
       
   207   also have "\<dots> = X ;; (A \<up> Suc (Suc n)) \<union> (B ;; (A \<up> Suc n)) \<union> (\<Union>m\<in>{0..n}. B ;; (A \<up> m))"
       
   208     by (simp add: seq_union_distrib_right seq_assoc)
       
   209   also have "\<dots> = X ;; (A \<up> Suc (Suc n)) \<union> (\<Union>m\<in>{0..Suc n}. B ;; (A \<up> m))"
       
   210     by (auto simp add: le_Suc_eq)
       
   211   finally show "X = X ;; (A \<up> Suc (Suc n)) \<union> (\<Union>m\<in>{0..Suc n}. B ;; (A \<up> m))" .
       
   212 qed
       
   213 
       
   214 theorem arden:
       
   215   assumes nemp: "[] \<notin> A"
       
   216   shows "X = X ;; A \<union> B \<longleftrightarrow> X = B ;; A\<star>"
       
   217 proof
       
   218   assume eq: "X = B ;; A\<star>"
       
   219   have "A\<star> = {[]} \<union> A\<star> ;; A" 
       
   220     unfolding seq_star_comm[symmetric]
       
   221     by (rule star_cases)
       
   222   then have "B ;; A\<star> = B ;; ({[]} \<union> A\<star> ;; A)"
       
   223     by (rule seq_add_left)
       
   224   also have "\<dots> = B \<union> B ;; (A\<star> ;; A)"
       
   225     unfolding seq_union_distrib_left by simp
       
   226   also have "\<dots> = B \<union> (B ;; A\<star>) ;; A" 
       
   227     by (simp only: seq_assoc)
       
   228   finally show "X = X ;; A \<union> B" 
       
   229     using eq by blast 
       
   230 next
       
   231   assume eq: "X = X ;; A \<union> B"
       
   232   { fix n::nat
       
   233     have "B ;; (A \<up> n) \<subseteq> X" using arden_helper[OF eq, of "n"] by auto }
       
   234   then have "B ;; A\<star> \<subseteq> X" 
       
   235     unfolding Seq_def Star_def UNION_def by auto
       
   236   moreover
       
   237   { fix s::string
       
   238     obtain k where "k = length s" by auto
       
   239     then have not_in: "s \<notin> X ;; (A \<up> Suc k)" 
       
   240       using seq_pow_length[OF nemp] by blast
       
   241     assume "s \<in> X"
       
   242     then have "s \<in> X ;; (A \<up> Suc k) \<union> (\<Union>m\<in>{0..k}. B ;; (A \<up> m))"
       
   243       using arden_helper[OF eq, of "k"] by auto
       
   244     then have "s \<in> (\<Union>m\<in>{0..k}. B ;; (A \<up> m))" using not_in by auto
       
   245     moreover
       
   246     have "(\<Union>m\<in>{0..k}. B ;; (A \<up> m)) \<subseteq> (\<Union>n. B ;; (A \<up> n))" by auto
       
   247     ultimately 
       
   248     have "s \<in> B ;; A\<star>" 
       
   249       unfolding seq_Union_left Star_def by auto }
       
   250   then have "X \<subseteq> B ;; A\<star>" by auto
       
   251   ultimately 
       
   252   show "X = B ;; A\<star>" by simp
       
   253 qed
       
   254 
       
   255 
       
   256 section {* Regular Expressions *}
       
   257 
       
   258 datatype rexp =
       
   259   NULL
       
   260 | EMPTY
       
   261 | CHAR char
       
   262 | SEQ rexp rexp
       
   263 | ALT rexp rexp
       
   264 | STAR rexp
       
   265 
       
   266 
       
   267 text {* 
       
   268   The function @{text L} is overloaded, with the idea that @{text "L x"} 
       
   269   evaluates to the language represented by the object @{text x}.
       
   270 *}
       
   271 
       
   272 consts L:: "'a \<Rightarrow> lang"
       
   273 
       
   274 overloading L_rexp \<equiv> "L::  rexp \<Rightarrow> lang"
       
   275 begin
       
   276 fun
       
   277   L_rexp :: "rexp \<Rightarrow> lang"
       
   278 where
       
   279     "L_rexp (NULL) = {}"
       
   280   | "L_rexp (EMPTY) = {[]}"
       
   281   | "L_rexp (CHAR c) = {[c]}"
       
   282   | "L_rexp (SEQ r1 r2) = (L_rexp r1) ;; (L_rexp r2)"
       
   283   | "L_rexp (ALT r1 r2) = (L_rexp r1) \<union> (L_rexp r2)"
       
   284   | "L_rexp (STAR r) = (L_rexp r)\<star>"
       
   285 end
       
   286 
       
   287 
       
   288 text {* ALT-combination for a set of regular expressions *}
       
   289 
       
   290 abbreviation
       
   291   Setalt  ("\<Uplus>_" [1000] 999) 
       
   292 where
       
   293   "\<Uplus>A \<equiv> folds ALT NULL A"
       
   294 
       
   295 text {* 
       
   296   For finite sets, @{term Setalt} is preserved under @{term L}.
       
   297 *}
       
   298 
       
   299 lemma folds_alt_simp [simp]:
       
   300   fixes rs::"rexp set"
       
   301   assumes a: "finite rs"
       
   302   shows "L (\<Uplus>rs) = \<Union> (L ` rs)"
       
   303 unfolding folds_def
       
   304 apply(rule set_eqI)
       
   305 apply(rule someI2_ex)
       
   306 apply(rule_tac finite_imp_fold_graph[OF a])
       
   307 apply(erule fold_graph.induct)
       
   308 apply(auto)
       
   309 done
       
   310 
       
   311 end