313 (*canonical interpretation*), |
322 (*canonical interpretation*), |
314 morphism: morphism, |
323 morphism: morphism, |
315 (*partial morphism of canonical interpretation*) |
324 (*partial morphism of canonical interpretation*) |
316 intro: thm, |
325 intro: thm, |
317 defs: thm list, |
326 defs: thm list, |
318 operations: (string * ((term * (typ * int)) * (term * typ))) list |
327 operations: (string * (term * (typ * int))) list, |
319 (*constant name ~> ((locale term, |
328 (*constant name ~> (locale term, |
320 (constant constraint, instantiaton index of class typ)), locale term & typ for uncheck)*) |
329 (constant constraint, instantiaton index of class typ))*) |
|
330 unchecks: (term * term) list |
321 }; |
331 }; |
322 |
332 |
323 fun rep_class_data (ClassData d) = d; |
333 fun rep_class_data (ClassData d) = d; |
324 fun mk_class_data ((consts, base_sort, inst, morphism, intro), |
334 fun mk_class_data ((consts, base_sort, inst, morphism, intro), |
325 (defs, operations)) = |
335 (defs, (operations, unchecks))) = |
326 ClassData { consts = consts, base_sort = base_sort, inst = inst, |
336 ClassData { consts = consts, base_sort = base_sort, inst = inst, |
327 morphism = morphism, intro = intro, defs = defs, |
337 morphism = morphism, intro = intro, defs = defs, |
328 operations = operations }; |
338 operations = operations, unchecks = unchecks }; |
329 fun map_class_data f (ClassData { consts, base_sort, inst, morphism, intro, |
339 fun map_class_data f (ClassData { consts, base_sort, inst, morphism, intro, |
330 defs, operations }) = |
340 defs, operations, unchecks }) = |
331 mk_class_data (f ((consts, base_sort, inst, morphism, intro), |
341 mk_class_data (f ((consts, base_sort, inst, morphism, intro), |
332 (defs, operations))); |
342 (defs, (operations, unchecks)))); |
333 fun merge_class_data _ (ClassData { consts = consts, |
343 fun merge_class_data _ (ClassData { consts = consts, |
334 base_sort = base_sort, inst = inst, morphism = morphism, intro = intro, |
344 base_sort = base_sort, inst = inst, morphism = morphism, intro = intro, |
335 defs = defs1, operations = operations1 }, |
345 defs = defs1, operations = operations1, unchecks = unchecks1 }, |
336 ClassData { consts = _, base_sort = _, inst = _, morphism = _, intro = _, |
346 ClassData { consts = _, base_sort = _, inst = _, morphism = _, intro = _, |
337 defs = defs2, operations = operations2 }) = |
347 defs = defs2, operations = operations2, unchecks = unchecks2 }) = |
338 mk_class_data ((consts, base_sort, inst, morphism, intro), |
348 mk_class_data ((consts, base_sort, inst, morphism, intro), |
339 (Thm.merge_thms (defs1, defs2), |
349 (Thm.merge_thms (defs1, defs2), |
340 AList.merge (op =) (K true) (operations1, operations2))); |
350 (AList.merge (op =) (K true) (operations1, operations2), |
|
351 Library.merge (op aconv o pairself snd) (unchecks1, unchecks2)))); |
341 |
352 |
342 structure ClassData = TheoryDataFun |
353 structure ClassData = TheoryDataFun |
343 ( |
354 ( |
344 type T = class_data Graph.T |
355 type T = class_data Graph.T |
345 val empty = Graph.empty; |
356 val empty = Graph.empty; |
433 |
445 |
434 (* updaters *) |
446 (* updaters *) |
435 |
447 |
436 fun add_class_data ((class, superclasses), (cs, base_sort, inst, phi, intro)) thy = |
448 fun add_class_data ((class, superclasses), (cs, base_sort, inst, phi, intro)) thy = |
437 let |
449 let |
438 val operations = map (fn (v_ty as (_, ty'), (c, ty)) => |
450 val operations = map (fn (v_ty, (c, ty)) => |
439 (c, ((Free v_ty, (Logic.varifyT ty, 0)), (Free v_ty, ty')))) cs; |
451 (c, ((Free v_ty, (Logic.varifyT ty, 0))))) cs; |
|
452 val unchecks = map (fn ((v, ty'), (c, _)) => |
|
453 (Free (v, Type.strip_sorts ty'), Const (c, Type.strip_sorts ty'))) cs; |
440 val cs = (map o pairself) fst cs; |
454 val cs = (map o pairself) fst cs; |
441 val add_class = Graph.new_node (class, |
455 val add_class = Graph.new_node (class, |
442 mk_class_data ((cs, base_sort, map (SOME o Const) inst, phi, intro), ([], operations))) |
456 mk_class_data ((cs, base_sort, map (SOME o Const) inst, phi, intro), ([], (operations, unchecks)))) |
443 #> fold (curry Graph.add_edge class) superclasses; |
457 #> fold (curry Graph.add_edge class) superclasses; |
444 in |
458 in |
445 ClassData.map add_class thy |
459 ClassData.map add_class thy |
446 end; |
460 end; |
447 |
461 |
448 fun register_operation class ((c, (t, t_rev)), some_def) thy = |
462 fun register_operation class (c, ((t, some_t_rev), some_def)) thy = |
449 let |
463 let |
450 val ty = Sign.the_const_constraint thy c; |
464 val ty = Sign.the_const_constraint thy c; |
451 val typargs = Sign.const_typargs thy (c, ty); |
465 val typargs = Sign.const_typargs thy (c, ty); |
452 val typidx = find_index (fn TVar ((v, _), _) => Name.aT = v | _ => false) typargs; |
466 val typidx = find_index (fn TVar ((v, _), _) => Name.aT = v | _ => false) typargs; |
453 val t_rev' = (map_types o map_atyps) |
467 fun mk_uncheck t_rev = |
454 (fn ty as TFree (v, _) => if Name.aT = v then TFree (v, []) else ty | ty => ty) t_rev; |
468 let |
455 val ty' = Term.fastype_of t_rev'; |
469 val t_rev' = map_types Type.strip_sorts t_rev; |
|
470 val ty' = Term.fastype_of t_rev'; |
|
471 in (t_rev', Const (c, ty')) end; |
|
472 val some_t_rev' = Option.map mk_uncheck some_t_rev; |
456 in |
473 in |
457 thy |
474 thy |
458 |> (ClassData.map o Graph.map_node class o map_class_data o apsnd) |
475 |> (ClassData.map o Graph.map_node class o map_class_data o apsnd) |
459 (fn (defs, operations) => |
476 (fn (defs, (operations, unchecks)) => |
460 (fold cons (the_list some_def) defs, |
477 (fold cons (the_list some_def) defs, |
461 (c, ((t, (ty, typidx)), (t_rev', ty'))) :: operations)) |
478 ((c, (t, (ty, typidx))) :: operations, fold cons (the_list some_t_rev') unchecks))) |
462 end; |
479 end; |
463 |
480 |
464 |
481 |
465 (** rule calculation, tactics and methods **) |
482 (** rule calculation, tactics and methods **) |
466 |
483 |
548 [("intro_classes", Method.no_args (Method.METHOD intro_classes_tac), |
565 [("intro_classes", Method.no_args (Method.METHOD intro_classes_tac), |
549 "back-chain introduction rules of classes"), |
566 "back-chain introduction rules of classes"), |
550 ("default", Method.thms_ctxt_args (Method.METHOD oo default_tac), |
567 ("default", Method.thms_ctxt_args (Method.METHOD oo default_tac), |
551 "apply some intro/elim rule")]); |
568 "apply some intro/elim rule")]); |
552 |
569 |
|
570 fun subclass_rule thy (sub, sup) = |
|
571 let |
|
572 val ctxt = Locale.init sub thy; |
|
573 val ctxt_thy = ProofContext.init thy; |
|
574 val props = |
|
575 Locale.global_asms_of thy sup |
|
576 |> maps snd |
|
577 |> map (ObjectLogic.ensure_propT thy); |
|
578 fun tac { prems, context } = |
|
579 Locale.intro_locales_tac true context prems |
|
580 ORELSE ALLGOALS assume_tac; |
|
581 in |
|
582 Goal.prove_multi ctxt [] [] props tac |
|
583 |> map (Assumption.export false ctxt ctxt_thy) |
|
584 |> Variable.export ctxt ctxt_thy |
|
585 end; |
|
586 |
|
587 fun prove_single_subclass (sub, sup) thms ctxt thy = |
|
588 let |
|
589 val ctxt_thy = ProofContext.init thy; |
|
590 val subclass_rule = Conjunction.intr_balanced thms |
|
591 |> Assumption.export false ctxt ctxt_thy |
|
592 |> singleton (Variable.export ctxt ctxt_thy); |
|
593 val sub_inst = Thm.ctyp_of thy (TVar ((Name.aT, 0), [sub])); |
|
594 val sub_ax = #axioms (AxClass.get_info thy sub); |
|
595 val classrel = |
|
596 #intro (AxClass.get_info thy sup) |
|
597 |> Drule.instantiate' [SOME sub_inst] [] |
|
598 |> OF_LAST (subclass_rule OF sub_ax) |
|
599 |> strip_all_ofclass thy (Sign.super_classes thy sup) |
|
600 |> Thm.strip_shyps |
|
601 in |
|
602 thy |
|
603 |> AxClass.add_classrel classrel |
|
604 |> prove_interpretation_in (ALLGOALS (ProofContext.fact_tac thms)) |
|
605 I (sub, Locale.Locale sup) |
|
606 |> ClassData.map (Graph.add_edge (sub, sup)) |
|
607 end; |
|
608 |
|
609 fun prove_subclass (sub, sup) thms ctxt thy = |
|
610 let |
|
611 val supclasses = Sign.complete_sort thy [sup] |
|
612 |> filter_out (fn class => Sign.subsort thy ([sub], [class])); |
|
613 fun transform sup' = subclass_rule thy (sup, sup') |> map (fn thm => thm OF thms); |
|
614 in |
|
615 thy |
|
616 |> fold_rev (fn sup' => prove_single_subclass (sub, sup') |
|
617 (transform sup') ctxt) supclasses |
|
618 end; |
|
619 |
553 |
620 |
554 (** classes and class target **) |
621 (** classes and class target **) |
555 |
622 |
556 (* class context syntax *) |
623 (* class context syntax *) |
557 |
624 |
558 structure ClassSyntax = ProofDataFun( |
625 structure ClassSyntax = ProofDataFun( |
559 type T = { |
626 type T = { |
560 constraints: (string * typ) list, |
627 constraints: (string * typ) list, |
561 base_sort: sort, |
628 base_sort: sort, |
562 local_operation: string * typ -> (typ * term) option, |
629 local_operation: string * typ -> (typ * term) option, |
563 rews: (term * term) list, |
630 unchecks: (term * term) list, |
564 passed: bool |
631 passed: bool |
565 } option; |
632 } option; |
566 fun init _ = NONE; |
633 fun init _ = NONE; |
567 ); |
634 ); |
568 |
635 |
569 fun synchronize_syntax thy sups base_sort ctxt = |
636 fun synchronize_syntax thy sups base_sort ctxt = |
570 let |
637 let |
|
638 (* constraints *) |
571 val operations = these_operations thy sups; |
639 val operations = these_operations thy sups; |
572 |
640 fun local_constraint (c, (_, (ty, _))) = |
573 (* constraints *) |
|
574 fun local_constraint (c, ((_, (ty, _)),_ )) = |
|
575 let |
641 let |
576 val ty' = ty |
642 val ty' = ty |
577 |> map_atyps (fn ty as TVar ((v, 0), _) => |
643 |> map_atyps (fn ty as TVar ((v, 0), _) => |
578 if v = Name.aT then TVar ((v, 0), base_sort) else ty) |
644 if v = Name.aT then TVar ((v, 0), base_sort) else ty) |
579 |> SOME; |
645 |> SOME; |
580 in (c, ty') end |
646 in (c, ty') end |
581 val constraints = (map o apsnd) (fst o snd o fst) operations; |
647 val constraints = (map o apsnd) (fst o snd) operations; |
582 |
648 |
583 (* check phase *) |
649 (* check phase *) |
584 val typargs = Consts.typargs (ProofContext.consts_of ctxt); |
650 val typargs = Consts.typargs (ProofContext.consts_of ctxt); |
585 fun check_const (c, ty) ((t, (_, idx)), _) = |
651 fun check_const (c, ty) (t, (_, idx)) = |
586 ((nth (typargs (c, ty)) idx), t); |
652 ((nth (typargs (c, ty)) idx), t); |
587 fun local_operation (c_ty as (c, _)) = AList.lookup (op =) operations c |
653 fun local_operation (c_ty as (c, _)) = AList.lookup (op =) operations c |
588 |> Option.map (check_const c_ty); |
654 |> Option.map (check_const c_ty); |
589 |
655 |
590 (* uncheck phase *) |
656 (* uncheck phase *) |
591 val rews = map (fn (c, (_, (t, ty))) => (t, Const (c, ty))) operations; |
657 val basify = |
|
658 map_atyps (fn ty as TFree (v, _) => if Name.aT = v then TFree (v, base_sort) |
|
659 else ty | ty => ty); |
|
660 val unchecks = these_unchecks thy sups |
|
661 |> (map o pairself o map_types) basify; |
592 in |
662 in |
593 ctxt |
663 ctxt |
594 |> fold (ProofContext.add_const_constraint o local_constraint) operations |
664 |> fold (ProofContext.add_const_constraint o local_constraint) operations |
595 |> ClassSyntax.map (K (SOME { |
665 |> ClassSyntax.map (K (SOME { |
596 constraints = constraints, |
666 constraints = constraints, |
597 base_sort = base_sort, |
667 base_sort = base_sort, |
598 local_operation = local_operation, |
668 local_operation = local_operation, |
599 rews = rews, |
669 unchecks = unchecks, |
600 passed = false |
670 passed = false |
601 })) |
671 })) |
602 end; |
672 end; |
603 |
673 |
604 fun refresh_syntax class ctxt = |
674 fun refresh_syntax class ctxt = |
606 val thy = ProofContext.theory_of ctxt; |
676 val thy = ProofContext.theory_of ctxt; |
607 val base_sort = (#base_sort o the_class_data thy) class; |
677 val base_sort = (#base_sort o the_class_data thy) class; |
608 in synchronize_syntax thy [class] base_sort ctxt end; |
678 in synchronize_syntax thy [class] base_sort ctxt end; |
609 |
679 |
610 val mark_passed = (ClassSyntax.map o Option.map) |
680 val mark_passed = (ClassSyntax.map o Option.map) |
611 (fn { constraints, base_sort, local_operation, rews, passed } => |
681 (fn { constraints, base_sort, local_operation, unchecks, passed } => |
612 { constraints = constraints, base_sort = base_sort, |
682 { constraints = constraints, base_sort = base_sort, |
613 local_operation = local_operation, rews = rews, passed = true }); |
683 local_operation = local_operation, unchecks = unchecks, passed = true }); |
614 |
684 |
615 fun sort_term_check ts ctxt = |
685 fun sort_term_check ts ctxt = |
616 let |
686 let |
617 val { constraints, base_sort, local_operation, passed, ... } = |
687 val { constraints, base_sort, local_operation, passed, ... } = |
618 the (ClassSyntax.get ctxt); |
688 the (ClassSyntax.get ctxt); |
832 val phi = morphism thy class; |
903 val phi = morphism thy class; |
833 |
904 |
834 val c' = Sign.full_name thy' c; |
905 val c' = Sign.full_name thy' c; |
835 val rews = map (Logic.dest_equals o Thm.prop_of) (these_defs thy' [class]) |
906 val rews = map (Logic.dest_equals o Thm.prop_of) (these_defs thy' [class]) |
836 val rhs' = (Pattern.rewrite_term thy rews [] o Morphism.term phi) rhs; |
907 val rhs' = (Pattern.rewrite_term thy rews [] o Morphism.term phi) rhs; |
837 val rhs'' = map_types Logic.unvarifyT rhs'; |
908 val ty' = (Logic.unvarifyT o Term.fastype_of) rhs'; |
838 val ty' = Term.fastype_of rhs''; |
|
839 |
909 |
840 val c'' = NameSpace.full (Sign.naming_of thy' |> NameSpace.add_path prfx) c; |
910 val c'' = NameSpace.full (Sign.naming_of thy' |> NameSpace.add_path prfx) c; |
841 val ty'' = (Type.strip_sorts o Logic.unvarifyT) (Sign.the_const_constraint thy' c''); |
911 val ty'' = (Type.strip_sorts o Logic.unvarifyT) (Sign.the_const_constraint thy' c''); |
842 in |
912 in |
843 thy' |
913 thy' |
844 |> Sign.add_const_constraint (c'', SOME ty'') (*FIXME*) |
914 |> Sign.add_const_constraint (c'', SOME ty'') (*FIXME*) |
845 |> Sign.hide_consts_i false [c''] (*FIXME*) |
915 |> Sign.hide_consts_i false [c''] (*FIXME*) |
846 |> Sign.add_abbrev (#1 prmode) pos (c, map_types Type.strip_sorts rhs') |> snd |
916 |> Sign.add_abbrev (#1 prmode) pos (c, map_types Type.strip_sorts rhs') |> snd |
847 |> Sign.add_const_constraint (c', SOME ty') |
917 |> Sign.add_const_constraint (c', SOME ty') |
848 |> Sign.notation true prmode [(Const (c', ty'), mx)] |
918 |> Sign.notation true prmode [(Const (c', ty'), mx)] |
849 |> register_operation class ((c', (rhs, rhs'')), NONE) |
919 |> register_operation class (c', ((rhs, NONE), NONE)) |
850 |> Sign.restore_naming thy |
920 |> Sign.restore_naming thy |
851 end; |
921 end; |
852 |
922 |
853 end; |
923 end; |