2 ID: $Id$ |
2 ID: $Id$ |
3 Author: Tobias Nipkow and Stefan Berghofer |
3 Author: Tobias Nipkow and Stefan Berghofer |
4 |
4 |
5 Meta-level Simplification. |
5 Meta-level Simplification. |
6 *) |
6 *) |
|
7 |
|
8 infix 4 |
|
9 setsubgoaler setloop addloop delloop setSSolver addSSolver setSolver |
|
10 addSolver addsimps delsimps addeqcongs deleqcongs addcongs delcongs |
|
11 setmksimps setmkeqTrue setmkcong setmksym settermless addsimprocs delsimprocs; |
7 |
12 |
8 signature BASIC_META_SIMPLIFIER = |
13 signature BASIC_META_SIMPLIFIER = |
9 sig |
14 sig |
10 val trace_simp: bool ref |
15 val trace_simp: bool ref |
11 val debug_simp: bool ref |
16 val debug_simp: bool ref |
12 val simp_depth_limit: int ref |
17 val simp_depth_limit: int ref |
13 end; |
18 end; |
14 |
19 |
|
20 signature AUX_SIMPLIFIER = |
|
21 sig |
|
22 type meta_simpset |
|
23 type simproc |
|
24 val mk_simproc: string -> cterm list |
|
25 -> (Sign.sg -> thm list -> term -> thm option) -> simproc |
|
26 type solver |
|
27 val mk_solver: string -> (thm list -> int -> tactic) -> solver |
|
28 type simpset |
|
29 val empty_ss: simpset |
|
30 val rep_ss: simpset -> |
|
31 {mss: meta_simpset, |
|
32 mk_cong: thm -> thm, |
|
33 subgoal_tac: simpset -> int -> tactic, |
|
34 loop_tacs: (string * (int -> tactic)) list, |
|
35 unsafe_solvers: solver list, |
|
36 solvers: solver list}; |
|
37 val print_ss: simpset -> unit |
|
38 val setsubgoaler: simpset * (simpset -> int -> tactic) -> simpset |
|
39 val setloop: simpset * (int -> tactic) -> simpset |
|
40 val addloop: simpset * (string * (int -> tactic)) -> simpset |
|
41 val delloop: simpset * string -> simpset |
|
42 val setSSolver: simpset * solver -> simpset |
|
43 val addSSolver: simpset * solver -> simpset |
|
44 val setSolver: simpset * solver -> simpset |
|
45 val addSolver: simpset * solver -> simpset |
|
46 val setmksimps: simpset * (thm -> thm list) -> simpset |
|
47 val setmkeqTrue: simpset * (thm -> thm option) -> simpset |
|
48 val setmkcong: simpset * (thm -> thm) -> simpset |
|
49 val setmksym: simpset * (thm -> thm option) -> simpset |
|
50 val settermless: simpset * (term * term -> bool) -> simpset |
|
51 val addsimps: simpset * thm list -> simpset |
|
52 val delsimps: simpset * thm list -> simpset |
|
53 val addeqcongs: simpset * thm list -> simpset |
|
54 val deleqcongs: simpset * thm list -> simpset |
|
55 val addcongs: simpset * thm list -> simpset |
|
56 val delcongs: simpset * thm list -> simpset |
|
57 val addsimprocs: simpset * simproc list -> simpset |
|
58 val delsimprocs: simpset * simproc list -> simpset |
|
59 val merge_ss: simpset * simpset -> simpset |
|
60 val prems_of_ss: simpset -> thm list |
|
61 val generic_simp_tac: bool -> bool * bool * bool -> simpset -> int -> tactic |
|
62 val simproc: Sign.sg -> string -> string list |
|
63 -> (Sign.sg -> thm list -> term -> thm option) -> simproc |
|
64 val simproc_i: Sign.sg -> string -> term list |
|
65 -> (Sign.sg -> thm list -> term -> thm option) -> simproc |
|
66 val clear_ss : simpset -> simpset |
|
67 val simp_thm : bool * bool * bool -> simpset -> thm -> thm |
|
68 val simp_cterm: bool * bool * bool -> simpset -> cterm -> thm |
|
69 end; |
|
70 |
15 signature META_SIMPLIFIER = |
71 signature META_SIMPLIFIER = |
16 sig |
72 sig |
17 include BASIC_META_SIMPLIFIER |
73 include BASIC_META_SIMPLIFIER |
|
74 include AUX_SIMPLIFIER |
18 exception SIMPLIFIER of string * thm |
75 exception SIMPLIFIER of string * thm |
19 exception SIMPROC_FAIL of string * exn |
76 exception SIMPROC_FAIL of string * exn |
20 type meta_simpset |
|
21 val dest_mss : meta_simpset -> |
77 val dest_mss : meta_simpset -> |
22 {simps: thm list, congs: thm list, procs: (string * cterm list) list} |
78 {simps: thm list, congs: thm list, procs: (string * cterm list) list} |
23 val empty_mss : meta_simpset |
79 val empty_mss : meta_simpset |
24 val clear_mss : meta_simpset -> meta_simpset |
80 val clear_mss : meta_simpset -> meta_simpset |
25 val merge_mss : meta_simpset * meta_simpset -> meta_simpset |
81 val merge_mss : meta_simpset * meta_simpset -> meta_simpset |
525 fun set_termless |
584 fun set_termless |
526 (Mss {rules, congs, procs, bounds, prems, mk_rews, depth, ...}, termless) = |
585 (Mss {rules, congs, procs, bounds, prems, mk_rews, depth, ...}, termless) = |
527 mk_mss (rules, congs, procs, bounds, prems, mk_rews, termless, depth); |
586 mk_mss (rules, congs, procs, bounds, prems, mk_rews, termless, depth); |
528 |
587 |
529 |
588 |
|
589 |
|
590 (** simplification procedures **) |
|
591 |
|
592 (* datatype simproc *) |
|
593 |
|
594 datatype simproc = |
|
595 Simproc of string * cterm list * (Sign.sg -> thm list -> term -> thm option) * stamp; |
|
596 |
|
597 fun mk_simproc name lhss proc = |
|
598 Simproc (name, map (Thm.cterm_fun Logic.varify) lhss, proc, stamp ()); |
|
599 |
|
600 fun simproc sg name ss = |
|
601 mk_simproc name (map (fn s => Thm.read_cterm sg (s, TypeInfer.logicT)) ss); |
|
602 fun simproc_i sg name = mk_simproc name o map (Thm.cterm_of sg); |
|
603 |
|
604 fun rep_simproc (Simproc args) = args; |
|
605 |
|
606 |
|
607 |
|
608 (** solvers **) |
|
609 |
|
610 datatype solver = Solver of string * (thm list -> int -> tactic) * stamp; |
|
611 |
|
612 fun mk_solver name solver = Solver (name, solver, stamp()); |
|
613 fun eq_solver (Solver (_, _, s1), Solver(_, _, s2)) = s1 = s2; |
|
614 |
|
615 val merge_solvers = gen_merge_lists eq_solver; |
|
616 |
|
617 fun app_sols [] _ _ = no_tac |
|
618 | app_sols (Solver(_,solver,_)::sols) thms i = |
|
619 solver thms i ORELSE app_sols sols thms i; |
|
620 |
|
621 |
|
622 |
|
623 (** simplification sets **) |
|
624 |
|
625 (* type simpset *) |
|
626 |
|
627 datatype simpset = |
|
628 Simpset of { |
|
629 mss: meta_simpset, |
|
630 mk_cong: thm -> thm, |
|
631 subgoal_tac: simpset -> int -> tactic, |
|
632 loop_tacs: (string * (int -> tactic)) list, |
|
633 unsafe_solvers: solver list, |
|
634 solvers: solver list}; |
|
635 |
|
636 fun make_ss mss mk_cong subgoal_tac loop_tacs unsafe_solvers solvers = |
|
637 Simpset {mss = mss, mk_cong = mk_cong, subgoal_tac = subgoal_tac, |
|
638 loop_tacs = loop_tacs, unsafe_solvers = unsafe_solvers, solvers = solvers}; |
|
639 |
|
640 val empty_ss = |
|
641 let val mss = set_mk_sym (empty_mss, Some o symmetric_fun) |
|
642 in make_ss mss I (K (K no_tac)) [] [] [] end; |
|
643 |
|
644 fun rep_ss (Simpset args) = args; |
|
645 fun prems_of_ss (Simpset {mss, ...}) = prems_of_mss mss; |
|
646 |
|
647 |
|
648 (* print simpsets *) |
|
649 |
|
650 fun print_ss ss = |
|
651 let |
|
652 val Simpset {mss, ...} = ss; |
|
653 val {simps, procs, congs} = dest_mss mss; |
|
654 |
|
655 val pretty_thms = map Display.pretty_thm; |
|
656 fun pretty_proc (name, lhss) = |
|
657 Pretty.big_list (name ^ ":") (map Display.pretty_cterm lhss); |
|
658 in |
|
659 [Pretty.big_list "simplification rules:" (pretty_thms simps), |
|
660 Pretty.big_list "simplification procedures:" (map pretty_proc procs), |
|
661 Pretty.big_list "congruences:" (pretty_thms congs)] |
|
662 |> Pretty.chunks |> Pretty.writeln |
|
663 end; |
|
664 |
|
665 |
|
666 (* extend simpsets *) |
|
667 |
|
668 fun (Simpset {mss, mk_cong, subgoal_tac = _, loop_tacs, unsafe_solvers, solvers}) |
|
669 setsubgoaler subgoal_tac = |
|
670 make_ss mss mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; |
|
671 |
|
672 fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs = _, unsafe_solvers, solvers}) |
|
673 setloop tac = |
|
674 make_ss mss mk_cong subgoal_tac [("", tac)] unsafe_solvers solvers; |
|
675 |
|
676 fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers}) |
|
677 addloop tac = make_ss mss mk_cong subgoal_tac |
|
678 (case assoc_string (loop_tacs, (#1 tac)) of None => () | Some x => |
|
679 warning ("overwriting looper " ^ quote (#1 tac)); overwrite (loop_tacs, tac)) |
|
680 unsafe_solvers solvers; |
|
681 |
|
682 fun (ss as Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers}) |
|
683 delloop name = |
|
684 let val (del, rest) = partition (fn (n, _) => n = name) loop_tacs in |
|
685 if null del then (warning ("No such looper in simpset: " ^ name); ss) |
|
686 else make_ss mss mk_cong subgoal_tac rest unsafe_solvers solvers |
|
687 end; |
|
688 |
|
689 fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, ...}) |
|
690 setSSolver solver = |
|
691 make_ss mss mk_cong subgoal_tac loop_tacs unsafe_solvers [solver]; |
|
692 |
|
693 fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers}) |
|
694 addSSolver sol = |
|
695 make_ss mss mk_cong subgoal_tac loop_tacs unsafe_solvers (merge_solvers solvers [sol]); |
|
696 |
|
697 fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers = _, solvers}) |
|
698 setSolver unsafe_solver = |
|
699 make_ss mss mk_cong subgoal_tac loop_tacs [unsafe_solver] solvers; |
|
700 |
|
701 fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers}) |
|
702 addSolver sol = |
|
703 make_ss mss mk_cong subgoal_tac loop_tacs (merge_solvers unsafe_solvers [sol]) solvers; |
|
704 |
|
705 fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers}) |
|
706 setmksimps mk_simps = |
|
707 make_ss (set_mk_rews (mss, mk_simps)) mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; |
|
708 |
|
709 fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers}) |
|
710 setmkeqTrue mk_eq_True = |
|
711 make_ss (set_mk_eq_True (mss, mk_eq_True)) mk_cong subgoal_tac loop_tacs |
|
712 unsafe_solvers solvers; |
|
713 |
|
714 fun (Simpset {mss, mk_cong = _, subgoal_tac, loop_tacs, unsafe_solvers, solvers}) |
|
715 setmkcong mk_cong = |
|
716 make_ss mss mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; |
|
717 |
|
718 fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers}) |
|
719 setmksym mksym = |
|
720 make_ss (set_mk_sym (mss, mksym)) mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; |
|
721 |
|
722 fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers}) |
|
723 settermless termless = |
|
724 make_ss (set_termless (mss, termless)) mk_cong subgoal_tac loop_tacs |
|
725 unsafe_solvers solvers; |
|
726 |
|
727 fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers}) |
|
728 addsimps rews = |
|
729 make_ss (add_simps (mss, rews)) mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; |
|
730 |
|
731 fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers}) |
|
732 delsimps rews = |
|
733 make_ss (del_simps (mss, rews)) mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; |
|
734 |
|
735 fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers}) |
|
736 addeqcongs newcongs = |
|
737 make_ss (add_congs (mss, newcongs)) mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; |
|
738 |
|
739 fun (Simpset {mss, subgoal_tac, mk_cong, loop_tacs, unsafe_solvers, solvers}) |
|
740 deleqcongs oldcongs = |
|
741 make_ss (del_congs (mss, oldcongs)) mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; |
|
742 |
|
743 fun (ss as Simpset {mk_cong, ...}) addcongs newcongs = |
|
744 ss addeqcongs map mk_cong newcongs; |
|
745 |
|
746 fun (ss as Simpset {mk_cong, ...}) delcongs oldcongs = |
|
747 ss deleqcongs map mk_cong oldcongs; |
|
748 |
|
749 fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers}) |
|
750 addsimprocs simprocs = |
|
751 make_ss (add_simprocs (mss, map rep_simproc simprocs)) mk_cong subgoal_tac loop_tacs |
|
752 unsafe_solvers solvers; |
|
753 |
|
754 fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers}) |
|
755 delsimprocs simprocs = |
|
756 make_ss (del_simprocs (mss, map rep_simproc simprocs)) mk_cong subgoal_tac |
|
757 loop_tacs unsafe_solvers solvers; |
|
758 |
|
759 fun clear_ss (Simpset {mss, mk_cong, subgoal_tac, loop_tacs = _, unsafe_solvers, solvers}) = |
|
760 make_ss (clear_mss mss) mk_cong subgoal_tac [] unsafe_solvers solvers; |
|
761 |
|
762 |
|
763 (* merge simpsets *) |
|
764 |
|
765 (*ignores subgoal_tac of 2nd simpset!*) |
|
766 |
|
767 fun merge_ss |
|
768 (Simpset {mss = mss1, mk_cong, loop_tacs = loop_tacs1, subgoal_tac, |
|
769 unsafe_solvers = unsafe_solvers1, solvers = solvers1}, |
|
770 Simpset {mss = mss2, mk_cong = _, loop_tacs = loop_tacs2, subgoal_tac = _, |
|
771 unsafe_solvers = unsafe_solvers2, solvers = solvers2}) = |
|
772 make_ss (merge_mss (mss1, mss2)) mk_cong subgoal_tac |
|
773 (merge_alists loop_tacs1 loop_tacs2) |
|
774 (merge_solvers unsafe_solvers1 unsafe_solvers2) |
|
775 (merge_solvers solvers1 solvers2); |
530 |
776 |
531 (** rewriting **) |
777 (** rewriting **) |
532 |
778 |
533 (* |
779 (* |
534 Uses conversions, see: |
780 Uses conversions, see: |
963 |
1209 |
964 (*simple term rewriting -- without proofs*) |
1210 (*simple term rewriting -- without proofs*) |
965 fun rewrite_term sg rules procs = |
1211 fun rewrite_term sg rules procs = |
966 Pattern.rewrite_term (Sign.tsig_of sg) (map decomp_simp' rules) procs; |
1212 Pattern.rewrite_term (Sign.tsig_of sg) (map decomp_simp' rules) procs; |
967 |
1213 |
|
1214 (*Rewrite subgoal i only. SELECT_GOAL avoids inefficiencies in goals_conv.*) |
|
1215 fun asm_rewrite_goal_tac mode prover_tac mss = |
|
1216 SELECT_GOAL |
|
1217 (PRIMITIVE (rewrite_goal_rule mode (SINGLE o prover_tac) mss 1)); |
|
1218 |
|
1219 (** simplification tactics **) |
|
1220 |
|
1221 fun solve_all_tac (mk_cong, subgoal_tac, loop_tacs, unsafe_solvers) mss = |
|
1222 let |
|
1223 val ss = |
|
1224 make_ss mss mk_cong subgoal_tac loop_tacs unsafe_solvers unsafe_solvers; |
|
1225 val solve1_tac = (subgoal_tac ss THEN_ALL_NEW (K no_tac)) 1 |
|
1226 in DEPTH_SOLVE solve1_tac end; |
|
1227 |
|
1228 fun loop_tac loop_tacs = FIRST'(map snd loop_tacs); |
|
1229 |
|
1230 (*note: may instantiate unknowns that appear also in other subgoals*) |
|
1231 fun generic_simp_tac safe mode = |
|
1232 fn (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers, ...}) => |
|
1233 let |
|
1234 val solvs = app_sols (if safe then solvers else unsafe_solvers); |
|
1235 fun simp_loop_tac i = |
|
1236 asm_rewrite_goal_tac mode |
|
1237 (solve_all_tac (mk_cong, subgoal_tac, loop_tacs, unsafe_solvers)) |
|
1238 mss i |
|
1239 THEN (solvs (prems_of_mss mss) i ORELSE |
|
1240 TRY ((loop_tac loop_tacs THEN_ALL_NEW simp_loop_tac) i)) |
|
1241 in simp_loop_tac end; |
|
1242 |
|
1243 (** simplification rules and conversions **) |
|
1244 |
|
1245 fun simp rew mode |
|
1246 (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, ...}) thm = |
|
1247 let |
|
1248 val tacf = solve_all_tac (mk_cong, subgoal_tac, loop_tacs, unsafe_solvers); |
|
1249 fun prover m th = apsome fst (Seq.pull (tacf m th)); |
|
1250 in rew mode prover mss thm end; |
|
1251 |
|
1252 val simp_thm = simp rewrite_thm; |
|
1253 val simp_cterm = simp rewrite_cterm; |
|
1254 |
968 end; |
1255 end; |
969 |
1256 |
970 structure BasicMetaSimplifier: BASIC_META_SIMPLIFIER = MetaSimplifier; |
1257 structure BasicMetaSimplifier: BASIC_META_SIMPLIFIER = MetaSimplifier; |
971 open BasicMetaSimplifier; |
1258 open BasicMetaSimplifier; |