wenzelm@4870: (* Title: HOL/Record.thy wenzelm@32763: Author: Wolfgang Naraschewski, TU Muenchen wenzelm@32763: Author: Markus Wenzel, TU Muenchen wenzelm@32763: Author: Norbert Schirmer, TU Muenchen wenzelm@32763: Author: Thomas Sewell, NICTA haftmann@33595: Author: Florian Haftmann, TU Muenchen wenzelm@4870: *) wenzelm@4870: wenzelm@22817: header {* Extensible records with structural subtyping *} wenzelm@22817: nipkow@15131: theory Record blanchet@56048: imports Quickcheck_Exhaustive wenzelm@46950: keywords "record" :: thy_decl nipkow@15131: begin wenzelm@4870: haftmann@33595: subsection {* Introduction *} haftmann@33595: haftmann@33595: text {* haftmann@33595: Records are isomorphic to compound tuple types. To implement haftmann@33595: efficient records, we make this isomorphism explicit. Consider the haftmann@33595: record access/update simplification @{text "alpha (beta_update f haftmann@33595: rec) = alpha rec"} for distinct fields alpha and beta of some record haftmann@33595: rec with n fields. There are @{text "n ^ 2"} such theorems, which haftmann@33595: prohibits storage of all of them for large n. The rules can be haftmann@33595: proved on the fly by case decomposition and simplification in O(n) haftmann@33595: time. By creating O(n) isomorphic-tuple types while defining the haftmann@33595: record, however, we can prove the access/update simplification in haftmann@33595: @{text "O(log(n)^2)"} time. haftmann@33595: haftmann@33595: The O(n) cost of case decomposition is not because O(n) steps are haftmann@33595: taken, but rather because the resulting rule must contain O(n) new haftmann@33595: variables and an O(n) size concrete record construction. To sidestep haftmann@33595: this cost, we would like to avoid case decomposition in proving haftmann@33595: access/update theorems. haftmann@33595: haftmann@33595: Record types are defined as isomorphic to tuple types. For instance, haftmann@33595: a record type with fields @{text "'a"}, @{text "'b"}, @{text "'c"} haftmann@33595: and @{text "'d"} might be introduced as isomorphic to @{text "'a \ haftmann@33595: ('b \ ('c \ 'd))"}. If we balance the tuple tree to @{text "('a \ haftmann@33595: 'b) \ ('c \ 'd)"} then accessors can be defined by converting to the haftmann@33595: underlying type then using O(log(n)) fst or snd operations. haftmann@33595: Updators can be defined similarly, if we introduce a @{text haftmann@33595: "fst_update"} and @{text "snd_update"} function. Furthermore, we can haftmann@33595: prove the access/update theorem in O(log(n)) steps by using simple haftmann@33595: rewrites on fst, snd, @{text "fst_update"} and @{text "snd_update"}. haftmann@33595: haftmann@33595: The catch is that, although O(log(n)) steps were taken, the haftmann@33595: underlying type we converted to is a tuple tree of size haftmann@33595: O(n). Processing this term type wastes performance. We avoid this haftmann@33595: for large n by taking each subtree of size K and defining a new type haftmann@33595: isomorphic to that tuple subtree. A record can now be defined as haftmann@33595: isomorphic to a tuple tree of these O(n/K) new types, or, if @{text haftmann@33595: "n > K*K"}, we can repeat the process, until the record can be haftmann@33595: defined in terms of a tuple tree of complexity less than the haftmann@33595: constant K. haftmann@33595: haftmann@33595: If we prove the access/update theorem on this type with the huffman@44922: analogous steps to the tuple tree, we consume @{text "O(log(n)^2)"} haftmann@33595: time as the intermediate terms are @{text "O(log(n))"} in size and huffman@44922: the types needed have size bounded by K. To enable this analogous haftmann@33595: traversal, we define the functions seen below: @{text haftmann@34151: "iso_tuple_fst"}, @{text "iso_tuple_snd"}, @{text "iso_tuple_fst_update"} haftmann@34151: and @{text "iso_tuple_snd_update"}. These functions generalise tuple haftmann@33595: operations by taking a parameter that encapsulates a tuple haftmann@33595: isomorphism. The rewrites needed on these functions now need an haftmann@33595: additional assumption which is that the isomorphism works. haftmann@33595: haftmann@33595: These rewrites are typically used in a structured way. They are here haftmann@33595: presented as the introduction rule @{text "isomorphic_tuple.intros"} haftmann@33595: rather than as a rewrite rule set. The introduction form is an haftmann@33595: optimisation, as net matching can be performed at one term location haftmann@33595: for each step rather than the simplifier searching the term for haftmann@33595: possible pattern matches. The rule set is used as it is viewed haftmann@33595: outside the locale, with the locale assumption (that the isomorphism haftmann@33595: is valid) left as a rule assumption. All rules are structured to aid haftmann@33595: net matching, using either a point-free form or an encapsulating haftmann@33595: predicate. haftmann@33595: *} haftmann@33595: haftmann@33595: subsection {* Operators and lemmas for types isomorphic to tuples *} haftmann@33595: wenzelm@35132: datatype ('a, 'b, 'c) tuple_isomorphism = wenzelm@35132: Tuple_Isomorphism "'a \ 'b \ 'c" "'b \ 'c \ 'a" haftmann@33595: wenzelm@35132: primrec wenzelm@35132: repr :: "('a, 'b, 'c) tuple_isomorphism \ 'a \ 'b \ 'c" where haftmann@34151: "repr (Tuple_Isomorphism r a) = r" haftmann@33595: wenzelm@35132: primrec wenzelm@35132: abst :: "('a, 'b, 'c) tuple_isomorphism \ 'b \ 'c \ 'a" where haftmann@34151: "abst (Tuple_Isomorphism r a) = a" haftmann@33595: wenzelm@35132: definition wenzelm@35132: iso_tuple_fst :: "('a, 'b, 'c) tuple_isomorphism \ 'a \ 'b" where haftmann@34151: "iso_tuple_fst isom = fst \ repr isom" haftmann@33595: wenzelm@35132: definition wenzelm@35132: iso_tuple_snd :: "('a, 'b, 'c) tuple_isomorphism \ 'a \ 'c" where haftmann@34151: "iso_tuple_snd isom = snd \ repr isom" haftmann@33595: wenzelm@35132: definition wenzelm@35132: iso_tuple_fst_update :: wenzelm@35132: "('a, 'b, 'c) tuple_isomorphism \ ('b \ 'b) \ ('a \ 'a)" where haftmann@34151: "iso_tuple_fst_update isom f = abst isom \ apfst f \ repr isom" haftmann@33595: wenzelm@35132: definition wenzelm@35132: iso_tuple_snd_update :: wenzelm@35132: "('a, 'b, 'c) tuple_isomorphism \ ('c \ 'c) \ ('a \ 'a)" where haftmann@34151: "iso_tuple_snd_update isom f = abst isom \ apsnd f \ repr isom" haftmann@33595: wenzelm@35132: definition wenzelm@35132: iso_tuple_cons :: wenzelm@35132: "('a, 'b, 'c) tuple_isomorphism \ 'b \ 'c \ 'a" where haftmann@34151: "iso_tuple_cons isom = curry (abst isom)" haftmann@33595: haftmann@33595: haftmann@33595: subsection {* Logical infrastructure for records *} haftmann@33595: wenzelm@35132: definition wenzelm@35132: iso_tuple_surjective_proof_assist :: "'a \ 'b \ ('a \ 'b) \ bool" where haftmann@34151: "iso_tuple_surjective_proof_assist x y f \ f x = y" haftmann@33595: wenzelm@35132: definition wenzelm@35132: iso_tuple_update_accessor_cong_assist :: wenzelm@35132: "(('b \ 'b) \ ('a \ 'a)) \ ('a \ 'b) \ bool" where haftmann@38394: "iso_tuple_update_accessor_cong_assist upd ac \ haftmann@38394: (\f v. upd (\x. f (ac v)) v = upd f v) \ (\v. upd id v = v)" haftmann@33595: wenzelm@35132: definition wenzelm@35132: iso_tuple_update_accessor_eq_assist :: wenzelm@35132: "(('b \ 'b) \ ('a \ 'a)) \ ('a \ 'b) \ 'a \ ('b \ 'b) \ 'a \ 'b \ bool" where haftmann@38394: "iso_tuple_update_accessor_eq_assist upd ac v f v' x \ haftmann@38394: upd f v = v' \ ac v = x \ iso_tuple_update_accessor_cong_assist upd ac" haftmann@33595: haftmann@33595: lemma update_accessor_congruence_foldE: haftmann@38394: assumes uac: "iso_tuple_update_accessor_cong_assist upd ac" haftmann@38394: and r: "r = r'" and v: "ac r' = v'" wenzelm@35132: and f: "\v. v' = v \ f v = f' v" wenzelm@35132: shows "upd f r = upd f' r'" haftmann@33595: using uac r v [symmetric] haftmann@38394: apply (subgoal_tac "upd (\x. f (ac r')) r' = upd (\x. f' (ac r')) r'") haftmann@34151: apply (simp add: iso_tuple_update_accessor_cong_assist_def) haftmann@33595: apply (simp add: f) haftmann@33595: done haftmann@33595: haftmann@33595: lemma update_accessor_congruence_unfoldE: haftmann@38394: "iso_tuple_update_accessor_cong_assist upd ac \ haftmann@38394: r = r' \ ac r' = v' \ (\v. v = v' \ f v = f' v) \ wenzelm@35132: upd f r = upd f' r'" haftmann@33595: apply (erule(2) update_accessor_congruence_foldE) haftmann@33595: apply simp haftmann@33595: done haftmann@33595: haftmann@34151: lemma iso_tuple_update_accessor_cong_assist_id: haftmann@38394: "iso_tuple_update_accessor_cong_assist upd ac \ upd id = id" haftmann@34151: by rule (simp add: iso_tuple_update_accessor_cong_assist_def) haftmann@33595: haftmann@33595: lemma update_accessor_noopE: haftmann@38394: assumes uac: "iso_tuple_update_accessor_cong_assist upd ac" haftmann@38394: and ac: "f (ac x) = ac x" wenzelm@35132: shows "upd f x = x" wenzelm@35132: using uac haftmann@38394: by (simp add: ac iso_tuple_update_accessor_cong_assist_id [OF uac, unfolded id_def] wenzelm@35132: cong: update_accessor_congruence_unfoldE [OF uac]) haftmann@33595: haftmann@33595: lemma update_accessor_noop_compE: haftmann@38394: assumes uac: "iso_tuple_update_accessor_cong_assist upd ac" haftmann@38394: and ac: "f (ac x) = ac x" wenzelm@35132: shows "upd (g \ f) x = upd g x" haftmann@38394: by (simp add: ac cong: update_accessor_congruence_unfoldE[OF uac]) haftmann@33595: haftmann@33595: lemma update_accessor_cong_assist_idI: haftmann@34151: "iso_tuple_update_accessor_cong_assist id id" haftmann@34151: by (simp add: iso_tuple_update_accessor_cong_assist_def) haftmann@33595: haftmann@33595: lemma update_accessor_cong_assist_triv: haftmann@38394: "iso_tuple_update_accessor_cong_assist upd ac \ haftmann@38394: iso_tuple_update_accessor_cong_assist upd ac" haftmann@33595: by assumption haftmann@33595: haftmann@33595: lemma update_accessor_accessor_eqE: haftmann@38394: "iso_tuple_update_accessor_eq_assist upd ac v f v' x \ ac v = x" haftmann@34151: by (simp add: iso_tuple_update_accessor_eq_assist_def) haftmann@33595: haftmann@33595: lemma update_accessor_updator_eqE: haftmann@38394: "iso_tuple_update_accessor_eq_assist upd ac v f v' x \ upd f v = v'" haftmann@34151: by (simp add: iso_tuple_update_accessor_eq_assist_def) haftmann@33595: haftmann@34151: lemma iso_tuple_update_accessor_eq_assist_idI: haftmann@34151: "v' = f v \ iso_tuple_update_accessor_eq_assist id id v f v' v" haftmann@34151: by (simp add: iso_tuple_update_accessor_eq_assist_def update_accessor_cong_assist_idI) haftmann@33595: haftmann@34151: lemma iso_tuple_update_accessor_eq_assist_triv: haftmann@38394: "iso_tuple_update_accessor_eq_assist upd ac v f v' x \ haftmann@38394: iso_tuple_update_accessor_eq_assist upd ac v f v' x" haftmann@33595: by assumption haftmann@33595: haftmann@34151: lemma iso_tuple_update_accessor_cong_from_eq: haftmann@38394: "iso_tuple_update_accessor_eq_assist upd ac v f v' x \ haftmann@38394: iso_tuple_update_accessor_cong_assist upd ac" haftmann@34151: by (simp add: iso_tuple_update_accessor_eq_assist_def) haftmann@33595: haftmann@34151: lemma iso_tuple_surjective_proof_assistI: haftmann@34151: "f x = y \ iso_tuple_surjective_proof_assist x y f" haftmann@34151: by (simp add: iso_tuple_surjective_proof_assist_def) haftmann@33595: haftmann@34151: lemma iso_tuple_surjective_proof_assist_idE: haftmann@34151: "iso_tuple_surjective_proof_assist x y id \ x = y" haftmann@34151: by (simp add: iso_tuple_surjective_proof_assist_def) haftmann@33595: haftmann@33595: locale isomorphic_tuple = haftmann@33595: fixes isom :: "('a, 'b, 'c) tuple_isomorphism" haftmann@34151: assumes repr_inv: "\x. abst isom (repr isom x) = x" wenzelm@35132: and abst_inv: "\y. repr isom (abst isom y) = y" haftmann@33595: begin haftmann@33595: wenzelm@35132: lemma repr_inj: "repr isom x = repr isom y \ x = y" wenzelm@35132: by (auto dest: arg_cong [of "repr isom x" "repr isom y" "abst isom"] wenzelm@35132: simp add: repr_inv) haftmann@33595: wenzelm@35132: lemma abst_inj: "abst isom x = abst isom y \ x = y" wenzelm@35132: by (auto dest: arg_cong [of "abst isom x" "abst isom y" "repr isom"] wenzelm@35132: simp add: abst_inv) haftmann@34151: haftmann@34151: lemmas simps = Let_def repr_inv abst_inv repr_inj abst_inj haftmann@33595: haftmann@34151: lemma iso_tuple_access_update_fst_fst: haftmann@33595: "f o h g = j o f \ wenzelm@35132: (f o iso_tuple_fst isom) o (iso_tuple_fst_update isom o h) g = wenzelm@35132: j o (f o iso_tuple_fst isom)" haftmann@34151: by (clarsimp simp: iso_tuple_fst_update_def iso_tuple_fst_def simps huffman@44922: fun_eq_iff) haftmann@33595: haftmann@34151: lemma iso_tuple_access_update_snd_snd: haftmann@33595: "f o h g = j o f \ wenzelm@35132: (f o iso_tuple_snd isom) o (iso_tuple_snd_update isom o h) g = wenzelm@35132: j o (f o iso_tuple_snd isom)" haftmann@34151: by (clarsimp simp: iso_tuple_snd_update_def iso_tuple_snd_def simps huffman@44922: fun_eq_iff) haftmann@33595: haftmann@34151: lemma iso_tuple_access_update_fst_snd: wenzelm@35132: "(f o iso_tuple_fst isom) o (iso_tuple_snd_update isom o h) g = wenzelm@35132: id o (f o iso_tuple_fst isom)" haftmann@34151: by (clarsimp simp: iso_tuple_snd_update_def iso_tuple_fst_def simps huffman@44922: fun_eq_iff) haftmann@33595: haftmann@34151: lemma iso_tuple_access_update_snd_fst: wenzelm@35132: "(f o iso_tuple_snd isom) o (iso_tuple_fst_update isom o h) g = wenzelm@35132: id o (f o iso_tuple_snd isom)" haftmann@34151: by (clarsimp simp: iso_tuple_fst_update_def iso_tuple_snd_def simps huffman@44922: fun_eq_iff) haftmann@33595: haftmann@34151: lemma iso_tuple_update_swap_fst_fst: haftmann@33595: "h f o j g = j g o h f \ wenzelm@35132: (iso_tuple_fst_update isom o h) f o (iso_tuple_fst_update isom o j) g = wenzelm@35132: (iso_tuple_fst_update isom o j) g o (iso_tuple_fst_update isom o h) f" huffman@44922: by (clarsimp simp: iso_tuple_fst_update_def simps apfst_compose fun_eq_iff) haftmann@33595: haftmann@34151: lemma iso_tuple_update_swap_snd_snd: haftmann@33595: "h f o j g = j g o h f \ wenzelm@35132: (iso_tuple_snd_update isom o h) f o (iso_tuple_snd_update isom o j) g = wenzelm@35132: (iso_tuple_snd_update isom o j) g o (iso_tuple_snd_update isom o h) f" huffman@44922: by (clarsimp simp: iso_tuple_snd_update_def simps apsnd_compose fun_eq_iff) haftmann@33595: haftmann@34151: lemma iso_tuple_update_swap_fst_snd: wenzelm@35132: "(iso_tuple_snd_update isom o h) f o (iso_tuple_fst_update isom o j) g = wenzelm@35132: (iso_tuple_fst_update isom o j) g o (iso_tuple_snd_update isom o h) f" wenzelm@35132: by (clarsimp simp: iso_tuple_fst_update_def iso_tuple_snd_update_def huffman@44922: simps fun_eq_iff) haftmann@33595: haftmann@34151: lemma iso_tuple_update_swap_snd_fst: wenzelm@35132: "(iso_tuple_fst_update isom o h) f o (iso_tuple_snd_update isom o j) g = wenzelm@35132: (iso_tuple_snd_update isom o j) g o (iso_tuple_fst_update isom o h) f" huffman@44922: by (clarsimp simp: iso_tuple_fst_update_def iso_tuple_snd_update_def simps huffman@44922: fun_eq_iff) haftmann@33595: haftmann@34151: lemma iso_tuple_update_compose_fst_fst: haftmann@33595: "h f o j g = k (f o g) \ wenzelm@35132: (iso_tuple_fst_update isom o h) f o (iso_tuple_fst_update isom o j) g = wenzelm@35132: (iso_tuple_fst_update isom o k) (f o g)" huffman@44922: by (clarsimp simp: iso_tuple_fst_update_def simps apfst_compose fun_eq_iff) haftmann@33595: haftmann@34151: lemma iso_tuple_update_compose_snd_snd: haftmann@33595: "h f o j g = k (f o g) \ wenzelm@35132: (iso_tuple_snd_update isom o h) f o (iso_tuple_snd_update isom o j) g = wenzelm@35132: (iso_tuple_snd_update isom o k) (f o g)" huffman@44922: by (clarsimp simp: iso_tuple_snd_update_def simps apsnd_compose fun_eq_iff) haftmann@33595: haftmann@34151: lemma iso_tuple_surjective_proof_assist_step: haftmann@34151: "iso_tuple_surjective_proof_assist v a (iso_tuple_fst isom o f) \ wenzelm@35132: iso_tuple_surjective_proof_assist v b (iso_tuple_snd isom o f) \ wenzelm@35132: iso_tuple_surjective_proof_assist v (iso_tuple_cons isom a b) f" haftmann@34151: by (clarsimp simp: iso_tuple_surjective_proof_assist_def simps haftmann@34151: iso_tuple_fst_def iso_tuple_snd_def iso_tuple_cons_def) haftmann@33595: haftmann@34151: lemma iso_tuple_fst_update_accessor_cong_assist: haftmann@34151: assumes "iso_tuple_update_accessor_cong_assist f g" wenzelm@35132: shows "iso_tuple_update_accessor_cong_assist wenzelm@35132: (iso_tuple_fst_update isom o f) (g o iso_tuple_fst isom)" haftmann@33595: proof - wenzelm@35132: from assms have "f id = id" wenzelm@35132: by (rule iso_tuple_update_accessor_cong_assist_id) wenzelm@35132: with assms show ?thesis wenzelm@35132: by (clarsimp simp: iso_tuple_update_accessor_cong_assist_def simps wenzelm@35132: iso_tuple_fst_update_def iso_tuple_fst_def) haftmann@33595: qed haftmann@33595: haftmann@34151: lemma iso_tuple_snd_update_accessor_cong_assist: haftmann@34151: assumes "iso_tuple_update_accessor_cong_assist f g" wenzelm@35132: shows "iso_tuple_update_accessor_cong_assist wenzelm@35132: (iso_tuple_snd_update isom o f) (g o iso_tuple_snd isom)" haftmann@33595: proof - wenzelm@35132: from assms have "f id = id" wenzelm@35132: by (rule iso_tuple_update_accessor_cong_assist_id) wenzelm@35132: with assms show ?thesis wenzelm@35132: by (clarsimp simp: iso_tuple_update_accessor_cong_assist_def simps wenzelm@35132: iso_tuple_snd_update_def iso_tuple_snd_def) haftmann@33595: qed haftmann@33595: haftmann@34151: lemma iso_tuple_fst_update_accessor_eq_assist: haftmann@34151: assumes "iso_tuple_update_accessor_eq_assist f g a u a' v" wenzelm@35132: shows "iso_tuple_update_accessor_eq_assist wenzelm@35132: (iso_tuple_fst_update isom o f) (g o iso_tuple_fst isom) haftmann@34151: (iso_tuple_cons isom a b) u (iso_tuple_cons isom a' b) v" haftmann@33595: proof - haftmann@33595: from assms have "f id = id" wenzelm@35132: by (auto simp add: iso_tuple_update_accessor_eq_assist_def wenzelm@35132: intro: iso_tuple_update_accessor_cong_assist_id) wenzelm@35132: with assms show ?thesis wenzelm@35132: by (clarsimp simp: iso_tuple_update_accessor_eq_assist_def wenzelm@35132: iso_tuple_fst_update_def iso_tuple_fst_def wenzelm@35132: iso_tuple_update_accessor_cong_assist_def iso_tuple_cons_def simps) haftmann@33595: qed haftmann@33595: haftmann@34151: lemma iso_tuple_snd_update_accessor_eq_assist: haftmann@34151: assumes "iso_tuple_update_accessor_eq_assist f g b u b' v" wenzelm@35132: shows "iso_tuple_update_accessor_eq_assist wenzelm@35132: (iso_tuple_snd_update isom o f) (g o iso_tuple_snd isom) haftmann@34151: (iso_tuple_cons isom a b) u (iso_tuple_cons isom a b') v" haftmann@33595: proof - haftmann@33595: from assms have "f id = id" wenzelm@35132: by (auto simp add: iso_tuple_update_accessor_eq_assist_def wenzelm@35132: intro: iso_tuple_update_accessor_cong_assist_id) wenzelm@35132: with assms show ?thesis wenzelm@35132: by (clarsimp simp: iso_tuple_update_accessor_eq_assist_def wenzelm@35132: iso_tuple_snd_update_def iso_tuple_snd_def wenzelm@35132: iso_tuple_update_accessor_cong_assist_def iso_tuple_cons_def simps) haftmann@33595: qed haftmann@33595: haftmann@34151: lemma iso_tuple_cons_conj_eqI: haftmann@33595: "a = c \ b = d \ P \ Q \ haftmann@34151: iso_tuple_cons isom a b = iso_tuple_cons isom c d \ P \ Q" haftmann@34151: by (clarsimp simp: iso_tuple_cons_def simps) haftmann@33595: haftmann@33595: lemmas intros = wenzelm@35132: iso_tuple_access_update_fst_fst wenzelm@35132: iso_tuple_access_update_snd_snd wenzelm@35132: iso_tuple_access_update_fst_snd wenzelm@35132: iso_tuple_access_update_snd_fst wenzelm@35132: iso_tuple_update_swap_fst_fst wenzelm@35132: iso_tuple_update_swap_snd_snd wenzelm@35132: iso_tuple_update_swap_fst_snd wenzelm@35132: iso_tuple_update_swap_snd_fst wenzelm@35132: iso_tuple_update_compose_fst_fst wenzelm@35132: iso_tuple_update_compose_snd_snd wenzelm@35132: iso_tuple_surjective_proof_assist_step wenzelm@35132: iso_tuple_fst_update_accessor_eq_assist wenzelm@35132: iso_tuple_snd_update_accessor_eq_assist wenzelm@35132: iso_tuple_fst_update_accessor_cong_assist wenzelm@35132: iso_tuple_snd_update_accessor_cong_assist wenzelm@35132: iso_tuple_cons_conj_eqI haftmann@33595: haftmann@33595: end haftmann@33595: haftmann@33595: lemma isomorphic_tuple_intro: haftmann@33595: fixes repr abst haftmann@33595: assumes repr_inj: "\x y. repr x = repr y \ x = y" wenzelm@35132: and abst_inv: "\z. repr (abst z) = z" wenzelm@35132: and v: "v \ Tuple_Isomorphism repr abst" haftmann@33595: shows "isomorphic_tuple v" haftmann@34151: proof wenzelm@35132: fix x have "repr (abst (repr x)) = repr x" haftmann@34151: by (simp add: abst_inv) wenzelm@35132: then show "Record.abst v (Record.repr v x) = x" haftmann@34151: by (simp add: v repr_inj) wenzelm@35132: next wenzelm@35132: fix y wenzelm@35132: show "Record.repr v (Record.abst v y) = y" haftmann@34151: by (simp add: v) (fact abst_inv) haftmann@34151: qed haftmann@33595: haftmann@33595: definition haftmann@34151: "tuple_iso_tuple \ Tuple_Isomorphism id id" haftmann@33595: haftmann@34151: lemma tuple_iso_tuple: haftmann@34151: "isomorphic_tuple tuple_iso_tuple" haftmann@34151: by (simp add: isomorphic_tuple_intro [OF _ _ reflexive] tuple_iso_tuple_def) haftmann@33595: wenzelm@35132: lemma refl_conj_eq: "Q = R \ P \ Q \ P \ R" haftmann@33595: by simp haftmann@33595: blanchet@54147: lemma iso_tuple_UNIV_I: "x \ UNIV \ True" haftmann@33595: by simp haftmann@33595: haftmann@34151: lemma iso_tuple_True_simp: "(True \ PROP P) \ PROP P" haftmann@33595: by simp haftmann@33595: schirmer@14700: lemma prop_subst: "s = t \ PROP P t \ PROP P s" schirmer@14700: by simp wenzelm@11826: wenzelm@35132: lemma K_record_comp: "(\x. c) \ f = (\x. c)" schirmer@25705: by (simp add: comp_def) wenzelm@11821: haftmann@33595: wenzelm@11833: subsection {* Concrete record syntax *} wenzelm@4870: wenzelm@41229: nonterminal wenzelm@41229: ident and wenzelm@41229: field_type and wenzelm@41229: field_types and wenzelm@41229: field and wenzelm@41229: fields and wenzelm@41229: field_update and wenzelm@41229: field_updates wenzelm@41229: wenzelm@4870: syntax wenzelm@11821: "_constify" :: "id => ident" ("_") wenzelm@11821: "_constify" :: "longid => ident" ("_") wenzelm@5198: wenzelm@35144: "_field_type" :: "ident => type => field_type" ("(2_ ::/ _)") wenzelm@11821: "" :: "field_type => field_types" ("_") wenzelm@35144: "_field_types" :: "field_type => field_types => field_types" ("_,/ _") wenzelm@11821: "_record_type" :: "field_types => type" ("(3'(| _ |'))") wenzelm@35144: "_record_type_scheme" :: "field_types => type => type" ("(3'(| _,/ (2... ::/ _) |'))") wenzelm@5198: wenzelm@35144: "_field" :: "ident => 'a => field" ("(2_ =/ _)") wenzelm@11821: "" :: "field => fields" ("_") wenzelm@35144: "_fields" :: "field => fields => fields" ("_,/ _") wenzelm@11821: "_record" :: "fields => 'a" ("(3'(| _ |'))") wenzelm@35144: "_record_scheme" :: "fields => 'a => 'a" ("(3'(| _,/ (2... =/ _) |'))") wenzelm@5198: wenzelm@35146: "_field_update" :: "ident => 'a => field_update" ("(2_ :=/ _)") wenzelm@35146: "" :: "field_update => field_updates" ("_") wenzelm@35146: "_field_updates" :: "field_update => field_updates => field_updates" ("_,/ _") wenzelm@35146: "_record_update" :: "'a => field_updates => 'b" ("_/(3'(| _ |'))" [900, 0] 900) wenzelm@4870: wenzelm@10331: syntax (xsymbols) wenzelm@11821: "_record_type" :: "field_types => type" ("(3\_\)") wenzelm@35132: "_record_type_scheme" :: "field_types => type => type" ("(3\_,/ (2\ ::/ _)\)") wenzelm@35132: "_record" :: "fields => 'a" ("(3\_\)") wenzelm@35132: "_record_scheme" :: "fields => 'a => 'a" ("(3\_,/ (2\ =/ _)\)") wenzelm@35146: "_record_update" :: "'a => field_updates => 'b" ("_/(3\_\)" [900, 0] 900) wenzelm@9729: tsewell@32752: haftmann@33595: subsection {* Record package *} tsewell@32752: wenzelm@56732: ML_file "Tools/record.ML" wenzelm@10641: wenzelm@36176: hide_const (open) Tuple_Isomorphism repr abst iso_tuple_fst iso_tuple_snd haftmann@34151: iso_tuple_fst_update iso_tuple_snd_update iso_tuple_cons haftmann@34151: iso_tuple_surjective_proof_assist iso_tuple_update_accessor_cong_assist haftmann@34151: iso_tuple_update_accessor_eq_assist tuple_iso_tuple haftmann@33595: wenzelm@4870: end