huffman@35430
|
1 |
(* Title: HOLCF/Tools/domain/domain_constructors.ML
|
huffman@35430
|
2 |
Author: Brian Huffman
|
huffman@35430
|
3 |
|
huffman@35430
|
4 |
Defines constructor functions for a given domain isomorphism
|
huffman@35430
|
5 |
and proves related theorems.
|
huffman@35430
|
6 |
*)
|
huffman@35430
|
7 |
|
huffman@35430
|
8 |
signature DOMAIN_CONSTRUCTORS =
|
huffman@35430
|
9 |
sig
|
huffman@35430
|
10 |
val add_domain_constructors :
|
huffman@35777
|
11 |
binding
|
huffman@35467
|
12 |
-> (binding * (bool * binding option * typ) list * mixfix) list
|
huffman@35500
|
13 |
-> Domain_Take_Proofs.iso_info
|
huffman@35430
|
14 |
-> theory
|
huffman@35430
|
15 |
-> { con_consts : term list,
|
huffman@35437
|
16 |
con_betas : thm list,
|
huffman@35781
|
17 |
nchotomy : thm,
|
huffman@35443
|
18 |
exhaust : thm,
|
huffman@35781
|
19 |
compacts : thm list,
|
huffman@35438
|
20 |
con_rews : thm list,
|
huffman@35442
|
21 |
inverts : thm list,
|
huffman@35442
|
22 |
injects : thm list,
|
huffman@35444
|
23 |
dist_les : thm list,
|
huffman@35444
|
24 |
dist_eqs : thm list,
|
huffman@35445
|
25 |
cases : thm list,
|
huffman@35446
|
26 |
sel_rews : thm list,
|
huffman@35448
|
27 |
dis_rews : thm list,
|
huffman@35454
|
28 |
match_rews : thm list,
|
huffman@35454
|
29 |
pat_rews : thm list
|
huffman@35439
|
30 |
} * theory;
|
huffman@35430
|
31 |
end;
|
huffman@35430
|
32 |
|
huffman@35430
|
33 |
|
huffman@35430
|
34 |
structure Domain_Constructors :> DOMAIN_CONSTRUCTORS =
|
huffman@35430
|
35 |
struct
|
huffman@35430
|
36 |
|
huffman@35461
|
37 |
open HOLCF_Library;
|
huffman@35561
|
38 |
|
huffman@35462
|
39 |
infixr 6 ->>;
|
huffman@35462
|
40 |
infix -->>;
|
huffman@35561
|
41 |
infix 9 `;
|
huffman@35430
|
42 |
|
huffman@35432
|
43 |
(************************** miscellaneous functions ***************************)
|
huffman@35432
|
44 |
|
huffman@35447
|
45 |
val simple_ss =
|
huffman@35447
|
46 |
HOL_basic_ss addsimps simp_thms;
|
huffman@35442
|
47 |
|
huffman@35445
|
48 |
val beta_ss =
|
huffman@35445
|
49 |
HOL_basic_ss
|
huffman@35445
|
50 |
addsimps simp_thms
|
huffman@35445
|
51 |
addsimps [@{thm beta_cfun}]
|
huffman@35445
|
52 |
addsimprocs [@{simproc cont_proc}];
|
huffman@35445
|
53 |
|
huffman@35430
|
54 |
fun define_consts
|
huffman@35430
|
55 |
(specs : (binding * term * mixfix) list)
|
huffman@35430
|
56 |
(thy : theory)
|
huffman@35430
|
57 |
: (term list * thm list) * theory =
|
huffman@35430
|
58 |
let
|
huffman@35442
|
59 |
fun mk_decl (b, t, mx) = (b, fastype_of t, mx);
|
huffman@35430
|
60 |
val decls = map mk_decl specs;
|
huffman@35430
|
61 |
val thy = Cont_Consts.add_consts decls thy;
|
huffman@35430
|
62 |
fun mk_const (b, T, mx) = Const (Sign.full_name thy b, T);
|
huffman@35430
|
63 |
val consts = map mk_const decls;
|
huffman@35430
|
64 |
fun mk_def c (b, t, mx) =
|
huffman@35430
|
65 |
(Binding.suffix_name "_def" b, Logic.mk_equals (c, t));
|
huffman@35430
|
66 |
val defs = map2 mk_def consts specs;
|
huffman@35430
|
67 |
val (def_thms, thy) =
|
huffman@35430
|
68 |
PureThy.add_defs false (map Thm.no_attributes defs) thy;
|
huffman@35430
|
69 |
in
|
huffman@35430
|
70 |
((consts, def_thms), thy)
|
huffman@35430
|
71 |
end;
|
huffman@35430
|
72 |
|
huffman@35435
|
73 |
fun prove
|
huffman@35432
|
74 |
(thy : theory)
|
huffman@35435
|
75 |
(defs : thm list)
|
huffman@35433
|
76 |
(goal : term)
|
huffman@35435
|
77 |
(tacs : {prems: thm list, context: Proof.context} -> tactic list)
|
huffman@35433
|
78 |
: thm =
|
huffman@35435
|
79 |
let
|
huffman@35435
|
80 |
fun tac {prems, context} =
|
huffman@35435
|
81 |
rewrite_goals_tac defs THEN
|
huffman@35435
|
82 |
EVERY (tacs {prems = map (rewrite_rule defs) prems, context = context})
|
huffman@35435
|
83 |
in
|
huffman@35435
|
84 |
Goal.prove_global thy [] [] goal tac
|
huffman@35435
|
85 |
end;
|
huffman@35430
|
86 |
|
huffman@35469
|
87 |
fun get_vars_avoiding
|
huffman@35469
|
88 |
(taken : string list)
|
huffman@35469
|
89 |
(args : (bool * typ) list)
|
huffman@35469
|
90 |
: (term list * term list) =
|
huffman@35469
|
91 |
let
|
huffman@35469
|
92 |
val Ts = map snd args;
|
huffman@35469
|
93 |
val ns = Name.variant_list taken (Datatype_Prop.make_tnames Ts);
|
huffman@35469
|
94 |
val vs = map Free (ns ~~ Ts);
|
huffman@35469
|
95 |
val nonlazy = map snd (filter_out (fst o fst) (args ~~ vs));
|
huffman@35469
|
96 |
in
|
huffman@35469
|
97 |
(vs, nonlazy)
|
huffman@35469
|
98 |
end;
|
huffman@35469
|
99 |
|
huffman@35469
|
100 |
fun get_vars args = get_vars_avoiding [] args;
|
huffman@35469
|
101 |
|
huffman@35431
|
102 |
(************** generating beta reduction rules from definitions **************)
|
huffman@35430
|
103 |
|
huffman@35431
|
104 |
local
|
huffman@35431
|
105 |
fun arglist (Const _ $ Abs (s, T, t)) =
|
huffman@35431
|
106 |
let
|
huffman@35431
|
107 |
val arg = Free (s, T);
|
huffman@35431
|
108 |
val (args, body) = arglist (subst_bound (arg, t));
|
huffman@35431
|
109 |
in (arg :: args, body) end
|
huffman@35431
|
110 |
| arglist t = ([], t);
|
huffman@35431
|
111 |
in
|
huffman@35431
|
112 |
fun beta_of_def thy def_thm =
|
huffman@35431
|
113 |
let
|
huffman@35431
|
114 |
val (con, lam) = Logic.dest_equals (concl_of def_thm);
|
huffman@35431
|
115 |
val (args, rhs) = arglist lam;
|
huffman@35432
|
116 |
val lhs = list_ccomb (con, args);
|
huffman@35431
|
117 |
val goal = mk_equals (lhs, rhs);
|
huffman@35431
|
118 |
val cs = ContProc.cont_thms lam;
|
huffman@35431
|
119 |
val betas = map (fn c => mk_meta_eq (c RS @{thm beta_cfun})) cs;
|
huffman@35431
|
120 |
in
|
huffman@35435
|
121 |
prove thy (def_thm::betas) goal (K [rtac reflexive_thm 1])
|
huffman@35431
|
122 |
end;
|
huffman@35431
|
123 |
end;
|
huffman@35430
|
124 |
|
huffman@35432
|
125 |
(******************************************************************************)
|
huffman@35439
|
126 |
(************* definitions and theorems for constructor functions *************)
|
huffman@35439
|
127 |
(******************************************************************************)
|
huffman@35439
|
128 |
|
huffman@35439
|
129 |
fun add_constructors
|
huffman@35440
|
130 |
(spec : (binding * (bool * typ) list * mixfix) list)
|
huffman@35439
|
131 |
(abs_const : term)
|
huffman@35439
|
132 |
(iso_locale : thm)
|
huffman@35439
|
133 |
(thy : theory)
|
huffman@35439
|
134 |
=
|
huffman@35439
|
135 |
let
|
huffman@35439
|
136 |
|
huffman@35439
|
137 |
(* get theorems about rep and abs *)
|
huffman@35439
|
138 |
val abs_strict = iso_locale RS @{thm iso.abs_strict};
|
huffman@35439
|
139 |
|
huffman@35443
|
140 |
(* get types of type isomorphism *)
|
huffman@35443
|
141 |
val (rhsT, lhsT) = dest_cfunT (fastype_of abs_const);
|
huffman@35443
|
142 |
|
huffman@35441
|
143 |
fun vars_of args =
|
huffman@35441
|
144 |
let
|
huffman@35441
|
145 |
val Ts = map snd args;
|
huffman@35441
|
146 |
val ns = Datatype_Prop.make_tnames Ts;
|
huffman@35441
|
147 |
in
|
huffman@35441
|
148 |
map Free (ns ~~ Ts)
|
huffman@35441
|
149 |
end;
|
huffman@35441
|
150 |
|
huffman@35439
|
151 |
(* define constructor functions *)
|
huffman@35439
|
152 |
val ((con_consts, con_defs), thy) =
|
huffman@35439
|
153 |
let
|
huffman@35440
|
154 |
fun one_arg (lazy, T) var = if lazy then mk_up var else var;
|
huffman@35439
|
155 |
fun one_con (_,args,_) = mk_stuple (map2 one_arg args (vars_of args));
|
huffman@35439
|
156 |
fun mk_abs t = abs_const ` t;
|
huffman@35439
|
157 |
val rhss = map mk_abs (mk_sinjects (map one_con spec));
|
huffman@35439
|
158 |
fun mk_def (bind, args, mx) rhs =
|
huffman@35439
|
159 |
(bind, big_lambdas (vars_of args) rhs, mx);
|
huffman@35439
|
160 |
in
|
huffman@35439
|
161 |
define_consts (map2 mk_def spec rhss) thy
|
huffman@35439
|
162 |
end;
|
huffman@35439
|
163 |
|
huffman@35439
|
164 |
(* prove beta reduction rules for constructors *)
|
huffman@35439
|
165 |
val con_betas = map (beta_of_def thy) con_defs;
|
huffman@35439
|
166 |
|
huffman@35439
|
167 |
(* replace bindings with terms in constructor spec *)
|
huffman@35439
|
168 |
val spec' : (term * (bool * typ) list) list =
|
huffman@35440
|
169 |
let fun one_con con (b, args, mx) = (con, args);
|
huffman@35439
|
170 |
in map2 one_con con_consts spec end;
|
huffman@35439
|
171 |
|
huffman@35443
|
172 |
(* prove exhaustiveness of constructors *)
|
huffman@35443
|
173 |
local
|
huffman@35443
|
174 |
fun arg2typ n (true, T) = (n+1, mk_upT (TVar (("'a", n), @{sort cpo})))
|
huffman@35443
|
175 |
| arg2typ n (false, T) = (n+1, TVar (("'a", n), @{sort pcpo}));
|
huffman@35443
|
176 |
fun args2typ n [] = (n, oneT)
|
huffman@35443
|
177 |
| args2typ n [arg] = arg2typ n arg
|
huffman@35443
|
178 |
| args2typ n (arg::args) =
|
huffman@35443
|
179 |
let
|
huffman@35443
|
180 |
val (n1, t1) = arg2typ n arg;
|
huffman@35443
|
181 |
val (n2, t2) = args2typ n1 args
|
huffman@35443
|
182 |
in (n2, mk_sprodT (t1, t2)) end;
|
huffman@35443
|
183 |
fun cons2typ n [] = (n, oneT)
|
huffman@35443
|
184 |
| cons2typ n [con] = args2typ n (snd con)
|
huffman@35443
|
185 |
| cons2typ n (con::cons) =
|
huffman@35443
|
186 |
let
|
huffman@35443
|
187 |
val (n1, t1) = args2typ n (snd con);
|
huffman@35443
|
188 |
val (n2, t2) = cons2typ n1 cons
|
huffman@35443
|
189 |
in (n2, mk_ssumT (t1, t2)) end;
|
huffman@35443
|
190 |
val ct = ctyp_of thy (snd (cons2typ 1 spec'));
|
huffman@35443
|
191 |
val thm1 = instantiate' [SOME ct] [] @{thm exh_start};
|
huffman@35443
|
192 |
val thm2 = rewrite_rule (map mk_meta_eq @{thms ex_defined_iffs}) thm1;
|
huffman@35443
|
193 |
val thm3 = rewrite_rule [mk_meta_eq @{thm conj_assoc}] thm2;
|
huffman@35443
|
194 |
|
huffman@35512
|
195 |
val y = Free ("y", lhsT);
|
huffman@35443
|
196 |
fun one_con (con, args) =
|
huffman@35443
|
197 |
let
|
huffman@35512
|
198 |
val (vs, nonlazy) = get_vars_avoiding ["y"] args;
|
huffman@35512
|
199 |
val eqn = mk_eq (y, list_ccomb (con, vs));
|
huffman@35443
|
200 |
val conj = foldr1 mk_conj (eqn :: map mk_defined nonlazy);
|
huffman@35443
|
201 |
in Library.foldr mk_ex (vs, conj) end;
|
huffman@35512
|
202 |
val goal = mk_trp (foldr1 mk_disj (mk_undef y :: map one_con spec'));
|
huffman@36241
|
203 |
(* first rules replace "y = UU \/ P" with "rep$y = UU \/ P" *)
|
huffman@35443
|
204 |
val tacs = [
|
huffman@35443
|
205 |
rtac (iso_locale RS @{thm iso.casedist_rule}) 1,
|
huffman@35443
|
206 |
rewrite_goals_tac [mk_meta_eq (iso_locale RS @{thm iso.iso_swap})],
|
huffman@35443
|
207 |
rtac thm3 1];
|
huffman@35443
|
208 |
in
|
huffman@35781
|
209 |
val nchotomy = prove thy con_betas goal (K tacs);
|
huffman@35781
|
210 |
val exhaust =
|
huffman@35781
|
211 |
(nchotomy RS @{thm exh_casedist0})
|
huffman@35443
|
212 |
|> rewrite_rule @{thms exh_casedists}
|
huffman@36241
|
213 |
|> Drule.zero_var_indexes;
|
huffman@35443
|
214 |
end;
|
huffman@35443
|
215 |
|
huffman@35439
|
216 |
(* prove compactness rules for constructors *)
|
huffman@35781
|
217 |
val compacts =
|
huffman@35439
|
218 |
let
|
huffman@35439
|
219 |
val rules = @{thms compact_sinl compact_sinr compact_spair
|
huffman@35439
|
220 |
compact_up compact_ONE};
|
huffman@35439
|
221 |
val tacs =
|
huffman@35439
|
222 |
[rtac (iso_locale RS @{thm iso.compact_abs}) 1,
|
huffman@35439
|
223 |
REPEAT (resolve_tac rules 1 ORELSE atac 1)];
|
huffman@35439
|
224 |
fun con_compact (con, args) =
|
huffman@35439
|
225 |
let
|
huffman@35441
|
226 |
val vs = vars_of args;
|
huffman@35439
|
227 |
val con_app = list_ccomb (con, vs);
|
huffman@35439
|
228 |
val concl = mk_trp (mk_compact con_app);
|
huffman@35439
|
229 |
val assms = map (mk_trp o mk_compact) vs;
|
huffman@35439
|
230 |
val goal = Logic.list_implies (assms, concl);
|
huffman@35439
|
231 |
in
|
huffman@35439
|
232 |
prove thy con_betas goal (K tacs)
|
huffman@35439
|
233 |
end;
|
huffman@35439
|
234 |
in
|
huffman@35439
|
235 |
map con_compact spec'
|
huffman@35439
|
236 |
end;
|
huffman@35439
|
237 |
|
huffman@35439
|
238 |
(* prove strictness rules for constructors *)
|
huffman@35439
|
239 |
local
|
huffman@35439
|
240 |
fun con_strict (con, args) =
|
huffman@35439
|
241 |
let
|
huffman@35439
|
242 |
val rules = abs_strict :: @{thms con_strict_rules};
|
huffman@35470
|
243 |
val (vs, nonlazy) = get_vars args;
|
huffman@35439
|
244 |
fun one_strict v' =
|
huffman@35439
|
245 |
let
|
huffman@35442
|
246 |
val UU = mk_bottom (fastype_of v');
|
huffman@35439
|
247 |
val vs' = map (fn v => if v = v' then UU else v) vs;
|
huffman@35439
|
248 |
val goal = mk_trp (mk_undef (list_ccomb (con, vs')));
|
huffman@35439
|
249 |
val tacs = [simp_tac (HOL_basic_ss addsimps rules) 1];
|
huffman@35439
|
250 |
in prove thy con_betas goal (K tacs) end;
|
huffman@35439
|
251 |
in map one_strict nonlazy end;
|
huffman@35439
|
252 |
|
huffman@35439
|
253 |
fun con_defin (con, args) =
|
huffman@35439
|
254 |
let
|
huffman@35439
|
255 |
fun iff_disj (t, []) = HOLogic.mk_not t
|
huffman@35439
|
256 |
| iff_disj (t, ts) = mk_eq (t, foldr1 HOLogic.mk_disj ts);
|
huffman@35470
|
257 |
val (vs, nonlazy) = get_vars args;
|
huffman@35439
|
258 |
val lhs = mk_undef (list_ccomb (con, vs));
|
huffman@35439
|
259 |
val rhss = map mk_undef nonlazy;
|
huffman@35439
|
260 |
val goal = mk_trp (iff_disj (lhs, rhss));
|
huffman@35439
|
261 |
val rule1 = iso_locale RS @{thm iso.abs_defined_iff};
|
huffman@35439
|
262 |
val rules = rule1 :: @{thms con_defined_iff_rules};
|
huffman@35439
|
263 |
val tacs = [simp_tac (HOL_ss addsimps rules) 1];
|
huffman@35439
|
264 |
in prove thy con_betas goal (K tacs) end;
|
huffman@35439
|
265 |
in
|
huffman@35439
|
266 |
val con_stricts = maps con_strict spec';
|
huffman@35439
|
267 |
val con_defins = map con_defin spec';
|
huffman@35439
|
268 |
val con_rews = con_stricts @ con_defins;
|
huffman@35439
|
269 |
end;
|
huffman@35439
|
270 |
|
huffman@35442
|
271 |
(* prove injectiveness of constructors *)
|
huffman@35442
|
272 |
local
|
huffman@35442
|
273 |
fun pgterm rel (con, args) =
|
huffman@35442
|
274 |
let
|
huffman@35442
|
275 |
fun prime (Free (n, T)) = Free (n^"'", T)
|
huffman@35442
|
276 |
| prime t = t;
|
huffman@35470
|
277 |
val (xs, nonlazy) = get_vars args;
|
huffman@35442
|
278 |
val ys = map prime xs;
|
huffman@35442
|
279 |
val lhs = rel (list_ccomb (con, xs), list_ccomb (con, ys));
|
huffman@35442
|
280 |
val rhs = foldr1 mk_conj (ListPair.map rel (xs, ys));
|
huffman@35442
|
281 |
val concl = mk_trp (mk_eq (lhs, rhs));
|
huffman@35442
|
282 |
val zs = case args of [_] => [] | _ => nonlazy;
|
huffman@35442
|
283 |
val assms = map (mk_trp o mk_defined) zs;
|
huffman@35442
|
284 |
val goal = Logic.list_implies (assms, concl);
|
huffman@35442
|
285 |
in prove thy con_betas goal end;
|
huffman@35442
|
286 |
val cons' = filter (fn (_, args) => not (null args)) spec';
|
huffman@35442
|
287 |
in
|
huffman@35442
|
288 |
val inverts =
|
huffman@35442
|
289 |
let
|
huffman@35442
|
290 |
val abs_below = iso_locale RS @{thm iso.abs_below};
|
huffman@35442
|
291 |
val rules1 = abs_below :: @{thms sinl_below sinr_below spair_below up_below};
|
huffman@35442
|
292 |
val rules2 = @{thms up_defined spair_defined ONE_defined}
|
huffman@35442
|
293 |
val rules = rules1 @ rules2;
|
huffman@35442
|
294 |
val tacs = [asm_simp_tac (simple_ss addsimps rules) 1];
|
huffman@35442
|
295 |
in map (fn c => pgterm mk_below c (K tacs)) cons' end;
|
huffman@35442
|
296 |
val injects =
|
huffman@35442
|
297 |
let
|
huffman@35442
|
298 |
val abs_eq = iso_locale RS @{thm iso.abs_eq};
|
huffman@35442
|
299 |
val rules1 = abs_eq :: @{thms sinl_eq sinr_eq spair_eq up_eq};
|
huffman@35442
|
300 |
val rules2 = @{thms up_defined spair_defined ONE_defined}
|
huffman@35442
|
301 |
val rules = rules1 @ rules2;
|
huffman@35442
|
302 |
val tacs = [asm_simp_tac (simple_ss addsimps rules) 1];
|
huffman@35442
|
303 |
in map (fn c => pgterm mk_eq c (K tacs)) cons' end;
|
huffman@35442
|
304 |
end;
|
huffman@35442
|
305 |
|
huffman@35444
|
306 |
(* prove distinctness of constructors *)
|
huffman@35444
|
307 |
local
|
huffman@35444
|
308 |
fun map_dist (f : 'a -> 'a -> 'b) (xs : 'a list) : 'b list =
|
huffman@35444
|
309 |
flat (map_index (fn (i, x) => map (f x) (nth_drop i xs)) xs);
|
huffman@35444
|
310 |
fun prime (Free (n, T)) = Free (n^"'", T)
|
huffman@35444
|
311 |
| prime t = t;
|
huffman@35444
|
312 |
fun iff_disj (t, []) = mk_not t
|
huffman@35444
|
313 |
| iff_disj (t, ts) = mk_eq (t, foldr1 mk_disj ts);
|
huffman@35444
|
314 |
fun iff_disj2 (t, [], us) = mk_not t
|
huffman@35444
|
315 |
| iff_disj2 (t, ts, []) = mk_not t
|
huffman@35444
|
316 |
| iff_disj2 (t, ts, us) =
|
huffman@35444
|
317 |
mk_eq (t, mk_conj (foldr1 mk_disj ts, foldr1 mk_disj us));
|
huffman@35444
|
318 |
fun dist_le (con1, args1) (con2, args2) =
|
huffman@35444
|
319 |
let
|
huffman@35470
|
320 |
val (vs1, zs1) = get_vars args1;
|
huffman@35470
|
321 |
val (vs2, zs2) = get_vars args2 |> pairself (map prime);
|
huffman@35444
|
322 |
val lhs = mk_below (list_ccomb (con1, vs1), list_ccomb (con2, vs2));
|
huffman@35444
|
323 |
val rhss = map mk_undef zs1;
|
huffman@35444
|
324 |
val goal = mk_trp (iff_disj (lhs, rhss));
|
huffman@35444
|
325 |
val rule1 = iso_locale RS @{thm iso.abs_below};
|
huffman@35444
|
326 |
val rules = rule1 :: @{thms con_below_iff_rules};
|
huffman@35444
|
327 |
val tacs = [simp_tac (HOL_ss addsimps rules) 1];
|
huffman@35444
|
328 |
in prove thy con_betas goal (K tacs) end;
|
huffman@35444
|
329 |
fun dist_eq (con1, args1) (con2, args2) =
|
huffman@35444
|
330 |
let
|
huffman@35470
|
331 |
val (vs1, zs1) = get_vars args1;
|
huffman@35470
|
332 |
val (vs2, zs2) = get_vars args2 |> pairself (map prime);
|
huffman@35444
|
333 |
val lhs = mk_eq (list_ccomb (con1, vs1), list_ccomb (con2, vs2));
|
huffman@35444
|
334 |
val rhss1 = map mk_undef zs1;
|
huffman@35444
|
335 |
val rhss2 = map mk_undef zs2;
|
huffman@35444
|
336 |
val goal = mk_trp (iff_disj2 (lhs, rhss1, rhss2));
|
huffman@35444
|
337 |
val rule1 = iso_locale RS @{thm iso.abs_eq};
|
huffman@35444
|
338 |
val rules = rule1 :: @{thms con_eq_iff_rules};
|
huffman@35444
|
339 |
val tacs = [simp_tac (HOL_ss addsimps rules) 1];
|
huffman@35444
|
340 |
in prove thy con_betas goal (K tacs) end;
|
huffman@35444
|
341 |
in
|
huffman@35444
|
342 |
val dist_les = map_dist dist_le spec';
|
huffman@35444
|
343 |
val dist_eqs = map_dist dist_eq spec';
|
huffman@35444
|
344 |
end;
|
huffman@35442
|
345 |
|
huffman@35439
|
346 |
val result =
|
huffman@35439
|
347 |
{
|
huffman@35439
|
348 |
con_consts = con_consts,
|
huffman@35439
|
349 |
con_betas = con_betas,
|
huffman@35781
|
350 |
nchotomy = nchotomy,
|
huffman@35443
|
351 |
exhaust = exhaust,
|
huffman@35781
|
352 |
compacts = compacts,
|
huffman@35442
|
353 |
con_rews = con_rews,
|
huffman@35442
|
354 |
inverts = inverts,
|
huffman@35444
|
355 |
injects = injects,
|
huffman@35444
|
356 |
dist_les = dist_les,
|
huffman@35444
|
357 |
dist_eqs = dist_eqs
|
huffman@35439
|
358 |
};
|
huffman@35439
|
359 |
in
|
huffman@35439
|
360 |
(result, thy)
|
huffman@35439
|
361 |
end;
|
huffman@35439
|
362 |
|
huffman@35439
|
363 |
(******************************************************************************)
|
huffman@35445
|
364 |
(**************** definition and theorems for case combinator *****************)
|
huffman@35445
|
365 |
(******************************************************************************)
|
huffman@35445
|
366 |
|
huffman@35445
|
367 |
fun add_case_combinator
|
huffman@35445
|
368 |
(spec : (term * (bool * typ) list) list)
|
huffman@35445
|
369 |
(lhsT : typ)
|
huffman@35777
|
370 |
(dbind : binding)
|
huffman@35445
|
371 |
(con_betas : thm list)
|
huffman@35781
|
372 |
(exhaust : thm)
|
huffman@35445
|
373 |
(iso_locale : thm)
|
huffman@35472
|
374 |
(rep_const : term)
|
huffman@35446
|
375 |
(thy : theory)
|
huffman@35446
|
376 |
: ((typ -> term) * thm list) * theory =
|
huffman@35445
|
377 |
let
|
huffman@35445
|
378 |
|
huffman@35445
|
379 |
(* prove rep/abs rules *)
|
huffman@35445
|
380 |
val rep_strict = iso_locale RS @{thm iso.rep_strict};
|
huffman@35445
|
381 |
val abs_inverse = iso_locale RS @{thm iso.abs_iso};
|
huffman@35445
|
382 |
|
huffman@35445
|
383 |
(* calculate function arguments of case combinator *)
|
huffman@35472
|
384 |
val tns = map (fst o dest_TFree) (snd (dest_Type lhsT));
|
huffman@35472
|
385 |
val resultT = TFree (Name.variant tns "'t", @{sort pcpo});
|
huffman@35446
|
386 |
fun fTs T = map (fn (_, args) => map snd args -->> T) spec;
|
huffman@35445
|
387 |
val fns = Datatype_Prop.indexify_names (map (K "f") spec);
|
huffman@35446
|
388 |
val fs = map Free (fns ~~ fTs resultT);
|
huffman@35446
|
389 |
fun caseT T = fTs T -->> (lhsT ->> T);
|
huffman@35445
|
390 |
|
huffman@35472
|
391 |
(* definition of case combinator *)
|
huffman@35472
|
392 |
local
|
huffman@35777
|
393 |
val case_bind = Binding.suffix_name "_when" dbind;
|
huffman@35784
|
394 |
fun lambda_arg (lazy, v) t =
|
huffman@35784
|
395 |
(if lazy then mk_fup else I) (big_lambda v t);
|
huffman@35784
|
396 |
fun lambda_args [] t = mk_one_when t
|
huffman@35784
|
397 |
| lambda_args (x::[]) t = lambda_arg x t
|
huffman@35784
|
398 |
| lambda_args (x::xs) t = mk_ssplit (lambda_arg x (lambda_args xs t));
|
huffman@35472
|
399 |
fun one_con f (_, args) =
|
huffman@35472
|
400 |
let
|
huffman@35784
|
401 |
val Ts = map snd args;
|
huffman@35472
|
402 |
val ns = Name.variant_list fns (Datatype_Prop.make_tnames Ts);
|
huffman@35472
|
403 |
val vs = map Free (ns ~~ Ts);
|
huffman@35472
|
404 |
in
|
huffman@35784
|
405 |
lambda_args (map fst args ~~ vs) (list_ccomb (f, vs))
|
huffman@35472
|
406 |
end;
|
huffman@35785
|
407 |
fun mk_sscases [t] = mk_strictify t
|
huffman@35785
|
408 |
| mk_sscases ts = foldr1 mk_sscase ts;
|
huffman@35784
|
409 |
val body = mk_sscases (map2 one_con fs spec);
|
huffman@35472
|
410 |
val rhs = big_lambdas fs (mk_cfcomp (body, rep_const));
|
huffman@35472
|
411 |
val ((case_consts, case_defs), thy) =
|
huffman@35472
|
412 |
define_consts [(case_bind, rhs, NoSyn)] thy;
|
huffman@35472
|
413 |
val case_name = Sign.full_name thy case_bind;
|
huffman@35472
|
414 |
in
|
huffman@35472
|
415 |
val case_def = hd case_defs;
|
huffman@35472
|
416 |
fun case_const T = Const (case_name, caseT T);
|
huffman@35472
|
417 |
val case_app = list_ccomb (case_const resultT, fs);
|
huffman@35472
|
418 |
val thy = thy;
|
huffman@35472
|
419 |
end;
|
huffman@35445
|
420 |
|
huffman@35458
|
421 |
(* define syntax for case combinator *)
|
huffman@35458
|
422 |
(* TODO: re-implement case syntax using a parse translation *)
|
huffman@35458
|
423 |
local
|
huffman@35458
|
424 |
open Syntax
|
huffman@35458
|
425 |
fun syntax c = Syntax.mark_const (fst (dest_Const c));
|
huffman@35458
|
426 |
fun xconst c = Long_Name.base_name (fst (dest_Const c));
|
huffman@35458
|
427 |
fun c_ast authentic con =
|
huffman@35458
|
428 |
Constant (if authentic then syntax con else xconst con);
|
huffman@35471
|
429 |
fun showint n = string_of_int (n+1);
|
huffman@35471
|
430 |
fun expvar n = Variable ("e" ^ showint n);
|
huffman@35471
|
431 |
fun argvar n (m, _) = Variable ("a" ^ showint n ^ "_" ^ showint m);
|
huffman@35471
|
432 |
fun argvars n args = map_index (argvar n) args;
|
huffman@35458
|
433 |
fun app s (l, r) = mk_appl (Constant s) [l, r];
|
huffman@35458
|
434 |
val cabs = app "_cabs";
|
huffman@35458
|
435 |
val capp = app @{const_syntax Rep_CFun};
|
huffman@35458
|
436 |
val capps = Library.foldl capp
|
huffman@35458
|
437 |
fun con1 authentic n (con,args) =
|
huffman@35458
|
438 |
Library.foldl capp (c_ast authentic con, argvars n args);
|
huffman@35471
|
439 |
fun case1 authentic (n, c) =
|
huffman@35458
|
440 |
app "_case1" (con1 authentic n c, expvar n);
|
huffman@35471
|
441 |
fun arg1 (n, (con,args)) = List.foldr cabs (expvar n) (argvars n args);
|
huffman@35471
|
442 |
fun when1 n (m, c) =
|
huffman@35471
|
443 |
if n = m then arg1 (n, c) else (Constant @{const_syntax UU});
|
huffman@35458
|
444 |
val case_constant = Constant (syntax (case_const dummyT));
|
huffman@35458
|
445 |
fun case_trans authentic =
|
huffman@35458
|
446 |
ParsePrintRule
|
huffman@35458
|
447 |
(app "_case_syntax"
|
huffman@35458
|
448 |
(Variable "x",
|
huffman@35471
|
449 |
foldr1 (app "_case2") (map_index (case1 authentic) spec)),
|
huffman@35471
|
450 |
capp (capps (case_constant, map_index arg1 spec), Variable "x"));
|
huffman@35471
|
451 |
fun one_abscon_trans authentic (n, c) =
|
huffman@35458
|
452 |
ParsePrintRule
|
huffman@35458
|
453 |
(cabs (con1 authentic n c, expvar n),
|
huffman@35471
|
454 |
capps (case_constant, map_index (when1 n) spec));
|
huffman@35458
|
455 |
fun abscon_trans authentic =
|
huffman@35471
|
456 |
map_index (one_abscon_trans authentic) spec;
|
huffman@35458
|
457 |
val trans_rules : ast Syntax.trrule list =
|
huffman@35458
|
458 |
case_trans false :: case_trans true ::
|
huffman@35458
|
459 |
abscon_trans false @ abscon_trans true;
|
huffman@35458
|
460 |
in
|
huffman@35458
|
461 |
val thy = Sign.add_trrules_i trans_rules thy;
|
huffman@35458
|
462 |
end;
|
huffman@35458
|
463 |
|
huffman@35445
|
464 |
(* prove beta reduction rule for case combinator *)
|
huffman@35445
|
465 |
val case_beta = beta_of_def thy case_def;
|
huffman@35445
|
466 |
|
huffman@35445
|
467 |
(* prove strictness of case combinator *)
|
huffman@35445
|
468 |
val case_strict =
|
huffman@35445
|
469 |
let
|
huffman@35472
|
470 |
val defs = case_beta :: map mk_meta_eq [rep_strict, @{thm cfcomp2}];
|
huffman@35472
|
471 |
val goal = mk_trp (mk_strict case_app);
|
huffman@35482
|
472 |
val rules = @{thms sscase1 ssplit1 strictify1 one_when1};
|
huffman@35482
|
473 |
val tacs = [resolve_tac rules 1];
|
huffman@35445
|
474 |
in prove thy defs goal (K tacs) end;
|
huffman@35445
|
475 |
|
huffman@35445
|
476 |
(* prove rewrites for case combinator *)
|
huffman@35445
|
477 |
local
|
huffman@35445
|
478 |
fun one_case (con, args) f =
|
huffman@35445
|
479 |
let
|
huffman@35469
|
480 |
val (vs, nonlazy) = get_vars args;
|
huffman@35445
|
481 |
val assms = map (mk_trp o mk_defined) nonlazy;
|
huffman@35445
|
482 |
val lhs = case_app ` list_ccomb (con, vs);
|
huffman@35445
|
483 |
val rhs = list_ccomb (f, vs);
|
huffman@35445
|
484 |
val concl = mk_trp (mk_eq (lhs, rhs));
|
huffman@35445
|
485 |
val goal = Logic.list_implies (assms, concl);
|
huffman@35445
|
486 |
val defs = case_beta :: con_betas;
|
huffman@35474
|
487 |
val rules1 = @{thms strictify2 sscase2 sscase3 ssplit2 fup2 ID1};
|
huffman@35445
|
488 |
val rules2 = @{thms con_defined_iff_rules};
|
huffman@35472
|
489 |
val rules3 = @{thms cfcomp2 one_when2};
|
huffman@35472
|
490 |
val rules = abs_inverse :: rules1 @ rules2 @ rules3;
|
huffman@35445
|
491 |
val tacs = [asm_simp_tac (beta_ss addsimps rules) 1];
|
huffman@35445
|
492 |
in prove thy defs goal (K tacs) end;
|
huffman@35445
|
493 |
in
|
huffman@35445
|
494 |
val case_apps = map2 one_case spec fs;
|
huffman@35445
|
495 |
end
|
huffman@35445
|
496 |
|
huffman@35445
|
497 |
in
|
huffman@35446
|
498 |
((case_const, case_strict :: case_apps), thy)
|
huffman@35445
|
499 |
end
|
huffman@35445
|
500 |
|
huffman@35445
|
501 |
(******************************************************************************)
|
huffman@35432
|
502 |
(************** definitions and theorems for selector functions ***************)
|
huffman@35432
|
503 |
(******************************************************************************)
|
huffman@35432
|
504 |
|
huffman@35432
|
505 |
fun add_selectors
|
huffman@35432
|
506 |
(spec : (term * (bool * binding option * typ) list) list)
|
huffman@35432
|
507 |
(rep_const : term)
|
huffman@35432
|
508 |
(abs_inv : thm)
|
huffman@35432
|
509 |
(rep_strict : thm)
|
huffman@35432
|
510 |
(rep_strict_iff : thm)
|
huffman@35432
|
511 |
(con_betas : thm list)
|
huffman@35432
|
512 |
(thy : theory)
|
huffman@35432
|
513 |
: thm list * theory =
|
huffman@35432
|
514 |
let
|
huffman@35432
|
515 |
|
huffman@35432
|
516 |
(* define selector functions *)
|
huffman@35432
|
517 |
val ((sel_consts, sel_defs), thy) =
|
huffman@35432
|
518 |
let
|
huffman@35442
|
519 |
fun rangeT s = snd (dest_cfunT (fastype_of s));
|
huffman@35432
|
520 |
fun mk_outl s = mk_cfcomp (from_sinl (dest_ssumT (rangeT s)), s);
|
huffman@35432
|
521 |
fun mk_outr s = mk_cfcomp (from_sinr (dest_ssumT (rangeT s)), s);
|
huffman@35432
|
522 |
fun mk_sfst s = mk_cfcomp (sfst_const (dest_sprodT (rangeT s)), s);
|
huffman@35432
|
523 |
fun mk_ssnd s = mk_cfcomp (ssnd_const (dest_sprodT (rangeT s)), s);
|
huffman@35432
|
524 |
fun mk_down s = mk_cfcomp (from_up (dest_upT (rangeT s)), s);
|
huffman@35432
|
525 |
|
huffman@35432
|
526 |
fun sels_of_arg s (lazy, NONE, T) = []
|
huffman@35432
|
527 |
| sels_of_arg s (lazy, SOME b, T) =
|
huffman@35432
|
528 |
[(b, if lazy then mk_down s else s, NoSyn)];
|
huffman@35432
|
529 |
fun sels_of_args s [] = []
|
huffman@35432
|
530 |
| sels_of_args s (v :: []) = sels_of_arg s v
|
huffman@35432
|
531 |
| sels_of_args s (v :: vs) =
|
huffman@35432
|
532 |
sels_of_arg (mk_sfst s) v @ sels_of_args (mk_ssnd s) vs;
|
huffman@35432
|
533 |
fun sels_of_cons s [] = []
|
huffman@35432
|
534 |
| sels_of_cons s ((con, args) :: []) = sels_of_args s args
|
huffman@35432
|
535 |
| sels_of_cons s ((con, args) :: cs) =
|
huffman@35432
|
536 |
sels_of_args (mk_outl s) args @ sels_of_cons (mk_outr s) cs;
|
huffman@35432
|
537 |
val sel_eqns : (binding * term * mixfix) list =
|
huffman@35432
|
538 |
sels_of_cons rep_const spec;
|
huffman@35432
|
539 |
in
|
huffman@35432
|
540 |
define_consts sel_eqns thy
|
huffman@35432
|
541 |
end
|
huffman@35432
|
542 |
|
huffman@35432
|
543 |
(* replace bindings with terms in constructor spec *)
|
huffman@35432
|
544 |
val spec2 : (term * (bool * term option * typ) list) list =
|
huffman@35432
|
545 |
let
|
huffman@35432
|
546 |
fun prep_arg (lazy, NONE, T) sels = ((lazy, NONE, T), sels)
|
huffman@35432
|
547 |
| prep_arg (lazy, SOME _, T) sels =
|
huffman@35432
|
548 |
((lazy, SOME (hd sels), T), tl sels);
|
huffman@35432
|
549 |
fun prep_con (con, args) sels =
|
huffman@35432
|
550 |
apfst (pair con) (fold_map prep_arg args sels);
|
huffman@35432
|
551 |
in
|
huffman@35432
|
552 |
fst (fold_map prep_con spec sel_consts)
|
huffman@35432
|
553 |
end;
|
huffman@35432
|
554 |
|
huffman@35432
|
555 |
(* prove selector strictness rules *)
|
huffman@35432
|
556 |
val sel_stricts : thm list =
|
huffman@35432
|
557 |
let
|
huffman@35435
|
558 |
val rules = rep_strict :: @{thms sel_strict_rules};
|
huffman@35435
|
559 |
val tacs = [simp_tac (HOL_basic_ss addsimps rules) 1];
|
huffman@35432
|
560 |
fun sel_strict sel =
|
huffman@35432
|
561 |
let
|
huffman@35432
|
562 |
val goal = mk_trp (mk_strict sel);
|
huffman@35432
|
563 |
in
|
huffman@35435
|
564 |
prove thy sel_defs goal (K tacs)
|
huffman@35432
|
565 |
end
|
huffman@35432
|
566 |
in
|
huffman@35432
|
567 |
map sel_strict sel_consts
|
huffman@35432
|
568 |
end
|
huffman@35432
|
569 |
|
huffman@35432
|
570 |
(* prove selector application rules *)
|
huffman@35432
|
571 |
val sel_apps : thm list =
|
huffman@35432
|
572 |
let
|
huffman@35435
|
573 |
val defs = con_betas @ sel_defs;
|
huffman@35442
|
574 |
val rules = abs_inv :: @{thms sel_app_rules};
|
huffman@35442
|
575 |
val tacs = [asm_simp_tac (simple_ss addsimps rules) 1];
|
huffman@35432
|
576 |
fun sel_apps_of (i, (con, args)) =
|
huffman@35432
|
577 |
let
|
huffman@35432
|
578 |
val Ts : typ list = map #3 args;
|
huffman@35432
|
579 |
val ns : string list = Datatype_Prop.make_tnames Ts;
|
huffman@35432
|
580 |
val vs : term list = map Free (ns ~~ Ts);
|
huffman@35432
|
581 |
val con_app : term = list_ccomb (con, vs);
|
huffman@35432
|
582 |
val vs' : (bool * term) list = map #1 args ~~ vs;
|
huffman@35432
|
583 |
fun one_same (n, sel, T) =
|
huffman@35432
|
584 |
let
|
huffman@35432
|
585 |
val xs = map snd (filter_out fst (nth_drop n vs'));
|
huffman@35432
|
586 |
val assms = map (mk_trp o mk_defined) xs;
|
huffman@35432
|
587 |
val concl = mk_trp (mk_eq (sel ` con_app, nth vs n));
|
huffman@35432
|
588 |
val goal = Logic.list_implies (assms, concl);
|
huffman@35432
|
589 |
in
|
huffman@35435
|
590 |
prove thy defs goal (K tacs)
|
huffman@35432
|
591 |
end;
|
huffman@35432
|
592 |
fun one_diff (n, sel, T) =
|
huffman@35432
|
593 |
let
|
huffman@35432
|
594 |
val goal = mk_trp (mk_eq (sel ` con_app, mk_bottom T));
|
huffman@35432
|
595 |
in
|
huffman@35435
|
596 |
prove thy defs goal (K tacs)
|
huffman@35432
|
597 |
end;
|
huffman@35432
|
598 |
fun one_con (j, (_, args')) : thm list =
|
huffman@35432
|
599 |
let
|
huffman@35432
|
600 |
fun prep (i, (lazy, NONE, T)) = NONE
|
huffman@35432
|
601 |
| prep (i, (lazy, SOME sel, T)) = SOME (i, sel, T);
|
huffman@35432
|
602 |
val sels : (int * term * typ) list =
|
huffman@35432
|
603 |
map_filter prep (map_index I args');
|
huffman@35432
|
604 |
in
|
huffman@35432
|
605 |
if i = j
|
huffman@35432
|
606 |
then map one_same sels
|
huffman@35432
|
607 |
else map one_diff sels
|
huffman@35432
|
608 |
end
|
huffman@35432
|
609 |
in
|
huffman@35432
|
610 |
flat (map_index one_con spec2)
|
huffman@35432
|
611 |
end
|
huffman@35432
|
612 |
in
|
huffman@35432
|
613 |
flat (map_index sel_apps_of spec2)
|
huffman@35432
|
614 |
end
|
huffman@35432
|
615 |
|
huffman@35432
|
616 |
(* prove selector definedness rules *)
|
huffman@35432
|
617 |
val sel_defins : thm list =
|
huffman@35432
|
618 |
let
|
huffman@35435
|
619 |
val rules = rep_strict_iff :: @{thms sel_defined_iff_rules};
|
huffman@35435
|
620 |
val tacs = [simp_tac (HOL_basic_ss addsimps rules) 1];
|
huffman@35432
|
621 |
fun sel_defin sel =
|
huffman@35432
|
622 |
let
|
huffman@35442
|
623 |
val (T, U) = dest_cfunT (fastype_of sel);
|
huffman@35432
|
624 |
val x = Free ("x", T);
|
huffman@35432
|
625 |
val lhs = mk_eq (sel ` x, mk_bottom U);
|
huffman@35432
|
626 |
val rhs = mk_eq (x, mk_bottom T);
|
huffman@35432
|
627 |
val goal = mk_trp (mk_eq (lhs, rhs));
|
huffman@35432
|
628 |
in
|
huffman@35435
|
629 |
prove thy sel_defs goal (K tacs)
|
huffman@35432
|
630 |
end
|
huffman@35432
|
631 |
fun one_arg (false, SOME sel, T) = SOME (sel_defin sel)
|
huffman@35432
|
632 |
| one_arg _ = NONE;
|
huffman@35432
|
633 |
in
|
huffman@35432
|
634 |
case spec2 of
|
huffman@35432
|
635 |
[(con, args)] => map_filter one_arg args
|
huffman@35432
|
636 |
| _ => []
|
huffman@35432
|
637 |
end;
|
huffman@35432
|
638 |
|
huffman@35432
|
639 |
in
|
huffman@35432
|
640 |
(sel_stricts @ sel_defins @ sel_apps, thy)
|
huffman@35432
|
641 |
end
|
huffman@35432
|
642 |
|
huffman@35432
|
643 |
(******************************************************************************)
|
huffman@35446
|
644 |
(************ definitions and theorems for discriminator functions ************)
|
huffman@35446
|
645 |
(******************************************************************************)
|
huffman@35446
|
646 |
|
huffman@35446
|
647 |
fun add_discriminators
|
huffman@35446
|
648 |
(bindings : binding list)
|
huffman@35446
|
649 |
(spec : (term * (bool * typ) list) list)
|
huffman@35447
|
650 |
(lhsT : typ)
|
huffman@35781
|
651 |
(exhaust : thm)
|
huffman@35446
|
652 |
(case_const : typ -> term)
|
huffman@35447
|
653 |
(case_rews : thm list)
|
huffman@35446
|
654 |
(thy : theory) =
|
huffman@35446
|
655 |
let
|
huffman@35446
|
656 |
|
huffman@35446
|
657 |
fun vars_of args =
|
huffman@35446
|
658 |
let
|
huffman@35446
|
659 |
val Ts = map snd args;
|
huffman@35446
|
660 |
val ns = Datatype_Prop.make_tnames Ts;
|
huffman@35446
|
661 |
in
|
huffman@35446
|
662 |
map Free (ns ~~ Ts)
|
huffman@35446
|
663 |
end;
|
huffman@35446
|
664 |
|
huffman@35446
|
665 |
(* define discriminator functions *)
|
huffman@35446
|
666 |
local
|
huffman@35446
|
667 |
fun dis_fun i (j, (con, args)) =
|
huffman@35446
|
668 |
let
|
huffman@35469
|
669 |
val (vs, nonlazy) = get_vars args;
|
huffman@35446
|
670 |
val tr = if i = j then @{term TT} else @{term FF};
|
huffman@35446
|
671 |
in
|
huffman@35446
|
672 |
big_lambdas vs tr
|
huffman@35446
|
673 |
end;
|
huffman@35446
|
674 |
fun dis_eqn (i, bind) : binding * term * mixfix =
|
huffman@35446
|
675 |
let
|
huffman@35446
|
676 |
val dis_bind = Binding.prefix_name "is_" bind;
|
huffman@35446
|
677 |
val rhs = list_ccomb (case_const trT, map_index (dis_fun i) spec);
|
huffman@35446
|
678 |
in
|
huffman@35446
|
679 |
(dis_bind, rhs, NoSyn)
|
huffman@35446
|
680 |
end;
|
huffman@35446
|
681 |
in
|
huffman@35446
|
682 |
val ((dis_consts, dis_defs), thy) =
|
huffman@35446
|
683 |
define_consts (map_index dis_eqn bindings) thy
|
huffman@35446
|
684 |
end;
|
huffman@35446
|
685 |
|
huffman@35447
|
686 |
(* prove discriminator strictness rules *)
|
huffman@35447
|
687 |
local
|
huffman@35447
|
688 |
fun dis_strict dis =
|
huffman@35447
|
689 |
let val goal = mk_trp (mk_strict dis);
|
huffman@35447
|
690 |
in prove thy dis_defs goal (K [rtac (hd case_rews) 1]) end;
|
huffman@35447
|
691 |
in
|
huffman@35447
|
692 |
val dis_stricts = map dis_strict dis_consts;
|
huffman@35447
|
693 |
end;
|
huffman@35447
|
694 |
|
huffman@35447
|
695 |
(* prove discriminator/constructor rules *)
|
huffman@35447
|
696 |
local
|
huffman@35447
|
697 |
fun dis_app (i, dis) (j, (con, args)) =
|
huffman@35447
|
698 |
let
|
huffman@35469
|
699 |
val (vs, nonlazy) = get_vars args;
|
huffman@35447
|
700 |
val lhs = dis ` list_ccomb (con, vs);
|
huffman@35447
|
701 |
val rhs = if i = j then @{term TT} else @{term FF};
|
huffman@35447
|
702 |
val assms = map (mk_trp o mk_defined) nonlazy;
|
huffman@35447
|
703 |
val concl = mk_trp (mk_eq (lhs, rhs));
|
huffman@35447
|
704 |
val goal = Logic.list_implies (assms, concl);
|
huffman@35447
|
705 |
val tacs = [asm_simp_tac (beta_ss addsimps case_rews) 1];
|
huffman@35447
|
706 |
in prove thy dis_defs goal (K tacs) end;
|
huffman@35447
|
707 |
fun one_dis (i, dis) =
|
huffman@35447
|
708 |
map_index (dis_app (i, dis)) spec;
|
huffman@35447
|
709 |
in
|
huffman@35447
|
710 |
val dis_apps = flat (map_index one_dis dis_consts);
|
huffman@35447
|
711 |
end;
|
huffman@35447
|
712 |
|
huffman@35447
|
713 |
(* prove discriminator definedness rules *)
|
huffman@35447
|
714 |
local
|
huffman@35447
|
715 |
fun dis_defin dis =
|
huffman@35447
|
716 |
let
|
huffman@35447
|
717 |
val x = Free ("x", lhsT);
|
huffman@35447
|
718 |
val simps = dis_apps @ @{thms dist_eq_tr};
|
huffman@35447
|
719 |
val tacs =
|
huffman@35447
|
720 |
[rtac @{thm iffI} 1,
|
huffman@35447
|
721 |
asm_simp_tac (HOL_basic_ss addsimps dis_stricts) 2,
|
huffman@35781
|
722 |
rtac exhaust 1, atac 1,
|
huffman@35447
|
723 |
DETERM_UNTIL_SOLVED (CHANGED
|
huffman@35447
|
724 |
(asm_full_simp_tac (simple_ss addsimps simps) 1))];
|
huffman@35447
|
725 |
val goal = mk_trp (mk_eq (mk_undef (dis ` x), mk_undef x));
|
huffman@35447
|
726 |
in prove thy [] goal (K tacs) end;
|
huffman@35447
|
727 |
in
|
huffman@35447
|
728 |
val dis_defins = map dis_defin dis_consts;
|
huffman@35447
|
729 |
end;
|
huffman@35447
|
730 |
|
huffman@35446
|
731 |
in
|
huffman@35447
|
732 |
(dis_stricts @ dis_defins @ dis_apps, thy)
|
huffman@35446
|
733 |
end;
|
huffman@35446
|
734 |
|
huffman@35446
|
735 |
(******************************************************************************)
|
huffman@35448
|
736 |
(*************** definitions and theorems for match combinators ***************)
|
huffman@35448
|
737 |
(******************************************************************************)
|
huffman@35448
|
738 |
|
huffman@35448
|
739 |
fun add_match_combinators
|
huffman@35448
|
740 |
(bindings : binding list)
|
huffman@35448
|
741 |
(spec : (term * (bool * typ) list) list)
|
huffman@35448
|
742 |
(lhsT : typ)
|
huffman@35781
|
743 |
(exhaust : thm)
|
huffman@35448
|
744 |
(case_const : typ -> term)
|
huffman@35448
|
745 |
(case_rews : thm list)
|
huffman@35448
|
746 |
(thy : theory) =
|
huffman@35448
|
747 |
let
|
huffman@35448
|
748 |
|
huffman@35448
|
749 |
(* get a fresh type variable for the result type *)
|
huffman@35448
|
750 |
val resultT : typ =
|
huffman@35448
|
751 |
let
|
huffman@35448
|
752 |
val ts : string list = map (fst o dest_TFree) (snd (dest_Type lhsT));
|
huffman@35448
|
753 |
val t : string = Name.variant ts "'t";
|
huffman@35448
|
754 |
in TFree (t, @{sort pcpo}) end;
|
huffman@35448
|
755 |
|
huffman@35448
|
756 |
(* define match combinators *)
|
huffman@35448
|
757 |
local
|
huffman@35448
|
758 |
val x = Free ("x", lhsT);
|
huffman@35448
|
759 |
fun k args = Free ("k", map snd args -->> mk_matchT resultT);
|
huffman@35448
|
760 |
val fail = mk_fail resultT;
|
huffman@35448
|
761 |
fun mat_fun i (j, (con, args)) =
|
huffman@35448
|
762 |
let
|
huffman@35469
|
763 |
val (vs, nonlazy) = get_vars_avoiding ["x","k"] args;
|
huffman@35448
|
764 |
in
|
huffman@35448
|
765 |
if i = j then k args else big_lambdas vs fail
|
huffman@35448
|
766 |
end;
|
huffman@35448
|
767 |
fun mat_eqn (i, (bind, (con, args))) : binding * term * mixfix =
|
huffman@35448
|
768 |
let
|
huffman@35448
|
769 |
val mat_bind = Binding.prefix_name "match_" bind;
|
huffman@35448
|
770 |
val funs = map_index (mat_fun i) spec
|
huffman@35448
|
771 |
val body = list_ccomb (case_const (mk_matchT resultT), funs);
|
huffman@35448
|
772 |
val rhs = big_lambda x (big_lambda (k args) (body ` x));
|
huffman@35448
|
773 |
in
|
huffman@35448
|
774 |
(mat_bind, rhs, NoSyn)
|
huffman@35448
|
775 |
end;
|
huffman@35448
|
776 |
in
|
huffman@35448
|
777 |
val ((match_consts, match_defs), thy) =
|
huffman@35448
|
778 |
define_consts (map_index mat_eqn (bindings ~~ spec)) thy
|
huffman@35448
|
779 |
end;
|
huffman@35448
|
780 |
|
huffman@35449
|
781 |
(* register match combinators with fixrec package *)
|
huffman@35449
|
782 |
local
|
huffman@35449
|
783 |
val con_names = map (fst o dest_Const o fst) spec;
|
huffman@35449
|
784 |
val mat_names = map (fst o dest_Const) match_consts;
|
huffman@35449
|
785 |
in
|
huffman@35449
|
786 |
val thy = Fixrec.add_matchers (con_names ~~ mat_names) thy;
|
huffman@35449
|
787 |
end;
|
huffman@35449
|
788 |
|
huffman@35452
|
789 |
(* prove strictness of match combinators *)
|
huffman@35452
|
790 |
local
|
huffman@35452
|
791 |
fun match_strict mat =
|
huffman@35452
|
792 |
let
|
huffman@35452
|
793 |
val (T, (U, V)) = apsnd dest_cfunT (dest_cfunT (fastype_of mat));
|
huffman@35452
|
794 |
val k = Free ("k", U);
|
huffman@35452
|
795 |
val goal = mk_trp (mk_eq (mat ` mk_bottom T ` k, mk_bottom V));
|
huffman@35452
|
796 |
val tacs = [asm_simp_tac (beta_ss addsimps case_rews) 1];
|
huffman@35452
|
797 |
in prove thy match_defs goal (K tacs) end;
|
huffman@35452
|
798 |
in
|
huffman@35452
|
799 |
val match_stricts = map match_strict match_consts;
|
huffman@35452
|
800 |
end;
|
huffman@35452
|
801 |
|
huffman@35452
|
802 |
(* prove match/constructor rules *)
|
huffman@35452
|
803 |
local
|
huffman@35452
|
804 |
val fail = mk_fail resultT;
|
huffman@35452
|
805 |
fun match_app (i, mat) (j, (con, args)) =
|
huffman@35452
|
806 |
let
|
huffman@35469
|
807 |
val (vs, nonlazy) = get_vars_avoiding ["k"] args;
|
huffman@35452
|
808 |
val (_, (kT, _)) = apsnd dest_cfunT (dest_cfunT (fastype_of mat));
|
huffman@35452
|
809 |
val k = Free ("k", kT);
|
huffman@35452
|
810 |
val lhs = mat ` list_ccomb (con, vs) ` k;
|
huffman@35452
|
811 |
val rhs = if i = j then list_ccomb (k, vs) else fail;
|
huffman@35452
|
812 |
val assms = map (mk_trp o mk_defined) nonlazy;
|
huffman@35452
|
813 |
val concl = mk_trp (mk_eq (lhs, rhs));
|
huffman@35452
|
814 |
val goal = Logic.list_implies (assms, concl);
|
huffman@35452
|
815 |
val tacs = [asm_simp_tac (beta_ss addsimps case_rews) 1];
|
huffman@35452
|
816 |
in prove thy match_defs goal (K tacs) end;
|
huffman@35452
|
817 |
fun one_match (i, mat) =
|
huffman@35452
|
818 |
map_index (match_app (i, mat)) spec;
|
huffman@35452
|
819 |
in
|
huffman@35452
|
820 |
val match_apps = flat (map_index one_match match_consts);
|
huffman@35452
|
821 |
end;
|
huffman@35452
|
822 |
|
huffman@35448
|
823 |
in
|
huffman@35448
|
824 |
(match_stricts @ match_apps, thy)
|
huffman@35448
|
825 |
end;
|
huffman@35448
|
826 |
|
huffman@35448
|
827 |
(******************************************************************************)
|
huffman@35454
|
828 |
(************** definitions and theorems for pattern combinators **************)
|
huffman@35454
|
829 |
(******************************************************************************)
|
huffman@35454
|
830 |
|
huffman@35454
|
831 |
fun add_pattern_combinators
|
huffman@35454
|
832 |
(bindings : binding list)
|
huffman@35454
|
833 |
(spec : (term * (bool * typ) list) list)
|
huffman@35454
|
834 |
(lhsT : typ)
|
huffman@35781
|
835 |
(exhaust : thm)
|
huffman@35454
|
836 |
(case_const : typ -> term)
|
huffman@35454
|
837 |
(case_rews : thm list)
|
huffman@35454
|
838 |
(thy : theory) =
|
huffman@35454
|
839 |
let
|
huffman@35454
|
840 |
|
huffman@35468
|
841 |
(* utility functions *)
|
huffman@35468
|
842 |
fun mk_pair_pat (p1, p2) =
|
huffman@35468
|
843 |
let
|
huffman@35468
|
844 |
val T1 = fastype_of p1;
|
huffman@35468
|
845 |
val T2 = fastype_of p2;
|
huffman@35468
|
846 |
val (U1, V1) = apsnd dest_matchT (dest_cfunT T1);
|
huffman@35468
|
847 |
val (U2, V2) = apsnd dest_matchT (dest_cfunT T2);
|
huffman@35468
|
848 |
val pat_typ = [T1, T2] --->
|
huffman@35468
|
849 |
(mk_prodT (U1, U2) ->> mk_matchT (mk_prodT (V1, V2)));
|
huffman@35468
|
850 |
val pat_const = Const (@{const_name cpair_pat}, pat_typ);
|
huffman@35468
|
851 |
in
|
huffman@35468
|
852 |
pat_const $ p1 $ p2
|
huffman@35468
|
853 |
end;
|
huffman@35468
|
854 |
fun mk_tuple_pat [] = return_const HOLogic.unitT
|
huffman@35468
|
855 |
| mk_tuple_pat ps = foldr1 mk_pair_pat ps;
|
huffman@35468
|
856 |
fun branch_const (T,U,V) =
|
huffman@35468
|
857 |
Const (@{const_name branch},
|
huffman@35468
|
858 |
(T ->> mk_matchT U) --> (U ->> V) ->> T ->> mk_matchT V);
|
huffman@35468
|
859 |
|
huffman@35454
|
860 |
(* define pattern combinators *)
|
huffman@35454
|
861 |
local
|
huffman@35454
|
862 |
val tns = map (fst o dest_TFree) (snd (dest_Type lhsT));
|
huffman@35454
|
863 |
|
huffman@35454
|
864 |
fun pat_eqn (i, (bind, (con, args))) : binding * term * mixfix =
|
huffman@35454
|
865 |
let
|
huffman@35454
|
866 |
val pat_bind = Binding.suffix_name "_pat" bind;
|
huffman@35454
|
867 |
val Ts = map snd args;
|
huffman@35454
|
868 |
val Vs =
|
huffman@35468
|
869 |
(map (K "'t") args)
|
huffman@35454
|
870 |
|> Datatype_Prop.indexify_names
|
huffman@35454
|
871 |
|> Name.variant_list tns
|
huffman@35454
|
872 |
|> map (fn t => TFree (t, @{sort pcpo}));
|
huffman@35454
|
873 |
val patNs = Datatype_Prop.indexify_names (map (K "pat") args);
|
huffman@35454
|
874 |
val patTs = map2 (fn T => fn V => T ->> mk_matchT V) Ts Vs;
|
huffman@35454
|
875 |
val pats = map Free (patNs ~~ patTs);
|
huffman@35454
|
876 |
val fail = mk_fail (mk_tupleT Vs);
|
huffman@35469
|
877 |
val (vs, nonlazy) = get_vars_avoiding patNs args;
|
huffman@35454
|
878 |
val rhs = big_lambdas vs (mk_tuple_pat pats ` mk_tuple vs);
|
huffman@35454
|
879 |
fun one_fun (j, (_, args')) =
|
huffman@35454
|
880 |
let
|
huffman@35469
|
881 |
val (vs', nonlazy) = get_vars_avoiding patNs args';
|
huffman@35454
|
882 |
in if i = j then rhs else big_lambdas vs' fail end;
|
huffman@35454
|
883 |
val funs = map_index one_fun spec;
|
huffman@35454
|
884 |
val body = list_ccomb (case_const (mk_matchT (mk_tupleT Vs)), funs);
|
huffman@35454
|
885 |
in
|
huffman@35454
|
886 |
(pat_bind, lambdas pats body, NoSyn)
|
huffman@35454
|
887 |
end;
|
huffman@35454
|
888 |
in
|
huffman@35454
|
889 |
val ((pat_consts, pat_defs), thy) =
|
huffman@35454
|
890 |
define_consts (map_index pat_eqn (bindings ~~ spec)) thy
|
huffman@35454
|
891 |
end;
|
huffman@35454
|
892 |
|
huffman@35454
|
893 |
(* syntax translations for pattern combinators *)
|
huffman@35454
|
894 |
local
|
huffman@35454
|
895 |
open Syntax
|
huffman@35454
|
896 |
fun syntax c = Syntax.mark_const (fst (dest_Const c));
|
huffman@35454
|
897 |
fun app s (l, r) = Syntax.mk_appl (Constant s) [l, r];
|
huffman@35454
|
898 |
val capp = app @{const_syntax Rep_CFun};
|
huffman@35454
|
899 |
val capps = Library.foldl capp
|
huffman@35454
|
900 |
|
huffman@35454
|
901 |
fun app_var x = Syntax.mk_appl (Constant "_variable") [x, Variable "rhs"];
|
huffman@35454
|
902 |
fun app_pat x = Syntax.mk_appl (Constant "_pat") [x];
|
huffman@35454
|
903 |
fun args_list [] = Constant "_noargs"
|
huffman@35454
|
904 |
| args_list xs = foldr1 (app "_args") xs;
|
huffman@35454
|
905 |
fun one_case_trans (pat, (con, args)) =
|
huffman@35454
|
906 |
let
|
huffman@35454
|
907 |
val cname = Constant (syntax con);
|
huffman@35456
|
908 |
val pname = Constant (syntax pat);
|
huffman@35454
|
909 |
val ns = 1 upto length args;
|
huffman@35454
|
910 |
val xs = map (fn n => Variable ("x"^(string_of_int n))) ns;
|
huffman@35454
|
911 |
val ps = map (fn n => Variable ("p"^(string_of_int n))) ns;
|
huffman@35454
|
912 |
val vs = map (fn n => Variable ("v"^(string_of_int n))) ns;
|
huffman@35454
|
913 |
in
|
huffman@35454
|
914 |
[ParseRule (app_pat (capps (cname, xs)),
|
huffman@35454
|
915 |
mk_appl pname (map app_pat xs)),
|
huffman@35454
|
916 |
ParseRule (app_var (capps (cname, xs)),
|
huffman@35454
|
917 |
app_var (args_list xs)),
|
huffman@35454
|
918 |
PrintRule (capps (cname, ListPair.map (app "_match") (ps,vs)),
|
huffman@35454
|
919 |
app "_match" (mk_appl pname ps, args_list vs))]
|
huffman@35454
|
920 |
end;
|
huffman@35454
|
921 |
val trans_rules : Syntax.ast Syntax.trrule list =
|
huffman@35454
|
922 |
maps one_case_trans (pat_consts ~~ spec);
|
huffman@35454
|
923 |
in
|
huffman@35454
|
924 |
val thy = Sign.add_trrules_i trans_rules thy;
|
huffman@35454
|
925 |
end;
|
huffman@35454
|
926 |
|
huffman@35468
|
927 |
(* prove strictness and reduction rules of pattern combinators *)
|
huffman@35468
|
928 |
local
|
huffman@35468
|
929 |
val tns = map (fst o dest_TFree) (snd (dest_Type lhsT));
|
huffman@35468
|
930 |
val rn = Name.variant tns "'r";
|
huffman@35468
|
931 |
val R = TFree (rn, @{sort pcpo});
|
huffman@35468
|
932 |
fun pat_lhs (pat, args) =
|
huffman@35468
|
933 |
let
|
huffman@35468
|
934 |
val Ts = map snd args;
|
huffman@35468
|
935 |
val Vs =
|
huffman@35468
|
936 |
(map (K "'t") args)
|
huffman@35468
|
937 |
|> Datatype_Prop.indexify_names
|
huffman@35468
|
938 |
|> Name.variant_list (rn::tns)
|
huffman@35468
|
939 |
|> map (fn t => TFree (t, @{sort pcpo}));
|
huffman@35468
|
940 |
val patNs = Datatype_Prop.indexify_names (map (K "pat") args);
|
huffman@35468
|
941 |
val patTs = map2 (fn T => fn V => T ->> mk_matchT V) Ts Vs;
|
huffman@35468
|
942 |
val pats = map Free (patNs ~~ patTs);
|
huffman@35468
|
943 |
val k = Free ("rhs", mk_tupleT Vs ->> R);
|
huffman@35468
|
944 |
val branch1 = branch_const (lhsT, mk_tupleT Vs, R);
|
huffman@35468
|
945 |
val fun1 = (branch1 $ list_comb (pat, pats)) ` k;
|
huffman@35468
|
946 |
val branch2 = branch_const (mk_tupleT Ts, mk_tupleT Vs, R);
|
huffman@35468
|
947 |
val fun2 = (branch2 $ mk_tuple_pat pats) ` k;
|
huffman@35468
|
948 |
val taken = "rhs" :: patNs;
|
huffman@35468
|
949 |
in (fun1, fun2, taken) end;
|
huffman@35468
|
950 |
fun pat_strict (pat, (con, args)) =
|
huffman@35468
|
951 |
let
|
huffman@35468
|
952 |
val (fun1, fun2, taken) = pat_lhs (pat, args);
|
huffman@35468
|
953 |
val defs = @{thm branch_def} :: pat_defs;
|
huffman@35468
|
954 |
val goal = mk_trp (mk_strict fun1);
|
huffman@36989
|
955 |
val rules = @{thms maybe_when_rews} @ case_rews;
|
huffman@35468
|
956 |
val tacs = [simp_tac (beta_ss addsimps rules) 1];
|
huffman@35468
|
957 |
in prove thy defs goal (K tacs) end;
|
huffman@35468
|
958 |
fun pat_apps (i, (pat, (con, args))) =
|
huffman@35468
|
959 |
let
|
huffman@35468
|
960 |
val (fun1, fun2, taken) = pat_lhs (pat, args);
|
huffman@35468
|
961 |
fun pat_app (j, (con', args')) =
|
huffman@35468
|
962 |
let
|
huffman@35469
|
963 |
val (vs, nonlazy) = get_vars_avoiding taken args';
|
huffman@35468
|
964 |
val con_app = list_ccomb (con', vs);
|
huffman@35468
|
965 |
val assms = map (mk_trp o mk_defined) nonlazy;
|
huffman@35468
|
966 |
val rhs = if i = j then fun2 ` mk_tuple vs else mk_fail R;
|
huffman@35468
|
967 |
val concl = mk_trp (mk_eq (fun1 ` con_app, rhs));
|
huffman@35468
|
968 |
val goal = Logic.list_implies (assms, concl);
|
huffman@35468
|
969 |
val defs = @{thm branch_def} :: pat_defs;
|
huffman@36989
|
970 |
val rules = @{thms maybe_when_rews} @ case_rews;
|
huffman@35468
|
971 |
val tacs = [asm_simp_tac (beta_ss addsimps rules) 1];
|
huffman@35468
|
972 |
in prove thy defs goal (K tacs) end;
|
huffman@35468
|
973 |
in map_index pat_app spec end;
|
huffman@35468
|
974 |
in
|
huffman@35468
|
975 |
val pat_stricts = map pat_strict (pat_consts ~~ spec);
|
huffman@35468
|
976 |
val pat_apps = flat (map_index pat_apps (pat_consts ~~ spec));
|
huffman@35468
|
977 |
end;
|
huffman@35468
|
978 |
|
huffman@35454
|
979 |
in
|
huffman@35468
|
980 |
(pat_stricts @ pat_apps, thy)
|
huffman@35454
|
981 |
end
|
huffman@35454
|
982 |
|
huffman@35454
|
983 |
(******************************************************************************)
|
huffman@35436
|
984 |
(******************************* main function ********************************)
|
huffman@35436
|
985 |
(******************************************************************************)
|
huffman@35436
|
986 |
|
huffman@35436
|
987 |
fun add_domain_constructors
|
huffman@35777
|
988 |
(dbind : binding)
|
huffman@35467
|
989 |
(spec : (binding * (bool * binding option * typ) list * mixfix) list)
|
huffman@35500
|
990 |
(iso_info : Domain_Take_Proofs.iso_info)
|
huffman@35436
|
991 |
(thy : theory) =
|
huffman@35436
|
992 |
let
|
huffman@35777
|
993 |
val dname = Binding.name_of dbind;
|
huffman@35436
|
994 |
|
huffman@35467
|
995 |
(* retrieve facts about rep/abs *)
|
huffman@35467
|
996 |
val lhsT = #absT iso_info;
|
huffman@35467
|
997 |
val {rep_const, abs_const, ...} = iso_info;
|
huffman@35467
|
998 |
val abs_iso_thm = #abs_inverse iso_info;
|
huffman@35467
|
999 |
val rep_iso_thm = #rep_inverse iso_info;
|
huffman@35436
|
1000 |
val iso_locale = @{thm iso.intro} OF [abs_iso_thm, rep_iso_thm];
|
huffman@35436
|
1001 |
val rep_strict = iso_locale RS @{thm iso.rep_strict};
|
huffman@35436
|
1002 |
val abs_strict = iso_locale RS @{thm iso.abs_strict};
|
huffman@35436
|
1003 |
val rep_defined_iff = iso_locale RS @{thm iso.rep_defined_iff};
|
huffman@35436
|
1004 |
val abs_defined_iff = iso_locale RS @{thm iso.abs_defined_iff};
|
huffman@35436
|
1005 |
|
huffman@35473
|
1006 |
(* qualify constants and theorems with domain name *)
|
huffman@35473
|
1007 |
val thy = Sign.add_path dname thy;
|
huffman@35473
|
1008 |
|
huffman@35436
|
1009 |
(* define constructor functions *)
|
huffman@35443
|
1010 |
val (con_result, thy) =
|
huffman@35440
|
1011 |
let
|
huffman@35440
|
1012 |
fun prep_arg (lazy, sel, T) = (lazy, T);
|
huffman@35440
|
1013 |
fun prep_con (b, args, mx) = (b, map prep_arg args, mx);
|
huffman@35440
|
1014 |
val con_spec = map prep_con spec;
|
huffman@35440
|
1015 |
in
|
huffman@35440
|
1016 |
add_constructors con_spec abs_const iso_locale thy
|
huffman@35440
|
1017 |
end;
|
huffman@35781
|
1018 |
val {con_consts, con_betas, exhaust, ...} = con_result;
|
huffman@35445
|
1019 |
|
huffman@35445
|
1020 |
(* define case combinator *)
|
huffman@35446
|
1021 |
val ((case_const : typ -> term, cases : thm list), thy) =
|
huffman@35445
|
1022 |
let
|
huffman@35445
|
1023 |
fun prep_arg (lazy, sel, T) = (lazy, T);
|
huffman@35445
|
1024 |
fun prep_con c (b, args, mx) = (c, map prep_arg args);
|
huffman@35445
|
1025 |
val case_spec = map2 prep_con con_consts spec;
|
huffman@35445
|
1026 |
in
|
huffman@35777
|
1027 |
add_case_combinator case_spec lhsT dbind
|
huffman@35781
|
1028 |
con_betas exhaust iso_locale rep_const thy
|
huffman@35445
|
1029 |
end;
|
huffman@35436
|
1030 |
|
huffman@35432
|
1031 |
(* define and prove theorems for selector functions *)
|
huffman@35432
|
1032 |
val (sel_thms : thm list, thy : theory) =
|
huffman@35446
|
1033 |
let
|
huffman@35446
|
1034 |
val sel_spec : (term * (bool * binding option * typ) list) list =
|
huffman@35446
|
1035 |
map2 (fn con => fn (b, args, mx) => (con, args)) con_consts spec;
|
huffman@35446
|
1036 |
in
|
huffman@35446
|
1037 |
add_selectors sel_spec rep_const
|
huffman@35446
|
1038 |
abs_iso_thm rep_strict rep_defined_iff con_betas thy
|
huffman@35446
|
1039 |
end;
|
huffman@35446
|
1040 |
|
huffman@35446
|
1041 |
(* define and prove theorems for discriminator functions *)
|
huffman@35446
|
1042 |
val (dis_thms : thm list, thy : theory) =
|
huffman@35446
|
1043 |
let
|
huffman@35446
|
1044 |
val bindings = map #1 spec;
|
huffman@35446
|
1045 |
fun prep_arg (lazy, sel, T) = (lazy, T);
|
huffman@35446
|
1046 |
fun prep_con c (b, args, mx) = (c, map prep_arg args);
|
huffman@35446
|
1047 |
val dis_spec = map2 prep_con con_consts spec;
|
huffman@35446
|
1048 |
in
|
huffman@35447
|
1049 |
add_discriminators bindings dis_spec lhsT
|
huffman@35781
|
1050 |
exhaust case_const cases thy
|
huffman@35446
|
1051 |
end
|
huffman@35432
|
1052 |
|
huffman@35448
|
1053 |
(* define and prove theorems for match combinators *)
|
huffman@35448
|
1054 |
val (match_thms : thm list, thy : theory) =
|
huffman@35448
|
1055 |
let
|
huffman@35448
|
1056 |
val bindings = map #1 spec;
|
huffman@35448
|
1057 |
fun prep_arg (lazy, sel, T) = (lazy, T);
|
huffman@35448
|
1058 |
fun prep_con c (b, args, mx) = (c, map prep_arg args);
|
huffman@35448
|
1059 |
val mat_spec = map2 prep_con con_consts spec;
|
huffman@35448
|
1060 |
in
|
huffman@35448
|
1061 |
add_match_combinators bindings mat_spec lhsT
|
huffman@35781
|
1062 |
exhaust case_const cases thy
|
huffman@35448
|
1063 |
end
|
huffman@35448
|
1064 |
|
huffman@35454
|
1065 |
(* define and prove theorems for pattern combinators *)
|
huffman@35454
|
1066 |
val (pat_thms : thm list, thy : theory) =
|
huffman@35454
|
1067 |
let
|
huffman@35454
|
1068 |
val bindings = map #1 spec;
|
huffman@35454
|
1069 |
fun prep_arg (lazy, sel, T) = (lazy, T);
|
huffman@35454
|
1070 |
fun prep_con c (b, args, mx) = (c, map prep_arg args);
|
huffman@35454
|
1071 |
val pat_spec = map2 prep_con con_consts spec;
|
huffman@35454
|
1072 |
in
|
huffman@35454
|
1073 |
add_pattern_combinators bindings pat_spec lhsT
|
huffman@35781
|
1074 |
exhaust case_const cases thy
|
huffman@35454
|
1075 |
end
|
huffman@35454
|
1076 |
|
huffman@35432
|
1077 |
(* restore original signature path *)
|
huffman@35432
|
1078 |
val thy = Sign.parent_path thy;
|
huffman@35430
|
1079 |
|
huffman@35430
|
1080 |
val result =
|
huffman@35430
|
1081 |
{ con_consts = con_consts,
|
huffman@35437
|
1082 |
con_betas = con_betas,
|
huffman@35781
|
1083 |
nchotomy = #nchotomy con_result,
|
huffman@35781
|
1084 |
exhaust = exhaust,
|
huffman@35781
|
1085 |
compacts = #compacts con_result,
|
huffman@35443
|
1086 |
con_rews = #con_rews con_result,
|
huffman@35443
|
1087 |
inverts = #inverts con_result,
|
huffman@35443
|
1088 |
injects = #injects con_result,
|
huffman@35444
|
1089 |
dist_les = #dist_les con_result,
|
huffman@35444
|
1090 |
dist_eqs = #dist_eqs con_result,
|
huffman@35445
|
1091 |
cases = cases,
|
huffman@35446
|
1092 |
sel_rews = sel_thms,
|
huffman@35448
|
1093 |
dis_rews = dis_thms,
|
huffman@35454
|
1094 |
match_rews = match_thms,
|
huffman@35454
|
1095 |
pat_rews = pat_thms };
|
huffman@35430
|
1096 |
in
|
huffman@35430
|
1097 |
(result, thy)
|
huffman@35430
|
1098 |
end;
|
huffman@35430
|
1099 |
|
huffman@35430
|
1100 |
end;
|