314 | dups => error ("Inconsistent sort constraints for " ^ commas dups) |
316 | dups => error ("Inconsistent sort constraints for " ^ commas dups) |
315 in (T, sorts') end; |
317 in (T, sorts') end; |
316 |
318 |
317 fun gen_domain_isomorphism |
319 fun gen_domain_isomorphism |
318 (prep_typ: theory -> 'a -> (string * sort) list -> typ * (string * sort) list) |
320 (prep_typ: theory -> 'a -> (string * sort) list -> typ * (string * sort) list) |
319 (doms_raw: (string list * binding * mixfix * 'a) list) |
321 (doms_raw: (string list * binding * mixfix * 'a * (binding * binding) option) list) |
320 (thy: theory) |
322 (thy: theory) |
321 : theory = |
323 : theory = |
322 let |
324 let |
323 val _ = Theory.requires thy "Representable" "domain isomorphisms"; |
325 val _ = Theory.requires thy "Representable" "domain isomorphisms"; |
324 |
326 |
325 (* this theory is used just for parsing *) |
327 (* this theory is used just for parsing *) |
326 val tmp_thy = thy |> |
328 val tmp_thy = thy |> |
327 Theory.copy |> |
329 Theory.copy |> |
328 Sign.add_types (map (fn (tvs, tname, mx, _) => |
330 Sign.add_types (map (fn (tvs, tname, mx, _, morphs) => |
329 (tname, length tvs, mx)) doms_raw); |
331 (tname, length tvs, mx)) doms_raw); |
330 |
332 |
331 fun prep_dom thy (vs, t, mx, typ_raw) sorts = |
333 fun prep_dom thy (vs, t, mx, typ_raw, morphs) sorts = |
332 let val (typ, sorts') = prep_typ thy typ_raw sorts |
334 let val (typ, sorts') = prep_typ thy typ_raw sorts |
333 in ((vs, t, mx, typ), sorts') end; |
335 in ((vs, t, mx, typ, morphs), sorts') end; |
334 |
336 |
335 val (doms : (string list * binding * mixfix * typ) list, |
337 val (doms : (string list * binding * mixfix * typ * (binding * binding) option) list, |
336 sorts : (string * sort) list) = |
338 sorts : (string * sort) list) = |
337 fold_map (prep_dom tmp_thy) doms_raw []; |
339 fold_map (prep_dom tmp_thy) doms_raw []; |
338 |
340 |
339 (* domain equations *) |
341 (* domain equations *) |
340 fun mk_dom_eqn (vs, tbind, mx, rhs) = |
342 fun mk_dom_eqn (vs, tbind, mx, rhs, morphs) = |
341 let fun arg v = TFree (v, the (AList.lookup (op =) sorts v)); |
343 let fun arg v = TFree (v, the (AList.lookup (op =) sorts v)); |
342 in (Type (Sign.full_name tmp_thy tbind, map arg vs), rhs) end; |
344 in (Type (Sign.full_name tmp_thy tbind, map arg vs), rhs) end; |
343 val dom_eqns = map mk_dom_eqn doms; |
345 val dom_eqns = map mk_dom_eqn doms; |
344 |
346 |
345 (* check for valid type parameters *) |
347 (* check for valid type parameters *) |
346 val (tyvars, _, _, _)::_ = doms; |
348 val (tyvars, _, _, _, _)::_ = doms; |
347 val new_doms = map (fn (tvs, tname, mx, _) => |
349 val new_doms = map (fn (tvs, tname, mx, _, _) => |
348 let val full_tname = Sign.full_name tmp_thy tname |
350 let val full_tname = Sign.full_name tmp_thy tname |
349 in |
351 in |
350 (case duplicates (op =) tvs of |
352 (case duplicates (op =) tvs of |
351 [] => |
353 [] => |
352 if eq_set (op =) (tyvars, tvs) then (full_tname, tvs) |
354 if eq_set (op =) (tyvars, tvs) then (full_tname, tvs) |
353 else error ("Mutually recursive domains must have same type parameters") |
355 else error ("Mutually recursive domains must have same type parameters") |
354 | dups => error ("Duplicate parameter(s) for domain " ^ quote (Binding.str_of tname) ^ |
356 | dups => error ("Duplicate parameter(s) for domain " ^ quote (Binding.str_of tname) ^ |
355 " : " ^ commas dups)) |
357 " : " ^ commas dups)) |
356 end) doms; |
358 end) doms; |
357 val dom_binds = map (fn (_, tbind, _, _) => tbind) doms; |
359 val dom_binds = map (fn (_, tbind, _, _, _) => tbind) doms; |
|
360 val morphs = map (fn (_, _, _, _, morphs) => morphs) doms; |
358 |
361 |
359 (* declare deflation combinator constants *) |
362 (* declare deflation combinator constants *) |
360 fun declare_defl_const (vs, tbind, mx, rhs) thy = |
363 fun declare_defl_const (vs, tbind, mx, rhs, morphs) thy = |
361 let |
364 let |
362 val defl_type = Library.foldr cfunT (map (K deflT) vs, deflT); |
365 val defl_type = Library.foldr cfunT (map (K deflT) vs, deflT); |
363 val defl_bind = Binding.suffix_name "_defl" tbind; |
366 val defl_bind = Binding.suffix_name "_defl" tbind; |
364 in |
367 in |
365 Sign.declare_const ((defl_bind, defl_type), NoSyn) thy |
368 Sign.declare_const ((defl_bind, defl_type), NoSyn) thy |
381 val defl_binds = map (Binding.suffix_name "_defl") dom_binds; |
384 val defl_binds = map (Binding.suffix_name "_defl") dom_binds; |
382 val ((defl_apply_thms, defl_unfold_thms), thy) = |
385 val ((defl_apply_thms, defl_unfold_thms), thy) = |
383 add_fixdefs (defl_binds ~~ defl_specs) thy; |
386 add_fixdefs (defl_binds ~~ defl_specs) thy; |
384 |
387 |
385 (* define types using deflation combinators *) |
388 (* define types using deflation combinators *) |
386 fun make_repdef ((vs, tbind, mx, _), defl_const) thy = |
389 fun make_repdef ((vs, tbind, mx, _, _), defl_const) thy = |
387 let |
390 let |
388 fun tfree a = TFree (a, the (AList.lookup (op =) sorts a)) |
391 fun tfree a = TFree (a, the (AList.lookup (op =) sorts a)) |
389 val reps = map (mk_Rep_of o tfree) vs; |
392 val reps = map (mk_Rep_of o tfree) vs; |
390 val defl = Library.foldl mk_capply (defl_const, reps); |
393 val defl = Library.foldl mk_capply (defl_const, reps); |
391 val ((_, _, _, {REP, ...}), thy) = |
394 val ((_, _, _, {REP, ...}), thy) = |
414 val (_, thy) = thy |> |
417 val (_, thy) = thy |> |
415 (PureThy.add_thms o map Thm.no_attributes) |
418 (PureThy.add_thms o map Thm.no_attributes) |
416 (REP_eq_binds ~~ REP_eq_thms); |
419 (REP_eq_binds ~~ REP_eq_thms); |
417 |
420 |
418 (* define rep/abs functions *) |
421 (* define rep/abs functions *) |
419 fun mk_rep_abs (tbind, (lhsT, rhsT)) thy = |
422 fun mk_rep_abs ((tbind, morphs), (lhsT, rhsT)) thy = |
420 let |
423 let |
421 val rep_type = cfunT (lhsT, rhsT); |
424 val rep_type = cfunT (lhsT, rhsT); |
422 val abs_type = cfunT (rhsT, lhsT); |
425 val abs_type = cfunT (rhsT, lhsT); |
423 val rep_bind = Binding.suffix_name "_rep" tbind; |
426 val rep_bind = Binding.suffix_name "_rep" tbind; |
424 val abs_bind = Binding.suffix_name "_abs" tbind; |
427 val abs_bind = Binding.suffix_name "_abs" tbind; |
|
428 val (rep_bind, abs_bind) = the_default (rep_bind, abs_bind) morphs; |
425 val (rep_const, thy) = thy |> |
429 val (rep_const, thy) = thy |> |
426 Sign.declare_const ((rep_bind, rep_type), NoSyn); |
430 Sign.declare_const ((rep_bind, rep_type), NoSyn); |
427 val (abs_const, thy) = thy |> |
431 val (abs_const, thy) = thy |> |
428 Sign.declare_const ((abs_bind, abs_type), NoSyn); |
432 Sign.declare_const ((abs_bind, abs_type), NoSyn); |
429 val rep_eqn = Logic.mk_equals (rep_const, coerce_const rep_type); |
433 val rep_eqn = Logic.mk_equals (rep_const, coerce_const rep_type); |