(* * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) * * SPDX-License-Identifier: BSD-2-Clause *) (* Lemmas and automation for automatically cancelling shared parts of the heap predicate * in a sep_fold *) theory Sep_Fold_Cancel imports Sep_Algebra_L4v Sep_Forward begin lemma sep_fold_cong1: "(\x s. P x s = P' x s) \ sep_fold P Q R xs s \ sep_fold P' Q R xs s" apply (induct xs arbitrary: s; clarsimp simp: sep_fold_def) apply (erule sep_conj_impl, fastforce) apply (sep_cancel, sep_mp) by (clarsimp) lemma sep_fold_cong2: "(\x s. Q x s = Q' x s) \ sep_fold P Q R xs s \ sep_fold P Q' R xs s" apply (induct xs arbitrary: s; clarsimp simp: sep_fold_def) apply (erule sep_conj_impl, fastforce) apply (sep_cancel) apply (sep_drule (direct) sep_mp_gen) by (clarsimp) lemma sep_fold_cong3: "(\ s. R s = R' s) \ sep_fold P Q R xs s \ sep_fold P Q R' xs s" apply (induct xs arbitrary: s; clarsimp simp: sep_fold_def) apply (erule sep_conj_impl, fastforce) apply (sep_cancel) apply (sep_drule (direct) sep_mp_gen) by (clarsimp) lemma sep_fold_strengthen_final: "\\s. R s \ R' s; \{P} \* {Q} \* {R}\ xs s\ \ \{P} \* {Q} \* {R'}\ xs s" apply (induct xs arbitrary: s) apply (clarsimp simp: sep_fold_def) apply (clarsimp simp: sep_fold_def) apply (sep_cancel)+ apply (sep_mp) apply (clarsimp) done lemma sep_factor_foldI__: "(\* map P xs \* foldr (\x R. Q x \* R) xs R) s \ sep_fold P Q R xs s" apply (clarsimp simp: sep_fold_def) apply (induct xs arbitrary: s; clarsimp) apply sep_cancel+ apply sep_mp apply (clarsimp simp: sep_conj_ac) done lemma sep_factor_foldI_: "(\* map (\_. I) xs \* sep_fold P Q R xs) s \ sep_fold (\x. I \* P x) Q R xs s" apply (induct xs arbitrary: s) apply (clarsimp simp: sep_fold_def) apply (clarsimp simp: sep_fold_def) apply (sep_cancel+, clarsimp, sep_mp) apply (clarsimp simp: sep_conj_ac) done lemma sep_factor_foldI': "(I \* (sep_fold P Q (I \* R) xs)) s \ sep_fold (\x. I \* P x) (\x. I \* Q x) R xs s" apply (induct xs arbitrary:s; clarsimp simp: sep_fold_def) apply (sep_solve) apply (sep_cancel)+ apply (sep_mp) apply (clarsimp simp: sep_conj_ac) done lemma sep_factor_foldI'': "(\s. R s \ (R' \* (R' \* R)) s) \ precise R' \ (R' \* sep_fold P Q (R' -* R) xs) s \ sep_fold (\x. R' \* P x) (\x. R' \* Q x) R xs s" apply (induct xs arbitrary:s; clarsimp simp: sep_fold_def) apply (erule septract_mp[where R'=R']) apply (assumption)+ apply (clarsimp simp: sep_conj_ac) apply (sep_cancel)+ apply (sep_mp) by (clarsimp simp: sep_conj_ac) ML \ fun sep_fold_tactic ctxt = rotator' ctxt (resolve_tac ctxt [@{thm sep_fold_cong2 }]) (resolve_tac ctxt [@{thm sep_factor_foldI' }]) |> rotator' ctxt (resolve_tac ctxt [@{thm sep_fold_cong1 }]); \ method_setup sep_fold_cancel_inner = \Scan.succeed (SIMPLE_METHOD' o sep_fold_tactic)\ \Simple elimination of conjuncts\ (* Cancels out shared resources according to the rule sep_factor_foldI' *) lemma sep_map_set_sep_foldI: "distinct xs \ (sep_map_set_conj P (set xs) \* (sep_map_set_conj Q (set xs) \* R)) s \ \{P} \* {Q} \* {R}\ xs s" apply (induct xs arbitrary: s; clarsimp simp: sep_fold_def) apply (sep_solve) apply (sep_cancel)+ apply (sep_mp) apply (clarsimp simp: sep_conj_ac) done lemma sep_fold_pure: "P \ sep_fold P' Q R xs s \ sep_fold (\x s. P \ P' x s) Q R xs s " by (clarsimp simp: sep_fold_def) lemma sep_fold_pure': "sep_fold P' Q R xs s \ (\x. x \ set xs \ P x) \ sep_fold (\x s. P x \ P' x s) Q R xs s " apply (clarsimp simp: sep_fold_def) apply (induct xs arbitrary: s; clarsimp) apply (sep_cancel)+ apply (sep_mp) apply (clarsimp) done lemma sep_fold_pure'': "sep_fold P' Q R xs s \ (\x. x \ set xs \ P x) \ sep_fold (\x s. P' x s \ P x ) Q R xs s " apply (clarsimp simp: sep_fold_def) apply (induct xs arbitrary: s; clarsimp) apply (sep_cancel)+ apply (sep_mp) apply (clarsimp) done method sep_fold_cancel = ( sep_flatten?, ((rule sep_fold_pure' sep_fold_pure'')+)?, (sep_fold_cancel_inner, sep_cancel, sep_flatten?)+ ) end