src/HOL/Library/Cancellation/cancel.ML
author wenzelm
Mon, 13 Apr 2020 22:08:14 +0200
changeset 71751 abf3e80bd815
parent 70326 aa7c49651f4e
child 78800 0b3700d31758
permissions -rw-r--r--
tuned NEWS;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
65367
83c30e290702 tuned headers;
wenzelm
parents: 65029
diff changeset
     1
(*  Title:      HOL/Library/Cancellation/cancel.ML
83c30e290702 tuned headers;
wenzelm
parents: 65029
diff changeset
     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
83c30e290702 tuned headers;
wenzelm
parents: 65029
diff changeset
     5
This simproc allows handling of types with constructors (e.g., add_mset for
83c30e290702 tuned headers;
wenzelm
parents: 65029
diff changeset
     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
wenzelm
parents: 69593
diff changeset
    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
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 65367
diff changeset
    52
      Named_Theorems.get ctxt \<^named_theorems>\<open>cancelation_simproc_pre\<close> addsimprocs
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 65367
diff changeset
    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
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 65367
diff changeset
    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
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 65367
diff changeset
    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
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 65367
diff changeset
    70
              Named_Theorems.get ctxt \<^named_theorems>\<open>cancelation_simproc_post\<close> addsimprocs
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 65367
diff changeset
    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;