author | kleing |
Tue, 13 May 2003 08:59:21 +0200 | |
changeset 14024 | 213dcc39358f |
parent 13480 | bb72bd43c6c3 |
child 14387 | e96d5c42c4b0 |
permissions | -rw-r--r-- |
7072 | 1 |
(* Title: Provers/Arith/assoc_fold.ML |
2 |
ID: $Id$ |
|
3 |
Author: Lawrence C Paulson, Cambridge University Computer Laboratory |
|
4 |
Copyright 1999 University of Cambridge |
|
5 |
||
6 |
Simplification procedure for associative operators + and * on numeric types |
|
7 |
||
8 |
Performs constant folding when the literals are separated, as in 3+n+4. |
|
9 |
*) |
|
10 |
||
11 |
||
12 |
signature ASSOC_FOLD_DATA = |
|
13 |
sig |
|
13462 | 14 |
val ss : simpset (*basic simpset of object-logtic*) |
15 |
val eq_reflection : thm (*object-equality to meta-equality*) |
|
16 |
val sg_ref : Sign.sg_ref (*the operator's signature*) |
|
17 |
val T : typ (*the operator's numeric type*) |
|
18 |
val plus : term (*the operator being folded*) |
|
19 |
val add_ac : thm list (*AC-rewrites for plus*) |
|
7072 | 20 |
end; |
21 |
||
22 |
||
23 |
functor Assoc_Fold (Data: ASSOC_FOLD_DATA) = |
|
24 |
struct |
|
25 |
||
26 |
val assoc_ss = Data.ss addsimps Data.add_ac; |
|
27 |
||
28 |
exception Assoc_fail; |
|
29 |
||
30 |
fun mk_sum [] = raise Assoc_fail |
|
31 |
| mk_sum tms = foldr1 (fn (x,y) => Data.plus $ x $ y) tms; |
|
32 |
||
33 |
(*Separate the literals from the other terms being combined*) |
|
34 |
fun sift_terms (t, (lits,others)) = |
|
35 |
case t of |
|
13462 | 36 |
Const("Numeral.number_of", _) $ _ => |
37 |
(t::lits, others) (*new literal*) |
|
38 |
| (f as Const _) $ x $ y => |
|
39 |
if f = Data.plus |
|
7072 | 40 |
then sift_terms (x, sift_terms (y, (lits,others))) |
13462 | 41 |
else (lits, t::others) (*arbitrary summand*) |
42 |
| _ => (lits, t::others); |
|
7072 | 43 |
|
44 |
val trace = ref false; |
|
45 |
||
46 |
(*Make a simproc to combine all literals in a associative nest*) |
|
47 |
fun proc sg _ lhs = |
|
48 |
let fun show t = string_of_cterm (Thm.cterm_of sg t) |
|
12262 | 49 |
val _ = if !trace then tracing ("assoc_fold simproc: LHS = " ^ show lhs) |
13462 | 50 |
else () |
7072 | 51 |
val (lits,others) = sift_terms (lhs, ([],[])) |
52 |
val _ = if length lits < 2 |
|
53 |
then raise Assoc_fail (*we can't reduce the number of terms*) |
|
13462 | 54 |
else () |
7072 | 55 |
val rhs = Data.plus $ mk_sum lits $ mk_sum others |
12262 | 56 |
val _ = if !trace then tracing ("RHS = " ^ show rhs) else () |
13480
bb72bd43c6c3
use Tactic.prove instead of prove_goalw_cterm in internal proofs!
wenzelm
parents:
13462
diff
changeset
|
57 |
val th = Tactic.prove sg [] [] (Logic.mk_equals (lhs, rhs)) |
bb72bd43c6c3
use Tactic.prove instead of prove_goalw_cterm in internal proofs!
wenzelm
parents:
13462
diff
changeset
|
58 |
(fn _ => rtac Data.eq_reflection 1 THEN |
bb72bd43c6c3
use Tactic.prove instead of prove_goalw_cterm in internal proofs!
wenzelm
parents:
13462
diff
changeset
|
59 |
simp_tac assoc_ss 1) |
7072 | 60 |
in Some th end |
61 |
handle Assoc_fail => None; |
|
13462 | 62 |
|
63 |
val conv = |
|
64 |
Simplifier.simproc_i (Sign.deref Data.sg_ref) "assoc_fold" |
|
65 |
[Data.plus $ Free ("x", Data.T) $ Free ("y",Data.T)] proc; |
|
7072 | 66 |
|
67 |
end; |
|
68 |
||
69 |
||
70 |
(*test data: |
|
8999 | 71 |
set timing; |
7072 | 72 |
|
73 |
Goal "(#3 * (a * #34)) * (#2 * b * #9) = (x::int)"; |
|
74 |
||
75 |
Goal "a + b + c + d + e + f + g + h + i + j + k + l + m + n + oo + p + q + r + s + t + u + v + (w + x + y + z + a + #2 + b + #2 + c + #2 + d + #2 + e) + #2 + f + (#2 + g + #2 + h + #2 + i) + #2 + (j + #2 + k + #2 + l + #2 + m + #2) + n + #2 + (oo + #2 + p + #2 + q + #2 + r) + #2 + s + #2 + t + #2 + u + #2 + v + #2 + w + #2 + x + #2 + y + #2 + z + #2 = (uu::nat)"; |
|
76 |
*) |