src/HOL/Library/EfficientNat.thy
changeset 15570 8d8c70b41bab
parent 15531 08c8dad8e399
child 15574 b1d1b5bfc464
equal deleted inserted replaced
15569:1b3115d1a8df 15570:8d8c70b41bab
    98 fun remove_suc thy thms =
    98 fun remove_suc thy thms =
    99   let
    99   let
   100     val Suc_if_eq' = Thm.transfer thy Suc_if_eq;
   100     val Suc_if_eq' = Thm.transfer thy Suc_if_eq;
   101     val ctzero = cterm_of (sign_of Main.thy) HOLogic.zero;
   101     val ctzero = cterm_of (sign_of Main.thy) HOLogic.zero;
   102     val vname = variant (map fst
   102     val vname = variant (map fst
   103       (foldl add_term_varnames ([], map prop_of thms))) "x";
   103       (Library.foldl add_term_varnames ([], map prop_of thms))) "x";
   104     val cv = cterm_of (sign_of Main.thy) (Var ((vname, 0), HOLogic.natT));
   104     val cv = cterm_of (sign_of Main.thy) (Var ((vname, 0), HOLogic.natT));
   105     fun lhs_of th = snd (Thm.dest_comb
   105     fun lhs_of th = snd (Thm.dest_comb
   106       (fst (Thm.dest_comb (snd (Thm.dest_comb (cprop_of th))))));
   106       (fst (Thm.dest_comb (snd (Thm.dest_comb (cprop_of th))))));
   107     fun rhs_of th = snd (Thm.dest_comb (snd (Thm.dest_comb (cprop_of th))));
   107     fun rhs_of th = snd (Thm.dest_comb (snd (Thm.dest_comb (cprop_of th))));
   108     fun find_vars ct = (case term_of ct of
   108     fun find_vars ct = (case term_of ct of
   112         in 
   112         in 
   113           map (apfst (pairself (fn ct => Thm.capply ct ct2))) (find_vars ct1) @
   113           map (apfst (pairself (fn ct => Thm.capply ct ct2))) (find_vars ct1) @
   114           map (apfst (pairself (Thm.capply ct1))) (find_vars ct2)
   114           map (apfst (pairself (Thm.capply ct1))) (find_vars ct2)
   115         end
   115         end
   116       | _ => []);
   116       | _ => []);
   117     val eqs1 = flat (map
   117     val eqs1 = List.concat (map
   118       (fn th => map (pair th) (find_vars (lhs_of th))) thms);
   118       (fn th => map (pair th) (find_vars (lhs_of th))) thms);
   119     val eqs2 = map (fn x as (_, ((_, ctzero), _)) => (x, mapfilter (fn th =>
   119     val eqs2 = map (fn x as (_, ((_, ctzero), _)) => (x, List.mapPartial (fn th =>
   120       SOME (th, Thm.cterm_match (lhs_of th, ctzero))
   120       SOME (th, Thm.cterm_match (lhs_of th, ctzero))
   121         handle Pattern.MATCH => NONE) thms)) eqs1;
   121         handle Pattern.MATCH => NONE) thms)) eqs1;
   122     fun distinct_vars vs = forall is_Var vs andalso null (duplicates vs);
   122     fun distinct_vars vs = forall is_Var vs andalso null (duplicates vs);
   123     val eqs2' = map (apsnd (filter (fn (_, (_, s)) =>
   123     val eqs2' = map (apsnd (List.filter (fn (_, (_, s)) =>
   124       distinct_vars (map (term_of o snd) s)))) eqs2;
   124       distinct_vars (map (term_of o snd) s)))) eqs2;
   125     fun mk_thms b ((th, ((ct, _), cv')), (th', s) :: _) =
   125     fun mk_thms b ((th, ((ct, _), cv')), (th', s) :: _) =
   126       let
   126       let
   127         val th'' = Thm.instantiate s th';
   127         val th'' = Thm.instantiate s th';
   128         val th''' =
   128         val th''' =
   131              (Drule.instantiate'
   131              (Drule.instantiate'
   132                [SOME (ctyp_of_term ct)] [SOME (Thm.cabs cv ct),
   132                [SOME (ctyp_of_term ct)] [SOME (Thm.cabs cv ct),
   133                  SOME (rhs_of th''), SOME (Thm.cabs cv' (rhs_of th)), SOME cv']
   133                  SOME (rhs_of th''), SOME (Thm.cabs cv' (rhs_of th)), SOME cv']
   134                Suc_if_eq')) th'') (Thm.forall_intr cv' th)
   134                Suc_if_eq')) th'') (Thm.forall_intr cv' th)
   135       in
   135       in
   136         mapfilter (fn thm =>
   136         List.mapPartial (fn thm =>
   137           if thm = th then SOME th'''
   137           if thm = th then SOME th'''
   138           else if b andalso thm = th' then NONE
   138           else if b andalso thm = th' then NONE
   139           else SOME thm) thms
   139           else SOME thm) thms
   140       end
   140       end
   141   in
   141   in
   158 
   158 
   159 fun remove_suc_clause thy thms =
   159 fun remove_suc_clause thy thms =
   160   let
   160   let
   161     val Suc_clause' = Thm.transfer thy Suc_clause;
   161     val Suc_clause' = Thm.transfer thy Suc_clause;
   162     val vname = variant (map fst
   162     val vname = variant (map fst
   163       (foldl add_term_varnames ([], map prop_of thms))) "x";
   163       (Library.foldl add_term_varnames ([], map prop_of thms))) "x";
   164     fun find_var (t as Const ("Suc", _) $ (v as Var _)) = SOME (t, v)
   164     fun find_var (t as Const ("Suc", _) $ (v as Var _)) = SOME (t, v)
   165       | find_var (t $ u) = (case find_var t of NONE => find_var u | x => x)
   165       | find_var (t $ u) = (case find_var t of NONE => find_var u | x => x)
   166       | find_var _ = NONE;
   166       | find_var _ = NONE;
   167     fun find_thm th =
   167     fun find_thm th =
   168       let val th' = ObjectLogic.atomize_thm th
   168       let val th' = ObjectLogic.atomize_thm th
   169       in apsome (pair (th, th')) (find_var (prop_of th')) end
   169       in Option.map (pair (th, th')) (find_var (prop_of th')) end
   170   in
   170   in
   171     case get_first find_thm thms of
   171     case get_first find_thm thms of
   172       NONE => thms
   172       NONE => thms
   173     | SOME ((th, th'), (Sucv, v)) =>
   173     | SOME ((th, th'), (Sucv, v)) =>
   174         let
   174         let
   189 
   189 
   190 fun clause_suc_preproc thy ths =
   190 fun clause_suc_preproc thy ths =
   191   let val dest = fst o HOLogic.dest_mem o HOLogic.dest_Trueprop
   191   let val dest = fst o HOLogic.dest_mem o HOLogic.dest_Trueprop
   192   in
   192   in
   193     if forall (can (dest o concl_of)) ths andalso
   193     if forall (can (dest o concl_of)) ths andalso
   194       exists (fn th => "Suc" mem foldr add_term_consts
   194       exists (fn th => "Suc" mem Library.foldr add_term_consts
   195         (mapfilter (try dest) (concl_of th :: prems_of th), [])) ths
   195         (List.mapPartial (try dest) (concl_of th :: prems_of th), [])) ths
   196     then remove_suc_clause thy ths else ths
   196     then remove_suc_clause thy ths else ths
   197   end;
   197   end;
   198 
   198 
   199 val suc_preproc_setup =
   199 val suc_preproc_setup =
   200   [Codegen.add_preprocessor eqn_suc_preproc,
   200   [Codegen.add_preprocessor eqn_suc_preproc,