1 (* Title: HOL/ex/Points.thy |
1 (* Title: HOL/ex/Points.thy |
2 ID: $Id$ |
2 ID: $Id$ |
3 Author: Wolfgang Naraschewski and Markus Wenzel, TU Muenchen |
3 Author: Wolfgang Naraschewski and Markus Wenzel, TU Muenchen |
4 |
|
5 Basic use of extensible records in HOL, including the famous points |
|
6 and coloured points. |
|
7 *) |
4 *) |
8 |
5 |
9 Points = Main + |
6 theory Points = Main:; |
|
7 |
|
8 title "Basic use of extensible records in HOL, including the famous points |
|
9 and coloured points."; |
10 |
10 |
11 |
11 |
12 (** points **) |
12 section "Points"; |
13 |
13 |
14 record point = |
14 record point = |
15 x :: nat |
15 x :: nat |
16 y :: nat |
16 y :: nat; |
17 |
17 |
18 (* |
18 text {| |
19 To find out, which theorems are produced by the record declaration, |
19 Apart many other things, above record declaration produces the |
20 type the following commands: |
20 following theorems: |
21 |
21 |
22 thms "point.simps"; |
22 thms "point.simps" |
23 thms "point.iffs"; |
23 thms "point.iffs" |
24 thms "point.update_defs"; |
24 thms "point.update_defs" |
25 |
25 |
26 The set of theorems "point.simps" is added automatically to the |
26 The set of theorems "point.simps" is added automatically to the |
27 standard simpset, "point.iffs" is added to the claset and simpset. |
27 standard simpset, "point.iffs" is added to the claset and simpset. |
28 *) |
28 |}; |
|
29 |
|
30 text {| |
|
31 Record declarations define new type abbreviations: |
|
32 |
|
33 point = "(| x :: nat, y :: nat |)" |
|
34 'a point_scheme = "(| x :: nat, y :: nat, ... :: 'a |)" |
|
35 |
|
36 Extensions `...' must be in type class `more'! |
|
37 |}; |
|
38 |
|
39 consts foo1 :: point; |
|
40 consts foo2 :: "(| x :: nat, y :: nat |)"; |
|
41 consts foo3 :: "'a => ('a::more) point_scheme"; |
|
42 consts foo4 :: "'a => (| x :: nat, y :: nat, ... :: 'a |)"; |
29 |
43 |
30 |
44 |
31 (* |
45 subsection "Introducing concrete records and record schemes"; |
32 Record declarations define new type abbreviations: |
|
33 |
46 |
34 point = (| x :: nat, y :: nat |) |
47 defs |
35 'a point_scheme = (| x :: nat, y :: nat, ... :: 'a |) |
48 foo1_def: "foo1 == (| x = 1, y = 0 |)" |
36 |
49 foo3_def: "foo3 ext == (| x = 1, y = 0, ... = ext |)"; |
37 Extensions `...' must be in type class `more'! |
|
38 *) |
|
39 |
|
40 consts foo1 :: point |
|
41 consts foo2 :: "(| x :: nat, y :: nat |)" |
|
42 consts foo3 :: 'a => ('a::more) point_scheme |
|
43 consts foo4 :: "'a => (| x :: nat, y :: nat, ... :: 'a |)" |
|
44 |
50 |
45 |
51 |
46 (* Introducing concrete records and record schemes *) |
52 subsection "Record selection and record update"; |
47 |
53 |
48 defs |
54 constdefs |
49 foo1_def "foo1 == (| x = 1, y = 0 |)" |
55 getX :: "('a::more) point_scheme => nat" |
50 foo3_def "foo3 ext == (| x = 1, y = 0, ... = ext |)" |
56 "getX r == x r" |
|
57 setX :: "('a::more) point_scheme => nat => 'a point_scheme" |
|
58 "setX r n == r (| x := n |)"; |
51 |
59 |
52 |
60 |
53 (* Record selection and record update *) |
61 subsection "Some lemmas about records"; |
54 |
62 |
55 constdefs |
63 text "Note: any of these goals may be solved with a single |
56 getX :: ('a::more) point_scheme => nat |
64 stroke of auto or force."; |
57 "getX r == x r" |
|
58 setX :: ('a::more) point_scheme => nat => 'a point_scheme |
|
59 "setX r n == r (| x := n |)" |
|
60 |
65 |
61 |
66 |
62 (* concrete records are type instances of record schemes *) |
67 text "basic simplifications"; |
|
68 |
|
69 lemma "x (| x = m, y = n, ... = p |) = m"; |
|
70 by simp; |
|
71 |
|
72 lemma "(| x = m, y = n, ... = p |) (| x:= 0 |) = (| x = 0, y = n, ... = p |)"; |
|
73 by simp; |
|
74 |
|
75 |
|
76 text "splitting quantifiers: the !!r is NECESSARY"; |
|
77 |
|
78 lemma "!!r. r (| x := n |) (| y := m |) = r (| y := m |) (| x := n |)"; |
|
79 proof record_split; |
|
80 fix a b rest; |
|
81 show "(| x = a, y = b, ... = rest |)(| x := n, y := m |) = |
|
82 (| x = a, y = b, ... = rest |)(| y := m, x := n |)"; |
|
83 by simp; |
|
84 qed; |
|
85 |
|
86 lemma "!!r. r (| x := n |) (| x := m |) = r (| x := m |)"; |
|
87 proof record_split; |
|
88 fix a b rest; |
|
89 show "(| x = a, y = b, ... = rest |)(| x := n, x := m |) = |
|
90 (| x = a, y = b, ... = rest |)(| x := m |)"; |
|
91 by simp; |
|
92 qed; |
|
93 |
|
94 |
|
95 text "equality of records"; |
|
96 |
|
97 lemma "(| x = n, y = p |) = (| x = n', y = p' |) --> n = n'" (is "??EQ --> _"); |
|
98 proof; |
|
99 assume ??EQ; |
|
100 thus "n = n'"; by simp; |
|
101 qed; |
|
102 |
|
103 |
|
104 text "concrete records are type instances of record schemes"; |
63 |
105 |
64 constdefs |
106 constdefs |
65 foo5 :: nat |
107 foo5 :: nat |
66 "foo5 == getX (| x = 1, y = 0 |)" |
108 "foo5 == getX (| x = 1, y = 0 |)"; |
67 |
109 |
68 |
110 |
69 (* manipulating the `...' (more-part) *) |
111 text "manipulating the `...' (more) part"; |
70 |
112 |
71 constdefs |
113 constdefs |
72 incX :: ('a::more) point_scheme => 'a point_scheme |
114 incX :: "('a::more) point_scheme => 'a point_scheme" |
73 "incX r == (| x = Suc (x r), y = y r, ... = point.more r |)" |
115 "incX r == (| x = Suc (x r), y = y r, ... = point.more r |)"; |
74 |
116 |
75 (*alternative definition*) |
117 lemma "!!r n. incX r = setX r (Suc (getX r))"; |
|
118 proof (unfold getX_def setX_def incX_def); |
|
119 show "!! r n. (| x = Suc (x r), y = y r, ... = more r |) = r(| x := Suc (x r) |)"; |
|
120 by (record_split, simp); |
|
121 qed; |
|
122 |
|
123 |
|
124 text "alternative definition"; |
|
125 |
76 constdefs |
126 constdefs |
77 incX' :: ('a::more) point_scheme => 'a point_scheme |
127 incX' :: "('a::more) point_scheme => 'a point_scheme" |
78 "incX' r == r (| x := Suc (x r) |)" |
128 "incX' r == r (| x := Suc (x r) |)"; |
79 |
129 |
80 |
130 |
81 |
131 |
82 (** coloured points: record extension **) |
132 section "coloured points: record extension"; |
83 |
133 |
84 datatype colour = Red | Green | Blue |
134 datatype colour = Red | Green | Blue; |
85 |
135 |
86 record cpoint = point + |
136 record cpoint = point + |
87 colour :: colour |
137 colour :: colour; |
88 |
138 |
89 |
139 |
90 (* |
140 text {| |
91 The record declaration defines new type constructors: |
141 The record declaration defines new type constructors: |
92 |
142 |
93 cpoint = (| x :: nat, y :: nat, colour :: colour |) |
143 cpoint = (| x :: nat, y :: nat, colour :: colour |) |
94 'a cpoint_scheme = (| x :: nat, y :: nat, colour :: colour, ... :: 'a |) |
144 'a cpoint_scheme = (| x :: nat, y :: nat, colour :: colour, ... :: 'a |) |
95 *) |
145 |}; |
96 |
146 |
97 consts foo6 :: cpoint |
147 consts foo6 :: cpoint; |
98 consts foo7 :: "(| x :: nat, y :: nat, colour :: colour |)" |
148 consts foo7 :: "(| x :: nat, y :: nat, colour :: colour |)"; |
99 consts foo8 :: ('a::more) cpoint_scheme |
149 consts foo8 :: "('a::more) cpoint_scheme"; |
100 consts foo9 :: "(| x :: nat, y :: nat, colour :: colour, ... :: 'a |)" |
150 consts foo9 :: "(| x :: nat, y :: nat, colour :: colour, ... :: 'a |)"; |
101 |
151 |
102 |
152 |
103 (* functions on point schemes work for cpoints as well *) |
153 text "functions on point schemes work for cpoints as well"; |
104 |
154 |
105 constdefs |
155 constdefs |
106 foo10 :: nat |
156 foo10 :: nat |
107 "foo10 == getX (| x = 2, y = 0, colour = Blue |)" |
157 "foo10 == getX (| x = 2, y = 0, colour = Blue |)"; |
108 |
158 |
109 |
159 |
110 (* non-coercive structural subtyping *) |
160 subsection "Non-coercive structural subtyping"; |
111 |
161 |
112 (*foo11 has type cpoint, not type point*) (*Great!*) |
162 text "foo11 has type cpoint, not type point --- Great!"; |
|
163 |
113 constdefs |
164 constdefs |
114 foo11 :: cpoint |
165 foo11 :: cpoint |
115 "foo11 == setX (| x = 2, y = 0, colour = Blue |) 0" |
166 "foo11 == setX (| x = 2, y = 0, colour = Blue |) 0"; |
116 |
167 |
117 |
168 |
118 |
169 |
119 (** other features **) |
170 section "Other features"; |
120 |
171 |
121 (* field names contribute to record identity *) |
172 text "field names contribute to record identity"; |
122 |
173 |
123 record point' = |
174 record point' = |
124 x' :: nat |
175 x' :: nat |
125 y' :: nat |
176 y' :: nat; |
126 |
177 |
127 consts |
178 consts |
128 foo12 :: nat |
179 foo12 :: nat; |
129 (*"foo12 == getX (| x' = 2, y' = 0 |)"*) (*invalid*) |
180 |
|
181 text {| Definition @{term "foo12 == getX (| x' = 2, y' = 0 |)"} is invalid |}; |
130 |
182 |
131 |
183 |
132 (* polymorphic records *) |
184 text "polymorphic records"; |
133 |
185 |
134 record 'a point'' = point + |
186 record 'a point'' = point + |
135 content :: 'a |
187 content :: 'a; |
136 |
188 |
137 types cpoint'' = colour point'' |
189 types cpoint'' = "colour point''"; |
138 |
190 |
139 |
191 |
|
192 text "Have a lot of fun!"; |
140 |
193 |
141 (*Have a lot of fun!*) |
194 end; |
142 |
|
143 end |
|