src/HOL/Library/Efficient_Nat.thy
changeset 29874 ffed4bd4bfad
parent 29869 a2594b5c945a
child 30663 0b6aff7451b2
     1.1 --- a/src/HOL/Library/Efficient_Nat.thy	Mon Feb 16 19:11:15 2009 +0100
     1.2 +++ b/src/HOL/Library/Efficient_Nat.thy	Mon Feb 16 19:11:16 2009 +0100
     1.3 @@ -105,10 +105,16 @@
     1.4    This can be accomplished by applying the following transformation rules:
     1.5  *}
     1.6  
     1.7 -lemma Suc_if_eq: "(\<And>n. f (Suc n) = h n) \<Longrightarrow> f 0 = g \<Longrightarrow>
     1.8 +lemma Suc_if_eq': "(\<And>n. f (Suc n) = h n) \<Longrightarrow> f 0 = g \<Longrightarrow>
     1.9    f n = (if n = 0 then g else h (n - 1))"
    1.10    by (cases n) simp_all
    1.11  
    1.12 +lemma Suc_if_eq: "(\<And>n. f (Suc n) \<equiv> h n) \<Longrightarrow> f 0 \<equiv> g \<Longrightarrow>
    1.13 +  f n \<equiv> if n = 0 then g else h (n - 1)"
    1.14 +  by (rule eq_reflection, rule Suc_if_eq')
    1.15 +    (rule meta_eq_to_obj_eq, assumption,
    1.16 +     rule meta_eq_to_obj_eq, assumption)
    1.17 +
    1.18  lemma Suc_clause: "(\<And>n. P n (Suc n)) \<Longrightarrow> n \<noteq> 0 \<Longrightarrow> P (n - 1) n"
    1.19    by (cases n) simp_all
    1.20  
    1.21 @@ -123,14 +129,14 @@
    1.22  setup {*
    1.23  let
    1.24  
    1.25 -fun remove_suc thy thms =
    1.26 +fun gen_remove_suc Suc_if_eq dest_judgement thy thms =
    1.27    let
    1.28      val vname = Name.variant (map fst
    1.29 -      (fold (Term.add_var_names o Thm.full_prop_of) thms [])) "x";
    1.30 +      (fold (Term.add_var_names o Thm.full_prop_of) thms [])) "n";
    1.31      val cv = cterm_of thy (Var ((vname, 0), HOLogic.natT));
    1.32      fun lhs_of th = snd (Thm.dest_comb
    1.33 -      (fst (Thm.dest_comb (snd (Thm.dest_comb (cprop_of th))))));
    1.34 -    fun rhs_of th = snd (Thm.dest_comb (snd (Thm.dest_comb (cprop_of th))));
    1.35 +      (fst (Thm.dest_comb (dest_judgement (cprop_of th)))));
    1.36 +    fun rhs_of th = snd (Thm.dest_comb (dest_judgement (cprop_of th)));
    1.37      fun find_vars ct = (case term_of ct of
    1.38          (Const (@{const_name Suc}, _) $ Var _) => [(cv, snd (Thm.dest_comb ct))]
    1.39        | _ $ _ =>
    1.40 @@ -150,7 +156,7 @@
    1.41               (Drule.instantiate'
    1.42                 [SOME (ctyp_of_term ct)] [SOME (Thm.cabs cv ct),
    1.43                   SOME (Thm.cabs cv' (rhs_of th)), NONE, SOME cv']
    1.44 -               @{thm Suc_if_eq})) (Thm.forall_intr cv' th)
    1.45 +               Suc_if_eq)) (Thm.forall_intr cv' th)
    1.46        in
    1.47          case map_filter (fn th'' =>
    1.48              SOME (th'', singleton
    1.49 @@ -161,20 +167,26 @@
    1.50                let val (ths1, ths2) = split_list thps
    1.51                in SOME (subtract Thm.eq_thm (th :: ths1) thms @ ths2) end
    1.52        end
    1.53 -  in case get_first mk_thms eqs of
    1.54 -      NONE => thms
    1.55 -    | SOME x => remove_suc thy x
    1.56 +  in get_first mk_thms eqs end;
    1.57 +
    1.58 +fun gen_eqn_suc_preproc Suc_if_eq dest_judgement dest_lhs thy thms =
    1.59 +  let
    1.60 +    val dest = dest_lhs o prop_of;
    1.61 +    val contains_suc = exists_Const (fn (c, _) => c = @{const_name Suc});
    1.62 +  in
    1.63 +    if forall (can dest) thms andalso exists (contains_suc o dest) thms
    1.64 +      then perhaps_loop (gen_remove_suc Suc_if_eq dest_judgement thy) thms
    1.65 +       else NONE
    1.66    end;
    1.67  
    1.68 -fun eqn_suc_preproc thy ths =
    1.69 -  let
    1.70 -    val dest = fst o HOLogic.dest_eq o HOLogic.dest_Trueprop o prop_of;
    1.71 -    val contains_suc = exists_Const (fn (c, _) => c = @{const_name Suc});
    1.72 -  in
    1.73 -    if forall (can dest) ths andalso
    1.74 -      exists (contains_suc o dest) ths
    1.75 -    then remove_suc thy ths else ths
    1.76 -  end;
    1.77 +fun eqn_suc_preproc thy = map fst
    1.78 +  #> gen_eqn_suc_preproc
    1.79 +      @{thm Suc_if_eq} I (fst o Logic.dest_equals) thy
    1.80 +  #> (Option.map o map) (Code_Unit.mk_eqn thy);
    1.81 +
    1.82 +fun eqn_suc_preproc' thy thms = gen_eqn_suc_preproc
    1.83 +  @{thm Suc_if_eq'} (snd o Thm.dest_comb) (fst o HOLogic.dest_eq o HOLogic.dest_Trueprop) thy thms
    1.84 +  |> the_default thms;
    1.85  
    1.86  fun remove_suc_clause thy thms =
    1.87    let
    1.88 @@ -215,27 +227,11 @@
    1.89          (map_filter (try dest) (concl_of th :: prems_of th))) ths
    1.90      then remove_suc_clause thy ths else ths
    1.91    end;
    1.92 -
    1.93 -fun lift f thy eqns1 =
    1.94 -  let
    1.95 -    val eqns2 = burrow_fst Drule.zero_var_indexes_list eqns1;
    1.96 -    val thms3 = try (map fst
    1.97 -      #> map (fn thm => thm RS @{thm meta_eq_to_obj_eq})
    1.98 -      #> f thy
    1.99 -      #> map (fn thm => thm RS @{thm eq_reflection})
   1.100 -      #> map (Conv.fconv_rule Drule.beta_eta_conversion)) eqns2;
   1.101 -    val thms4 = Option.map Drule.zero_var_indexes_list thms3;
   1.102 -  in case thms4
   1.103 -   of NONE => NONE
   1.104 -    | SOME thms4 => if Thm.eq_thms (map fst eqns2, thms4)
   1.105 -        then NONE else SOME (map (apfst (AxClass.overload thy) o Code_Unit.mk_eqn thy) thms4)
   1.106 -  end
   1.107 -
   1.108  in
   1.109  
   1.110 -  Codegen.add_preprocessor eqn_suc_preproc
   1.111 +  Codegen.add_preprocessor eqn_suc_preproc'
   1.112    #> Codegen.add_preprocessor clause_suc_preproc
   1.113 -  #> Code.add_functrans ("eqn_Suc", lift eqn_suc_preproc)
   1.114 +  #> Code.add_functrans ("eqn_Suc", eqn_suc_preproc)
   1.115  
   1.116  end;
   1.117  *}