11 |
11 |
12 subsection {* Abstract product types *} |
12 subsection {* Abstract product types *} |
13 |
13 |
14 constdefs |
14 constdefs |
15 product_type :: "('p => 'a * 'b) => ('a * 'b => 'p) => |
15 product_type :: "('p => 'a * 'b) => ('a * 'b => 'p) => |
16 ('a => 'b => 'p) => ('p \<Rightarrow> 'a) => ('p => 'b) => bool" |
16 ('a => 'b => 'p) => ('p => 'a) => ('p => 'b) => bool" |
17 "product_type Rep Abs pair dest1 dest2 == |
17 "product_type Rep Abs pair dest1 dest2 == |
18 type_definition Rep Abs UNIV \<and> |
18 type_definition Rep Abs UNIV \<and> |
19 pair = (\<lambda>a b. Abs (a, b)) \<and> |
19 pair = (\<lambda>a b. Abs (a, b)) \<and> |
20 dest1 = (\<lambda>p. fst (Rep p)) \<and> |
20 dest1 = (\<lambda>p. fst (Rep p)) \<and> |
21 dest2 = (\<lambda>p. snd (Rep p))" |
21 dest2 = (\<lambda>p. snd (Rep p))" |
22 |
22 |
23 lemma product_typeI: |
23 lemma product_typeI: |
24 "type_definition Rep Abs UNIV ==> |
24 "type_definition Rep Abs UNIV ==> |
25 pair == \<lambda>a b. Abs (a, b) ==> |
25 pair == \<lambda>a b. Abs (a, b) ==> |
26 dest1 == (\<lambda>p. fst (Rep p)) \<Longrightarrow> |
26 dest1 == (\<lambda>p. fst (Rep p)) ==> |
27 dest2 == (\<lambda>p. snd (Rep p)) \<Longrightarrow> |
27 dest2 == (\<lambda>p. snd (Rep p)) ==> |
28 product_type Rep Abs pair dest1 dest2" |
28 product_type Rep Abs pair dest1 dest2" |
29 by (simp add: product_type_def) |
29 by (simp add: product_type_def) |
30 |
30 |
31 lemma product_type_typedef: |
31 lemma product_type_typedef: |
32 "product_type Rep Abs pair dest1 dest2 ==> type_definition Rep Abs UNIV" |
32 "product_type Rep Abs pair dest1 dest2 ==> type_definition Rep Abs UNIV" |
91 qed |
91 qed |
92 qed |
92 qed |
93 |
93 |
94 theorem product_type_cases [cases set: product_type]: |
94 theorem product_type_cases [cases set: product_type]: |
95 "product_type Rep Abs pair dest1 dest2 ==> |
95 "product_type Rep Abs pair dest1 dest2 ==> |
96 (!!x y. p = pair x y \<Longrightarrow> C) ==> C" |
96 (!!x y. p = pair x y ==> C) ==> C" |
97 proof - |
97 proof - |
98 assume prod_type: "product_type Rep Abs pair dest1 dest2" |
98 assume prod_type: "product_type Rep Abs pair dest1 dest2" |
99 assume "!!x y. p = pair x y \<Longrightarrow> C" |
99 assume "!!x y. p = pair x y ==> C" |
100 with prod_type show C |
100 with prod_type show C |
101 by (induct p) (simp only: product_type_inject [OF prod_type], blast) |
101 by (induct p) (simp only: product_type_inject [OF prod_type], blast) |
102 qed |
102 qed |
103 |
103 |
104 theorem product_type_surjective_pairing: |
104 theorem product_type_surjective_pairing: |
110 (simp add: product_type_conv1 [OF rule_context] product_type_conv2 [OF rule_context]) |
110 (simp add: product_type_conv1 [OF rule_context] product_type_conv2 [OF rule_context]) |
111 qed |
111 qed |
112 |
112 |
113 theorem product_type_split_paired_all: |
113 theorem product_type_split_paired_all: |
114 "product_type Rep Abs pair dest1 dest2 ==> |
114 "product_type Rep Abs pair dest1 dest2 ==> |
115 (\<And>x. PROP P x) \<equiv> (\<And>a b. PROP P (pair a b))" |
115 (!!x. PROP P x) == (!!a b. PROP P (pair a b))" |
116 proof |
116 proof |
117 fix a b |
117 fix a b |
118 assume "!!x. PROP P x" |
118 assume "!!x. PROP P x" |
119 thus "PROP P (pair a b)" . |
119 thus "PROP P (pair a b)" . |
120 next |
120 next |
124 hence "PROP P (pair (dest1 x) (dest2 x))" . |
124 hence "PROP P (pair (dest1 x) (dest2 x))" . |
125 thus "PROP P x" by (simp only: product_type_surjective_pairing [OF rule_context, symmetric]) |
125 thus "PROP P x" by (simp only: product_type_surjective_pairing [OF rule_context, symmetric]) |
126 qed |
126 qed |
127 |
127 |
128 |
128 |
129 text {* \medskip Type class for record extensions. *} |
129 subsection {* Type class for record extensions *} |
130 |
130 |
131 axclass more < "term" |
131 axclass more < "term" |
132 instance unit :: more .. |
132 instance unit :: more .. |
133 |
133 |
134 |
134 |
135 subsection {* Record package setup *} |
135 subsection {* Concrete record syntax *} |
136 |
|
137 use "Tools/record_package.ML" |
|
138 setup RecordPackage.setup |
|
139 |
|
140 |
|
141 subsection {* Concrete syntax *} |
|
142 |
136 |
143 nonterminals |
137 nonterminals |
144 ident field_type field_types field fields update updates |
138 ident field_type field_types field fields update updates |
145 |
139 |
146 syntax |
140 syntax |
170 "_record_type_scheme" :: "[field_types, type] => type" ("(3\<lparr>_,/ (2\<dots> ::/ _)\<rparr>)") |
164 "_record_type_scheme" :: "[field_types, type] => type" ("(3\<lparr>_,/ (2\<dots> ::/ _)\<rparr>)") |
171 "_record" :: "fields => 'a" ("(3\<lparr>_\<rparr>)") |
165 "_record" :: "fields => 'a" ("(3\<lparr>_\<rparr>)") |
172 "_record_scheme" :: "[fields, 'a] => 'a" ("(3\<lparr>_,/ (2\<dots> =/ _)\<rparr>)") |
166 "_record_scheme" :: "[fields, 'a] => 'a" ("(3\<lparr>_,/ (2\<dots> =/ _)\<rparr>)") |
173 "_record_update" :: "['a, updates] => 'b" ("_/(3\<lparr>_\<rparr>)" [900,0] 900) |
167 "_record_update" :: "['a, updates] => 'b" ("_/(3\<lparr>_\<rparr>)" [900,0] 900) |
174 |
168 |
175 parse_translation {* |
169 |
176 let |
170 subsection {* Package setup *} |
177 fun update_name_tr (Free (x, T) :: ts) = |
171 |
178 Term.list_comb (Free (suffix RecordPackage.updateN x, T), ts) |
172 use "Tools/record_package.ML" |
179 | update_name_tr (Const (x, T) :: ts) = |
173 setup RecordPackage.setup |
180 Term.list_comb (Const (suffix RecordPackage.updateN x, T), ts) |
|
181 | update_name_tr (((c as Const ("_constrain", _)) $ t $ ty) :: ts) = |
|
182 Term.list_comb (c $ update_name_tr [t] $ |
|
183 (Syntax.const "fun" $ ty $ Syntax.const "dummy"), ts) |
|
184 | update_name_tr ts = raise TERM ("update_name_tr", ts); |
|
185 in [("_update_name", update_name_tr)] end |
|
186 *} |
|
187 |
174 |
188 end |
175 end |