src/HOL/Tools/abel_cancel.ML
author haftmann
Mon, 19 Jul 2010 16:09:43 +0200
changeset 37884 314a88278715
parent 35845 src/Provers/Arith/abel_cancel.ML@e5980f0ad025
child 37890 aae46a9ef66c
permissions -rw-r--r--
discontinued pretending that abel_cancel is logic-independent; cleaned up junk
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37884
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
     1
(*  Title:      HOL/Tools/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
37884
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
     5
Simplification procedures for abelian groups:
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
     6
- Cancel complementary terms in sums.
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
     7
- Cancel like terms on opposite sides of relations.
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
     8
*)
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
     9
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    10
signature ABEL_CANCEL =
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    11
sig
37884
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    12
  val sum_conv: simproc
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    13
  val rel_conv: simproc
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    14
end;
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    15
37884
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    16
structure Abel_Cancel: ABEL_CANCEL =
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    17
struct
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    18
37884
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    19
(* term order for abelian groups *)
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    20
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    21
fun agrp_ord (Const (a, _)) = find_index (fn a' => a = a')
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    22
      [@{const_name Groups.zero}, @{const_name Groups.plus},
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    23
        @{const_name Groups.uminus}, @{const_name Groups.minus}]
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    24
  | agrp_ord _ = ~1;
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    25
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    26
fun termless_agrp (a, b) = (Term_Ord.term_lpo agrp_ord (a, b) = LESS);
5728
1d1175ef2d56 eliminated 'let ... in structure ...' to make SML/NJ 0.93 happy;
wenzelm
parents: 5610
diff changeset
    27
