src/HOL/Tools/record.ML
changeset 74599 eceb93181ad9
parent 74595 71bafd70acbb
child 74610 87fc10f5826c
equal deleted inserted replaced
74598:5d91897a8e54 74599:eceb93181ad9
   105         (Typedef.add_typedef overloaded (raw_tyco, vs, NoSyn)
   105         (Typedef.add_typedef overloaded (raw_tyco, vs, NoSyn)
   106           (HOLogic.mk_UNIV repT) NONE (fn ctxt' => resolve_tac ctxt' [UNIV_witness] 1))
   106           (HOLogic.mk_UNIV repT) NONE (fn ctxt' => resolve_tac ctxt' [UNIV_witness] 1))
   107     |-> (fn (tyco, info) => get_typedef_info tyco vs info)
   107     |-> (fn (tyco, info) => get_typedef_info tyco vs info)
   108   end;
   108   end;
   109 
   109 
   110 fun mk_cons_tuple (left, right) =
   110 fun mk_cons_tuple (t, u) =
   111   let
   111   let val (A, B) = apply2 fastype_of (t, u)
   112     val (leftT, rightT) = (fastype_of left, fastype_of right);
   112   in \<^Const>\<open>iso_tuple_cons \<^Type>\<open>prod A B\<close> A B for \<^Const>\<open>tuple_iso_tuple A B\<close> t u\<close> end;
   113     val prodT = HOLogic.mk_prodT (leftT, rightT);
   113 
   114     val isomT = Type (\<^type_name>\<open>tuple_isomorphism\<close>, [prodT, leftT, rightT]);
   114 fun dest_cons_tuple \<^Const_>\<open>iso_tuple_cons _ _ _ for \<open>Const _\<close> t u\<close> = (t, u)
   115   in
       
   116     Const (\<^const_name>\<open>Record.iso_tuple_cons\<close>, isomT --> leftT --> rightT --> prodT) $
       
   117       Const (fst tuple_iso_tuple, isomT) $ left $ right
       
   118   end;
       
   119 
       
   120 fun dest_cons_tuple (Const (\<^const_name>\<open>Record.iso_tuple_cons\<close>, _) $ Const _ $ t $ u) = (t, u)
       
   121   | dest_cons_tuple t = raise TERM ("dest_cons_tuple", [t]);
   115   | dest_cons_tuple t = raise TERM ("dest_cons_tuple", [t]);
   122 
   116 
   123 fun add_iso_tuple_type overloaded (b, alphas) (leftT, rightT) thy =
   117 fun add_iso_tuple_type overloaded (b, alphas) (leftT, rightT) thy =
   124   let
   118   let
   125     val repT = HOLogic.mk_prodT (leftT, rightT);
   119     val repT = HOLogic.mk_prodT (leftT, rightT);
   147       |> Sign.declare_const_global ((isom_binding, isomT), NoSyn) |> snd
   141       |> Sign.declare_const_global ((isom_binding, isomT), NoSyn) |> snd
   148       |> Global_Theory.add_defs false
   142       |> Global_Theory.add_defs false
   149         [((Binding.concealed (Thm.def_binding isom_binding), Logic.mk_equals (isom, body)), [])];
   143         [((Binding.concealed (Thm.def_binding isom_binding), Logic.mk_equals (isom, body)), [])];
   150 
   144 
   151     val iso_tuple = isom_def RS (abs_inverse RS (rep_inject RS iso_tuple_intro));
   145     val iso_tuple = isom_def RS (abs_inverse RS (rep_inject RS iso_tuple_intro));
   152     val cons = Const (\<^const_name>\<open>Record.iso_tuple_cons\<close>, isomT --> leftT --> rightT --> absT);
   146     val cons = \<^Const>\<open>iso_tuple_cons absT leftT rightT\<close>;
   153 
   147 
   154     val thm_thy =
   148     val thm_thy =
   155       cdef_thy
   149       cdef_thy
   156       |> Iso_Tuple_Thms.map (Symtab.insert Thm.eq_thm_prop (isom_name, iso_tuple))
   150       |> Iso_Tuple_Thms.map (Symtab.insert Thm.eq_thm_prop (isom_name, iso_tuple))
   157       |> Sign.restore_naming thy
   151       |> Sign.restore_naming thy
   169       fun err s t = raise TERM ("iso_tuple_intros_tac: " ^ s, [t]);
   163       fun err s t = raise TERM ("iso_tuple_intros_tac: " ^ s, [t]);
   170 
   164 
   171       val goal' = Envir.beta_eta_contract goal;
   165       val goal' = Envir.beta_eta_contract goal;
   172       val is =
   166       val is =
   173         (case goal' of
   167         (case goal' of
   174           Const (\<^const_name>\<open>Trueprop\<close>, _) $
   168           \<^Const_>\<open>Trueprop for \<^Const>\<open>isomorphic_tuple _ _ _ for \<open>Const is\<close>\<close>\<close> => is
   175             (Const (\<^const_name>\<open>isomorphic_tuple\<close>, _) $ Const is) => is
       
   176         | _ => err "unexpected goal format" goal');
   169         | _ => err "unexpected goal format" goal');
   177       val isthm =
   170       val isthm =
   178         (case Symtab.lookup isthms (#1 is) of
   171         (case Symtab.lookup isthms (#1 is) of
   179           SOME isthm => isthm
   172           SOME isthm => isthm
   180         | NONE => err "no thm found for constant" (Const is));
   173         | NONE => err "no thm found for constant" (Const is));
   935     SOME u_name => u_name = s
   928     SOME u_name => u_name = s
   936   | NONE => raise TERM ("is_sel_upd_pair: not update", [Const (u, t')]));
   929   | NONE => raise TERM ("is_sel_upd_pair: not update", [Const (u, t')]));
   937 
   930 
   938 fun mk_comp_id f =
   931 fun mk_comp_id f =
   939   let val T = range_type (fastype_of f)
   932   let val T = range_type (fastype_of f)
   940   in HOLogic.mk_comp (Const (\<^const_name>\<open>Fun.id\<close>, T --> T), f) end;
   933   in HOLogic.mk_comp (\<^Const>\<open>id T\<close>, f) end;
   941 
   934 
   942 fun get_upd_funs (upd $ _ $ t) = upd :: get_upd_funs t
   935 fun get_upd_funs (upd $ _ $ t) = upd :: get_upd_funs t
   943   | get_upd_funs _ = [];
   936   | get_upd_funs _ = [];
   944 
   937 
   945 fun get_accupd_simps ctxt term defset =
   938 fun get_accupd_simps ctxt term defset =
  1270 val eq_simproc =
  1263 val eq_simproc =
  1271   Simplifier.make_simproc \<^context> "record_eq"
  1264   Simplifier.make_simproc \<^context> "record_eq"
  1272    {lhss = [\<^term>\<open>r = s\<close>],
  1265    {lhss = [\<^term>\<open>r = s\<close>],
  1273     proc = fn _ => fn ctxt => fn ct =>
  1266     proc = fn _ => fn ctxt => fn ct =>
  1274       (case Thm.term_of ct of
  1267       (case Thm.term_of ct of
  1275         Const (\<^const_name>\<open>HOL.eq\<close>, Type (_, [T, _])) $ _ $ _ =>
  1268         \<^Const_>\<open>HOL.eq T for _ _\<close> =>
  1276           (case rec_id ~1 T of
  1269           (case rec_id ~1 T of
  1277             "" => NONE
  1270             "" => NONE
  1278           | name =>
  1271           | name =>
  1279               (case get_equalities (Proof_Context.theory_of ctxt) name of
  1272               (case get_equalities (Proof_Context.theory_of ctxt) name of
  1280                 NONE => NONE
  1273                 NONE => NONE
  1323    {lhss = [\<^term>\<open>Ex t\<close>],
  1316    {lhss = [\<^term>\<open>Ex t\<close>],
  1324     proc = fn _ => fn ctxt => fn ct =>
  1317     proc = fn _ => fn ctxt => fn ct =>
  1325       let
  1318       let
  1326         val thy = Proof_Context.theory_of ctxt;
  1319         val thy = Proof_Context.theory_of ctxt;
  1327         val t = Thm.term_of ct;
  1320         val t = Thm.term_of ct;
  1328         fun mkeq (lr, Teq, (sel, Tsel), x) i =
  1321         fun mkeq (lr, T, (sel, Tsel), x) i =
  1329           if is_selector thy sel then
  1322           if is_selector thy sel then
  1330             let
  1323             let
  1331               val x' =
  1324               val x' =
  1332                 if not (Term.is_dependent x)
  1325                 if not (Term.is_dependent x)
  1333                 then Free ("x" ^ string_of_int i, range_type Tsel)
  1326                 then Free ("x" ^ string_of_int i, range_type Tsel)
  1334                 else raise TERM ("", [x]);
  1327                 else raise TERM ("", [x]);
  1335               val sel' = Const (sel, Tsel) $ Bound 0;
  1328               val sel' = Const (sel, Tsel) $ Bound 0;
  1336               val (l, r) = if lr then (sel', x') else (x', sel');
  1329               val (l, r) = if lr then (sel', x') else (x', sel');
  1337             in Const (\<^const_name>\<open>HOL.eq\<close>, Teq) $ l $ r end
  1330             in \<^Const>\<open>HOL.eq T for l r\<close> end
  1338           else raise TERM ("", [Const (sel, Tsel)]);
  1331           else raise TERM ("", [Const (sel, Tsel)]);
  1339 
  1332 
  1340         fun dest_sel_eq (Const (\<^const_name>\<open>HOL.eq\<close>, Teq) $ (Const (sel, Tsel) $ Bound 0) $ X) =
  1333         fun dest_sel_eq (\<^Const_>\<open>HOL.eq T\<close> $ (Const (sel, Tsel) $ Bound 0) $ X) =
  1341               (true, Teq, (sel, Tsel), X)
  1334               (true, T, (sel, Tsel), X)
  1342           | dest_sel_eq (Const (\<^const_name>\<open>HOL.eq\<close>, Teq) $ X $ (Const (sel, Tsel) $ Bound 0)) =
  1335           | dest_sel_eq (\<^Const_>\<open>HOL.eq T\<close> $ X $ (Const (sel, Tsel) $ Bound 0)) =
  1343               (false, Teq, (sel, Tsel), X)
  1336               (false, T, (sel, Tsel), X)
  1344           | dest_sel_eq _ = raise TERM ("", []);
  1337           | dest_sel_eq _ = raise TERM ("", []);
  1345       in
  1338       in
  1346         (case t of
  1339         (case t of
  1347           Const (\<^const_name>\<open>Ex\<close>, Tex) $ Abs (s, T, t) =>
  1340           \<^Const_>\<open>Ex T for \<open>Abs (s, _, t)\<close>\<close> =>
  1348            (let
  1341            (let
  1349              val eq = mkeq (dest_sel_eq t) 0;
  1342              val eq = mkeq (dest_sel_eq t) 0;
  1350              val prop =
  1343              val prop =
  1351                Logic.list_all ([("r", T)],
  1344                Logic.list_all ([("r", T)],
  1352                  Logic.mk_equals
  1345                  Logic.mk_equals (\<^Const>\<open>Ex T for \<open>Abs (s, T, eq)\<close>\<close>, \<^Const>\<open>True\<close>));
  1353                   (Const (\<^const_name>\<open>Ex\<close>, Tex) $ Abs (s, T, eq), \<^term>\<open>True\<close>));
       
  1354             in
  1346             in
  1355               SOME (Goal.prove_sorry_global thy [] [] prop
  1347               SOME (Goal.prove_sorry_global thy [] [] prop
  1356                 (fn {context = ctxt', ...} =>
  1348                 (fn {context = ctxt', ...} =>
  1357                   simp_tac (put_simpset (get_simpset thy) ctxt'
  1349                   simp_tac (put_simpset (get_simpset thy) ctxt'
  1358                     addsimps @{thms simp_thms} addsimprocs [split_simproc (K ~1)]) 1))
  1350                     addsimps @{thms simp_thms} addsimprocs [split_simproc (K ~1)]) 1))
  1711     val size = \<^term>\<open>i::natural\<close>;
  1703     val size = \<^term>\<open>i::natural\<close>;
  1712     fun termifyT T = HOLogic.mk_prodT (T, \<^typ>\<open>unit \<Rightarrow> term\<close>);
  1704     fun termifyT T = HOLogic.mk_prodT (T, \<^typ>\<open>unit \<Rightarrow> term\<close>);
  1713     val T = Type (tyco, map TFree vs);
  1705     val T = Type (tyco, map TFree vs);
  1714     val test_function = Free ("f", termifyT T --> \<^typ>\<open>(bool \<times> term list) option\<close>);
  1706     val test_function = Free ("f", termifyT T --> \<^typ>\<open>(bool \<times> term list) option\<close>);
  1715     val params = Name.invent_names Name.context "x" Ts;
  1707     val params = Name.invent_names Name.context "x" Ts;
  1716     fun full_exhaustiveT T =
  1708     fun mk_full_exhaustive U = \<^Const>\<open>full_exhaustive_class.full_exhaustive U\<close>;
  1717       (termifyT T --> \<^typ>\<open>(bool \<times> Code_Evaluation.term list) option\<close>) -->
       
  1718         \<^typ>\<open>natural\<close> --> \<^typ>\<open>(bool \<times> Code_Evaluation.term list) option\<close>;
       
  1719     fun mk_full_exhaustive T =
       
  1720       Const (\<^const_name>\<open>Quickcheck_Exhaustive.full_exhaustive_class.full_exhaustive\<close>,
       
  1721         full_exhaustiveT T);
       
  1722     val lhs = mk_full_exhaustive T $ test_function $ size;
  1709     val lhs = mk_full_exhaustive T $ test_function $ size;
  1723     val tc = test_function $ (HOLogic.mk_valtermify_app extN params T);
  1710     val tc = test_function $ (HOLogic.mk_valtermify_app extN params T);
  1724     val rhs = fold_rev (fn (v, T) => fn cont =>
  1711     val rhs = fold_rev (fn (v, U) => fn cont =>
  1725         mk_full_exhaustive T $ (lambda (Free (v, termifyT T)) cont) $ size) params tc;
  1712         mk_full_exhaustive U $ (lambda (Free (v, termifyT U)) cont) $ size) params tc;
  1726   in
  1713   in
  1727     (lhs, rhs)
  1714     (lhs, rhs)
  1728   end;
  1715   end;
  1729 
  1716 
  1730 fun instantiate_sort_record (sort, mk_eq) tyco vs extN Ts thy =
  1717 fun instantiate_sort_record (sort, mk_eq) tyco vs extN Ts thy =
  1754   end;
  1741   end;
  1755 
  1742 
  1756 fun add_code ext_tyco vs extT ext simps inject thy =
  1743 fun add_code ext_tyco vs extT ext simps inject thy =
  1757   if Config.get_global thy codegen then
  1744   if Config.get_global thy codegen then
  1758     let
  1745     let
  1759       val eq =
  1746       val eq = HOLogic.mk_Trueprop (HOLogic.mk_eq (\<^Const>\<open>HOL.equal extT\<close>, \<^Const>\<open>HOL.eq extT\<close>));
  1760         HOLogic.mk_Trueprop (HOLogic.mk_eq
       
  1761           (Const (\<^const_name>\<open>HOL.equal\<close>, extT --> extT --> HOLogic.boolT),
       
  1762            Const (\<^const_name>\<open>HOL.eq\<close>, extT --> extT --> HOLogic.boolT)));
       
  1763       fun tac ctxt eq_def =
  1747       fun tac ctxt eq_def =
  1764         Class.intro_classes_tac ctxt []
  1748         Class.intro_classes_tac ctxt []
  1765         THEN rewrite_goals_tac ctxt [Simpdata.mk_eq eq_def]
  1749         THEN rewrite_goals_tac ctxt [Simpdata.mk_eq eq_def]
  1766         THEN ALLGOALS (resolve_tac ctxt @{thms refl});
  1750         THEN ALLGOALS (resolve_tac ctxt @{thms refl});
  1767       fun mk_eq ctxt eq_def =
  1751       fun mk_eq ctxt eq_def =