src/Provers/Arith/cancel_factor.ML
changeset 23261 85f27f79232f
parent 20044 92cc2f4c7335
child 24630 351a308ab58d
equal deleted inserted replaced
23260:eb6d86fb7ed3 23261:85f27f79232f
    12   val dest_sum: term -> term list
    12   val dest_sum: term -> term list
    13   val mk_bal: term * term -> term
    13   val mk_bal: term * term -> term
    14   val dest_bal: term -> term * term
    14   val dest_bal: term -> term * term
    15   (*rules*)
    15   (*rules*)
    16   val prove_conv: tactic -> tactic -> Proof.context -> term * term -> thm
    16   val prove_conv: tactic -> tactic -> Proof.context -> term * term -> thm
    17   val norm_tac: tactic			(*AC0 etc.*)
    17   val norm_tac: tactic (*AC0 etc.*)
    18   val multiply_tac: IntInf.int -> tactic	(*apply a ~~ b  ==  k * a ~~ k * b  (for k > 0)*)
    18   val multiply_tac: integer -> tactic
       
    19     (*apply a ~~ b  ==  k * a ~~ k * b  (for k > 0)*)
    19 end;
    20 end;
    20 
    21 
    21 signature CANCEL_FACTOR =
    22 signature CANCEL_FACTOR =
    22 sig
    23 sig
    23   val proc: simpset -> term -> thm option
    24   val proc: simpset -> term -> thm option
    24 end;
    25 end;
    25 
    26 
    26 
    27 
    27 functor CancelFactorFun(Data: CANCEL_FACTOR_DATA): CANCEL_FACTOR =
    28 functor CancelFactorFun(Data: CANCEL_FACTOR_DATA): CANCEL_FACTOR =
    28 struct
    29 struct
    29 
       
    30 
       
    31 (* greatest common divisor *)
       
    32 
       
    33 fun gcd (0, n) = n
       
    34   | gcd (m, n) = gcd (n mod m, m);
       
    35 
       
    36 val gcds = foldl gcd;
       
    37 
    30 
    38 
    31 
    39 (* count terms *)
    32 (* count terms *)
    40 
    33 
    41 fun ins_term (t, []) = [(t, 1)]
    34 fun ins_term (t, []) = [(t, 1)]
    46 fun count_terms ts = foldr ins_term (sort Term.term_ord ts, []);
    39 fun count_terms ts = foldr ins_term (sort Term.term_ord ts, []);
    47 
    40 
    48 
    41 
    49 (* divide sum *)
    42 (* divide sum *)
    50 
    43 
    51 fun div_sum d tks =
    44 fun div_sum d =
    52   Data.mk_sum (flat (map (fn (t, k) => replicate (k div d) t) tks));
    45   Data.mk_sum o maps (fn (t, k) => replicate (k div d) t);
    53 
    46 
    54 
    47 
    55 (* the simplification procedure *)
    48 (* the simplification procedure *)
    56 
    49 
    57 fun proc ss t =
    50 fun proc ss t =
    62         ([_], _) => NONE
    55         ([_], _) => NONE
    63       | (_, [_]) => NONE
    56       | (_, [_]) => NONE
    64       | ts_us =>
    57       | ts_us =>
    65           let
    58           let
    66             val (tks, uks) = pairself count_terms ts_us;
    59             val (tks, uks) = pairself count_terms ts_us;
    67             val d = gcds (gcds (0, map snd tks), map snd uks);
    60             val d = 0
       
    61               |> fold (Integer.gcd o snd) tks
       
    62               |> fold (Integer.gcd o snd) uks;
       
    63             val d' = Integer.machine_int d;
    68           in
    64           in
    69             if d = 0 orelse d = 1 then NONE
    65             if d = 0 orelse d = 1 then NONE
    70             else SOME
    66             else SOME
    71               (Data.prove_conv (Data.multiply_tac d) Data.norm_tac (Simplifier.the_context ss)
    67               (Data.prove_conv (Data.multiply_tac d) Data.norm_tac (Simplifier.the_context ss)
    72                 (t, Data.mk_bal (div_sum d tks, div_sum d uks)))
    68                 (t, Data.mk_bal (div_sum d' tks, div_sum d' uks)))
    73           end));
    69           end));
    74 
    70 
    75 
    71 
    76 end;
    72 end;