author | wenzelm |
Mon, 13 Apr 2020 22:08:14 +0200 | |
changeset 71751 | abf3e80bd815 |
parent 70326 | aa7c49651f4e |
child 78800 | 0b3700d31758 |
permissions | -rw-r--r-- |
65367 | 1 |
(* Title: HOL/Library/Cancellation/cancel.ML |
2 |
Author: Lawrence C Paulson, Cambridge University Computer Laboratory |
|
65029
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
3 |
Author: Mathias Fleury, MPII |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
4 |
|
65367 | 5 |
This simproc allows handling of types with constructors (e.g., add_mset for |
6 |
multisets) and iteration of the addition (e.g., repeat_mset for multisets). |
|
65029
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
7 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
8 |
Beware that this simproc should not compete with any more specialised especially: |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
9 |
- nat: the handling for Suc is more complicated than what can be done here |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
10 |
- int: some normalisation is done (after the cancelation) and linarith relies on these. |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
11 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
12 |
Instead of "*", we have "iterate_add". |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
13 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
14 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
15 |
To quote Provers/Arith/cancel_numerals.ML: |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
16 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
17 |
Cancel common coefficients in balanced expressions: |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
18 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
19 |
i + #m*u + j ~~ i' + #m'*u + j' == #(m-m')*u + i + j ~~ i' + j' |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
20 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
21 |
where ~~ is an appropriate balancing operation (e.g. =, <=, <, -). |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
22 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
23 |
It works by (a) massaging both sides to bring the selected term to the front: |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
24 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
25 |
#m*u + (i + j) ~~ #m'*u + (i' + j') |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
26 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
27 |
(b) then using bal_add1 or bal_add2 to reach |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
28 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
29 |
#(m-m')*u + i + j ~~ i' + j' (if m'<=m) |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
30 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
31 |
or |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
32 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
33 |
i + j ~~ #(m'-m)*u + i' + j' (otherwise) |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
34 |
*) |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
35 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
36 |
signature CANCEL = |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
37 |
sig |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
38 |
val proc: Proof.context -> cterm -> thm option |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
39 |
end; |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
40 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
41 |
functor Cancel_Fun(Data: CANCEL_NUMERALS_DATA): CANCEL = |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
42 |
struct |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
43 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
44 |
structure Cancel_Numerals_Fun = CancelNumeralsFun(open Data) |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
45 |
exception SORT_NOT_GENERAL_ENOUGH of string * typ * term |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
46 |
(*the simplification procedure*) |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
47 |
fun proc ctxt ct = |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
48 |
let |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
49 |
val t = Thm.term_of ct |
70326 | 50 |
val (t', ctxt') = yield_singleton (Variable.import_terms true) t ctxt |
65029
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
51 |
val pre_simplified_ct = Simplifier.full_rewrite (clear_simpset ctxt addsimps |
69593 | 52 |
Named_Theorems.get ctxt \<^named_theorems>\<open>cancelation_simproc_pre\<close> addsimprocs |
53 |
[\<^simproc>\<open>NO_MATCH\<close>]) (Thm.cterm_of ctxt t'); |
|
65029
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
54 |
val t' = Thm.term_of (Thm.rhs_of pre_simplified_ct) |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
55 |
val export = singleton (Variable.export ctxt' ctxt) |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
56 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
57 |
val (t1,_) = Data.dest_bal t' |
69593 | 58 |
val sort_not_general_enough = ((fastype_of t1) = \<^typ>\<open>nat\<close>) orelse |
65029
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
59 |
Sorts.of_sort (Sign.classes_of (Proof_Context.theory_of ctxt)) |
69593 | 60 |
(fastype_of t1, \<^sort>\<open>comm_ring_1\<close>) |
65029
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
61 |
val _ = |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
62 |
if sort_not_general_enough |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
63 |
then raise SORT_NOT_GENERAL_ENOUGH("type too precise, another simproc should do the job", |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
64 |
fastype_of t1, t1) |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
65 |
else () |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
66 |
val canceled_thm = Cancel_Numerals_Fun.proc ctxt (Thm.rhs_of pre_simplified_ct) |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
67 |
fun add_pre_simplification thm = @{thm Pure.transitive} OF [pre_simplified_ct, thm] |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
68 |
fun add_post_simplification thm = |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
69 |
(let val post_simplified_ct = Simplifier.full_rewrite (clear_simpset ctxt addsimps |
69593 | 70 |
Named_Theorems.get ctxt \<^named_theorems>\<open>cancelation_simproc_post\<close> addsimprocs |
71 |
[\<^simproc>\<open>NO_MATCH\<close>]) |
|
65029
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
72 |
(Thm.rhs_of thm) |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
73 |
in @{thm Pure.transitive} OF [thm, post_simplified_ct] end) |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
74 |
in |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
75 |
Option.map (export o add_post_simplification o add_pre_simplification) canceled_thm |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
76 |
end |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
77 |
(* FIXME avoid handling of generic exceptions *) |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
78 |
handle TERM _ => NONE |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
79 |
| TYPE _ => NONE |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
80 |
| SORT_NOT_GENERAL_ENOUGH _ => NONE |
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
81 |
|
00731700e54f
cancellation simprocs generalising the multiset simprocs
fleury <Mathias.Fleury@mpi-inf.mpg.de>
parents:
diff
changeset
|
82 |
end; |