kuncar@53012: (* Title: HOL/Lifting_Option.thy kuncar@53012: Author: Brian Huffman and Ondrej Kuncar kuncar@53012: *) kuncar@53012: kuncar@53012: header {* Setup for Lifting/Transfer for the option type *} kuncar@53012: kuncar@53012: theory Lifting_Option traytel@53026: imports Lifting kuncar@53012: begin kuncar@53012: kuncar@53012: subsection {* Relator and predicator properties *} kuncar@53012: traytel@53026: definition kuncar@53012: option_rel :: "('a \ 'b \ bool) \ 'a option \ 'b option \ bool" kuncar@53012: where kuncar@53012: "option_rel R x y = (case (x, y) of (None, None) \ True kuncar@53012: | (Some x, Some y) \ R x y kuncar@53012: | _ \ False)" kuncar@53012: traytel@53026: lemma option_rel_simps[simp]: traytel@53026: "option_rel R None None = True" traytel@53026: "option_rel R (Some x) None = False" traytel@53026: "option_rel R None (Some y) = False" traytel@53026: "option_rel R (Some x) (Some y) = R x y" traytel@53026: unfolding option_rel_def by simp_all kuncar@53012: traytel@53026: abbreviation (input) option_pred :: "('a \ bool) \ 'a option \ bool" where traytel@53026: "option_pred \ option_case True" kuncar@53012: kuncar@53012: lemma option_rel_eq [relator_eq]: kuncar@53012: "option_rel (op =) = (op =)" traytel@53026: by (simp add: option_rel_def fun_eq_iff split: option.split) kuncar@53012: kuncar@53012: lemma option_rel_mono[relator_mono]: kuncar@53012: assumes "A \ B" kuncar@53012: shows "(option_rel A) \ (option_rel B)" traytel@53026: using assms by (auto simp: option_rel_def split: option.splits) kuncar@53012: kuncar@53012: lemma option_rel_OO[relator_distr]: kuncar@53012: "(option_rel A) OO (option_rel B) = option_rel (A OO B)" traytel@53026: by (rule ext)+ (auto simp: option_rel_def OO_def split: option.split) kuncar@53012: kuncar@53012: lemma Domainp_option[relator_domain]: kuncar@53012: assumes "Domainp A = P" kuncar@53012: shows "Domainp (option_rel A) = (option_pred P)" traytel@53026: using assms unfolding Domainp_iff[abs_def] option_rel_def[abs_def] kuncar@53012: by (auto iff: fun_eq_iff split: option.split) kuncar@53012: kuncar@53012: lemma reflp_option_rel[reflexivity_rule]: kuncar@53012: "reflp R \ reflp (option_rel R)" kuncar@53012: unfolding reflp_def split_option_all by simp kuncar@53012: kuncar@53012: lemma left_total_option_rel[reflexivity_rule]: kuncar@53012: "left_total R \ left_total (option_rel R)" kuncar@53012: unfolding left_total_def split_option_all split_option_ex by simp kuncar@53012: kuncar@53012: lemma left_unique_option_rel [reflexivity_rule]: kuncar@53012: "left_unique R \ left_unique (option_rel R)" kuncar@53012: unfolding left_unique_def split_option_all by simp kuncar@53012: kuncar@53012: lemma right_total_option_rel [transfer_rule]: kuncar@53012: "right_total R \ right_total (option_rel R)" kuncar@53012: unfolding right_total_def split_option_all split_option_ex by simp kuncar@53012: kuncar@53012: lemma right_unique_option_rel [transfer_rule]: kuncar@53012: "right_unique R \ right_unique (option_rel R)" kuncar@53012: unfolding right_unique_def split_option_all by simp kuncar@53012: kuncar@53012: lemma bi_total_option_rel [transfer_rule]: kuncar@53012: "bi_total R \ bi_total (option_rel R)" kuncar@53012: unfolding bi_total_def split_option_all split_option_ex by simp kuncar@53012: kuncar@53012: lemma bi_unique_option_rel [transfer_rule]: kuncar@53012: "bi_unique R \ bi_unique (option_rel R)" kuncar@53012: unfolding bi_unique_def split_option_all by simp kuncar@53012: kuncar@53012: lemma option_invariant_commute [invariant_commute]: kuncar@53012: "option_rel (Lifting.invariant P) = Lifting.invariant (option_pred P)" kuncar@53012: by (auto simp add: fun_eq_iff Lifting.invariant_def split_option_all) kuncar@53012: kuncar@53012: subsection {* Quotient theorem for the Lifting package *} kuncar@53012: kuncar@53012: lemma Quotient_option[quot_map]: kuncar@53012: assumes "Quotient R Abs Rep T" kuncar@53012: shows "Quotient (option_rel R) (Option.map Abs) kuncar@53012: (Option.map Rep) (option_rel T)" traytel@53026: using assms unfolding Quotient_alt_def option_rel_def kuncar@53012: by (simp split: option.split) kuncar@53012: kuncar@53012: subsection {* Transfer rules for the Transfer package *} kuncar@53012: kuncar@53012: context kuncar@53012: begin kuncar@53012: interpretation lifting_syntax . kuncar@53012: kuncar@53012: lemma None_transfer [transfer_rule]: "(option_rel A) None None" kuncar@53012: by simp kuncar@53012: kuncar@53012: lemma Some_transfer [transfer_rule]: "(A ===> option_rel A) Some Some" kuncar@53012: unfolding fun_rel_def by simp kuncar@53012: kuncar@53012: lemma option_case_transfer [transfer_rule]: kuncar@53012: "(B ===> (A ===> B) ===> option_rel A ===> B) option_case option_case" kuncar@53012: unfolding fun_rel_def split_option_all by simp kuncar@53012: kuncar@53012: lemma option_map_transfer [transfer_rule]: kuncar@53012: "((A ===> B) ===> option_rel A ===> option_rel B) Option.map Option.map" kuncar@53012: unfolding Option.map_def by transfer_prover kuncar@53012: kuncar@53012: lemma option_bind_transfer [transfer_rule]: kuncar@53012: "(option_rel A ===> (A ===> option_rel B) ===> option_rel B) kuncar@53012: Option.bind Option.bind" kuncar@53012: unfolding fun_rel_def split_option_all by simp kuncar@53012: kuncar@53012: end kuncar@53012: kuncar@53012: end kuncar@53012: