src/Provers/Arith/abel_cancel.ML
author wenzelm
Sat, 13 Mar 2010 16:44:12 +0100
changeset 35762 af3ff2ba4c54
parent 35267 8dfd816713c6
child 35845 e5980f0ad025
permissions -rw-r--r--
removed old CVS Ids; tuned headers;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
24584
01e83ffa6c54 fixed title
haftmann
parents: 22997
diff changeset
     1
(*  Title:      Provers/Arith/abel_cancel.ML
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
     2
    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
     3
    Copyright   1998  University of Cambridge
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
     4
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
     5
Simplification procedures for abelian groups (e.g. integers, reals,
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
     6
polymorphic types).
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
     7
13462
56610e2ba220 sane interface for simprocs;
wenzelm
parents: 12262
diff changeset
     8
- Cancel complementary terms in sums
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
     9
- Cancel like terms on opposite sides of relations
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    10
*)
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    11
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    12
signature ABEL_CANCEL =
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    13
sig
27250
7eef2b183032 simplified Abel_Cancel setup;
wenzelm
parents: 24584
diff changeset
    14
  val eq_reflection   : thm           (*object-equality to meta-equality*)
7eef2b183032 simplified Abel_Cancel setup;
wenzelm
parents: 24584
diff changeset
    15
  val T               : typ           (*the type of group elements*)
16569
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    16
  val cancel_ss       : simpset       (*abelian group cancel simpset*)
27250
7eef2b183032 simplified Abel_Cancel setup;
wenzelm
parents: 24584
diff changeset
    17
  val sum_pats        : cterm list
16569
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    18
  val eqI_rules       : thm list
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    19
  val dest_eqI        : thm -> term
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    20
end;
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    21
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    22
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    23
functor Abel_Cancel (Data: ABEL_CANCEL) =
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    24
struct
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    25
5728
1d1175ef2d56 eliminated 'let ... in structure ...' to make SML/NJ 0.93 happy;
wenzelm
parents: 5610
diff changeset
    26
open Data;
1d1175ef2d56 eliminated 'let ... in structure ...' to make SML/NJ 0.93 happy;
wenzelm
parents: 5610
diff changeset
    27
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    28
(* FIXME dependent on abstract syntax *)
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    29
35267
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 34974
diff changeset
    30
fun zero t = Const (@{const_name Groups.zero}, t);
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 34974
diff changeset
    31
fun minus t = Const (@{const_name Groups.uminus}, t --> t);
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    32
35267
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 34974
diff changeset
    33
fun add_terms pos (Const (@{const_name Groups.plus}, _) $ x $ y, ts) =
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    34
      add_terms pos (x, add_terms pos (y, ts))
35267
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 34974
diff changeset
    35
  | add_terms pos (Const (@{const_name Groups.minus}, _) $ x $ y, ts) =
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    36
      add_terms pos (x, add_terms (not pos) (y, ts))
35267
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 34974
diff changeset
    37
  | add_terms pos (Const (@{const_name Groups.uminus}, _) $ x, ts) =
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    38
      add_terms (not pos) (x, ts)
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    39
  | add_terms pos (x, ts) = (pos,x) :: ts;
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    40
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    41
fun terms fml = add_terms true (fml, []);
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    42
35267
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 34974
diff changeset
    43
fun zero1 pt (u as (c as Const(@{const_name Groups.plus},_)) $ x $ y) =
16569
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    44
      (case zero1 pt x of NONE => (case zero1 pt y of NONE => NONE
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    45
                                   | SOME z => SOME(c $ x $ z))
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    46
       | SOME z => SOME(c $ z $ y))
35267
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 34974
diff changeset
    47
  | zero1 (pos,t) (u as (c as Const(@{const_name Groups.minus},_)) $ x $ y) =
16569
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    48
      (case zero1 (pos,t) x of
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    49
         NONE => (case zero1 (not pos,t) y of NONE => NONE
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    50
                  | SOME z => SOME(c $ x $ z))
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    51
       | SOME z => SOME(c $ z $ y))
35267
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 34974
diff changeset
    52
  | zero1 (pos,t) (u as (c as Const(@{const_name Groups.uminus},_)) $ x) =
16569
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    53
      (case zero1 (not pos,t) x of NONE => NONE
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    54
       | SOME z => SOME(c $ z))
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    55
  | zero1 (pos,t) u =
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    56
      if pos andalso (t aconv u) then SOME(zero(fastype_of t)) else NONE
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    57
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    58
exception Cancel;
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    59
16569
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    60
fun find_common _ [] _ = raise Cancel
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    61
  | find_common opp ((p,l)::ls) rs =
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    62
      let val pr = if opp then not p else p
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    63
      in if exists (fn (q,r) => pr = q andalso l aconv r) rs then (p,l)
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    64
         else find_common opp ls rs
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    65
      end
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    66
16569
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    67
(* turns t1(t) OP t2(t) into t1(0) OP t2(0) where OP can be +, -, =, etc.
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    68
   If OP = +, it must be t2(-t) rather than t2(t)
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    69
*)
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    70
fun cancel t =
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    71
  let
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    72
    val c $ lhs $ rhs = t
35267
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 34974
diff changeset
    73
    val opp = case c of Const(@{const_name Groups.plus},_) => true | _ => false;
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    74
    val (pos,l) = find_common opp (terms lhs) (terms rhs)
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    75
    val posr = if opp then not pos else pos
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    76
    val t' = c $ (the(zero1 (pos,l) lhs)) $ (the(zero1 (posr,l) rhs))
16569
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    77
  in t' end;
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    78
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    79
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    80
(*A simproc to cancel complementary terms in arbitrary sums.*)
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    81
fun sum_proc ss t =
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    82
   let
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    83
     val t' = cancel t
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    84
     val thm =
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    85
       Goal.prove (Simplifier.the_context ss) [] [] (Logic.mk_equals (t, t'))
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    86
         (fn _ => simp_tac (Simplifier.inherit_context ss cancel_ss) 1)
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    87
   in SOME thm end handle Cancel => NONE;
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    88
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    89
val sum_conv =
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    90
  Simplifier.mk_simproc "cancel_sums"
27250
7eef2b183032 simplified Abel_Cancel setup;
wenzelm
parents: 24584
diff changeset
    91
    (map (Drule.cterm_fun Logic.varify) Data.sum_pats) (K sum_proc);
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    92
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    93
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    94
(*A simproc to cancel like terms on the opposite sides of relations:
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    95
   (x + y - z < -z + x) = (y < 0)
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    96
  Works for (=) and (<=) as well as (<), if the necessary rules are supplied.
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    97
  Reduces the problem to subtraction.*)
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    98
fun rel_proc ss t =
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    99
  let
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   100
    val t' = cancel t
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   101
    val thm = Goal.prove (Simplifier.the_context ss) [] [] (Logic.mk_equals (t, t'))
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   102
      (fn _ => rtac eq_reflection 1 THEN
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   103
                    resolve_tac eqI_rules 1 THEN
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   104
                    simp_tac (Simplifier.inherit_context ss cancel_ss) 1)
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   105
   in SOME thm end handle Cancel => NONE;
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
   106
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   107
val rel_conv =
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   108
  Simplifier.mk_simproc "cancel_relations"
27250
7eef2b183032 simplified Abel_Cancel setup;
wenzelm
parents: 24584
diff changeset
   109
    (map (fn th => Thm.cterm_of (Thm.theory_of_thm th) (Data.dest_eqI th)) eqI_rules) (K rel_proc);
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
   110
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
   111
end;