diff --git a/lib/Corres_UL.thy b/lib/Corres_UL.thy index 93804f156c..5054ec5a40 100644 --- a/lib/Corres_UL.thy +++ b/lib/Corres_UL.thy @@ -481,6 +481,18 @@ lemma corres_if3: (if G then a else b) (if G' then c else d)" by simp +lemma corres_if_strong: + "\\s s'. \(s, s') \ sr; R s; R' s'\ \ G = G'; + \G; G'\ \ corres_underlying sr nf nf' r P P' a c; + \\ G; \ G'\ \ corres_underlying sr nf nf' r Q Q' b d \ + \ corres_underlying sr nf nf' r + (R and (if G then P else Q)) (R' and (if G' then P' else Q')) + (if G then a else b) (if G' then c else d)" + by (fastforce simp: corres_underlying_def) + +lemmas corres_if_strong' = + corres_if_strong[where R=R and P=R and Q=R for R, + where R'=R' and P'=R' and Q'=R' for R', simplified] text \Some equivalences about liftM and other useful simps\ @@ -740,6 +752,11 @@ lemma corres_assert_assume: by (auto simp: bind_def assert_def fail_def return_def corres_underlying_def) +lemma corres_assert_assume_l: + "corres_underlying sr nf nf' rrel P Q (f ()) g + \ corres_underlying sr nf nf' rrel (P and (\s. P')) Q (assert P' >>= f) g" + by (force simp: corres_underlying_def assert_def return_def bind_def fail_def) + lemma corres_assert_gen_asm_cross: "\ \s s'. \(s, s') \ sr; P' s; Q' s'\ \ A; A \ corres_underlying sr nf nf' r P Q f (g ()) \ diff --git a/lib/ExtraCorres.thy b/lib/ExtraCorres.thy index b92de195f0..0054e44ace 100644 --- a/lib/ExtraCorres.thy +++ b/lib/ExtraCorres.thy @@ -5,7 +5,7 @@ *) theory ExtraCorres -imports Corres_UL +imports Corres_UL DetWPLib begin (* FIXME: the S in this rule is mainly to make the induction work, we don't actually need it in @@ -181,12 +181,17 @@ qed text \Some results concerning the interaction of abstract and concrete states\ +definition ex_abs_underlying :: "('a \ 'b) set \ ('a \ bool) \ 'b \ bool" where + "ex_abs_underlying sr P s' \ \s. (s,s') \ sr \ P s" + +lemma ex_absI[intro!]: + "(s, s') \ sr \ P s \ ex_abs_underlying sr P s'" + by (auto simp add: ex_abs_underlying_def) + lemma corres_u_nofail: - "corres_underlying S nf True r P P' f g \ (nf \ no_fail P f) \ - no_fail (\s'. \s. (s,s') \ S \ P s \ P' s') g" - apply (clarsimp simp add: corres_underlying_def no_fail_def) - apply fastforce - done + "\corres_underlying S nf True r P P' f g; nf \ no_fail P f\ + \ no_fail (P' and ex_abs_underlying S P) g" + by (fastforce simp: corres_underlying_def ex_abs_underlying_def no_fail_def) lemma wp_from_corres_u: "\ corres_underlying R nf nf' r G G' f f'; \P\ f \Q\; \P'\ f' \Q'\; nf \ no_fail P f \ \ @@ -204,7 +209,7 @@ lemma wp_from_corres_u_unit: lemma corres_nofail: "corres_underlying state_relation nf True r P P' f g \ (nf \ no_fail P f) \ no_fail (\s'. \s. (s,s') \ state_relation \ P s \ P' s') g" - by (rule corres_u_nofail) + by (fastforce intro: no_fail_pre corres_u_nofail simp: ex_abs_underlying_def) lemma wp_from_corres_unit: "\ corres_underlying state_relation nf nf' r G G' f f'; @@ -213,13 +218,6 @@ lemma wp_from_corres_unit: f' \\_ s'. \s. (s,s') \ state_relation \ Q s \ Q' s'\" by (auto intro!: wp_from_corres_u_unit) -definition ex_abs_underlying :: "('a \ 'b) set \ ('a \ bool) \ 'b \ bool" where - "ex_abs_underlying sr P s' \ \s. (s,s') \ sr \ P s" - -lemma ex_absI[intro!]: - "(s, s') \ sr \ P s \ ex_abs_underlying sr P s'" - by (auto simp add: ex_abs_underlying_def) - lemma corres_underlying_split_ex_abs: assumes ac: "corres_underlying srel nf nf' r' G G' a c" assumes bd: "\rv rv'. r' rv rv' \ @@ -251,6 +249,100 @@ lemma hoare_from_abs_inv: using assms by (fastforce intro: hoare_from_abs[where R=\ and S=\ and R'=\ and Q="\_. P" , simplified]) +lemma corres_from_valid: + assumes nf': "nf' \ no_fail (P' and ex_abs_underlying srel P) f'" + assumes + "\s. \\s'. P s \ P' s' \ (s, s') \ srel\ + f' \\rv' t'. \(rv, t) \ fst (f s). (t, t') \ srel \ rrel rv rv'\" + shows "corres_underlying srel nf nf' rrel P P' f f'" + using assms + by (fastforce simp: corres_underlying_def valid_def no_fail_def) + +lemma corres_from_valid_det: + assumes det: "det_wp P f" + assumes nf': "nf' \ no_fail (P' and ex_abs_underlying srel P) f'" + assumes valid: + "\s rv t. + \fst (f s) = {(rv, t)}; P s\ + \ \\s'. P' s' \ (s, s') \ srel\ f' \\rv' t'. (t, t') \ srel \ rrel rv rv'\" + shows "corres_underlying srel nf nf' rrel P P' f f'" + apply (clarsimp simp: corres_underlying_def) + apply (intro conjI) + apply (insert det) + apply (clarsimp simp: det_wp_def) + apply (force dest: use_valid[OF _ valid]) + apply (fastforce dest: nf' simp: no_fail_def ex_abs_underlying_def) + done + +lemma corres_noop_ex_abs: + assumes P: "\s. P s \ \\s'. (s, s') \ sr \ P' s'\ f \\rv s'. (s, s') \ sr \ r x rv\" + assumes nf': "nf' \ no_fail (P' and ex_abs_underlying sr P) f" + shows "corres_underlying sr nf nf' r P P' (return x) f" + apply (simp add: corres_underlying_def return_def) + apply clarsimp + apply (frule P) + apply (insert nf') + apply (fastforce simp: valid_def no_fail_def ex_abs_underlying_def) + done + +lemma corres_symb_exec_r_conj_ex_abs: + assumes z: "\rv. corres_underlying sr nf nf' r Q (R' rv) x (y rv)" + assumes y: "\Q'\ m \R'\" + assumes x: "\s. Q s \ \\s'. (s, s') \ sr \ P' s'\ m \\rv s'. (s, s') \ sr\" + assumes nf: "nf' \ no_fail (P' and ex_abs_underlying sr Q) m" + shows "corres_underlying sr nf nf' r Q (P' and Q') x (m >>= (\rv. y rv))" +proof - + have P: "corres_underlying sr nf nf' dc Q P' (return undefined) m" + apply (rule corres_noop_ex_abs) + apply (simp add: x) + apply (erule nf) + done + show ?thesis + apply (rule corres_guard_imp) + apply (subst return_bind[symmetric], rule corres_split[OF P]) + apply (rule z) + apply wp + apply (rule y) + apply simp+ + done +qed + +lemmas corres_symb_exec_r_conj_ex_abs_forwards = + corres_symb_exec_r_conj_ex_abs[where P'=P' and Q'=P' for P', simplified] + +lemma gets_the_corres_ex_abs': + "\no_ofail P a; no_ofail (P' and ex_abs_underlying sr P) b\ \ + corres_underlying sr False True r P P' (gets_the a) (gets_the b) + = (\s s'. P s \ P' s' \ (s, s') \ sr \ r (the (a s)) (the (b s')))" + by (fastforce simp: gets_the_def no_ofail_def corres_underlying_def split_def exec_gets + assert_opt_def fail_def return_def ex_abs_underlying_def) + +lemmas gets_the_corres_ex_abs = gets_the_corres_ex_abs'[THEN iffD2] + +lemma gets_the_corres': + "\no_ofail P a; no_ofail P' b\ \ + corres_underlying sr False True r P P' (gets_the a) (gets_the b) + = (\s s'. P s \ P' s' \ (s, s') \ sr \ r (the (a s)) (the (b s')))" + apply (erule gets_the_corres_ex_abs') + apply (fastforce intro: no_ofail_pre_imp) + done + +lemmas gets_the_corres = gets_the_corres'[THEN iffD2] + +lemma gets_the_corres_relation: + "\no_ofail P f; corres_underlying sr False True r P P' (gets_the f) (gets_the f'); + P s; P' s'; (s, s') \ sr\ + \ r (the (f s)) (the (f' s'))" + apply (rule_tac P=P and a=f and b=f' and P'=P' + in gets_the_corres_ex_abs'[THEN iffD1, rule_format]; + fastforce?) + apply (rule no_ofail_gets_the_eq[THEN iffD2]) + apply (fastforce intro: corres_u_nofail) + done + + +\ \Some @{term corres_underlying} rules for @{term whileLoop}\ + lemma in_whileLoop_corres: assumes body_corres: "\r r'. rrel r r' \ @@ -422,6 +514,10 @@ lemma ifM_corres: apply (wpsimp wp: abs_valid conc_valid hoare_vcg_if_lift2)+ done +lemmas ifM_corres' = + ifM_corres[where A=A and B=A and C=A for A, simplified, + where A'=A' and B'=A' and C'=A' for A', simplified] + lemma orM_corres: "\corres_underlying srel nf nf' (=) A A' a a'; corres_underlying srel nf nf' (=) R R' b b'; \B\ a \\c s. \ c \ R s\; \B'\ a' \\c s. \ c \ R' s\\ @@ -432,6 +528,9 @@ lemma orM_corres: apply (wpsimp | fastforce)+ done +lemmas orM_corres' = + orM_corres[where A=A and B=A for A, simplified, where A'=A' and B'=A' for A', simplified] + lemma andM_corres: "\corres_underlying srel nf nf' (=) A A' a a'; corres_underlying srel nf nf' (=) Q Q' b b'; \B\ a \\c s. c \ Q s\; \B'\ a' \\c s. c \ Q' s\\ @@ -451,4 +550,8 @@ lemma notM_corres: apply wpsimp+ done +lemma ifM_to_top_of_bind: + "((ifM test true false) >>= z) = ifM test (true >>= z) (false >>= z)" + by (force simp: ifM_def bind_def split: if_splits) + end diff --git a/lib/Heap_List.thy b/lib/Heap_List.thy new file mode 100644 index 0000000000..e8bae311db --- /dev/null +++ b/lib/Heap_List.thy @@ -0,0 +1,479 @@ +(* + * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) + * + * SPDX-License-Identifier: BSD-2-Clause + *) + +(* Singly-linked lists on heaps or projections from heaps, as predicate and as recursive function. + Loosely after ~~/src/HOL/Hoare/Pointer_Examples.thy *) + +theory Heap_List +imports Main "HOL-Library.Prefix_Order" ListLibLemmas +begin + +(* Given a heap projection that returns the next-pointer for an object at address x, + given a start pointer x, and an end pointer y, determine if the given list + is the path of addresses visited when following the next-pointers from x to y *) +primrec heap_path :: "('a \ 'a) \ 'a option \ 'a list \ 'a option \ bool" where + "heap_path hp x [] y = (x = y)" +| "heap_path hp x (a#as) y = (x = Some a \ heap_path hp (hp a) as y)" + +(* When a path ends in None, it is a singly-linked list *) +abbreviation heap_ls :: "('a \ 'a) \ 'a option \ 'a list \ bool" where + "heap_ls hp x xs \ heap_path hp x xs None" + +(* Walk a linked list of next pointers, recording which it visited. + Terminates artificially at loops, and otherwise because the address domain is finite *) +function heap_walk :: "('a::finite \ 'a) \ 'a option \ 'a list \ 'a list" where + "heap_walk hp None xs = xs" +| "heap_walk hp (Some x) xs = (if x \ set xs then xs else heap_walk hp (hp x) (xs@[x]))" + by pat_completeness auto + +lemma card_set_UNIV: + fixes xs :: "'a::finite list" + assumes "x \ set xs" + shows "card (set xs) < card(UNIV::'a set)" +proof - + have "finite (UNIV::'a set)" by simp + moreover + from assms have "set xs \ UNIV" by blast + ultimately + show ?thesis by (rule psubset_card_mono) +qed + +termination heap_walk + by (relation "measure (\(_, _, xs). card(UNIV :: 'a set) - card (set xs))"; + simp add: card_set_UNIV diff_less_mono2) + +lemma heap_path_append[simp]: + "heap_path hp start (xs @ ys) end = (\x. heap_path hp start xs x \ heap_path hp x ys end)" + by (induct xs arbitrary: start; simp) + +lemma heap_path_None[simp]: + "heap_path hp None xs end = (xs = [] \ end = None)" + by (cases xs, auto) + +lemma heap_ls_unique: + "\ heap_ls hp x xs; heap_ls hp x ys \ \ xs = ys" + by (induct xs arbitrary: ys x; simp) (case_tac ys; clarsimp) + +lemma heap_ls_hd_not_in_tl: + "heap_ls hp (hp x) xs \ x \ set xs" +proof + assume "x \ set xs" + then obtain ys zs where xs: "xs = ys @ x # zs" by (auto simp: in_set_conv_decomp) + moreover assume "heap_ls hp (hp x) xs" + moreover from this xs have "heap_ls hp (hp x) zs" by clarsimp + ultimately show False by (fastforce dest: heap_ls_unique) +qed + +lemma heap_ls_distinct: + "heap_ls hp x xs \ distinct xs" + by (induct xs arbitrary: x; clarsimp simp: heap_ls_hd_not_in_tl) + +lemma heap_ls_is_walk': + "\ heap_ls hp x xs; set xs \ set ys = {} \ \ heap_walk hp x ys = ys @ xs" + by (frule heap_ls_distinct) (induct xs arbitrary: x ys; clarsimp) + +lemma heap_ls_is_walk: + "heap_ls hp x xs \ heap_walk hp x [] = xs" + using heap_ls_is_walk' by fastforce + +lemma heap_path_end_unique: + "heap_path hp x xs y \ heap_path hp x xs y' \ y = y'" + by (induct xs arbitrary: x; clarsimp) + +lemma heap_path_head: + "heap_path hp x xs y \ xs \ [] \ x = Some (hd xs)" + by (induct xs arbitrary: x; clarsimp) + +lemma heap_path_non_nil_lookup_next: + "heap_path hp x (xs@z#ys) y \ hp z = (case ys of [] \ y | _ \ Some (hd ys))" + by (cases ys; fastforce) + +lemma heap_path_prefix: + "heap_path hp st ls ed \ \xs\ls. heap_path hp st xs (if xs = [] then st else hp (last xs))" + apply clarsimp + apply (erule Prefix_Order.prefixE) + by (metis append_butlast_last_id heap_path_append heap_path_non_nil_lookup_next list.case(1)) + +lemma heap_path_butlast: + "heap_path hp st ls ed \ ls \ [] \ heap_path hp st (butlast ls) (Some (last ls))" + by (induct ls rule: rev_induct; simp) + +lemma in_list_decompose_takeWhile: + "x \ set xs \ + xs = (takeWhile ((\) x) xs) @ x # (drop (length (takeWhile ((\) x) xs) + 1) xs)" + by (induct xs arbitrary: x; clarsimp) + +lemma takeWhile_neq_hd_eq_Nil[simp]: + "takeWhile ((\) (hd xs)) xs = Nil" + by (metis (full_types) hd_Cons_tl takeWhile.simps(1) takeWhile.simps(2)) + +lemma heap_not_in_dom[simp]: + "ptr \ dom hp \ hp(ptr := None) = hp" + by (auto simp: dom_def) + +lemma heap_path_takeWhile_lookup_next: + "\ heap_path hp st rs ed; r \ set rs \ + \ heap_path hp st (takeWhile ((\) r) rs) (Some r)" + apply (drule heap_path_prefix) + apply (subgoal_tac "takeWhile ((\) r) rs @ [r] \ rs", fastforce) + by (fastforce dest!: in_list_decompose_takeWhile intro: Prefix_Order.prefixI) + +lemma heap_path_heap_upd_not_in: + "\heap_path hp st rs ed; r \ set rs\ \ heap_path (hp(r:= x)) st rs ed" + by (induct rs arbitrary: st; clarsimp) + +lemma heap_path_last_update: + "\heap_path hp st xs end; xs \ []; distinct xs\ \ heap_path (hp(last xs := new)) st xs new" + by (induct xs arbitrary: st rule: rev_induct; simp add: heap_path_heap_upd_not_in) + +lemma heap_walk_lb: + "heap_walk hp x xs \ xs" + apply (induct xs rule: heap_walk.induct; clarsimp) + by (metis Prefix_Order.prefixE Prefix_Order.prefixI append_assoc) + +lemma heal_walk_Some_nonempty': + "heap_walk hp (Some x) [] > []" + by (fastforce intro: heap_walk_lb less_le_trans[where y="[x]"]) + +lemma heal_walk_Some_nonempty: + "heap_walk hp (Some x) [] \ []" + by (metis less_list_def heal_walk_Some_nonempty') + +lemma heap_walk_Nil_None: + "heap_walk hp st [] = [] \ st = None" + by (case_tac st; simp only: heal_walk_Some_nonempty) + +lemma heap_path_last_end: + "heap_path hp st xs end \ xs \ [] \ hp (last xs) = end" + by (induct xs rule: rev_induct; clarsimp) + +lemmas heap_ls_last_None = heap_path_last_end[where ?end=None] + +(* sym_heap *) + +definition sym_heap where + "sym_heap hp hp' \ \p p'. hp p = Some p' \ hp' p' = Some p" + +lemma sym_heapD1: + "sym_heap hp hp' \ hp p = Some p' \ hp' p' = Some p" + by (clarsimp simp: sym_heap_def) + +lemma sym_heapD2: + "sym_heap hp hp' \ hp' p' = Some p \ hp p = Some p'" + by (clarsimp simp: sym_heap_def) + +lemma sym_heap_symmetric: + "sym_heap hp hp' \ sym_heap hp' hp" + unfolding sym_heap_def by blast + +lemma sym_heap_None: + "\sym_heap hp hp'; hp p = None\ \ \p'. hp' p' \ Some p" unfolding sym_heap_def by force + +lemma sym_heap_remove_only: + "\sym_heap hp hp'; hp' y = Some x\ \ sym_heap (hp(x := None)) (hp'(y := None))" + apply (clarsimp simp: sym_heap_def) + apply (metis option.inject) + done + +lemma sym_heap_remove_only': + "\sym_heap hp hp'; hp y = Some x\ \ sym_heap (hp(y := None)) (hp'(x := None))" + apply (clarsimp simp: sym_heap_def) + apply (metis option.inject) + done + +lemma sym_heap_remove_middle_from_chain: + "\sym_heap hp hp'; before \ middle; middle \ after; + hp before = Some middle; hp middle = Some after\ + \ sym_heap (hp(before := Some after, middle := None)) + (hp'(after := Some before, middle := None))" + apply (clarsimp simp: sym_heap_def) + apply (metis option.simps(1)) + done + +lemma sym_heap_connect: + "\sym_heap hp hp'; hp a = None; hp' b = None \ \ sym_heap (hp(a \ b)) (hp'(b \ a))" + by (force simp: sym_heap_def) + +lemma sym_heap_insert_into_middle_of_chain: + "\sym_heap hp hp'; hp before = Some after; hp middle = None; hp' middle = None\ + \ sym_heap (hp(before \ middle, middle \ after)) (hp'(after \ middle, middle \ before))" + apply (clarsimp simp: sym_heap_def) + apply (metis option.simps) + done + +lemma sym_heap_path_reverse: + "sym_heap hp hp' \ + heap_path hp (Some p) (p#ps) (Some p') + \ heap_path hp' (Some p') (p'#(rev ps)) (Some p)" + unfolding sym_heap_def by (induct ps arbitrary: p p' rule: rev_induct; force) + +lemma sym_heap_ls_rev_Cons: + "\sym_heap hp hp'; heap_ls hp (Some p) (p#ps)\ + \ heap_path hp' (Some (last (p#ps))) (rev ps) (Some p)" + supply rev.simps[simp del] + apply (induct ps arbitrary: p rule: rev_induct; simp add: rev.simps) + by (auto dest!: sym_heap_path_reverse[THEN iffD1]) + +lemma sym_heap_ls_rev: + "\sym_heap hp hp'; heap_ls hp (Some p) ps\ + \ heap_path hp' (Some (last ps)) (butlast (rev ps)) (Some p) + \ hp (last ps) = None" + apply (induct ps arbitrary: p rule: rev_induct, simp) + apply (frule heap_path_head; clarsimp) + by (auto dest!: sym_heap_path_reverse[THEN iffD1]) + +lemma heap_path_sym_heap_non_nil_lookup_prev: + "\heap_ls hp x (xs @ z # ys); sym_heap hp hp'; xs \ []\ \ hp' z = (Some (last xs))" + supply heap_path_append[simp del] + apply (cut_tac xs="butlast xs" and z="last xs" and ys="z # ys" + in heap_path_non_nil_lookup_next[where hp=hp and x=x and y=None]) + apply (frule append_butlast_last_id) + apply (metis append_eq_Cons_conv append_eq_append_conv2) + apply (fastforce dest: sym_heapD1) + done + +lemma heap_ls_no_loops: + "\heap_ls hp st xs; p \ set xs\ \ hp p \ Some p" + apply (frule heap_ls_distinct) + apply (fastforce dest: split_list heap_path_non_nil_lookup_next split: list.splits) + done + +lemma heap_ls_prev_no_loops: + "\heap_ls hp st xs; p \ set xs; sym_heap hp hp'\ \ hp' p \ Some p" + by (fastforce dest: heap_ls_no_loops sym_heapD2) + +(* more on heap_path : next/prev in path *) + +lemma heap_path_extend: + "heap_path hp st (ls @ [p]) (hp p) \ heap_path hp st ls (Some p)" + by (induct ls rule: rev_induct; simp) + +lemma heap_path_prefix_heap_ls: + "\heap_ls hp st xs; heap_path hp st ys ed\ \ ys \ xs" + apply (induct xs arbitrary: ys st, simp) + apply (case_tac ys; clarsimp) + done + +lemma distinct_decompose2: + "\distinct xs; xs = ys @ x # y # zs\ + \ x \ y \ x \ set ys \ y \ set ys \ x \ set zs \ y \ set zs" + by (simp add: in_set_conv_decomp) + +lemma heap_path_distinct_next_cases: (* the other direction needs sym_heap *) + "\heap_path hp st xs ed; distinct xs; p \ set xs; hp p = Some np\ + \ ed = Some p \ ed = Some np \ np \ set xs" + apply (cases ed; simp) + apply (frule in_list_decompose_takeWhile) + apply (subgoal_tac "heap_ls hp st (takeWhile ((\) p) xs @ p # drop (length (takeWhile ((\) p) xs) + 1) xs)") + apply (drule heap_path_non_nil_lookup_next) + apply (case_tac "drop (length (takeWhile ((\) p) xs) + 1) xs"; simp) + apply (metis in_set_dropD list.set_intros(1)) + apply simp + apply (frule in_list_decompose_takeWhile) + apply (subgoal_tac "heap_path hp st (takeWhile ((\) p) xs @ p # drop (length (takeWhile ((\) p) xs) + 1) xs) ed") + apply (frule heap_path_non_nil_lookup_next) + apply (case_tac "drop (length (takeWhile ((\) p) xs) + 1) xs", simp) + apply (simp split: if_split_asm) + apply (drule (1) distinct_decompose2) + apply clarsimp + by (metis in_set_dropD list.set_intros(1)) simp + +lemma heap_ls_next_in_list: + "\heap_ls hp st xs; p \ set xs; hp p = Some np\ + \ np \ set xs" + apply (subgoal_tac "distinct xs") + by (fastforce dest!: heap_path_distinct_next_cases) (erule heap_ls_distinct) + +lemma heap_path_distinct_sym_prev_cases: + "\heap_path hp st xs ed; distinct xs; np \ set xs; hp p = Some np; sym_heap hp hp'\ + \ st = Some np \ p \ set xs" + apply (cases st; simp) + apply (rename_tac stp) + apply (case_tac "stp = np"; simp) + apply (cases xs; simp del: heap_path.simps) + apply (frule heap_path_head, simp) + apply (cases ed, clarsimp) + apply (frule sym_heap_ls_rev_Cons, fastforce) + apply (drule heap_path_distinct_next_cases[where hp=hp']; simp add: sym_heap_def) + apply simp + apply (simp del: heap_path.simps) + apply (frule (1) sym_heap_path_reverse[where hp'=hp', THEN iffD1]) + apply simp + apply (frule heap_path_distinct_next_cases[where hp=hp']; simp add: sym_heap_def) + apply fastforce + done + +lemma heap_ls_prev_cases: + "\heap_ls hp st xs; np \ set xs; hp p = Some np; sym_heap hp hp'\ + \ st = Some np \ p \ set xs" + apply (subgoal_tac "distinct xs") + by (fastforce dest!: heap_path_distinct_sym_prev_cases) (erule heap_ls_distinct) + +lemma heap_ls_prev_not_in: + "\heap_ls hp st xs; np \ set xs; hp p = Some np\ + \ p \ set xs" + by (meson heap_ls_next_in_list) + +lemma heap_path_distinct_prev_not_in: + "\heap_path hp st xs ed; distinct xs; np \ set xs; hp p = Some np; ed \ Some np; ed \ Some p\ + \ p \ set xs" + using heap_path_distinct_next_cases + by fastforce + +lemma heap_path_distinct_next_not_in: + "\heap_path hp st xs ed; distinct xs; p \ set xs; hp p = Some np; + sym_heap hp hp'; st \ Some np\ + \ np \ set xs" + by (fastforce dest!: heap_path_distinct_sym_prev_cases[simplified]) + +lemma heap_ls_next_not_in: + "\heap_ls hp st xs; p \ set xs; hp p = Some np; sym_heap hp hp'; st \ Some np\ + \ np \ set xs" + by (fastforce dest!: heap_ls_prev_cases[simplified]) + +lemma sym_heap_prev_None_is_start: + "\heap_ls hp st xs; sym_heap hp hp'; p \ set xs; hp' p = None\ + \ Some p = st" + using split_list_last heap_path_sym_heap_non_nil_lookup_prev + by fastforce + +lemma not_last_next_not_None: + "\heap_ls hp st xs; p \ set xs; p \ last xs\ \ hp p \ None" + by (fastforce intro: heap_path_head dest: split_list) + +lemma not_head_prev_not_None: + "\heap_ls hp st xs; p \ set xs; p \ hd xs; sym_heap hp hp'\ + \ hp' p \ None" + using sym_heap_prev_None_is_start heap_path_head + by fastforce + +(* more on heap_path *) + +lemma heap_ls_next_takeWhile_append: + "\heap_ls hp st xs; p \ set xs; hp p = Some np\ + \ takeWhile ((\) np) xs = (takeWhile ((\) p) xs) @ [p]" + apply (frule heap_ls_distinct) + apply (frule in_list_decompose_takeWhile) + apply (subgoal_tac "heap_ls hp st (takeWhile ((\) p) xs @ p # drop (length (takeWhile ((\) p) xs) + 1) xs)") + prefer 2 apply simp + apply (drule heap_path_non_nil_lookup_next) + apply (case_tac "drop (length (takeWhile ((\) p) xs) + 1) xs"; simp) + apply (subgoal_tac "np \ set xs") + prefer 2 apply (erule (2) heap_ls_next_in_list) + apply (frule in_list_decompose_takeWhile[where x=np]) + apply (drule (1) distinct_inj_middle[where x=np and xa="takeWhile ((\) np) xs" and ya="takeWhile ((\) p) xs @ [p]"]) + apply simp+ + done + +(* RT FIXME: Move *) +lemma takeWhile_neq_notin_same: + "x \ set xs \ takeWhile ((\) x) xs = xs" + using takeWhile_eq_all_conv by blast + +lemma heap_path_extend_takeWhile: + "\heap_ls hp st xs; heap_path hp st (takeWhile ((\) p) xs) (Some p); hp p = Some np\ + \ heap_path hp st (takeWhile ((\) np) xs) (Some np)" + apply (case_tac "p \ set xs") + apply (subst heap_ls_next_takeWhile_append[where p=p and np=np and hp=hp]; simp) + apply (drule takeWhile_neq_notin_same, simp) + apply (drule (1) heap_path_end_unique, simp) + done + +lemma heap_ls_next_takeWhile_append_sym: + "\heap_ls hp st xs; np \ set xs; st \ Some np; hp p = Some np; sym_heap hp hp'\ + \takeWhile ((\) np) xs = (takeWhile ((\) p) xs) @ [p]" + apply (frule (3) heap_ls_prev_cases, simp) + apply (fastforce elim!: heap_ls_next_takeWhile_append) + done + +lemma heap_path_curtail_takeWhile: + "\heap_ls hp st xs; heap_path hp st (takeWhile ((\) np) xs) (Some np); + st \ Some np; hp p = Some np; sym_heap hp hp'\ + \ heap_path hp st (takeWhile ((\) p) xs) (Some p)" + apply (case_tac "np \ set xs") + apply (drule (4) heap_ls_next_takeWhile_append_sym) + apply simp + apply (drule takeWhile_neq_notin_same, simp) + apply (drule (1) heap_path_end_unique, simp) + done + +(* more on heap_path : end *) + + +\ \Lemmas relating an update to the list to an update to the heap\ + +lemma heap_ls_prepend: + "\heap_ls hp st xs; new \ set xs; xs \ []\ + \ heap_ls (hp(new := Some (hd xs))) (Some new) (new # xs)" + apply simp + apply (erule heap_path_heap_upd_not_in[rotated]) + apply (frule (1) heap_path_head) + apply fastforce + done + +lemma heap_ls_append: + "\heap_ls hp st xs; xs \ []; new \ set xs\ + \ heap_ls (hp(last xs := Some new, new := None)) st (xs @ [new])" + apply (frule heap_ls_distinct) + apply simp + apply (rule heap_path_heap_upd_not_in) + apply (fastforce simp: heap_path_last_update) + apply assumption + done + +lemma heap_ls_list_insert_before: + "\heap_ls hp st (xs @ ys); new \ set (xs @ ys); xs \ []; ys \ []\ + \ heap_ls (hp(last xs := Some new, new := Some (hd ys))) st + (list_insert_before (xs @ ys) (hd ys) new)" + apply (frule heap_ls_distinct) + apply (subst list_insert_before_distinct; fastforce?) + apply simp + apply (rule conjI) + \ \the path until new\ + apply (fastforce intro: heap_path_heap_upd_not_in heap_path_last_update) + \ \the path from hd ys\ + apply (metis disjoint_iff_not_equal heap_path_head heap_path_heap_upd_not_in last_in_set) + done + +lemma heap_ls_remove_singleton: + "heap_ls hp st [x] \ heap_ls (hp(x := None)) None []" + by simp + +lemma heap_ls_remove_head_not_singleton: + "\heap_ls hp st xs; tl xs \ []\ + \ heap_ls (hp(hd xs := None)) (Some (hd (tl xs))) (tl xs)" + apply (frule heap_ls_distinct) + apply (cases xs; simp) + apply clarsimp + apply (frule heap_path_head) + apply fastforce + apply (fastforce elim!: heap_path_heap_upd_not_in) + done + +lemma heap_ls_remove_last_not_singleton: + "\heap_ls hp st xs; butlast xs \ []\ + \ heap_ls (hp((last (butlast xs)) := None)) st (butlast xs)" + apply (frule heap_ls_distinct) + apply (frule distinct_butlast) + apply (fastforce dest: heap_path_last_update heap_path_butlast) + done + +lemma heap_ls_remove_middle: + "\heap_ls hp st (xs @ a # ys); xs \ []; ys \ []\ + \ heap_ls (hp(last xs := Some (hd ys), a := None)) st (xs @ ys)" + apply (frule heap_ls_distinct) + apply simp + apply (rule_tac x="Some (hd ys)" in exI) + apply (rule conjI) + apply (fastforce intro: heap_path_heap_upd_not_in heap_path_last_update) + apply (rule heap_path_heap_upd_not_in) + apply (rule heap_path_heap_upd_not_in) + using heap_path_head apply fastforce + apply force + apply fastforce + done + +end \ No newline at end of file diff --git a/lib/Lib.thy b/lib/Lib.thy index 69c29df3f7a..1374020d11 100644 --- a/lib/Lib.thy +++ b/lib/Lib.thy @@ -2558,6 +2558,10 @@ lemma ranD: "v \ ran f \ \x. f x = Some v" by (auto simp: ran_def) +lemma fun_upd_swap: + "a \ c \ hp(c := d, a := b) = hp(a := b, c := d)" + by fastforce + text \Prevent clarsimp and others from creating Some from not None by folding this and unfolding again when safe.\ diff --git a/lib/ListLibLemmas.thy b/lib/ListLibLemmas.thy index bdb72d61f8..fdb3ba42cf 100644 --- a/lib/ListLibLemmas.thy +++ b/lib/ListLibLemmas.thy @@ -371,6 +371,32 @@ lemma list_insert_after_after: apply fastforce done +lemma list_insert_before_not_found: + "a \ set ls \ list_insert_before ls a new = ls" + by (induct ls; fastforce) + +lemma list_insert_before_nonempty: + "ls \ [] \ list_insert_before ls a new \ []" + by (induct ls; clarsimp) + +lemma list_insert_before_head: + "xs \ [] \ list_insert_before xs (hd xs) new = new # xs" + by (induct xs; fastforce) + +lemma last_of_list_insert_before: + "xs \ [] \ last (list_insert_before xs a new) = last xs" + by (induct xs; clarsimp simp: list_insert_before_nonempty) + +lemma list_insert_before_distinct: + "\distinct (xs @ ys); ys \ []\ \ list_insert_before (xs @ ys) (hd ys) new = xs @ new # ys" + by (induct xs; fastforce simp add: list_insert_before_head) + +lemma set_list_insert_before: + "\new \ set ls; before \ set ls\ \ set (list_insert_before ls before new) = set ls \ {new}" + apply (induct ls; clarsimp) + apply fastforce + done + lemma list_remove_removed: "set (list_remove list x) = (set list) - {x}" apply (induct list,simp+) diff --git a/lib/List_Lib.thy b/lib/List_Lib.thy index 936f86e6e6..e6471707cb 100644 --- a/lib/List_Lib.thy +++ b/lib/List_Lib.thy @@ -26,6 +26,12 @@ primrec list_insert_after :: "'a list \ 'a \ 'a \ \Inserts the value new immediately before the first occurence of a (if any) in the list\ +primrec list_insert_before :: "'a list \ 'a \ 'a \ 'a list" where + "list_insert_before [] a new = []" | + "list_insert_before (x # xs) a new = (if x = a then new # x # xs + else x # list_insert_before xs a new)" + primrec list_remove :: "'a list \ 'a \ 'a list" where "list_remove [] a = []" | "list_remove (x # xs) a = (if x = a then (list_remove xs a) diff --git a/lib/MonadicRewrite.thy b/lib/MonadicRewrite.thy index 3058fd921b..e4fbed6481 100644 --- a/lib/MonadicRewrite.thy +++ b/lib/MonadicRewrite.thy @@ -10,7 +10,7 @@ theory MonadicRewrite imports Monads.Nondet_VCG - Corres_UL + ExtraCorres Monads.Nondet_Empty_Fail Rules_Tac begin @@ -81,6 +81,10 @@ lemma monadic_rewrite_pre_imp_eq: "\ \s. P s \ f s = g s \ \ monadic_rewrite F E P f g" by (simp add: monadic_rewrite_def) +lemma monadic_rewrite_guard_arg_cong: + "(\s. P s \ x = y) \ monadic_rewrite F E P (f x) (f y)" + by (clarsimp simp: monadic_rewrite_def) + lemma monadic_rewrite_exists: "(\v. monadic_rewrite F E (Q v) m m') \ monadic_rewrite F E ((\s. \v. P v s \ Q v s) and (\s. \v. P v s)) m m'" @@ -693,7 +697,7 @@ lemma monadic_rewrite_refine_validE_R: by (simp add: validE_R_def validE_def monadic_rewrite_refine_valid) lemma monadic_rewrite_is_valid: - "\ monadic_rewrite False False P' f f'; \P\ do x <- f; g x od \Q\ \ + "\ monadic_rewrite False E P' f f'; \P\ do x <- f; g x od \Q\ \ \ \P and P'\ do x <- f'; g x od \Q\" by (fastforce simp: monadic_rewrite_def valid_def bind_def) @@ -740,6 +744,13 @@ lemma monadic_rewrite_corres_r_generic: \ corres_underlying R nf nf' r P (P' and Q) a c" by (fastforce simp: corres_underlying_def monadic_rewrite_def) +lemma monadic_rewrite_corres_r_generic_ex_abs: + "\ monadic_rewrite F E (\s'. Q s' \ ex_abs_underlying sr P s') c' c; + corres_underlying sr nf nf'' r P P' a c'; + F \ nf''; nf' \ nf'' \ + \ corres_underlying sr nf nf' r P (P' and Q) a c" + by (fastforce simp: corres_underlying_def monadic_rewrite_def) + lemma monadic_rewrite_corres_r: "\ monadic_rewrite False True Q c c'; corres_underlying R nf nf' r P P' a c' \ diff --git a/lib/Monads/nondet/Nondet_No_Fail.thy b/lib/Monads/nondet/Nondet_No_Fail.thy index 8bf7c5fd0b..6e30a191c2 100644 --- a/lib/Monads/nondet/Nondet_No_Fail.thy +++ b/lib/Monads/nondet/Nondet_No_Fail.thy @@ -130,7 +130,7 @@ lemma no_fail_returnOK[simp, wp]: by (simp add: returnOk_def) lemma no_fail_bind[wp]: - "\ no_fail P f; \rv. no_fail (R rv) (g rv); \Q\ f \R\ \ \ no_fail (P and Q) (f >>= (\rv. g rv))" + "\ \rv. no_fail (R rv) (g rv); \Q\ f \R\; no_fail P f \ \ no_fail (P and Q) (f >>= (\rv. g rv))" unfolding no_fail_def bind_def using post_by_hoare by fastforce diff --git a/lib/Monads/reader_option/Reader_Option_VCG.thy b/lib/Monads/reader_option/Reader_Option_VCG.thy index f1b2d6960c..278d25a24f 100644 --- a/lib/Monads/reader_option/Reader_Option_VCG.thy +++ b/lib/Monads/reader_option/Reader_Option_VCG.thy @@ -59,6 +59,10 @@ lemmas owhile_add_inv = owhile_inv_def[symmetric] (* WP rules for ovalid. *) +lemma ovalid_post_taut[wp]: + "\P\ f \\\\" + by (simp add: ovalid_def) + lemma ovalid_inv[wp]: "ovalid P f (\_. P)" by (simp add: ovalid_def) @@ -247,7 +251,7 @@ lemma no_ofail_ogets[wp]: by simp lemma no_ofail_obind[wp]: - "\ \r. no_ofail (P r) (g r); no_ofail Q f; ovalid Q f P \ \ no_ofail Q (obind f g)" + "\ \r. no_ofail (R r) (g r); \Q\ f \R\; no_ofail P f \ \ no_ofail (P and Q) (f |>> g)" by (auto simp: no_ofail_def obind_def ovalid_def) lemma no_ofail_K_bind[wp]: @@ -275,6 +279,11 @@ lemma no_ofail_oassert_opt[simp, wp]: "no_ofail (\_. P \ None) (oassert_opt P)" by (simp add: no_ofail_def oassert_opt_def split: option.splits) +lemma no_ofail_if[wp]: + "\ P \ no_ofail Q f; \ P \ no_ofail R g \ + \ no_ofail (if P then Q else R) (if P then f else g)" + by simp + lemma no_ofail_owhen[wp]: "(P \ no_ofail Q f) \ no_ofail (if P then Q else \) (owhen P f)" by (simp add: no_ofail_def owhen_def) @@ -287,11 +296,14 @@ lemma no_ofail_oassert[simp, wp]: "no_ofail (\_. P) (oassert P)" by (simp add: oassert_def no_ofail_def) -lemma no_ofail_gets_the: - "no_ofail P f \ no_fail P (gets_the (f :: ('s, 'a) lookup))" - by (fastforce simp: no_ofail_def no_fail_def gets_the_def gets_def - get_def assert_opt_def bind_def return_def fail_def - split: option.split) +lemma no_ofail_gets_the_eq: + "no_ofail P f \ no_fail P (gets_the (f :: ('s, 'a) lookup))" + by (auto simp: no_ofail_def no_fail_def gets_the_def gets_def + get_def assert_opt_def bind_def return_def fail_def + split: option.split) + +lemmas no_ofail_gets_the = + no_ofail_gets_the_eq[THEN iffD1] lemma no_ofail_is_triple[wp_trip]: "no_ofail P f = triple_judgement P f (\s f. f s \ None)" @@ -348,7 +360,7 @@ lemma ovalidNF_pre_imp: by (simp add: ovalidNF_def) lemma no_ofail_pre_imp: - "\ \s. P' s \ P s; no_ofail P f \ \ no_ofail P' f" + "\ no_ofail P f; \s. P' s \ P s \ \ no_ofail P' f" by (simp add: no_ofail_def) lemma ovalid_post_imp: diff --git a/proof/crefine/lib/AutoCorres_C.thy b/proof/crefine/lib/AutoCorres_C.thy index 6b3f6b7abf..1b189f0a66 100644 --- a/proof/crefine/lib/AutoCorres_C.thy +++ b/proof/crefine/lib/AutoCorres_C.thy @@ -934,10 +934,10 @@ lemma terminates_spec_no_fail: using normal by auto show ?thesis apply (clarsimp simp: ac AC_call_L1_def L2_call_L1_def) - apply (wpsimp wp: select_f_L1_call_simpl_no_fail no_fail_select - wp_del: select_f_wp) - apply (rule hoare_strengthen_post[OF select_f_L1_call_simpl_rv], fastforce) - apply (wpsimp wp: nf_pre)+ + apply (wpsimp wp_del: select_f_wp) + apply (rule hoare_strengthen_post[OF select_f_L1_call_simpl_rv], fastforce) + apply (wpsimp wp: select_f_L1_call_simpl_no_fail no_fail_select)+ + apply (fastforce simp: nf_pre) done qed diff --git a/proof/infoflow/refine/ADT_IF_Refine_C.thy b/proof/infoflow/refine/ADT_IF_Refine_C.thy index ec9dff489c..60d409bff2 100644 --- a/proof/infoflow/refine/ADT_IF_Refine_C.thy +++ b/proof/infoflow/refine/ADT_IF_Refine_C.thy @@ -193,23 +193,20 @@ lemma handleInterrupt_no_fail: lemma handleEvent_Interrupt_no_fail: "no_fail (invs' and ex_abs einvs) (handleEvent Interrupt)" apply (simp add: handleEvent_def) - apply (rule no_fail_pre) apply wp - apply (rule handleInterrupt_no_fail) - apply (simp add: crunch_simps) - apply (rule_tac Q="\r s. ex_abs (einvs) s \ invs' s \ - (\irq. r = Some irq - \ intStateIRQTable (ksInterruptState s) irq \ irqstate.IRQInactive)" - in hoare_strengthen_post) - apply (rule hoare_vcg_conj_lift) - apply (rule corres_ex_abs_lift) - apply (rule dmo_getActiveIRQ_corres) - apply wp - apply simp - apply wp - apply simp - apply (rule doMachineOp_getActiveIRQ_IRQ_active) - apply clarsimp + apply (rule handleInterrupt_no_fail) + apply (simp add: crunch_simps) + apply (rule_tac Q="\r s. ex_abs (einvs) s \ invs' s \ + (\irq. r = Some irq + \ intStateIRQTable (ksInterruptState s) irq \ irqstate.IRQInactive)" + in hoare_strengthen_post) + apply (rule hoare_vcg_conj_lift) + apply (rule corres_ex_abs_lift) + apply (rule dmo_getActiveIRQ_corres) + apply wpsimp + apply (wpsimp wp: doMachineOp_getActiveIRQ_IRQ_active) + apply clarsimp + apply wpsimp apply (clarsimp simp: invs'_def valid_state'_def) done diff --git a/proof/invariant-abstract/ARM/Machine_AI.thy b/proof/invariant-abstract/ARM/Machine_AI.thy index ab2f402f20..9077037067 100644 --- a/proof/invariant-abstract/ARM/Machine_AI.thy +++ b/proof/invariant-abstract/ARM/Machine_AI.thy @@ -271,8 +271,7 @@ lemma no_fail_invalidateCacheRange_I[simp, wp]: lemma no_fail_invalidateCacheRange_RAM[simp, wp]: "no_fail \ (invalidateCacheRange_RAM s e p)" apply (simp add: invalidateCacheRange_RAM_def lineStart_def cacheLineBits_def) - apply (rule no_fail_pre, wp no_fail_invalidateL2Range no_fail_invalidateByVA no_fail_dsb, simp) - apply (auto intro: hoare_post_taut) + apply (wpsimp wp: no_fail_invalidateL2Range no_fail_invalidateByVA no_fail_dsb) done lemma no_fail_branchFlushRange[simp, wp]: diff --git a/proof/invariant-abstract/ARM_HYP/Machine_AI.thy b/proof/invariant-abstract/ARM_HYP/Machine_AI.thy index 5a172f2603..b98d74625b 100644 --- a/proof/invariant-abstract/ARM_HYP/Machine_AI.thy +++ b/proof/invariant-abstract/ARM_HYP/Machine_AI.thy @@ -280,8 +280,7 @@ lemma no_fail_invalidateCacheRange_I[simp, wp]: lemma no_fail_invalidateCacheRange_RAM[simp, wp]: "no_fail \ (invalidateCacheRange_RAM s e p)" apply (simp add: invalidateCacheRange_RAM_def lineStart_def cacheLineBits_def) - apply (rule no_fail_pre, wp no_fail_invalidateL2Range no_fail_invalidateByVA no_fail_dsb, simp) - apply (auto intro: hoare_post_taut) + apply (wpsimp wp: no_fail_invalidateL2Range no_fail_invalidateByVA no_fail_dsb) done lemma no_fail_branchFlushRange[simp, wp]: diff --git a/proof/refine/AARCH64/Schedule_R.thy b/proof/refine/AARCH64/Schedule_R.thy index ec6dffbdf6..e31be58437 100644 --- a/proof/refine/AARCH64/Schedule_R.thy +++ b/proof/refine/AARCH64/Schedule_R.thy @@ -1575,11 +1575,6 @@ lemma corres_assert_ret: apply (simp add: assert_def return_def fail_def) done -lemma corres_assert_assume_l: - "corres dc P Q (f ()) g - \ corres dc (P and (\s. P')) Q (assert P' >>= f) g" - by (force simp: corres_underlying_def assert_def return_def bind_def fail_def) - lemma corres_assert_assume_r: "corres dc P Q f (g ()) \ corres dc P (Q and (\s. Q')) f (assert Q' >>= g)" diff --git a/proof/refine/AARCH64/TcbAcc_R.thy b/proof/refine/AARCH64/TcbAcc_R.thy index 2ae604d46e..d495a8db2d 100644 --- a/proof/refine/AARCH64/TcbAcc_R.thy +++ b/proof/refine/AARCH64/TcbAcc_R.thy @@ -1599,9 +1599,8 @@ lemma no_fail_asUser [wp]: "no_fail \ f \ no_fail (tcb_at' t) (asUser t f)" apply (simp add: asUser_def split_def) apply wp - apply (simp add: no_fail_def) - apply (wp hoare_drop_imps) - apply simp + apply (simp add: no_fail_def) + apply (wpsimp wp: hoare_drop_imps no_fail_threadGet)+ done lemma asUser_setRegister_corres: diff --git a/proof/refine/ARM/Schedule_R.thy b/proof/refine/ARM/Schedule_R.thy index 1eeb7b4351..8b3d92fa3e 100644 --- a/proof/refine/ARM/Schedule_R.thy +++ b/proof/refine/ARM/Schedule_R.thy @@ -1454,11 +1454,6 @@ lemma corres_assert_ret: apply (simp add: assert_def return_def fail_def) done -lemma corres_assert_assume_l: - "corres dc P Q (f ()) g - \ corres dc (P and (\s. P')) Q (assert P' >>= f) g" - by (force simp: corres_underlying_def assert_def return_def bind_def fail_def) - lemma corres_assert_assume_r: "corres dc P Q f (g ()) \ corres dc P (Q and (\s. Q')) f (assert Q' >>= g)" diff --git a/proof/refine/ARM/TcbAcc_R.thy b/proof/refine/ARM/TcbAcc_R.thy index b697dafd55..f040d40a8e 100644 --- a/proof/refine/ARM/TcbAcc_R.thy +++ b/proof/refine/ARM/TcbAcc_R.thy @@ -1534,9 +1534,8 @@ lemma no_fail_asUser [wp]: "no_fail \ f \ no_fail (tcb_at' t) (asUser t f)" apply (simp add: asUser_def split_def) apply wp - apply (simp add: no_fail_def) - apply (wp hoare_drop_imps) - apply simp + apply (simp add: no_fail_def) + apply (wpsimp wp: hoare_drop_imps no_fail_threadGet)+ done lemma asUser_setRegister_corres: diff --git a/proof/refine/ARM/Tcb_R.thy b/proof/refine/ARM/Tcb_R.thy index 6ca57825eb..07f0317cbc 100644 --- a/proof/refine/ARM/Tcb_R.thy +++ b/proof/refine/ARM/Tcb_R.thy @@ -341,9 +341,7 @@ lemma invokeTCB_WriteRegisters_corres: apply (rule asUser_corres) apply (simp add: zipWithM_mapM getRestartPC_def setNextPC_def) apply (rule corres_Id, simp+) - apply (rule no_fail_pre, wp no_fail_mapM) - apply clarsimp - apply (wp no_fail_setRegister | simp)+ + apply (wpsimp wp: no_fail_mapM no_fail_setRegister)+ apply (rule corres_split_nor[OF asUser_postModifyRegisters_corres[simplified]]) apply (rule corres_split_nor[OF corres_when[OF refl restart_corres]]) apply (rule corres_split_nor[OF corres_when[OF refl rescheduleRequired_corres]]) diff --git a/proof/refine/ARM_HYP/Schedule_R.thy b/proof/refine/ARM_HYP/Schedule_R.thy index 0b6d59bdc9..b4edbdf7f4 100644 --- a/proof/refine/ARM_HYP/Schedule_R.thy +++ b/proof/refine/ARM_HYP/Schedule_R.thy @@ -1550,11 +1550,6 @@ lemma corres_assert_ret: apply (simp add: assert_def return_def fail_def) done -lemma corres_assert_assume_l: - "corres dc P Q (f ()) g - \ corres dc (P and (\s. P')) Q (assert P' >>= f) g" - by (force simp: corres_underlying_def assert_def return_def bind_def fail_def) - lemma corres_assert_assume_r: "corres dc P Q f (g ()) \ corres dc P (Q and (\s. Q')) f (assert Q' >>= g)" diff --git a/proof/refine/ARM_HYP/TcbAcc_R.thy b/proof/refine/ARM_HYP/TcbAcc_R.thy index 409f3d5673..cecb49920c 100644 --- a/proof/refine/ARM_HYP/TcbAcc_R.thy +++ b/proof/refine/ARM_HYP/TcbAcc_R.thy @@ -1581,9 +1581,8 @@ lemma no_fail_asUser [wp]: "no_fail \ f \ no_fail (tcb_at' t) (asUser t f)" apply (simp add: asUser_def split_def) apply wp - apply (simp add: no_fail_def) - apply (wp hoare_drop_imps) - apply simp + apply (simp add: no_fail_def) + apply (wpsimp wp: hoare_drop_imps no_fail_threadGet)+ done lemma asUser_setRegister_corres: diff --git a/proof/refine/RISCV64/Schedule_R.thy b/proof/refine/RISCV64/Schedule_R.thy index 8524d6bdd5..2637f53166 100644 --- a/proof/refine/RISCV64/Schedule_R.thy +++ b/proof/refine/RISCV64/Schedule_R.thy @@ -1419,11 +1419,6 @@ lemma corres_assert_ret: apply (simp add: assert_def return_def fail_def) done -lemma corres_assert_assume_l: - "corres dc P Q (f ()) g - \ corres dc (P and (\s. P')) Q (assert P' >>= f) g" - by (force simp: corres_underlying_def assert_def return_def bind_def fail_def) - lemma corres_assert_assume_r: "corres dc P Q f (g ()) \ corres dc P (Q and (\s. Q')) f (assert Q' >>= g)" diff --git a/proof/refine/RISCV64/TcbAcc_R.thy b/proof/refine/RISCV64/TcbAcc_R.thy index 708fdaedcc..2cee7bc860 100644 --- a/proof/refine/RISCV64/TcbAcc_R.thy +++ b/proof/refine/RISCV64/TcbAcc_R.thy @@ -1568,9 +1568,8 @@ lemma no_fail_asUser [wp]: "no_fail \ f \ no_fail (tcb_at' t) (asUser t f)" apply (simp add: asUser_def split_def) apply wp - apply (simp add: no_fail_def) - apply (wp hoare_drop_imps) - apply simp + apply (simp add: no_fail_def) + apply (wpsimp wp: hoare_drop_imps no_fail_threadGet)+ done lemma asUser_setRegister_corres: diff --git a/proof/refine/RISCV64/Tcb_R.thy b/proof/refine/RISCV64/Tcb_R.thy index c4f071c007..4c9e2ac531 100644 --- a/proof/refine/RISCV64/Tcb_R.thy +++ b/proof/refine/RISCV64/Tcb_R.thy @@ -329,8 +329,8 @@ lemma invokeTCB_WriteRegisters_corres: apply (clarsimp simp: mask_def user_vtop_def cong: if_cong) apply simp - apply (rule no_fail_pre, wp no_fail_mapM) - apply (clarsimp, (wp no_fail_setRegister | simp)+) + apply (wpsimp wp: no_fail_mapM no_fail_setRegister) + apply simp apply (rule corres_split_nor[OF asUser_postModifyRegisters_corres[simplified]]) apply (rule corres_split_nor[OF corres_when[OF refl restart_corres]]) apply (rule corres_split_nor[OF corres_when[OF refl rescheduleRequired_corres]]) diff --git a/proof/refine/X64/IpcCancel_R.thy b/proof/refine/X64/IpcCancel_R.thy index 1c0bde4875..d18d63fc87 100644 --- a/proof/refine/X64/IpcCancel_R.thy +++ b/proof/refine/X64/IpcCancel_R.thy @@ -1448,10 +1448,7 @@ lemma no_fail_nativeThreadUsingFPU[wp]: "no_fail (\ and \) (X64.nativeThreadUsingFPU thread)" supply Collect_const[simp del] apply (simp only: X64.nativeThreadUsingFPU_def) - apply (rule no_fail_bind) - apply (simp add: Arch.no_fail_machine_op_lift) - apply simp - apply wp + apply (wpsimp wp: Arch.no_fail_machine_op_lift) done lemma (in delete_one) prepareThreadDelete_corres: diff --git a/proof/refine/X64/Schedule_R.thy b/proof/refine/X64/Schedule_R.thy index c1827abcf3..3aa19c9a3f 100644 --- a/proof/refine/X64/Schedule_R.thy +++ b/proof/refine/X64/Schedule_R.thy @@ -1418,11 +1418,6 @@ lemma corres_assert_ret: apply (simp add: assert_def return_def fail_def) done -lemma corres_assert_assume_l: - "corres dc P Q (f ()) g - \ corres dc (P and (\s. P')) Q (assert P' >>= f) g" - by (force simp: corres_underlying_def assert_def return_def bind_def fail_def) - lemma corres_assert_assume_r: "corres dc P Q f (g ()) \ corres dc P (Q and (\s. Q')) f (assert Q' >>= g)" diff --git a/proof/refine/X64/TcbAcc_R.thy b/proof/refine/X64/TcbAcc_R.thy index d4a9418bee..a93e6af8f7 100644 --- a/proof/refine/X64/TcbAcc_R.thy +++ b/proof/refine/X64/TcbAcc_R.thy @@ -1561,9 +1561,8 @@ lemma no_fail_asUser [wp]: "no_fail \ f \ no_fail (tcb_at' t) (asUser t f)" apply (simp add: asUser_def split_def) apply wp - apply (simp add: no_fail_def) - apply (wp hoare_drop_imps) - apply simp + apply (simp add: no_fail_def) + apply (wpsimp wp: hoare_drop_imps no_fail_threadGet)+ done lemma asUser_setRegister_corres: diff --git a/proof/refine/X64/Tcb_R.thy b/proof/refine/X64/Tcb_R.thy index 5d33d79026..f90c895e5b 100644 --- a/proof/refine/X64/Tcb_R.thy +++ b/proof/refine/X64/Tcb_R.thy @@ -344,7 +344,7 @@ lemma invokeTCB_WriteRegisters_corres: mask_def user_vtop_def cong: if_cong) apply simp - apply (rule no_fail_pre, wp no_fail_mapM) + apply (wpsimp wp: no_fail_mapM no_fail_setRegister) apply (clarsimp simp: sanitiseOrFlags_def sanitiseAndFlags_def) apply ((safe)[1], (wp no_fail_setRegister | simp)+) apply (rule corres_split_nor[OF asUser_postModifyRegisters_corres[simplified]]) diff --git a/tools/autocorres/tests/examples/FactorialTest.thy b/tools/autocorres/tests/examples/FactorialTest.thy index de0314c599..0cad8e4130 100644 --- a/tools/autocorres/tests/examples/FactorialTest.thy +++ b/tools/autocorres/tests/examples/FactorialTest.thy @@ -47,7 +47,7 @@ proof (induct n arbitrary: m rule: less_induct) show "no_ofail (\_. unat x < m) (factorial' m x)" apply (subst factorial'.simps) - apply (wp induct_asm ovalid_post_triv) + apply (wpsimp wp: induct_asm ovalid_post_triv) apply unat_arith done qed