| author | paulson <lp15@cam.ac.uk> | 
| Tue, 25 Jan 2022 14:13:33 +0000 | |
| changeset 75008 | 43b3d5318d72 | 
| 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; |