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-- |
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 | 2 |
Author: Lawrence C Paulson, Cambridge University Computer Laboratory |
3 |
Copyright 1998 University of Cambridge |
|
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 | 8 |
*) |
9 |
||
10 |
signature ABEL_CANCEL = |
|
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 | 14 |
end; |
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 | 17 |
struct |
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 | 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 | 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 | 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 | 72 |
(case zero1 pt x of NONE => (case zero1 pt y of NONE => NONE |
73 |
| SOME z => SOME(c $ x $ z)) |
|
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 | 76 |
(case zero1 (pos,t) x of |
77 |
NONE => (case zero1 (not pos,t) y of NONE => NONE |
|
78 |
| SOME z => SOME(c $ x $ z)) |
|
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 | 81 |
(case zero1 (not pos,t) x of NONE => NONE |
82 |
| SOME z => SOME(c $ z)) |
|
83 |
| zero1 (pos,t) u = |
|
84 |
if pos andalso (t aconv u) then SOME(zero(fastype_of t)) else NONE |
|
5589 | 85 |
|
20055
24c127b97ab5
simprocs: no theory argument -- use simpset context instead;
wenzelm
parents:
19798
diff
changeset
|
86 |
exception Cancel; |
5589 | 87 |
|
16569 | 88 |
fun find_common _ [] _ = raise Cancel |
89 |
| find_common opp ((p,l)::ls) rs = |
|
90 |
let val pr = if opp then not p else p |
|
91 |
in if exists (fn (q,r) => pr = q andalso l aconv r) rs then (p,l) |
|
92 |
else find_common opp ls rs |
|
93 |
end |
|
5589 | 94 |
|
16569 | 95 |
(* turns t1(t) OP t2(t) into t1(0) OP t2(0) where OP can be +, -, =, etc. |
96 |
If OP = +, it must be t2(-t) rather than t2(t) |
|
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 | 105 |
in t' end; |
106 |
||
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 | 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 | 120 |
|
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 | 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 | 138 |
|
139 |
end; |