theory BlahSep imports Word begin text {* Trivial setup for a typed heap and separating conjunction *} definition map_disj :: "('a \ 'b) \ ('a \ 'b) \ bool" (infix "\" 51) where "h\<^isub>0 \ h\<^isub>1 \ dom h\<^isub>0 \ dom h\<^isub>1 = {}" types heap_assert = "(32 word \ 8 word) \ bool" constdefs sep_true :: "heap_assert" "sep_true \ \s. True" constdefs sep_false :: "heap_assert" "sep_false \ \s. False" constdefs sep_empty :: "heap_assert" ("\") "\ \ \h. h = empty" constdefs sep_conj :: "heap_assert \ heap_assert \ heap_assert" (infixr "\\<^sup>*" 35) "P \\<^sup>* Q \ \h. \h\<^isub>0 h\<^isub>1. h\<^isub>0 \ h\<^isub>1 \ h = h\<^isub>0 ++ h\<^isub>1 \ P h\<^isub>0 \ Q h\<^isub>1" lemma sep_conjI: "\ P h\<^isub>0 ; Q h\<^isub>1 ; h\<^isub>0 \ h\<^isub>1 ; h = h\<^isub>0 ++ h\<^isub>1 \ \ (P \\<^sup>* Q) h" by (simp add: sep_conj_def, blast) lemma sep_conjD: "(P \\<^sup>* Q) h \ \h\<^isub>0 h\<^isub>1. h\<^isub>0 \ h\<^isub>1 \ h = h\<^isub>0 ++ h\<^isub>1 \ P h\<^isub>0 \ Q h\<^isub>1" by (simp add: sep_conj_def) lemma sep_true[simp]: "sep_true s" by (simp add: sep_true_def) lemma sep_false[simp]: "\sep_false x" by (simp add: sep_false_def) text {* First example: used to be able to use intro: ext without the exclamation *} lemma sep_conj_false_right: "(P \\<^sup>* sep_false) = sep_false" by (force dest: sep_conjD intro!: ext) (* NOTE: (auto dest: sep_conjD intro!: ext) also works, but needed the exclamation in the past, so that hasn't changed, only force has *) text {* Second example: didn't need any exclamation marks *} lemma sep_conj_exists2: "(P \\<^sup>* (\s. \x. Q x s)) = (\s. (\x. (P \\<^sup>* Q x) s))" by (force intro!: sep_conjI ext dest!: sep_conjD) (* NOTE: same as above, auto can be used, but needs exclamations and also did in the past, probably why we used force here *) text {* Third example: fact chaining and extra "-" *} consts delete :: "'a \ 'a list \ 'a list" lemma sep_conj_foldl_extract: assumes fold: "foldl op \\<^sup>* \ Ps s" assumes inP: "P \ set Ps" shows "(P \\<^sup>* sep_true) s" proof - let ?rest = "foldl op \\<^sup>* \ (delete P Ps)" have notnil: "Ps \ []" using inP by auto have rewrite: "(foldl op \\<^sup>* \ Ps) = (P \\<^sup>* ?rest)" using notnil inP proof (induct Ps arbitrary: P) case Nil thus ?case by simp next case (Cons x xs) hence IH: "\ xs \ [] ; P \ set xs \ \ (foldl op \\<^sup>* \ xs) = (P \\<^sup>* foldl op \\<^sup>* \ (delete P xs))" and in': "P \ set (x # xs)" (* These work, and work in slightly-pre-2009: by - assumption by - simp by - blast by auto *) (* And these do not work, but used to: by simp by blast *) (* However, in the old version I'm getting "Legacy feature! Implicit use of prems in assumption proof", so I guess there's my answer. Not sure what's the proper way to write these now. *) by - assumption oops