src/Provers/Arith/cancel_numerals.ML
author paulson
Tue, 18 Apr 2000 15:51:59 +0200
changeset 8736 0bfd6678a5fa
child 8760 9139453d7033
permissions -rw-r--r--
new simprocs for numerals of type "nat"
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8736
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
     1
(*  Title:      Provers/Arith/cancel_sums.ML
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
     2
    ID:         $Id$
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
     3
    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
     4
    Copyright   2000  University of Cambridge
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
     5
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
     6
Cancel common literals in balanced expressions:
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
     7
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
     8
     i + #m + j ~~ i' + #m' + j'  ==  #(m-m') + i + j ~~ i' + j'
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
     9
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    10
where ~~ is an appropriate balancing operation (e.g. =, <=, <, -).
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    11
*)
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    12
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    13
signature CANCEL_NUMERALS_DATA =
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    14
sig
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    15
  (*abstract syntax*)
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    16
  val mk_numeral: int -> term
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    17
  val find_first_numeral: term list -> int * term * term list
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    18
  val mk_sum: term list -> term
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    19
  val dest_sum: term -> term list
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    20
  val mk_bal: term * term -> term
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    21
  val dest_bal: term -> term * term
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    22
  (*proof tools*)
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    23
  val prove_conv: tactic list -> Sign.sg -> term * term -> thm option
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    24
  val subst_tac: term -> tactic
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    25
  val all_simp_tac: tactic
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    26
end;
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    27
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    28
signature CANCEL_NUMERALS =
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    29
sig
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    30
  val proc: Sign.sg -> thm list -> term -> thm option
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    31
end;
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    32
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    33
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    34
functor CancelNumeralsFun(Data: CANCEL_NUMERALS_DATA): CANCEL_NUMERALS =
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    35
struct
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    36
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    37
(*predicting the outputs of other simprocs given a term of the form
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    38
   (i + ... #m + ... j) - #n   *)
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    39
fun cancelled m n terms =
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    40
    if m = n then (*cancel_sums: sort the terms*)
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    41
	sort Term.term_ord terms 
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    42
    else          (*inverse_fold: subtract, keeping original term order*)
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    43
	Data.mk_numeral (m - n) :: terms;
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    44
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    45
(*the simplification procedure*)
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    46
fun proc sg _ t =
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    47
  let val (t1,t2) = Data.dest_bal t 
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    48
      val (n1, lit1, terms1) = Data.find_first_numeral (Data.dest_sum t1)
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    49
      and (n2, lit2, terms2) = Data.find_first_numeral (Data.dest_sum t2)
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    50
      val lit_n = if n1<n2 then lit1 else lit2
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    51
      and n     = BasisLibrary.Int.min (n1,n2)
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    52
          (*having both the literals and their integer values makes it
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    53
            more robust against negative natural number literals*)
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    54
  in
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    55
      Data.prove_conv [Data.subst_tac lit_n, Data.all_simp_tac] sg
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    56
	 (t, Data.mk_bal (Data.mk_sum (cancelled n1 n terms1),
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    57
			  Data.mk_sum (cancelled n2 n terms2)))
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    58
  end
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    59
  handle _ => None;
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    60
0bfd6678a5fa new simprocs for numerals of type "nat"
paulson
parents:
diff changeset
    61
end;