theory a2 (* Download the file RegExp.thy and put it in the same directory as this one: *) imports RegExp begin section "Question 1: Higher-Order Logic" lemma hol_a: "\(\x. P x) \ (\x. \P x)" (*TODO*) oops lemma hol_b: "(\x. P \ Q x) \ (P \ (\x. Q x))" (*TODO*) oops lemma hol_c: "\x. \f x \ f (g x) \ \x. f x \ f (g x)" (*TODO*) oops lemma hol_d: "\\x. \f x \ f (g x); \x. f x\ \ \x. f x \ f (g (g x))" (*TODO*) oops lemma hol_e: "(\x. Q x = P x) \ ((\x. P x) \ H) \ (\x. Q x) \ H" (*TODO*) oops lemma hol_f: "(\Q. (\x. P x \ Q) \ Q) \ (\x. P x)" (*TODO*) oops (*---------------------------------------------------------*) section "Question 2: Strings and Regular Expressions" (* An example string with newline characters *) definition test_str :: string where "test_str = ''some test abc hello text''" definition new_line :: char where "new_line = CHR ''\''" (*----------------*) (* Question 2 (a) *) primrec glue :: "'a \ 'a list list \ 'a list" where "glue a [] = TODO" (* test on some examples *) (* Define and test on some examples: chop :: "'a \ 'a list \ 'a list list" *) (*----------------*) (* Question 2 (b) *) primrec num_of :: "'a \ 'a list \ nat" where "num_of a [] = TODO" lemma length_glue: "length (glue a xss) = sum_list (map length xss) + length xss - 1" (*TODO*) oops lemma length_chop: "length (chop x xs) = num_of x xs + 1" (*TODO*) oops (*----------------*) (* Question 2 (c) *) lemma chop_sep: "ls \ set (chop a xs) \ a \ set ls" (*TODO*) oops lemma glue_chop: "glue a (chop a xs) = xs" (*TODO*) oops (*----------------*) (* Question 2 (d) *) (* TODO: define any_of :: "regexp list \ regexp" *) lemma lang_any_of[simp]: "lang (any_of rs) = \ (lang ` set rs)" (* TODO *) oops primrec repeat :: "word set \ nat \ word set" where "repeat A 0 = TODO" lemma star_repeat: "star A = (\n. repeat A n)" (* TODO *) oops (*----------------*) (* Question 2 (e) *) definition matches :: "regexp \ string \ bool" where "matches r w \ w \ lang r" definition matches_sub :: "regexp \ string \ bool" where "matches_sub r = matches TODO" primrec string :: "string \ regexp" where "string [] = TODO" primrec is_prefix :: "'a list \ 'a list \ bool" where "is_prefix [] ys = TODO" primrec is_substring :: "'a list \ 'a list \ bool" where "is_substring xs [] = TODO" (* TODO: test on some examples *) lemma matches_sub: "matches_sub r xs = (\xs' ys zs. xs = ys @ xs' @ zs \ matches r xs')" (* TODO *) oops lemma matches_string[simp]: "matches (string xs) ys = (ys = xs)" (* TODO *) oops lemma is_substring: "is_substring xs ys = (\bs cs. ys = bs @ xs @ cs)" (* TODO *) oops lemma matches_substring: "matches_sub (string xs) l = is_substring xs l" (* TODO *) oops (*----------------*) (* Question 2 (f) *) primrec rlen :: "regexp \ nat option" where "rlen (Atom a) = TODO" lemma rlen_string[simp]: "rlen (string xs) = Some (length xs)" (* TODO *) oops lemma rlen_lang: "rlen r = Some n \ \xs \ lang r. length xs = n" (* TODO *) oops (*---------------------------------------------------------*) section "Question 3: Normal Forms" (*----------------*) (* Question 3 (a) *) fun find_pat :: "'a list \ 'a list" where (* TODO *) value "find_pat ''cababc''" lemma hd_find_pat[simp]: "hd (find_pat xs) = hd xs" (* TODO *) oops lemma last_find_pat[simp]: "last (find_pat xs) = last xs" (* TODO *) oops lemma find_pat_neq: "(find_pat xs \ xs) = (\as bs x y. xs = as @ x # y # x # bs)" (* TODO *) oops lemma find_pat_eq: "(find_pat xs = xs) = (\as bs x y. xs \ as @ x # y # x # bs)" by (metis find_pat_neq) (*----------------*) (* Question 3 (b) *) lemma find_pat_neq_Cons: "find_pat xs \ xs \ find_pat (x#xs) \ x#xs" oops (* helper *) lemma find_pat_eq_Cons: "find_pat (x#xs) = x#xs \ find_pat xs = xs" oops (* helper *) lemma find_pat_Cons_find_pat: "find_pat (x#find_pat xs) = find_pat (find_pat (x#xs))" (* TODO *) oops lemma find_pat_app_find_pat: "find_pat (find_pat xs @ [x]) = find_pat (find_pat (xs @ [x]))" (* TODO *) oops lemma find_pat_appendD: "find_pat (xs @ ys) = xs @ ys \ find_pat xs = xs" oops (* helper *) lemma find_pat_eq_rev: "find_pat xs = xs \ find_pat (rev xs) = rev xs" (* TODO *) oops lemma find_pat_rev: "find_pat xs = xs \ find_pat (rev xs @ [x]) = rev (find_pat (x # xs))" (* TODO *) oops (*----------------*) (* Question 3 (c) *) fun nf :: "'a list \ 'a list" where "nf xs = (if find_pat xs = xs then xs else nf (find_pat xs))" (* Extract a lemma that helps Isabelle to prove termination here. Make it [simp]. *) sorry (* This means simp will not automatically unfold nf. Use "subst nf.simps" to unfold manually. *) declare nf.simps[simp del] value "nf ''cabacacb''" lemma nf_singles[simp]: "nf [] = []" "nf [x] = [x]" "nf [x,y] = [x,y]" by (auto simp: nf.simps) lemma nf_find_pat: "nf (find_pat xs) = nf xs" (* TODO *) oops lemma nf_fp: "find_pat (nf xs) = nf xs" (* TODO *) oops lemma nf_nf: "nf (nf xs) = nf xs" (* TODO *) oops lemma hd_nf: "hd (nf xs) = hd xs" (* TODO *) oops lemma last_nf: "last (nf xs) = last xs" (* TODO *) oops (*----------------*) (* Question 3 (d) *) lemma find_pat_nf_Cons: "find_pat xs = xs \ nf (x#xs) = find_pat (x#xs)" oops (* helper *) lemma nf_find_pat_Cons: "find_pat xs \ xs \ nf (x # find_pat xs) = nf (x # xs)" oops (* helper *) lemma nf_Cons_nf: "nf (x#nf xs) = nf (x#xs)" (* TODO *) oops lemma nf_hd_dist: "nf (x#xs) = find_pat (x#nf xs)" (* TODO *) oops lemma nf_last_dist: "nf (xs @ [x]) = find_pat (nf xs @ [x])" (* TODO *) oops lemma find_pat_rev_Cons: "rev (find_pat (x#nf xs)) = find_pat (rev (x#nf xs))" oops (* helper *) lemma nf_rev: "nf (rev xs) = rev (nf xs)" (* TODO *) oops end