37884
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    28
local
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    29
  val ac1 = mk_meta_eq @{thm add_assoc};
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    30
  val ac2 = mk_meta_eq @{thm add_commute};
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    31
  val ac3 = mk_meta_eq @{thm add_left_commute};
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    32
  fun solve_add_ac thy _ (_ $ (Const (@{const_name Groups.plus},_) $ _ $ _) $ _) =
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    33
        SOME ac1
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    34
    | solve_add_ac thy _ (_ $ x $ (Const (@{const_name Groups.plus},_) $ y $ z)) =
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    35
        if termless_agrp (y, x) then SOME ac3 else NONE
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    36
    | solve_add_ac thy _ (_ $ x $ y) =
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    37
        if termless_agrp (y, x) then SOME ac2 else NONE
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    38
    | solve_add_ac thy _ _ = NONE
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    39
in
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    40
  val add_ac_proc = Simplifier.simproc @{theory}
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    41
    "add_ac_proc" ["x + y::'a::ab_semigroup_add"] solve_add_ac;
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    42
end;
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    43
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    44
val cancel_ss = HOL_basic_ss settermless termless_agrp
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    45
  addsimprocs [add_ac_proc] addsimps
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    46
  [@{thm add_0_left}, @{thm add_0_right}, @{thm diff_minus},
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    47
   @{thm minus_add_distrib}, @{thm minus_minus}, @{thm minus_zero},
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    48
   @{thm right_minus}, @{thm left_minus}, @{thm add_minus_cancel},
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    49
   @{thm minus_add_cancel}];
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    50
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    51
val sum_pats = [@{cterm "x + y::'a::ab_group_add"}, @{cterm "x - y::'a::ab_group_add"}];
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    52
  
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    53
val eqI_rules = [@{thm diff_eq_diff_less}, @{thm diff_eq_diff_less_eq'}, @{thm diff_eq_diff_eq}];
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    54
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    55
val dest_eqI = 
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
    56
  fst o HOLogic.dest_bin @{const_name "op ="} HOLogic.boolT o HOLogic.dest_Trueprop o concl_of;
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    57
35267
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 34974
diff changeset
    58
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
    59
fun minus t = Const (@{const_name Groups.uminus}, t --> t);
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    60
35267
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 34974
diff changeset
    61
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
    62
      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
    63
  | 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
    64
      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
    65
  | 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
    66
      add_terms (not pos) (x, ts)
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    67
  | add_terms pos (x, ts) = (pos,x) :: ts;
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    68
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    69
fun terms fml = add_terms true (fml, []);
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    70
35267
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 34974
diff changeset
    71
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
    72
      (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
    73
                                   | SOME z => SOME(c $ x $ z))
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    74
       | SOME z => SOME(c $ z $ y))
35267
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 34974
diff changeset
    75
  | 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
    76
      (case zero1 (pos,t) x of
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    77
         NONE => (case zero1 (not pos,t) y of NONE => NONE
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    78
                  | SOME z => SOME(c $ x $ z))
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    79
       | SOME z => SOME(c $ z $ y))
35267
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 34974
diff changeset
    80
  | 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
    81
      (case zero1 (not pos,t) x of NONE => NONE
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    82
       | SOME z => SOME(c $ z))
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    83
  | zero1 (pos,t) u =
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    84
      if pos andalso (t aconv u) then SOME(zero(fastype_of t)) else NONE
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    85
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    86
exception Cancel;
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    87
16569
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    88
fun find_common _ [] _ = raise Cancel
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    89
  | find_common opp ((p,l)::ls) rs =
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    90
      let val pr = if opp then not p else p
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    91
      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
    92
         else find_common opp ls rs
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    93
      end
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
    94
16569
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    95
(* 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
    96
   If OP = +, it must be t2(-t) rather than t2(t)
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
    97
*)
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
    98
fun cancel 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 c $ lhs $ rhs = t
35267
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 34974
diff changeset
   101
    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
   102
    val (pos,l) = find_common opp (terms lhs) (terms rhs)
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   103
    val posr = if opp then not pos else pos
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   104
    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
   105
  in t' end;
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
   106
a12992c34c12 cancels completely within terms as well now.
nipkow
parents: 16423
diff changeset
   107
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   108
(*A simproc to cancel complementary terms in arbitrary sums.*)
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   109
fun sum_proc ss t =
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   110
   let
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   111
     val t' = cancel t
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   112
     val thm =
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   113
       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
   114
         (fn _ => simp_tac (Simplifier.inherit_context ss cancel_ss) 1)
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   115
   in SOME thm end handle Cancel => NONE;
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
   116
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   117
val sum_conv =
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   118
  Simplifier.mk_simproc "cancel_sums"
37884
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
   119
    (map (Drule.cterm_fun Logic.varify_global) sum_pats) (K sum_proc);
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
   120
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
   121
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   122
(*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
   123
   (x + y - z < -z + x) = (y < 0)
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   124
  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
   125
  Reduces the problem to subtraction.*)
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   126
fun rel_proc ss t =
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   127
  let
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   128
    val t' = cancel t
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   129
    val thm = Goal.prove (Simplifier.the_context ss) [] [] (Logic.mk_equals (t, t'))
37884
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
   130
      (fn _ => rtac @{thm eq_reflection} 1 THEN
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   131
                    resolve_tac eqI_rules 1 THEN
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   132
                    simp_tac (Simplifier.inherit_context ss cancel_ss) 1)
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   133
   in SOME thm end handle Cancel => NONE;
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
   134
20055
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   135
val rel_conv =
24c127b97ab5 simprocs: no theory argument -- use simpset context instead;
wenzelm
parents: 19798
diff changeset
   136
  Simplifier.mk_simproc "cancel_relations"
37884
314a88278715 discontinued pretending that abel_cancel is logic-independent; cleaned up junk
haftmann
parents: 35845
diff changeset
   137
    (map (fn th => Thm.cterm_of (Thm.theory_of_thm th) (dest_eqI th)) eqI_rules) (K rel_proc);
5589
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
   138
94c05305fb29 new simproc functor
paulson
parents:
diff changeset
   139
end;