141 section {* type definition for the quotient type *} |
141 section {* type definition for the quotient type *} |
142 |
142 |
143 (* the auxiliary data for the quotient types *) |
143 (* the auxiliary data for the quotient types *) |
144 use "quotient_info.ML" |
144 use "quotient_info.ML" |
145 |
145 |
146 ML {* |
|
147 fun error_msg pre post msg = |
|
148 msg |> quote |
|
149 |> enclose (pre ^ " ") (" " ^ post) |
|
150 |> error |
|
151 *} |
|
152 |
146 |
153 declare [[map list = (map, LIST_REL)]] |
147 declare [[map list = (map, LIST_REL)]] |
154 declare [[map * = (prod_fun, prod_rel)]] |
148 declare [[map * = (prod_fun, prod_rel)]] |
155 declare [[map "fun" = (fun_map, FUN_REL)]] |
149 declare [[map "fun" = (fun_map, FUN_REL)]] |
156 |
150 |
208 val nty = Type (s, ntys) |
198 val nty = Type (s, ntys) |
209 val ftys = map (op -->) tys |
199 val ftys = map (op -->) tys |
210 in |
200 in |
211 (case (maps_lookup (ProofContext.theory_of lthy) s) of |
201 (case (maps_lookup (ProofContext.theory_of lthy) s) of |
212 SOME info => (list_comb (Const (#mapfun info, ftys ---> (oty --> nty)), fs), (oty, nty)) |
202 SOME info => (list_comb (Const (#mapfun info, ftys ---> (oty --> nty)), fs), (oty, nty)) |
213 | NONE => raise ERROR ("no map association for type " ^ s)) |
203 | NONE => error ("no map association for type " ^ s)) |
214 end |
204 end |
215 |
205 |
216 fun get_fun_fun fs_tys = |
206 fun get_fun_fun fs_tys = |
217 let |
207 let |
218 val (fs, tys) = split_list fs_tys |
208 val (fs, tys) = split_list fs_tys |
235 end |
225 end |
236 |
226 |
237 fun mk_identity ty = Abs ("", ty, Bound 0) |
227 fun mk_identity ty = Abs ("", ty, Bound 0) |
238 |
228 |
239 in |
229 in |
240 if (AList.defined (op =) qenv ty) |
230 if (AList.defined (op=) qenv ty) |
241 then (get_const flag (the (lookup_qenv qenv ty))) |
231 then (get_const flag (the (lookup_qenv qenv ty))) |
242 else (case ty of |
232 else (case ty of |
243 TFree _ => (mk_identity ty, (ty, ty)) |
233 TFree _ => (mk_identity ty, (ty, ty)) |
244 | Type (_, []) => (mk_identity ty, (ty, ty)) |
234 | Type (_, []) => (mk_identity ty, (ty, ty)) |
245 | Type ("fun" , [ty1, ty2]) => |
235 | Type ("fun" , [ty1, ty2]) => |
248 | _ => raise ERROR ("no type variables") |
238 | _ => raise ERROR ("no type variables") |
249 ) |
239 ) |
250 end |
240 end |
251 *} |
241 *} |
252 |
242 |
253 text {* produces the definition for a lifted constant *} |
243 ML {* |
254 |
244 fun make_def nconst_bname rhs qty mx qenv lthy = |
255 ML {* |
|
256 fun get_const_def nconst otrm qenv lthy = |
|
257 let |
245 let |
258 val ty = fastype_of nconst |
246 val (arg_tys, res_ty) = strip_type qty |
259 val (arg_tys, res_ty) = strip_type ty |
|
260 |
247 |
261 val rep_fns = map (fst o get_fun repF qenv lthy) arg_tys |
248 val rep_fns = map (fst o get_fun repF qenv lthy) arg_tys |
262 val abs_fn = (fst o get_fun absF qenv lthy) res_ty |
249 val abs_fn = (fst o get_fun absF qenv lthy) res_ty |
263 |
250 |
264 fun mk_fun_map (t1,t2) = Const (@{const_name "fun_map"}, dummyT) $ t1 $ t2 |
251 fun mk_fun_map t s = |
265 |
252 Const (@{const_name "fun_map"}, dummyT) $ t $ s |
266 val fns = Library.foldr mk_fun_map (rep_fns, abs_fn) |
253 |
267 |> Syntax.check_term lthy |
254 val absrep_fn = fold_rev mk_fun_map rep_fns abs_fn |
|
255 |> Syntax.check_term lthy |
268 in |
256 in |
269 fns $ otrm |
257 define (nconst_bname, mx, absrep_fn $ rhs) lthy |
270 end |
258 end |
271 *} |
259 *} |
272 |
260 |
273 |
261 ML {* |
274 ML {* |
262 (* returns all subterms where two types differ *) |
275 fun exchange_ty qenv ty = |
|
276 case (lookup_snd (op =) qenv ty) of |
|
277 SOME qty => qty |
|
278 | NONE => |
|
279 (case ty of |
|
280 Type (s, tys) => Type (s, map (exchange_ty qenv) tys) |
|
281 | _ => ty |
|
282 ) |
|
283 *} |
|
284 |
|
285 ML {* |
|
286 fun ppair lthy (ty1, ty2) = |
|
287 "(" ^ (Syntax.string_of_typ lthy ty1) ^ "," ^ (Syntax.string_of_typ lthy ty2) ^ ")" |
|
288 *} |
|
289 |
|
290 ML {* |
|
291 fun print_env qenv lthy = |
|
292 map (ppair lthy) qenv |
|
293 |> commas |
|
294 |> tracing |
|
295 *} |
|
296 |
|
297 ML {* |
|
298 fun make_const_def nconst_bname otrm mx qenv lthy = |
|
299 let |
|
300 val otrm_ty = fastype_of otrm |
|
301 val nconst_ty = exchange_ty qenv otrm_ty |
|
302 val nconst = Const (Binding.name_of nconst_bname, nconst_ty) |
|
303 val def_trm = get_const_def nconst otrm qenv lthy |
|
304 in |
|
305 define (nconst_bname, mx, def_trm) lthy |
|
306 end |
|
307 *} |
|
308 |
|
309 ML {* |
|
310 (* difference of two types *) |
|
311 fun diff (T, S) Ds = |
263 fun diff (T, S) Ds = |
312 case (T, S) of |
264 case (T, S) of |
313 (TVar v, TVar u) => if v = u then Ds else (T, S)::Ds |
265 (TVar v, TVar u) => if v = u then Ds else (T, S)::Ds |
314 | (TFree x, TFree y) => if x = y then Ds else (T, S)::Ds |
266 | (TFree x, TFree y) => if x = y then Ds else (T, S)::Ds |
315 | (Type (a, Ts), Type (b, Us)) => |
267 | (Type (a, Ts), Type (b, Us)) => |
319 | diffs ([], []) Ds = Ds |
271 | diffs ([], []) Ds = Ds |
320 | diffs _ _ = error "Unequal length of type arguments" |
272 | diffs _ _ = error "Unequal length of type arguments" |
321 *} |
273 *} |
322 |
274 |
323 ML {* |
275 ML {* |
324 fun quotdef_cmd ((bind, qty, mx), (attr, prop)) lthy = |
276 fun error_msg lthy (qty, rty) = |
325 let |
277 let |
326 val (_, rhs) = Logic.dest_equals prop |
278 val qtystr = quote (Syntax.string_of_typ lthy qty) |
|
279 val rtystr = quote (Syntax.string_of_typ lthy rty) |
|
280 in |
|
281 error (implode ["Quotient type ", qtystr, " does not match with ", rtystr]) |
|
282 end |
|
283 |
|
284 |
|
285 fun sanity_chk lthy qenv = |
|
286 let |
|
287 val qenv' = Quotient_Info.mk_qenv lthy |
|
288 val thy = ProofContext.theory_of lthy |
|
289 |
|
290 fun is_inst thy (qty, rty) (qty', rty') = |
|
291 if Sign.typ_instance thy (qty, qty') |
|
292 then let |
|
293 val inst = Sign.typ_match thy (qty', qty) Vartab.empty |
|
294 in |
|
295 rty = Envir.subst_type inst rty' |
|
296 end |
|
297 else false |
|
298 |
|
299 fun chk_inst (qty, rty) = |
|
300 if exists (is_inst thy (qty, rty)) qenv' then true |
|
301 else error_msg lthy (qty, rty) |
|
302 in |
|
303 forall chk_inst qenv |
|
304 end |
|
305 *} |
|
306 |
|
307 ML {* |
|
308 fun quotdef ((bind, qty, mx), (attr, prop)) lthy = |
|
309 let |
|
310 val (_, prop') = PrimitiveDefs.dest_def lthy (K true) (K false) (K false) prop |
|
311 val (_, rhs) = PrimitiveDefs.abs_def prop' |
|
312 |
327 val rty = fastype_of rhs |
313 val rty = fastype_of rhs |
328 val qenv = distinct (op=) (diff (qty, rty) []) |
314 val qenv = distinct (op=) (diff (qty, rty) []) |
|
315 |
329 in |
316 in |
330 make_const_def bind rhs mx qenv lthy |
317 sanity_chk lthy qenv; |
331 end |
318 make_def bind rhs qty mx qenv lthy |
332 *} |
319 end |
333 |
320 *} |
334 ML {* |
321 |
335 val constdecl = |
322 ML {* |
336 OuterParse.binding -- |
323 val quotdef_parser = |
337 (OuterParse.$$$ "::" |-- OuterParse.!!! |
324 (OuterParse.binding -- |
338 (OuterParse.typ -- OuterParse.opt_mixfix' --| OuterParse.where_)) |
325 (OuterParse.$$$ "::" |-- OuterParse.!!! (OuterParse.typ -- |
339 >> OuterParse.triple2; |
326 OuterParse.opt_mixfix' --| OuterParse.where_)) >> OuterParse.triple2) -- |
340 *} |
327 (SpecParse.opt_thm_name ":" -- OuterParse.prop) |
341 |
328 *} |
342 ML {* |
329 |
343 val quotdef_parser = |
330 ML {* |
344 (constdecl -- (SpecParse.opt_thm_name ":" -- OuterParse.prop)) |
331 fun quotdef_cmd ((bind, qtystr, mx), (attr, propstr)) lthy = |
345 *} |
|
346 |
|
347 ML {* |
|
348 fun quotdef ((bind, qtystr, mx), (attr, propstr)) lthy = |
|
349 let |
332 let |
350 val qty = (Syntax.check_typ lthy o Syntax.parse_typ lthy) qtystr |
333 val qty = (Syntax.check_typ lthy o Syntax.parse_typ lthy) qtystr |
351 val prop = (Syntax.check_prop lthy o Syntax.parse_prop lthy) propstr |
334 val prop = (Syntax.check_prop lthy o Syntax.parse_prop lthy) propstr |
352 in |
335 in |
353 quotdef_cmd ((bind, qty, mx), (attr, prop)) lthy |> snd |
336 quotdef ((bind, qty, mx), (attr, prop)) lthy |> snd |
354 end |
337 end |
355 *} |
338 *} |
356 |
339 |
357 ML {* |
340 ML {* |
358 val _ = OuterSyntax.local_theory "quotient_def" "lifted definition of constants" |
341 val _ = OuterSyntax.local_theory "quotient_def" "lifted definition of constants" |
359 OuterKeyword.thy_decl (quotdef_parser >> quotdef) |
342 OuterKeyword.thy_decl (quotdef_parser >> quotdef_cmd) |
360 *} |
343 *} |
361 |
344 |
362 section {* ATOMIZE *} |
345 section {* ATOMIZE *} |
363 |
346 |
364 text {* |
347 text {* |