src/HOL/Tools/record.ML
changeset 33691 3db22a5707f3
parent 33612 2640cc1cfc2e
child 33711 2fdb11580b96
equal deleted inserted replaced
33653:feaf3627a844 33691:3db22a5707f3
  1006 
  1006 
  1007 
  1007 
  1008 
  1008 
  1009 (** record simprocs **)
  1009 (** record simprocs **)
  1010 
  1010 
  1011 fun quick_and_dirty_prove stndrd thy asms prop tac =
  1011 fun future_forward_prf_standard thy prf prop () =
  1012   if ! quick_and_dirty then
  1012    let val thm = if !quick_and_dirty then Skip_Proof.make_thm thy prop 
  1013     Goal.prove (ProofContext.init thy) [] []
  1013                  else Goal.future_result (ProofContext.init thy) (Future.fork_pri ~1 prf) prop;
  1014       (Logic.list_implies (map Logic.varify asms, Logic.varify prop))
  1014    in Drule.standard thm end;
  1015       (K (Skip_Proof.cheat_tac @{theory HOL}))
  1015 
  1016       (*Drule.standard can take quite a while for large records, thats why
  1016 fun prove_common immediate stndrd thy asms prop tac =
  1017         we varify the proposition manually here.*)
  1017   let val prv = if !quick_and_dirty then Skip_Proof.prove 
  1018   else
  1018                 else if immediate then Goal.prove else Goal.prove_future;
  1019     let val prf = Goal.prove (ProofContext.init thy) [] asms prop tac
  1019       val prf = prv (ProofContext.init thy) [] asms prop tac
  1020     in if stndrd then Drule.standard prf else prf end;
  1020   in if stndrd then Drule.standard prf else prf end;
  1021 
  1021 
  1022 fun quick_and_dirty_prf noopt opt () =
  1022 val prove_future_global = prove_common false;
  1023   if ! quick_and_dirty then noopt () else opt ();
  1023 val prove_global = prove_common true;
  1024 
  1024 
  1025 fun is_sel_upd_pair thy (Const (s, _)) (Const (u, t')) =
  1025 fun is_sel_upd_pair thy (Const (s, _)) (Const (u, t')) =
  1026   (case get_updates thy u of
  1026   (case get_updates thy u of
  1027     SOME u_name => u_name = s
  1027     SOME u_name => u_name = s
  1028   | NONE => raise TERM ("is_sel_upd_pair: not update", [Const (u, t')]));
  1028   | NONE => raise TERM ("is_sel_upd_pair: not update", [Const (u, t')]));
  1398 val record_ex_sel_eq_simproc =
  1398 val record_ex_sel_eq_simproc =
  1399   Simplifier.simproc @{theory HOL} "record_ex_sel_eq_simproc" ["Ex t"]
  1399   Simplifier.simproc @{theory HOL} "record_ex_sel_eq_simproc" ["Ex t"]
  1400     (fn thy => fn ss => fn t =>
  1400     (fn thy => fn ss => fn t =>
  1401       let
  1401       let
  1402         fun prove prop =
  1402         fun prove prop =
  1403           quick_and_dirty_prove true thy [] prop
  1403           prove_global true thy [] prop
  1404             (fn _ => simp_tac (Simplifier.inherit_context ss (get_simpset thy)
  1404             (fn _ => simp_tac (Simplifier.inherit_context ss (get_simpset thy)
  1405                 addsimps simp_thms addsimprocs [record_split_simproc (K ~1)]) 1);
  1405                 addsimps simp_thms addsimprocs [record_split_simproc (K ~1)]) 1);
  1406 
  1406 
  1407         fun mkeq (lr, Teq, (sel, Tsel), x) i =
  1407         fun mkeq (lr, Teq, (sel, Tsel), x) i =
  1408           if is_selector thy sel then
  1408           if is_selector thy sel then
  1663 
  1663 
  1664     fun mk_defs () =
  1664     fun mk_defs () =
  1665       typ_thy
  1665       typ_thy
  1666       |> Sign.add_consts_i [Syntax.no_syn (apfst (Binding.name o base) ext_decl)]
  1666       |> Sign.add_consts_i [Syntax.no_syn (apfst (Binding.name o base) ext_decl)]
  1667       |> PureThy.add_defs false [Thm.no_attributes (apfst Binding.name ext_spec)]
  1667       |> PureThy.add_defs false [Thm.no_attributes (apfst Binding.name ext_spec)]
       
  1668       ||> Theory.checkpoint
  1668     val ([ext_def], defs_thy) =
  1669     val ([ext_def], defs_thy) =
  1669       timeit_msg "record extension constructor def:" mk_defs;
  1670       timeit_msg "record extension constructor def:" mk_defs;
  1670 
  1671 
  1671 
  1672 
  1672     (* prepare propositions *)
  1673     (* prepare propositions *)
  1694       let val P = Free (Name.variant variants "P", extT --> Term.propT) in
  1695       let val P = Free (Name.variant variants "P", extT --> Term.propT) in
  1695         Logic.mk_equals
  1696         Logic.mk_equals
  1696          (All [dest_Free s] (P $ s), All (map dest_Free vars_more) (P $ ext))
  1697          (All [dest_Free s] (P $ s), All (map dest_Free vars_more) (P $ ext))
  1697       end;
  1698       end;
  1698 
  1699 
  1699     val prove_standard = quick_and_dirty_prove true defs_thy;
  1700     val prove_standard = prove_future_global true defs_thy;
  1700 
  1701 
  1701     fun inject_prf () =
  1702     fun inject_prf () =
  1702       simplify HOL_ss
  1703       simplify HOL_ss
  1703         (prove_standard [] inject_prop
  1704         (prove_standard [] inject_prop
  1704           (fn _ =>
  1705           (fn _ =>
  2043         (fn defs as ((sel_defs, upd_defs), derived_defs) =>
  2044         (fn defs as ((sel_defs, upd_defs), derived_defs) =>
  2044           fold Code.add_default_eqn sel_defs
  2045           fold Code.add_default_eqn sel_defs
  2045           #> fold Code.add_default_eqn upd_defs
  2046           #> fold Code.add_default_eqn upd_defs
  2046           #> fold Code.add_default_eqn derived_defs
  2047           #> fold Code.add_default_eqn derived_defs
  2047           #> pair defs)
  2048           #> pair defs)
       
  2049       ||> Theory.checkpoint
  2048     val (((sel_defs, upd_defs), derived_defs), defs_thy) =
  2050     val (((sel_defs, upd_defs), derived_defs), defs_thy) =
  2049       timeit_msg "record trfuns/tyabbrs/selectors/updates/make/fields/extend/truncate defs:"
  2051       timeit_msg "record trfuns/tyabbrs/selectors/updates/make/fields/extend/truncate defs:"
  2050         mk_defs;
  2052         mk_defs;
  2051 
  2053 
  2052     (* prepare propositions *)
  2054     (* prepare propositions *)
  2113       in All (map dest_Free [r0, s']) (Logic.list_implies (seleqs, r0 === s')) end;
  2115       in All (map dest_Free [r0, s']) (Logic.list_implies (seleqs, r0 === s')) end;
  2114 
  2116 
  2115 
  2117 
  2116     (* 3rd stage: thms_thy *)
  2118     (* 3rd stage: thms_thy *)
  2117 
  2119 
  2118     fun prove stndrd = quick_and_dirty_prove stndrd defs_thy;
  2120     fun prove stndrd = prove_future_global stndrd defs_thy;
  2119     val prove_standard = quick_and_dirty_prove true defs_thy;
  2121     val prove_standard = prove_future_global true defs_thy;
       
  2122     val future_forward_prf = future_forward_prf_standard defs_thy;
  2120 
  2123 
  2121     fun prove_simp stndrd ss simps =
  2124     fun prove_simp stndrd ss simps =
  2122       let val tac = simp_all_tac ss simps
  2125       let val tac = simp_all_tac ss simps
  2123       in fn prop => prove stndrd [] prop (K tac) end;
  2126       in fn prop => prove stndrd [] prop (K tac) end;
  2124 
  2127 
  2165           THEN try_param_tac "more" @{thm unit.induct} 1
  2168           THEN try_param_tac "more" @{thm unit.induct} 1
  2166           THEN resolve_tac prems 1)
  2169           THEN resolve_tac prems 1)
  2167       end;
  2170       end;
  2168     val induct = timeit_msg "record induct proof:" induct_prf;
  2171     val induct = timeit_msg "record induct proof:" induct_prf;
  2169 
  2172 
  2170     fun cases_scheme_prf_opt () =
  2173     fun cases_scheme_prf () =
  2171       let
  2174       let
  2172         val _ $ (Pvar $ _) = concl_of induct_scheme;
  2175         val _ $ (Pvar $ _) = concl_of induct_scheme;
  2173         val ind =
  2176         val ind =
  2174           cterm_instantiate
  2177           cterm_instantiate
  2175             [(cterm_of defs_thy Pvar, cterm_of defs_thy
  2178             [(cterm_of defs_thy Pvar, cterm_of defs_thy
  2176               (lambda w (HOLogic.imp $ HOLogic.mk_eq (r0, w) $ C)))]
  2179               (lambda w (HOLogic.imp $ HOLogic.mk_eq (r0, w) $ C)))]
  2177             induct_scheme;
  2180             induct_scheme;
  2178         in Drule.standard (ObjectLogic.rulify (mp OF [ind, refl])) end;
  2181         in ObjectLogic.rulify (mp OF [ind, refl]) end;
  2179 
  2182 
  2180     fun cases_scheme_prf_noopt () =
  2183     val cases_scheme_prf = future_forward_prf cases_scheme_prf cases_scheme_prop;
  2181       prove_standard [] cases_scheme_prop
       
  2182         (fn _ =>
       
  2183           EVERY1
       
  2184            [asm_full_simp_tac (HOL_basic_ss addsimps [atomize_all, atomize_imp]),
       
  2185             try_param_tac rN induct_scheme,
       
  2186             rtac impI,
       
  2187             REPEAT o etac allE,
       
  2188             etac mp,
       
  2189             rtac refl]);
       
  2190     val cases_scheme_prf = quick_and_dirty_prf cases_scheme_prf_noopt cases_scheme_prf_opt;
       
  2191     val cases_scheme = timeit_msg "record cases_scheme proof:" cases_scheme_prf;
  2184     val cases_scheme = timeit_msg "record cases_scheme proof:" cases_scheme_prf;
  2192 
  2185 
  2193     fun cases_prf () =
  2186     fun cases_prf () =
  2194       prove_standard [] cases_prop
  2187       prove_standard [] cases_prop
  2195         (fn _ =>
  2188         (fn _ =>
  2224     val split_meta = timeit_msg "record split_meta proof:" split_meta_prf;
  2217     val split_meta = timeit_msg "record split_meta proof:" split_meta_prf;
  2225     fun split_meta_standardise () = Drule.standard split_meta;
  2218     fun split_meta_standardise () = Drule.standard split_meta;
  2226     val split_meta_standard =
  2219     val split_meta_standard =
  2227       timeit_msg "record split_meta standard:" split_meta_standardise;
  2220       timeit_msg "record split_meta standard:" split_meta_standardise;
  2228 
  2221 
  2229     fun split_object_prf_opt () =
  2222     fun split_object_prf () =
  2230       let
  2223       let
  2231         val cPI= cterm_of defs_thy (lambda r0 (Trueprop (P $ r0)));
  2224         val cPI= cterm_of defs_thy (lambda r0 (Trueprop (P $ r0)));
  2232         val _ $ Abs (_, _, P $ _) = fst (Logic.dest_equals (concl_of split_meta_standard));
  2225         val _ $ Abs (_, _, P $ _) = fst (Logic.dest_equals (concl_of split_meta_standard));
  2233         val cP = cterm_of defs_thy P;
  2226         val cP = cterm_of defs_thy P;
  2234         val split_meta' = cterm_instantiate [(cP, cPI)] split_meta_standard;
  2227         val split_meta' = cterm_instantiate [(cP, cPI)] split_meta_standard;
  2245           assume cr                             (*All n m more. P (ext n m more)*)
  2238           assume cr                             (*All n m more. P (ext n m more)*)
  2246           |> obj_to_meta_all                    (*!!n m more. P (ext n m more)*)
  2239           |> obj_to_meta_all                    (*!!n m more. P (ext n m more)*)
  2247           |> equal_elim (symmetric split_meta') (*!!r. P r*)
  2240           |> equal_elim (symmetric split_meta') (*!!r. P r*)
  2248           |> meta_to_obj_all                    (*All r. P r*)
  2241           |> meta_to_obj_all                    (*All r. P r*)
  2249           |> implies_intr cr                    (* 2 ==> 1 *)
  2242           |> implies_intr cr                    (* 2 ==> 1 *)
  2250      in Drule.standard (thr COMP (thl COMP iffI)) end;
  2243      in thr COMP (thl COMP iffI) end;
  2251 
  2244 
  2252     fun split_object_prf_noopt () =
  2245 
  2253       prove_standard [] split_object_prop
  2246     val split_object_prf = future_forward_prf split_object_prf split_object_prop;
  2254         (fn _ =>
       
  2255           EVERY1
       
  2256            [rtac iffI,
       
  2257             REPEAT o rtac allI, etac allE, atac,
       
  2258             rtac allI, rtac induct_scheme, REPEAT o etac allE, atac]);
       
  2259 
       
  2260     val split_object_prf = quick_and_dirty_prf split_object_prf_noopt split_object_prf_opt;
       
  2261     val split_object = timeit_msg "record split_object proof:" split_object_prf;
  2247     val split_object = timeit_msg "record split_object proof:" split_object_prf;
  2262 
  2248 
  2263 
  2249 
  2264     fun split_ex_prf () =
  2250     fun split_ex_prf () =
  2265       let
  2251       let