theory RegExp imports Main begin (* --------------------------------------------- *) (* Defining the data type of regular expressions *) datatype regexp = Atom char | Alt regexp regexp | Conc regexp regexp (infixl "\" 60) | Star regexp | Neg regexp (* Some expressions: *) term "Neg (Atom a \ Atom b)" term "Star (Neg (Atom (CHR ''a''))) \ Atom (CHR ''b'')" (* Match everything: *) definition "Univ = Alt (Neg undefined) undefined" (* Match nothing: *) definition "null = Neg Univ" (* Match only the empty string: *) definition "epsilon = Star null" (* --------------------------------------------- *) (* Defining the language of a regular expression *) type_synonym word = "char list" inductive_set star for L where star_empty[simp,intro!]: "[] \ star L" | star_app[elim]: "\ u \ L; v \ star L \ \ u@v \ star L" definition conc :: "word set \ word set \ word set" where "conc A B \ { xs@ys |xs ys. xs \ A \ ys \ B}" primrec lang :: "regexp \ word set" where "lang (Atom c) = {[c]}" | "lang (Alt e1 e2) = lang e1 \ lang e2" | "lang (Conc e1 e2) = conc (lang e1) (lang e2)" | "lang (Star e) = star (lang e)" | "lang (Neg e) = -lang e" lemma lang_all[simp]: "lang Univ = UNIV" by (simp add: Univ_def) lemma lang_null[simp]: "lang null = {}" by (simp add: null_def) lemma star_empty[simp]: "star {} = {[]}" by (auto elim: star.induct) lemma lang_epsilon[simp]: "lang epsilon = {[]}" by (simp add: epsilon_def) lemma Alt_null: "lang (Alt x null) = lang x" by simp (*-----------------------------------------------------*) (* Defining the reverse of a regular expression *) primrec rrev :: "regexp \ regexp" where "rrev (Atom c) = Atom c" | "rrev (Alt e1 e2) = Alt (rrev e1) (rrev e2)" | "rrev (Conc e1 e2) = Conc (rrev e2) (rrev e1)" | "rrev (Star e) = Star (rrev e)" | "rrev (Neg e) = Neg (rrev e)" (*-----------------------------------------------------*) (* Correctness proof *) lemma star_one[intro]: "xs \ L \ xs \ star L" by (drule star_app[where v="[]"]; simp) lemma star_app2[elim]: "\ xs \ star L; ys \ L \ \ xs @ ys \ star L" by (erule star.induct) auto lemma star_rev1: "xs \ star (rev ` L) \ xs \ rev ` star L" apply (induct rule: star.induct; clarsimp) apply (rename_tac xs ys) apply (rule_tac x="ys@xs" in image_eqI, simp) apply fastforce done lemma star_rev2: "xs \ star L \ rev xs \ star (rev ` L)" by (induct rule: star.induct) auto lemma star_rev[simp]: "star (rev ` L) = rev ` star L" by (auto simp: star_rev1 star_rev2) lemma conc_rev[simp]: "conc (rev ` L2) (rev ` L1) = rev ` conc L1 L2" apply (simp add: conc_def) apply (rule equalityI) apply clarsimp apply (rename_tac xs ys) apply (rule_tac x="ys@xs" in image_eqI, auto)[1] apply fastforce done lemma neg_rev[simp]: "- rev ` L = rev ` (-L)" apply (rule bij_image_Compl_eq[symmetric]) apply (rule bijI, simp) apply (rule_tac f=rev in surjI) apply simp done lemma "lang (rrev e) = rev ` (lang e)" by (induct e; fastforce) end