(*Gottfried Barrow*) theory dID_lifting imports Complex_Main begin (******************************************************************************) (* dID: Relator and predicator properties, adapted from Lifting_Option.thy *) (******************************************************************************) datatype 'a dID = dIDc 'a primrec dIDget :: "'a dID => 'a" where "dIDget (dIDc x) = x" definition dID_rel :: "('a => 'b => bool) => 'a dID => 'b dID => bool" where "dID_rel R x y = (case (x, y) of (dIDc x, dIDc y) => R x y)" lemma dID_rel_simp [simp]: "dID_rel R (dIDc x) (dIDc y) = R x y" by(simp add: dID_rel_def) lemma dID_rel_eq [relator_eq]: "dID_rel (op =) = (op =)" by (simp add: dID_rel_def fun_eq_iff split: dID.split) lemma dID_rel_mono [relator_mono]: assumes "A \ B" shows "(dID_rel A) \ (dID_rel B)" using assms by (auto simp: dID_rel_def split: dID.splits) lemma dID_rel_OO [relator_distr]: "(dID_rel A) OO (dID_rel B) = dID_rel (A OO B)" apply(rule ext)+ apply(auto simp: dID_rel_def OO_def split: dID.split) by(metis dID.exhaust) lemma Domainp_dID [relator_domain]: assumes "Domainp A = P" shows "Domainp (dID_rel A) = (dID_case P)" using assms unfolding Domainp_iff[abs_def] dID_rel_def[abs_def] apply(auto iff: fun_eq_iff split: dID.split) apply (metis (full_types) dID.cases dID.exhaust) by(metis dID.cases) lemma reflp_dID_rel[reflexivity_rule]: "reflp R ==> reflp (dID_rel R)" unfolding reflp_def dID.split by(metis dID.exhaust dID_rel_simp) lemma left_total_dID_rel[reflexivity_rule]: "left_total R ==> left_total (dID_rel R)" unfolding left_total_def dID.split by(metis dID.exhaust dID_rel_simp) lemma left_unique_dID_rel [reflexivity_rule]: "left_unique R ==> left_unique (dID_rel R)" unfolding left_unique_def dID.split by(metis dID.exhaust dID_rel_simp) lemma right_total_dID_rel [transfer_rule]: "right_total R ==> right_total (dID_rel R)" unfolding right_total_def dID.split by(metis dID.exhaust dID_rel_simp) lemma right_unique_dID_rel [transfer_rule]: "right_unique R ==> right_unique (dID_rel R)" unfolding right_unique_def dID.split by(metis dID.exhaust dID_rel_simp) lemma bi_total_dID_rel [transfer_rule]: "bi_total R ==> bi_total (dID_rel R)" unfolding bi_total_def dID.split by(metis dID.exhaust dID_rel_simp) lemma bi_unique_dID_rel [transfer_rule]: "bi_unique R ==> bi_unique (dID_rel R)" unfolding bi_unique_def dID.split by(metis dID.exhaust dID_rel_simp dIDget.simps) lemma dID_invariant_commute [invariant_commute]: "dID_rel (Lifting.invariant P) = Lifting.invariant (dID_case P)" apply(auto simp add: fun_eq_iff Lifting.invariant_def dID.split) apply(metis (lifting, no_types) Domainp.DomainI Domainp.cases Domainp_dID dID.cases dID.exhaust) apply(metis (lifting, full_types) dID.exhaust dID_rel_simp) by(metis (lifting, mono_tags) dID.cases dID.exhaust dID_rel_def prod_caseI) (******************************************************************************) (* dID: Quotient theorem for the Lifting package *) (******************************************************************************) (*MY MAP: Based on Option.map in Option.thy.*) definition dID_map :: "('a => 'b) => 'a dID => 'b dID" where "dID_map = (%f x. case x of dIDc x => dIDc (f x))" lemma Quotient_dID [quot_map]: assumes "Quotient R Abs Rep T" shows "Quotient (dID_rel R) (dID_map Abs) (dID_map Rep) (dID_rel T)" using assms unfolding Quotient_alt_def dID_rel_def apply(simp split: dID.split) by(smt dID.cases dID.inject dID_map_def) (******************************************************************************) (* dID: Transfer rules for the Transfer package *) (******************************************************************************) context begin interpretation lifting_syntax . lemma dIDc_transfer [transfer_rule]: "(A ===> dID_rel A) dIDc dIDc" unfolding fun_rel_def by simp lemma dID_case_transfer [transfer_rule]: "((A ===> B) ===> dID_rel A ===> B) dID_case dID_case" unfolding fun_rel_def dID.split apply(auto) by(metis dID.cases dID.exhaust dID_rel_simp) lemma dID_map_transfer [transfer_rule]: "((A ===> B) ===> dID_rel A ===> dID_rel B) dID_map dID_map" unfolding dID_map_def by transfer_prover (*MY BIND: Based on Option.bind in Option.thy.*) primrec dID_bind :: "'a dID => ('a => 'b dID) => 'b dID" where "dID_bind (dIDc x) f = f x" lemma dID_bind_transfer [transfer_rule]: "(dID_rel A ===> (A ===> dID_rel B) ===> dID_rel B) dID_bind dID_bind" unfolding fun_rel_def dID.split by(metis dID.exhaust dID_bind.simps dID_rel_simp) end (******************************************************************************) end