src/HOL/Tools/numeral_simprocs.ML
changeset 36751 7f1da69cacb3
parent 36409 d323e7773aa8
child 36945 9bec62c10714
equal deleted inserted replaced
36750:912080b2c449 36751:7f1da69cacb3
     1 (* Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     1 (* Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     2    Copyright   2000  University of Cambridge
     2    Copyright   2000  University of Cambridge
     3 
     3 
     4 Simprocs for the integer numerals.
     4 Simprocs for the (integer) numerals.
     5 *)
     5 *)
     6 
     6 
     7 (*To quote from Provers/Arith/cancel_numeral_factor.ML:
     7 (*To quote from Provers/Arith/cancel_numeral_factor.ML:
     8 
     8 
     9 Cancels common coefficients in balanced expressions:
     9 Cancels common coefficients in balanced expressions:
    22   val cancel_factors: simproc list
    22   val cancel_factors: simproc list
    23   val cancel_numeral_factors: simproc list
    23   val cancel_numeral_factors: simproc list
    24   val field_combine_numerals: simproc
    24   val field_combine_numerals: simproc
    25   val field_cancel_numeral_factors: simproc list
    25   val field_cancel_numeral_factors: simproc list
    26   val num_ss: simpset
    26   val num_ss: simpset
       
    27   val field_comp_conv: conv
    27 end;
    28 end;
    28 
    29 
    29 structure Numeral_Simprocs : NUMERAL_SIMPROCS =
    30 structure Numeral_Simprocs : NUMERAL_SIMPROCS =
    30 struct
    31 struct
    31 
    32 
   600     ("divide_cancel_factor",
   601     ("divide_cancel_factor",
   601      ["((l::'a::field_inverse_zero) * m) / n",
   602      ["((l::'a::field_inverse_zero) * m) / n",
   602       "(l::'a::field_inverse_zero) / (m * n)"],
   603       "(l::'a::field_inverse_zero) / (m * n)"],
   603      K DivideCancelFactor.proc)];
   604      K DivideCancelFactor.proc)];
   604 
   605 
       
   606 local
       
   607  val zr = @{cpat "0"}
       
   608  val zT = ctyp_of_term zr
       
   609  val geq = @{cpat "op ="}
       
   610  val eqT = Thm.dest_ctyp (ctyp_of_term geq) |> hd
       
   611  val add_frac_eq = mk_meta_eq @{thm "add_frac_eq"}
       
   612  val add_frac_num = mk_meta_eq @{thm "add_frac_num"}
       
   613  val add_num_frac = mk_meta_eq @{thm "add_num_frac"}
       
   614 
       
   615  fun prove_nz ss T t =
       
   616     let
       
   617       val z = instantiate_cterm ([(zT,T)],[]) zr
       
   618       val eq = instantiate_cterm ([(eqT,T)],[]) geq
       
   619       val th = Simplifier.rewrite (ss addsimps @{thms simp_thms})
       
   620            (Thm.capply @{cterm "Trueprop"} (Thm.capply @{cterm "Not"}
       
   621                   (Thm.capply (Thm.capply eq t) z)))
       
   622     in equal_elim (symmetric th) TrueI
       
   623     end
       
   624 
       
   625  fun proc phi ss ct =
       
   626   let
       
   627     val ((x,y),(w,z)) =
       
   628          (Thm.dest_binop #> (fn (a,b) => (Thm.dest_binop a, Thm.dest_binop b))) ct
       
   629     val _ = map (HOLogic.dest_number o term_of) [x,y,z,w]
       
   630     val T = ctyp_of_term x
       
   631     val [y_nz, z_nz] = map (prove_nz ss T) [y, z]
       
   632     val th = instantiate' [SOME T] (map SOME [y,z,x,w]) add_frac_eq
       
   633   in SOME (implies_elim (implies_elim th y_nz) z_nz)
       
   634   end
       
   635   handle CTERM _ => NONE | TERM _ => NONE | THM _ => NONE
       
   636 
       
   637  fun proc2 phi ss ct =
       
   638   let
       
   639     val (l,r) = Thm.dest_binop ct
       
   640     val T = ctyp_of_term l
       
   641   in (case (term_of l, term_of r) of
       
   642       (Const(@{const_name Rings.divide},_)$_$_, _) =>
       
   643         let val (x,y) = Thm.dest_binop l val z = r
       
   644             val _ = map (HOLogic.dest_number o term_of) [x,y,z]
       
   645             val ynz = prove_nz ss T y
       
   646         in SOME (implies_elim (instantiate' [SOME T] (map SOME [y,x,z]) add_frac_num) ynz)
       
   647         end
       
   648      | (_, Const (@{const_name Rings.divide},_)$_$_) =>
       
   649         let val (x,y) = Thm.dest_binop r val z = l
       
   650             val _ = map (HOLogic.dest_number o term_of) [x,y,z]
       
   651             val ynz = prove_nz ss T y
       
   652         in SOME (implies_elim (instantiate' [SOME T] (map SOME [y,z,x]) add_num_frac) ynz)
       
   653         end
       
   654      | _ => NONE)
       
   655   end
       
   656   handle CTERM _ => NONE | TERM _ => NONE | THM _ => NONE
       
   657 
       
   658  fun is_number (Const(@{const_name Rings.divide},_)$a$b) = is_number a andalso is_number b
       
   659    | is_number t = can HOLogic.dest_number t
       
   660 
       
   661  val is_number = is_number o term_of
       
   662 
       
   663  fun proc3 phi ss ct =
       
   664   (case term_of ct of
       
   665     Const(@{const_name Orderings.less},_)$(Const(@{const_name Rings.divide},_)$_$_)$_ =>
       
   666       let
       
   667         val ((a,b),c) = Thm.dest_binop ct |>> Thm.dest_binop
       
   668         val _ = map is_number [a,b,c]
       
   669         val T = ctyp_of_term c
       
   670         val th = instantiate' [SOME T] (map SOME [a,b,c]) @{thm "divide_less_eq"}
       
   671       in SOME (mk_meta_eq th) end
       
   672   | Const(@{const_name Orderings.less_eq},_)$(Const(@{const_name Rings.divide},_)$_$_)$_ =>
       
   673       let
       
   674         val ((a,b),c) = Thm.dest_binop ct |>> Thm.dest_binop
       
   675         val _ = map is_number [a,b,c]
       
   676         val T = ctyp_of_term c
       
   677         val th = instantiate' [SOME T] (map SOME [a,b,c]) @{thm "divide_le_eq"}
       
   678       in SOME (mk_meta_eq th) end
       
   679   | Const("op =",_)$(Const(@{const_name Rings.divide},_)$_$_)$_ =>
       
   680       let
       
   681         val ((a,b),c) = Thm.dest_binop ct |>> Thm.dest_binop
       
   682         val _ = map is_number [a,b,c]
       
   683         val T = ctyp_of_term c
       
   684         val th = instantiate' [SOME T] (map SOME [a,b,c]) @{thm "divide_eq_eq"}
       
   685       in SOME (mk_meta_eq th) end
       
   686   | Const(@{const_name Orderings.less},_)$_$(Const(@{const_name Rings.divide},_)$_$_) =>
       
   687     let
       
   688       val (a,(b,c)) = Thm.dest_binop ct ||> Thm.dest_binop
       
   689         val _ = map is_number [a,b,c]
       
   690         val T = ctyp_of_term c
       
   691         val th = instantiate' [SOME T] (map SOME [a,b,c]) @{thm "less_divide_eq"}
       
   692       in SOME (mk_meta_eq th) end
       
   693   | Const(@{const_name Orderings.less_eq},_)$_$(Const(@{const_name Rings.divide},_)$_$_) =>
       
   694     let
       
   695       val (a,(b,c)) = Thm.dest_binop ct ||> Thm.dest_binop
       
   696         val _ = map is_number [a,b,c]
       
   697         val T = ctyp_of_term c
       
   698         val th = instantiate' [SOME T] (map SOME [a,b,c]) @{thm "le_divide_eq"}
       
   699       in SOME (mk_meta_eq th) end
       
   700   | Const("op =",_)$_$(Const(@{const_name Rings.divide},_)$_$_) =>
       
   701     let
       
   702       val (a,(b,c)) = Thm.dest_binop ct ||> Thm.dest_binop
       
   703         val _ = map is_number [a,b,c]
       
   704         val T = ctyp_of_term c
       
   705         val th = instantiate' [SOME T] (map SOME [a,b,c]) @{thm "eq_divide_eq"}
       
   706       in SOME (mk_meta_eq th) end
       
   707   | _ => NONE)
       
   708   handle TERM _ => NONE | CTERM _ => NONE | THM _ => NONE
       
   709 
       
   710 val add_frac_frac_simproc =
       
   711        make_simproc {lhss = [@{cpat "(?x::?'a::field)/?y + (?w::?'a::field)/?z"}],
       
   712                      name = "add_frac_frac_simproc",
       
   713                      proc = proc, identifier = []}
       
   714 
       
   715 val add_frac_num_simproc =
       
   716        make_simproc {lhss = [@{cpat "(?x::?'a::field)/?y + ?z"}, @{cpat "?z + (?x::?'a::field)/?y"}],
       
   717                      name = "add_frac_num_simproc",
       
   718                      proc = proc2, identifier = []}
       
   719 
       
   720 val ord_frac_simproc =
       
   721   make_simproc
       
   722     {lhss = [@{cpat "(?a::(?'a::{field, ord}))/?b < ?c"},
       
   723              @{cpat "(?a::(?'a::{field, ord}))/?b <= ?c"},
       
   724              @{cpat "?c < (?a::(?'a::{field, ord}))/?b"},
       
   725              @{cpat "?c <= (?a::(?'a::{field, ord}))/?b"},
       
   726              @{cpat "?c = ((?a::(?'a::{field, ord}))/?b)"},
       
   727              @{cpat "((?a::(?'a::{field, ord}))/ ?b) = ?c"}],
       
   728              name = "ord_frac_simproc", proc = proc3, identifier = []}
       
   729 
       
   730 val ths = [@{thm "mult_numeral_1"}, @{thm "mult_numeral_1_right"},
       
   731            @{thm "divide_Numeral1"},
       
   732            @{thm "divide_zero"}, @{thm "divide_Numeral0"},
       
   733            @{thm "divide_divide_eq_left"}, 
       
   734            @{thm "times_divide_eq_left"}, @{thm "times_divide_eq_right"},
       
   735            @{thm "times_divide_times_eq"},
       
   736            @{thm "divide_divide_eq_right"},
       
   737            @{thm "diff_def"}, @{thm "minus_divide_left"},
       
   738            @{thm "Numeral1_eq1_nat"}, @{thm "add_divide_distrib"} RS sym,
       
   739            @{thm field_divide_inverse} RS sym, @{thm inverse_divide}, 
       
   740            Conv.fconv_rule (Conv.arg_conv (Conv.arg1_conv (Conv.rewr_conv (mk_meta_eq @{thm mult_commute}))))   
       
   741            (@{thm field_divide_inverse} RS sym)]
       
   742 
       
   743 in
       
   744 
       
   745 val field_comp_conv = (Simplifier.rewrite
       
   746 (HOL_basic_ss addsimps @{thms "semiring_norm"}
       
   747               addsimps ths addsimps @{thms simp_thms}
       
   748               addsimprocs field_cancel_numeral_factors
       
   749                addsimprocs [add_frac_frac_simproc, add_frac_num_simproc,
       
   750                             ord_frac_simproc]
       
   751                 addcongs [@{thm "if_weak_cong"}]))
       
   752 then_conv (Simplifier.rewrite (HOL_basic_ss addsimps
       
   753   [@{thm numeral_1_eq_1},@{thm numeral_0_eq_0}] @ @{thms numerals(1-2)}))
       
   754 
       
   755 end
       
   756 
   605 end;
   757 end;
   606 
   758 
   607 Addsimprocs Numeral_Simprocs.cancel_numerals;
   759 Addsimprocs Numeral_Simprocs.cancel_numerals;
   608 Addsimprocs [Numeral_Simprocs.combine_numerals];
   760 Addsimprocs [Numeral_Simprocs.combine_numerals];
   609 Addsimprocs [Numeral_Simprocs.field_combine_numerals];
   761 Addsimprocs [Numeral_Simprocs.field_combine_numerals];