34 |
36 |
35 structure RecordPackage: RECORD_PACKAGE = |
37 structure RecordPackage: RECORD_PACKAGE = |
36 struct |
38 struct |
37 |
39 |
38 |
40 |
|
41 (*** utilities ***) |
|
42 |
|
43 (* string suffixes *) |
|
44 |
|
45 fun suffix sfx s = s ^ sfx; |
|
46 |
|
47 fun unsuffix sfx s = |
|
48 let |
|
49 val cs = explode s; |
|
50 val prfx_len = size s - size sfx; |
|
51 in |
|
52 if prfx_len >= 0 andalso implode (drop (prfx_len, cs)) = sfx then |
|
53 implode (take (prfx_len, cs)) |
|
54 else raise LIST "unsuffix" |
|
55 end; |
|
56 |
|
57 |
|
58 (* definitions and equations *) |
|
59 |
|
60 infix 0 :== === ; |
|
61 |
|
62 val (op :==) = Logic.mk_defpair; |
|
63 val (op ===) = HOLogic.mk_Trueprop o HOLogic.mk_eq; |
|
64 |
|
65 fun get_defs thy specs = map (PureThy.get_tthm thy o fst) specs; |
|
66 fun add_simps ss simps = Simplifier.addsimps (ss, map Attribute.thm_of simps); |
|
67 |
|
68 |
|
69 (* proof by simplification *) |
|
70 |
|
71 fun prove_simp opt_ss simps = |
|
72 let |
|
73 val ss = add_simps (if_none opt_ss HOL_basic_ss) simps; |
|
74 fun prove thy goal = |
|
75 Attribute.tthm_of |
|
76 (Goals.prove_goalw_cterm [] (Thm.cterm_of (Theory.sign_of thy) goal) |
|
77 (K [ALLGOALS (Simplifier.simp_tac ss)]) |
|
78 handle ERROR => error ("The error(s) above occurred while trying to prove " |
|
79 ^ quote (Sign.string_of_term (Theory.sign_of thy) goal))); |
|
80 in prove end; |
|
81 |
|
82 |
|
83 |
39 (*** syntax operations ***) |
84 (*** syntax operations ***) |
40 |
85 |
41 (** names **) |
86 (** name components **) |
42 |
|
43 (* name components *) |
|
44 |
87 |
45 val moreN = "more"; |
88 val moreN = "more"; |
46 val schemeN = "_scheme"; |
89 val schemeN = "_scheme"; |
47 val fieldN = "_field"; |
90 val fieldN = "_field"; |
48 val field_typeN = "_field_type"; |
91 val field_typeN = "_field_type"; |
314 |
340 |
315 |
341 |
316 |
342 |
317 (** internal theory extenders **) |
343 (** internal theory extenders **) |
318 |
344 |
319 (* utils *) |
345 (* field_definitions *) |
320 |
346 |
321 fun get_defs thy specs = map (PureThy.get_tthm thy o fst) specs; |
347 (*theorems from Prod.thy*) |
322 |
|
323 (*proof by simplification*) |
|
324 fun prove_simp opt_ss simps = |
|
325 let |
|
326 val ss = if_none opt_ss HOL_basic_ss addsimps (map Attribute.thm_of simps); |
|
327 fun prove thy goal = |
|
328 Attribute.tthm_of |
|
329 (Goals.prove_goalw_cterm [] (Thm.cterm_of (Theory.sign_of thy) goal) |
|
330 (K [ALLGOALS (Simplifier.simp_tac ss)]) |
|
331 handle ERROR => error ("The error(s) above occurred while trying to prove " |
|
332 ^ quote (Sign.string_of_term (Theory.sign_of thy) goal))); |
|
333 in prove end; |
|
334 |
|
335 (*thms from Prod.thy*) |
|
336 val prod_convs = map Attribute.tthm_of [fst_conv, snd_conv]; |
348 val prod_convs = map Attribute.tthm_of [fst_conv, snd_conv]; |
337 |
349 |
338 |
350 |
339 (* field_definitions *) (* FIXME tune; actual typedefs! *) |
351 fun field_definitions fields names zeta moreT more vars named_vars thy = |
340 |
|
341 fun field_definitions fields names zeta moreT more vars thy = |
|
342 let |
352 let |
343 val base = Sign.base_name; |
353 val base = Sign.base_name; |
344 |
354 |
345 |
355 |
346 (* prepare declarations and definitions *) |
356 (* prepare declarations and definitions *) |
355 val field_decls = map (mk_fieldC moreT) fields; |
365 val field_decls = map (mk_fieldC moreT) fields; |
356 val dest_decls = map (mk_fstC moreT) fields @ map (mk_sndC moreT) fields; |
366 val dest_decls = map (mk_fstC moreT) fields @ map (mk_sndC moreT) fields; |
357 |
367 |
358 (*field constructors*) |
368 (*field constructors*) |
359 fun mk_field_spec (c, v) = |
369 fun mk_field_spec (c, v) = |
360 mk_def (mk_field ((c, v), more), HOLogic.mk_prod (v, more)); |
370 mk_field ((c, v), more) :== HOLogic.mk_prod (v, more); |
361 val field_specs = ListPair.map mk_field_spec (names, vars); |
371 val field_specs = map mk_field_spec named_vars; |
362 |
372 |
363 (*field destructors*) |
373 (*field destructors*) |
364 fun mk_dest_spec dest dest' (c, T) = |
374 fun mk_dest_spec dest dest' (c, T) = |
365 let |
375 let |
366 val p = Free ("p", mk_fieldT ((c, T), moreT)); |
376 val p = Free ("p", mk_fieldT ((c, T), moreT)); |
367 val p' = Free ("p", HOLogic.mk_prodT (T, moreT)); (*Note: field types are just abbreviations*) |
377 val p' = Free ("p", HOLogic.mk_prodT (T, moreT)); |
368 in mk_def (dest p, dest' p') end; |
378 (*note: field types are just abbreviations*) |
|
379 in dest p :== dest' p' end; |
369 val dest_specs = |
380 val dest_specs = |
370 map (mk_dest_spec mk_fst HOLogic.mk_fst) fields @ |
381 map (mk_dest_spec mk_fst HOLogic.mk_fst) fields @ |
371 map (mk_dest_spec mk_snd HOLogic.mk_snd) fields; |
382 map (mk_dest_spec mk_snd HOLogic.mk_snd) fields; |
372 |
383 |
373 |
384 |
374 (* prepare theorems *) |
385 (* prepare theorems *) |
|
386 |
375 fun mk_dest_prop dest dest' (c, v) = |
387 fun mk_dest_prop dest dest' (c, v) = |
376 mk_eq (dest (mk_field ((c, v), more)), dest' (v, more)); |
388 dest (mk_field ((c, v), more)) === dest' (v, more); |
377 val dest_props = |
389 val dest_props = |
378 ListPair.map (mk_dest_prop mk_fst fst) (names, vars) @ |
390 map (mk_dest_prop mk_fst fst) named_vars @ map (mk_dest_prop mk_snd snd) named_vars; |
379 ListPair.map (mk_dest_prop mk_snd snd) (names, vars); |
|
380 |
391 |
381 |
392 |
382 (* 1st stage: defs_thy *) |
393 (* 1st stage: defs_thy *) |
383 |
394 |
384 val defs_thy = |
395 val defs_thy = |
429 val parent_names = map fst parent_fields; |
440 val parent_names = map fst parent_fields; |
430 val parent_types = map snd parent_fields; |
441 val parent_types = map snd parent_fields; |
431 val parent_len = length parent_fields; |
442 val parent_len = length parent_fields; |
432 val parent_xs = variantlist (map (base o fst) parent_fields, [moreN]); |
443 val parent_xs = variantlist (map (base o fst) parent_fields, [moreN]); |
433 val parent_vars = ListPair.map Free (parent_xs, parent_types); |
444 val parent_vars = ListPair.map Free (parent_xs, parent_types); |
|
445 val parent_named_vars = parent_names ~~ parent_vars; |
434 |
446 |
435 val fields = map (apfst full) bfields; |
447 val fields = map (apfst full) bfields; |
436 val names = map fst fields; |
448 val names = map fst fields; |
437 val types = map snd fields; |
449 val types = map snd fields; |
438 val len = length fields; |
450 val len = length fields; |
439 val xs = variantlist (map fst bfields, moreN :: parent_xs); |
451 val xs = variantlist (map fst bfields, moreN :: parent_xs); |
440 val vars = ListPair.map Free (xs, types); |
452 val vars = ListPair.map Free (xs, types); |
|
453 val named_vars = names ~~ vars; |
441 |
454 |
442 val all_fields = parent_fields @ fields; |
455 val all_fields = parent_fields @ fields; |
443 val all_names = parent_names @ names; |
456 val all_names = parent_names @ names; |
444 val all_types = parent_types @ types; |
457 val all_types = parent_types @ types; |
445 val all_len = parent_len + len; |
458 val all_len = parent_len + len; |
446 val all_xs = parent_xs @ xs; |
459 val all_xs = parent_xs @ xs; |
447 val all_vars = parent_vars @ vars; |
460 val all_vars = parent_vars @ vars; |
448 |
461 val all_named_vars = parent_named_vars @ named_vars; |
449 |
462 |
450 val zeta = variant alphas "'z"; |
463 val zeta = variant alphas "'z"; |
451 val moreT = TFree (zeta, moreS); |
464 val moreT = TFree (zeta, moreS); |
452 val more = Free (variant xs moreN, moreT); |
465 val more = Free (variant xs moreN, moreT); |
|
466 fun more_part t = mk_more t (full moreN); |
|
467 |
|
468 val parent_more = funpow parent_len mk_snd; |
|
469 val idxs = 0 upto (len - 1); |
453 |
470 |
454 val rec_schemeT = mk_recordT (all_fields, moreT); |
471 val rec_schemeT = mk_recordT (all_fields, moreT); |
|
472 val rec_scheme = mk_record (all_named_vars, more); |
|
473 val r = Free ("r", rec_schemeT); |
455 val recT = mk_recordT (all_fields, HOLogic.unitT); |
474 val recT = mk_recordT (all_fields, HOLogic.unitT); |
456 val r = Free ("r", rec_schemeT); |
|
457 |
|
458 val parent_more = funpow parent_len mk_snd; |
|
459 |
475 |
460 |
476 |
461 (* prepare print translation functions *) |
477 (* prepare print translation functions *) |
462 |
478 |
463 val field_tr'_names = |
479 val field_tr'_names = |
481 (* record (scheme) type abbreviation *) |
496 (* record (scheme) type abbreviation *) |
482 val recordT_specs = |
497 val recordT_specs = |
483 [(suffix schemeN bname, alphas @ [zeta], rec_schemeT, Syntax.NoSyn), |
498 [(suffix schemeN bname, alphas @ [zeta], rec_schemeT, Syntax.NoSyn), |
484 (bname, alphas, recT, Syntax.NoSyn)]; |
499 (bname, alphas, recT, Syntax.NoSyn)]; |
485 |
500 |
486 (*field selectors*) |
501 (*selectors*) |
487 fun mk_sel_spec (i, c) = |
502 fun mk_sel_spec (i, c) = |
488 mk_def (mk_sel r c, mk_fst (funpow i mk_snd (parent_more r))); |
503 mk_sel r c :== mk_fst (funpow i mk_snd (parent_more r)); |
489 val sel_specs = ListPair.map mk_sel_spec (0 upto (len - 1), names); |
504 val sel_specs = |
490 |
505 ListPair.map mk_sel_spec (idxs, names) @ |
491 (*more quasi-selector*) |
506 [more_part r :== funpow len mk_snd (parent_more r)]; |
492 val more_part = Const (full moreN, rec_schemeT --> moreT) $ r; |
507 |
493 val more_spec = mk_def (more_part, funpow len mk_snd (parent_more r)); |
|
494 |
|
495 (*updates*) |
508 (*updates*) |
|
509 val all_sels = all_names ~~ map (mk_sel r) all_names; |
496 fun mk_upd_spec (i, (c, x)) = |
510 fun mk_upd_spec (i, (c, x)) = |
497 let |
511 mk_update r (c, x) :== |
498 val prfx = map (mk_sel r) (parent_names @ take (i, names)); |
512 mk_record (nth_update (c, x) (parent_len + i, all_sels), more_part r) |
499 val sffx = map (mk_sel r) (drop (i + 1, names)); |
513 val update_specs = ListPair.map mk_upd_spec (idxs, named_vars); |
500 in mk_def (mk_update r (c, x), mk_record (all_names ~~ (prfx @ [x] @ sffx), more_part)) end; |
|
501 val update_specs = ListPair.map mk_upd_spec (0 upto (len - 1), names ~~ vars); |
|
502 |
514 |
503 (*makes*) |
515 (*makes*) |
504 val make_scheme = Const (mk_makeC rec_schemeT (full make_schemeN, all_types @ [moreT])); |
516 val make_scheme = Const (mk_makeC rec_schemeT (full make_schemeN, all_types @ [moreT])); |
505 val make = Const (mk_makeC recT (full makeN, all_types)); |
517 val make = Const (mk_makeC recT (full makeN, all_types)); |
506 val make_specs = |
518 val make_specs = |
507 map mk_def |
519 [list_comb (make_scheme, all_vars) $ more :== rec_scheme, |
508 [(list_comb (make_scheme, all_vars) $ more, mk_record (all_names ~~ all_vars, more)), |
520 list_comb (make, all_vars) :== mk_record (all_named_vars, HOLogic.unit)]; |
509 (list_comb (make, all_vars), mk_record (all_names ~~ all_vars, HOLogic.unit))]; |
521 |
|
522 |
|
523 (* prepare propositions *) |
|
524 |
|
525 (*selectors*) |
|
526 val sel_props = |
|
527 map (fn (c, x) => mk_sel rec_scheme c === x) named_vars @ |
|
528 [more_part rec_scheme === more]; |
|
529 |
|
530 (*updates*) |
|
531 fun mk_upd_prop (i, (c, T)) = |
|
532 let val x' = Free (variant all_xs (base c ^ "'"), T) in |
|
533 mk_update rec_scheme (c, x') === |
|
534 mk_record (nth_update (c, x') (parent_len + i, all_named_vars), more) |
|
535 end; |
|
536 val update_props = ListPair.map mk_upd_prop (idxs, fields); |
510 |
537 |
511 |
538 |
512 (* 1st stage: fields_thy *) |
539 (* 1st stage: fields_thy *) |
513 |
540 |
514 val (fields_thy, field_simps) = |
541 val (fields_thy, field_simps) = |
515 thy |
542 thy |
516 |> Theory.add_path bname |
543 |> Theory.add_path bname |
517 |> field_definitions fields names zeta moreT more vars; |
544 |> field_definitions fields names zeta moreT more vars named_vars; |
518 |
545 |
519 |
546 |
520 (* 2nd stage: defs_thy *) |
547 (* 2nd stage: defs_thy *) |
521 |
548 |
522 val defs_thy = |
549 val defs_thy = |
523 fields_thy |
550 fields_thy |
524 |> Theory.parent_path |
551 |> Theory.parent_path |
525 |> Theory.add_tyabbrs_i recordT_specs (*not made part of record name space!*) |
552 |> Theory.add_tyabbrs_i recordT_specs (*not made part of record name space!*) |
526 |> Theory.add_path bname |
553 |> Theory.add_path bname |
527 |> Theory.add_trfuns field_trfuns |
554 |> Theory.add_trfuns field_trfuns |
528 |> (Theory.add_consts_i o map (Syntax.no_syn o apfst base)) |
555 |> (Theory.add_consts_i o map Syntax.no_syn) |
529 (sel_decls @ [more_decl] @ update_decls @ make_decls) |
556 (sel_decls @ update_decls @ make_decls) |
530 |> (PureThy.add_defs_i o map Attribute.none) |
557 |> (PureThy.add_defs_i o map Attribute.none) |
531 (sel_specs @ [more_spec] @ update_specs @ make_specs); |
558 (sel_specs @ update_specs @ make_specs); |
532 |
559 |
533 val sel_defs = get_defs defs_thy sel_specs; |
560 val sel_defs = get_defs defs_thy sel_specs; |
534 val more_def = hd (get_defs defs_thy [more_spec]); |
|
535 val update_defs = get_defs defs_thy update_specs; |
561 val update_defs = get_defs defs_thy update_specs; |
536 val make_defs = get_defs defs_thy make_specs; |
562 val make_defs = get_defs defs_thy make_specs; |
537 |
563 |
538 |
564 |
539 (* 3rd stage: thms_thy *) |
565 (* 3rd stage: thms_thy *) |
541 val parent_simpset = |
567 val parent_simpset = |
542 (case parent of |
568 (case parent of |
543 None => HOL_basic_ss |
569 None => HOL_basic_ss |
544 | Some (_, pname) => #simpset (the (get_record thy pname))); |
570 | Some (_, pname) => #simpset (the (get_record thy pname))); |
545 |
571 |
546 val simpset = parent_simpset; (* FIXME *) |
572 val pss = Some parent_simpset; |
|
573 |
|
574 val sel_convs = map (prove_simp pss (sel_defs @ field_simps) defs_thy) sel_props; |
|
575 val update_convs = map (prove_simp pss (update_defs @ sel_convs) defs_thy) update_props; |
|
576 val simps = field_simps @ sel_convs @ update_convs @ make_defs; |
547 |
577 |
548 val thms_thy = |
578 val thms_thy = |
549 defs_thy |
579 defs_thy |
550 |> (PureThy.add_tthmss o map Attribute.none) |
580 |> (PureThy.add_tthmss o map Attribute.none) |
551 [("sel_defs", sel_defs), |
581 [("selector_defs", sel_defs), |
552 ("update_defs", update_defs), |
582 ("update_defs", update_defs), |
553 ("make_defs", make_defs)]; |
583 ("make_defs", make_defs), |
554 |
584 ("selector_convs", sel_convs), |
555 (* |> record_theorems FIXME *) |
585 ("update_convs", update_convs)] |
|
586 |> PureThy.add_tthmss [(("simps", simps), [Simplifier.simp_add_global])]; |
556 |
587 |
557 |
588 |
558 (* 4th stage: final_thy *) |
589 (* 4th stage: final_thy *) |
|
590 |
|
591 val simpset = add_simps parent_simpset simps; |
559 |
592 |
560 val final_thy = |
593 val final_thy = |
561 thms_thy |
594 thms_thy |
562 |> put_record name {args = args, parent = parent, fields = fields, simpset = simpset} |
595 |> put_record name {args = args, parent = parent, fields = fields, simpset = simpset} |
563 |> Theory.parent_path; |
596 |> Theory.parent_path; |