src/HOL/Integ/int_factor_simprocs.ML
changeset 23067 b4f38a12f74a
parent 22997 d4f3b015b50b
equal deleted inserted replaced
23066:26a9157b620a 23067:b4f38a12f74a
    58     [@{thm add_0}, @{thm add_0_right}, @{thm mult_zero_left},
    58     [@{thm add_0}, @{thm add_0_right}, @{thm mult_zero_left},
    59       @{thm mult_zero_right}, @{thm mult_num1}, @{thm mult_1_right}];
    59       @{thm mult_zero_right}, @{thm mult_num1}, @{thm mult_1_right}];
    60   end
    60   end
    61 
    61 
    62 (*Version for integer division*)
    62 (*Version for integer division*)
    63 structure DivCancelNumeralFactor = CancelNumeralFactorFun
    63 structure IntDivCancelNumeralFactor = CancelNumeralFactorFun
    64  (open CancelNumeralFactorCommon
    64  (open CancelNumeralFactorCommon
    65   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
    65   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
    66   val mk_bal   = HOLogic.mk_binop @{const_name Divides.div}
    66   val mk_bal   = HOLogic.mk_binop @{const_name Divides.div}
    67   val dest_bal = HOLogic.dest_bin @{const_name Divides.div} HOLogic.intT
    67   val dest_bal = HOLogic.dest_bin @{const_name Divides.div} HOLogic.intT
    68   val cancel = int_mult_div_cancel1 RS trans
    68   val cancel = int_mult_div_cancel1 RS trans
    69   val neg_exchanges = false
    69   val neg_exchanges = false
    70 )
    70 )
    71 
    71 
    72 (*Version for fields*)
    72 (*Version for fields*)
    73 structure FieldDivCancelNumeralFactor = CancelNumeralFactorFun
    73 structure DivideCancelNumeralFactor = CancelNumeralFactorFun
    74  (open CancelNumeralFactorCommon
    74  (open CancelNumeralFactorCommon
    75   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
    75   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
    76   val mk_bal   = HOLogic.mk_binop @{const_name HOL.divide}
    76   val mk_bal   = HOLogic.mk_binop @{const_name HOL.divide}
    77   val dest_bal = HOLogic.dest_bin @{const_name HOL.divide} Term.dummyT
    77   val dest_bal = HOLogic.dest_bin @{const_name HOL.divide} Term.dummyT
    78   val cancel = @{thm mult_divide_cancel_left} RS trans
    78   val cancel = @{thm mult_divide_cancel_left} RS trans
    79   val neg_exchanges = false
    79   val neg_exchanges = false
    80 )
    80 )
    81 
    81 
    82 (*Version for ordered rings: mult_cancel_left requires an ordering*)
       
    83 structure EqCancelNumeralFactor = CancelNumeralFactorFun
    82 structure EqCancelNumeralFactor = CancelNumeralFactorFun
    84  (open CancelNumeralFactorCommon
    83  (open CancelNumeralFactorCommon
    85   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
    84   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
    86   val mk_bal   = HOLogic.mk_eq
    85   val mk_bal   = HOLogic.mk_eq
    87   val dest_bal = HOLogic.dest_bin "op =" Term.dummyT
    86   val dest_bal = HOLogic.dest_bin "op =" Term.dummyT
    88   val cancel = @{thm mult_cancel_left} RS trans
    87   val cancel = @{thm mult_cancel_left} RS trans
    89   val neg_exchanges = false
    88   val neg_exchanges = false
    90 )
    89 )
    91 
    90 
    92 (*Version for (unordered) fields*)
       
    93 structure FieldEqCancelNumeralFactor = CancelNumeralFactorFun
       
    94  (open CancelNumeralFactorCommon
       
    95   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
       
    96   val mk_bal   = HOLogic.mk_eq
       
    97   val dest_bal = HOLogic.dest_bin "op =" Term.dummyT
       
    98   val cancel = @{thm field_mult_cancel_left} RS trans
       
    99   val neg_exchanges = false
       
   100 )
       
   101 
       
   102 structure LessCancelNumeralFactor = CancelNumeralFactorFun
    91 structure LessCancelNumeralFactor = CancelNumeralFactorFun
   103  (open CancelNumeralFactorCommon
    92  (open CancelNumeralFactorCommon
   104   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
    93   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
   105   val mk_bal   = HOLogic.mk_binrel @{const_name Orderings.less}
    94   val mk_bal   = HOLogic.mk_binrel @{const_name Orderings.less}
   106   val dest_bal = HOLogic.dest_bin @{const_name Orderings.less} Term.dummyT
    95   val dest_bal = HOLogic.dest_bin @{const_name Orderings.less} Term.dummyT
   115   val dest_bal = HOLogic.dest_bin @{const_name Orderings.less_eq} Term.dummyT
   104   val dest_bal = HOLogic.dest_bin @{const_name Orderings.less_eq} Term.dummyT
   116   val cancel = @{thm mult_le_cancel_left} RS trans
   105   val cancel = @{thm mult_le_cancel_left} RS trans
   117   val neg_exchanges = true
   106   val neg_exchanges = true
   118 )
   107 )
   119 
   108 
   120 val ring_cancel_numeral_factors =
   109 val cancel_numeral_factors =
   121   map Int_Numeral_Base_Simprocs.prep_simproc
   110   map Int_Numeral_Base_Simprocs.prep_simproc
   122    [("ring_eq_cancel_numeral_factor",
   111    [("ring_eq_cancel_numeral_factor",
   123      ["(l::'a::{ordered_idom,number_ring}) * m = n",
   112      ["(l::'a::{idom,number_ring}) * m = n",
   124       "(l::'a::{ordered_idom,number_ring}) = m * n"],
   113       "(l::'a::{idom,number_ring}) = m * n"],
   125      K EqCancelNumeralFactor.proc),
   114      K EqCancelNumeralFactor.proc),
   126     ("ring_less_cancel_numeral_factor",
   115     ("ring_less_cancel_numeral_factor",
   127      ["(l::'a::{ordered_idom,number_ring}) * m < n",
   116      ["(l::'a::{ordered_idom,number_ring}) * m < n",
   128       "(l::'a::{ordered_idom,number_ring}) < m * n"],
   117       "(l::'a::{ordered_idom,number_ring}) < m * n"],
   129      K LessCancelNumeralFactor.proc),
   118      K LessCancelNumeralFactor.proc),
   131      ["(l::'a::{ordered_idom,number_ring}) * m <= n",
   120      ["(l::'a::{ordered_idom,number_ring}) * m <= n",
   132       "(l::'a::{ordered_idom,number_ring}) <= m * n"],
   121       "(l::'a::{ordered_idom,number_ring}) <= m * n"],
   133      K LeCancelNumeralFactor.proc),
   122      K LeCancelNumeralFactor.proc),
   134     ("int_div_cancel_numeral_factors",
   123     ("int_div_cancel_numeral_factors",
   135      ["((l::int) * m) div n", "(l::int) div (m * n)"],
   124      ["((l::int) * m) div n", "(l::int) div (m * n)"],
   136      K DivCancelNumeralFactor.proc)];
   125      K IntDivCancelNumeralFactor.proc),
   137 
   126     ("divide_cancel_numeral_factor",
   138 
   127      ["((l::'a::{division_by_zero,field,number_ring}) * m) / n",
       
   128       "(l::'a::{division_by_zero,field,number_ring}) / (m * n)",
       
   129       "((number_of v)::'a::{division_by_zero,field,number_ring}) / (number_of w)"],
       
   130      K DivideCancelNumeralFactor.proc)];
       
   131 
       
   132 (* referenced by rat_arith.ML *)
   139 val field_cancel_numeral_factors =
   133 val field_cancel_numeral_factors =
   140   map Int_Numeral_Base_Simprocs.prep_simproc
   134   map Int_Numeral_Base_Simprocs.prep_simproc
   141    [("field_eq_cancel_numeral_factor",
   135    [("field_eq_cancel_numeral_factor",
   142      ["(l::'a::{field,number_ring}) * m = n",
   136      ["(l::'a::{field,number_ring}) * m = n",
   143       "(l::'a::{field,number_ring}) = m * n"],
   137       "(l::'a::{field,number_ring}) = m * n"],
   144      K FieldEqCancelNumeralFactor.proc),
   138      K EqCancelNumeralFactor.proc),
   145     ("field_cancel_numeral_factor",
   139     ("field_cancel_numeral_factor",
   146      ["((l::'a::{division_by_zero,field,number_ring}) * m) / n",
   140      ["((l::'a::{division_by_zero,field,number_ring}) * m) / n",
   147       "(l::'a::{division_by_zero,field,number_ring}) / (m * n)",
   141       "(l::'a::{division_by_zero,field,number_ring}) / (m * n)",
   148       "((number_of v)::'a::{division_by_zero,field,number_ring}) / (number_of w)"],
   142       "((number_of v)::'a::{division_by_zero,field,number_ring}) / (number_of w)"],
   149      K FieldDivCancelNumeralFactor.proc)]
   143      K DivideCancelNumeralFactor.proc)]
   150 
   144 
   151 end;
   145 end;
   152 
   146 
   153 Addsimprocs ring_cancel_numeral_factors;
   147 Addsimprocs cancel_numeral_factors;
   154 Addsimprocs field_cancel_numeral_factors;
       
   155 
   148 
   156 (*examples:
   149 (*examples:
   157 print_depth 22;
   150 print_depth 22;
   158 set timing;
   151 set timing;
   159 set trace_simp;
   152 set trace_simp;
   253   val trans_tac         = fn _ => trans_tac
   246   val trans_tac         = fn _ => trans_tac
   254   val norm_ss = HOL_ss addsimps mult_1s @ mult_ac
   247   val norm_ss = HOL_ss addsimps mult_1s @ mult_ac
   255   fun norm_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss))
   248   fun norm_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss))
   256   end;
   249   end;
   257 
   250 
   258 (*mult_cancel_left requires an ordered comm_ring_1, such as int. The version in
   251 (*mult_cancel_left requires a ring with no zero divisors.*)
   259   rat_arith.ML works for all fields.*)
       
   260 structure EqCancelFactor = ExtractCommonTermFun
   252 structure EqCancelFactor = ExtractCommonTermFun
   261  (open CancelFactorCommon
   253  (open CancelFactorCommon
   262   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
   254   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
   263   val mk_bal   = HOLogic.mk_eq
   255   val mk_bal   = HOLogic.mk_eq
   264   val dest_bal = HOLogic.dest_bin "op =" HOLogic.intT
   256   val dest_bal = HOLogic.dest_bin "op =" Term.dummyT
   265   val simplify_meta_eq  = cancel_simplify_meta_eq @{thm mult_cancel_left}
   257   val simplify_meta_eq  = cancel_simplify_meta_eq @{thm mult_cancel_left}
   266 );
   258 );
   267 
   259 
   268 (*int_mult_div_cancel_disj is for integer division (div). The version in
   260 (*int_mult_div_cancel_disj is for integer division (div).*)
   269   rat_arith.ML works for all fields, using real division (/).*)
   261 structure IntDivCancelFactor = ExtractCommonTermFun
   270 structure DivideCancelFactor = ExtractCommonTermFun
       
   271  (open CancelFactorCommon
   262  (open CancelFactorCommon
   272   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
   263   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
   273   val mk_bal   = HOLogic.mk_binop @{const_name Divides.div}
   264   val mk_bal   = HOLogic.mk_binop @{const_name Divides.div}
   274   val dest_bal = HOLogic.dest_bin @{const_name Divides.div} HOLogic.intT
   265   val dest_bal = HOLogic.dest_bin @{const_name Divides.div} HOLogic.intT
   275   val simplify_meta_eq  = cancel_simplify_meta_eq int_mult_div_cancel_disj
   266   val simplify_meta_eq  = cancel_simplify_meta_eq int_mult_div_cancel_disj
   276 );
   267 );
   277 
   268 
   278 val int_cancel_factor =
   269 (*Version for all fields, including unordered ones (type complex).*)
   279   map Int_Numeral_Base_Simprocs.prep_simproc
   270 structure DivideCancelFactor = ExtractCommonTermFun
   280    [("ring_eq_cancel_factor", ["(l::int) * m = n", "(l::int) = m * n"],
       
   281     K EqCancelFactor.proc),
       
   282     ("int_divide_cancel_factor", ["((l::int) * m) div n", "(l::int) div (m*n)"],
       
   283      K DivideCancelFactor.proc)];
       
   284 
       
   285 (** Versions for all fields, including unordered ones (type complex).*)
       
   286 
       
   287 structure FieldEqCancelFactor = ExtractCommonTermFun
       
   288  (open CancelFactorCommon
       
   289   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
       
   290   val mk_bal   = HOLogic.mk_eq
       
   291   val dest_bal = HOLogic.dest_bin "op =" Term.dummyT
       
   292   val simplify_meta_eq  = cancel_simplify_meta_eq @{thm field_mult_cancel_left}
       
   293 );
       
   294 
       
   295 structure FieldDivideCancelFactor = ExtractCommonTermFun
       
   296  (open CancelFactorCommon
   271  (open CancelFactorCommon
   297   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
   272   val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
   298   val mk_bal   = HOLogic.mk_binop @{const_name HOL.divide}
   273   val mk_bal   = HOLogic.mk_binop @{const_name HOL.divide}
   299   val dest_bal = HOLogic.dest_bin @{const_name HOL.divide} Term.dummyT
   274   val dest_bal = HOLogic.dest_bin @{const_name HOL.divide} Term.dummyT
   300   val simplify_meta_eq  = cancel_simplify_meta_eq @{thm mult_divide_cancel_eq_if}
   275   val simplify_meta_eq  = cancel_simplify_meta_eq @{thm mult_divide_cancel_eq_if}
   301 );
   276 );
   302 
   277 
   303 (*The number_ring class is necessary because the simprocs refer to the
   278 (*The number_ring class is necessary because the simprocs refer to the
   304   binary number 1.  FIXME: probably they could use 1 instead.*)
   279   binary number 1.  FIXME: probably they could use 1 instead.*)
   305 val field_cancel_factor =
   280 val cancel_factors =
   306   map Int_Numeral_Base_Simprocs.prep_simproc
   281   map Int_Numeral_Base_Simprocs.prep_simproc
   307    [("field_eq_cancel_factor",
   282    [("ring_eq_cancel_factor",
   308      ["(l::'a::{field,number_ring}) * m = n",
   283      ["(l::'a::{idom,number_ring}) * m = n",
   309       "(l::'a::{field,number_ring}) = m * n"],
   284       "(l::'a::{idom,number_ring}) = m * n"],
   310      K FieldEqCancelFactor.proc),
   285     K EqCancelFactor.proc),
   311     ("field_divide_cancel_factor",
   286     ("int_div_cancel_factor",
       
   287      ["((l::int) * m) div n", "(l::int) div (m * n)"],
       
   288      K IntDivCancelFactor.proc),
       
   289     ("divide_cancel_factor",
   312      ["((l::'a::{division_by_zero,field,number_ring}) * m) / n",
   290      ["((l::'a::{division_by_zero,field,number_ring}) * m) / n",
   313       "(l::'a::{division_by_zero,field,number_ring}) / (m * n)"],
   291       "(l::'a::{division_by_zero,field,number_ring}) / (m * n)"],
   314      K FieldDivideCancelFactor.proc)];
   292      K DivideCancelFactor.proc)];
   315 
   293 
   316 end;
   294 end;
   317 
   295 
   318 Addsimprocs int_cancel_factor;
   296 Addsimprocs cancel_factors;
   319 Addsimprocs field_cancel_factor;
       
   320 
   297 
   321 
   298 
   322 (*examples:
   299 (*examples:
   323 print_depth 22;
   300 print_depth 22;
   324 set timing;
   301 set timing;