src/HOL/Tools/Nitpick/nitpick_hol.ML
changeset 69597 ff784d5a5bfb
parent 69593 3dda49e08b9d
child 69991 6b097aeb3650
equal deleted inserted replaced
69596:c8a2755bf220 69597:ff784d5a5bfb
   329   if String.isPrefix nitpick_prefix s then
   329   if String.isPrefix nitpick_prefix s then
   330     case strip_first_name_sep s of (s1, "") => s1 | (_, s2) => original_name s2
   330     case strip_first_name_sep s of (s1, "") => s1 | (_, s2) => original_name s2
   331   else
   331   else
   332     s
   332     s
   333 
   333 
   334 fun s_conj (t1, @{const True}) = t1
   334 fun s_conj (t1, \<^const>\<open>True\<close>) = t1
   335   | s_conj (@{const True}, t2) = t2
   335   | s_conj (\<^const>\<open>True\<close>, t2) = t2
   336   | s_conj (t1, t2) =
   336   | s_conj (t1, t2) =
   337     if t1 = @{const False} orelse t2 = @{const False} then @{const False}
   337     if t1 = \<^const>\<open>False\<close> orelse t2 = \<^const>\<open>False\<close> then \<^const>\<open>False\<close>
   338     else HOLogic.mk_conj (t1, t2)
   338     else HOLogic.mk_conj (t1, t2)
   339 
   339 
   340 fun s_disj (t1, @{const False}) = t1
   340 fun s_disj (t1, \<^const>\<open>False\<close>) = t1
   341   | s_disj (@{const False}, t2) = t2
   341   | s_disj (\<^const>\<open>False\<close>, t2) = t2
   342   | s_disj (t1, t2) =
   342   | s_disj (t1, t2) =
   343     if t1 = @{const True} orelse t2 = @{const True} then @{const True}
   343     if t1 = \<^const>\<open>True\<close> orelse t2 = \<^const>\<open>True\<close> then \<^const>\<open>True\<close>
   344     else HOLogic.mk_disj (t1, t2)
   344     else HOLogic.mk_disj (t1, t2)
   345 
   345 
   346 fun strip_connective conn_t (t as (t0 $ t1 $ t2)) =
   346 fun strip_connective conn_t (t as (t0 $ t1 $ t2)) =
   347     if t0 = conn_t then strip_connective t0 t2 @ strip_connective t0 t1 else [t]
   347     if t0 = conn_t then strip_connective t0 t2 @ strip_connective t0 t1 else [t]
   348   | strip_connective _ t = [t]
   348   | strip_connective _ t = [t]
   349 
   349 
   350 fun strip_any_connective (t as (t0 $ _ $ _)) =
   350 fun strip_any_connective (t as (t0 $ _ $ _)) =
   351     if t0 = @{const HOL.conj} orelse t0 = @{const HOL.disj} then
   351     if t0 = \<^const>\<open>HOL.conj\<close> orelse t0 = \<^const>\<open>HOL.disj\<close> then
   352       (strip_connective t0 t, t0)
   352       (strip_connective t0 t, t0)
   353     else
   353     else
   354       ([t], @{const Not})
   354       ([t], \<^const>\<open>Not\<close>)
   355   | strip_any_connective t = ([t], @{const Not})
   355   | strip_any_connective t = ([t], \<^const>\<open>Not\<close>)
   356 val conjuncts_of = strip_connective @{const HOL.conj}
   356 val conjuncts_of = strip_connective \<^const>\<open>HOL.conj\<close>
   357 val disjuncts_of = strip_connective @{const HOL.disj}
   357 val disjuncts_of = strip_connective \<^const>\<open>HOL.disj\<close>
   358 
   358 
   359 (* When you add constants to these lists, make sure to handle them in
   359 (* When you add constants to these lists, make sure to handle them in
   360    "Nitpick_Nut.nut_from_term", and perhaps in "Nitpick_Mono.consider_term" as
   360    "Nitpick_Nut.nut_from_term", and perhaps in "Nitpick_Mono.consider_term" as
   361    well. *)
   361    well. *)
   362 val built_in_consts =
   362 val built_in_consts =
   795     let
   795     let
   796       val {qtyp, equiv_rel, equiv_thm, ...} =
   796       val {qtyp, equiv_rel, equiv_thm, ...} =
   797         the (Quotient_Info.lookup_quotients thy s)
   797         the (Quotient_Info.lookup_quotients thy s)
   798       val partial =
   798       val partial =
   799         case Thm.prop_of equiv_thm of
   799         case Thm.prop_of equiv_thm of
   800           @{const Trueprop} $ (Const (\<^const_name>\<open>equivp\<close>, _) $ _) => false
   800           \<^const>\<open>Trueprop\<close> $ (Const (\<^const_name>\<open>equivp\<close>, _) $ _) => false
   801         | @{const Trueprop} $ (Const (\<^const_name>\<open>part_equivp\<close>, _) $ _) => true
   801         | \<^const>\<open>Trueprop\<close> $ (Const (\<^const_name>\<open>part_equivp\<close>, _) $ _) => true
   802         | _ => raise NOT_SUPPORTED "Ill-formed quotient type equivalence \
   802         | _ => raise NOT_SUPPORTED "Ill-formed quotient type equivalence \
   803                                    \relation theorem"
   803                                    \relation theorem"
   804       val Ts' = qtyp |> dest_Type |> snd
   804       val Ts' = qtyp |> dest_Type |> snd
   805     in (subst_atomic_types (Ts' ~~ Ts) equiv_rel, partial) end
   805     in (subst_atomic_types (Ts' ~~ Ts) equiv_rel, partial) end
   806   | equiv_relation_for_quot_type _ T =
   806   | equiv_relation_for_quot_type _ T =
   946   let
   946   let
   947     fun close_up zs zs' =
   947     fun close_up zs zs' =
   948       fold (fn (z as ((s, _), T)) => fn t' =>
   948       fold (fn (z as ((s, _), T)) => fn t' =>
   949                Logic.all_const T $ Abs (s, T, abstract_over (Var z, t')))
   949                Logic.all_const T $ Abs (s, T, abstract_over (Var z, t')))
   950            (take (length zs' - length zs) zs')
   950            (take (length zs' - length zs) zs')
   951     fun aux zs (@{const Pure.imp} $ t1 $ t2) =
   951     fun aux zs (\<^const>\<open>Pure.imp\<close> $ t1 $ t2) =
   952         let val zs' = Term.add_vars t1 zs in
   952         let val zs' = Term.add_vars t1 zs in
   953           close_up zs zs' (Logic.mk_implies (t1, aux zs' t2))
   953           close_up zs zs' (Logic.mk_implies (t1, aux zs' t2))
   954         end
   954         end
   955       | aux zs t = close_up zs (Term.add_vars t zs) t
   955       | aux zs t = close_up zs (Term.add_vars t zs) t
   956   in aux [] end
   956   in aux [] end
   957 
   957 
   958 fun distinctness_formula T =
   958 fun distinctness_formula T =
   959   all_distinct_unordered_pairs_of
   959   all_distinct_unordered_pairs_of
   960   #> map (fn (t1, t2) => @{const Not} $ (HOLogic.eq_const T $ t1 $ t2))
   960   #> map (fn (t1, t2) => \<^const>\<open>Not\<close> $ (HOLogic.eq_const T $ t1 $ t2))
   961   #> List.foldr (s_conj o swap) @{const True}
   961   #> List.foldr (s_conj o swap) \<^const>\<open>True\<close>
   962 
   962 
   963 fun zero_const T = Const (\<^const_name>\<open>zero_class.zero\<close>, T)
   963 fun zero_const T = Const (\<^const_name>\<open>zero_class.zero\<close>, T)
   964 fun suc_const T = Const (\<^const_name>\<open>Suc\<close>, T --> T)
   964 fun suc_const T = Const (\<^const_name>\<open>Suc\<close>, T --> T)
   965 
   965 
   966 fun uncached_data_type_constrs ({ctxt, ...} : hol_context) (T as Type (s, _)) =
   966 fun uncached_data_type_constrs ({ctxt, ...} : hol_context) (T as Type (s, _)) =
   984                [(\<^const_name>\<open>Quot\<close>, rep_type_for_quot_type ctxt T --> T)]
   984                [(\<^const_name>\<open>Quot\<close>, rep_type_for_quot_type ctxt T --> T)]
   985              else case typedef_info ctxt s of
   985              else case typedef_info ctxt s of
   986                SOME {abs_type, rep_type, Abs_name, ...} =>
   986                SOME {abs_type, rep_type, Abs_name, ...} =>
   987                [(Abs_name, varify_and_instantiate_type ctxt abs_type T rep_type --> T)]
   987                [(Abs_name, varify_and_instantiate_type ctxt abs_type T rep_type --> T)]
   988              | NONE =>
   988              | NONE =>
   989                if T = \<^typ>\<open>ind\<close> then [dest_Const @{const Zero_Rep}, dest_Const @{const Suc_Rep}]
   989                if T = \<^typ>\<open>ind\<close> then [dest_Const \<^const>\<open>Zero_Rep\<close>, dest_Const \<^const>\<open>Suc_Rep\<close>]
   990                else [])
   990                else [])
   991   | uncached_data_type_constrs _ _ = []
   991   | uncached_data_type_constrs _ _ = []
   992 
   992 
   993 fun data_type_constrs (hol_ctxt as {constr_cache, ...}) T =
   993 fun data_type_constrs (hol_ctxt as {constr_cache, ...}) T =
   994   case AList.lookup (op =) (!constr_cache) T of
   994   case AList.lookup (op =) (!constr_cache) T of
  1143 
  1143 
  1144 fun s_betapply _ (t1 as Const (\<^const_name>\<open>Pure.eq\<close>, _) $ t1', t2) =
  1144 fun s_betapply _ (t1 as Const (\<^const_name>\<open>Pure.eq\<close>, _) $ t1', t2) =
  1145     if t1' aconv t2 then \<^prop>\<open>True\<close> else t1 $ t2
  1145     if t1' aconv t2 then \<^prop>\<open>True\<close> else t1 $ t2
  1146   | s_betapply _ (t1 as Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t1', t2) =
  1146   | s_betapply _ (t1 as Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t1', t2) =
  1147     if t1' aconv t2 then \<^term>\<open>True\<close> else t1 $ t2
  1147     if t1' aconv t2 then \<^term>\<open>True\<close> else t1 $ t2
  1148   | s_betapply _ (Const (\<^const_name>\<open>If\<close>, _) $ @{const True} $ t1', _) = t1'
  1148   | s_betapply _ (Const (\<^const_name>\<open>If\<close>, _) $ \<^const>\<open>True\<close> $ t1', _) = t1'
  1149   | s_betapply _ (Const (\<^const_name>\<open>If\<close>, _) $ @{const False} $ _, t2) = t2
  1149   | s_betapply _ (Const (\<^const_name>\<open>If\<close>, _) $ \<^const>\<open>False\<close> $ _, t2) = t2
  1150   | s_betapply Ts (Const (\<^const_name>\<open>Let\<close>,
  1150   | s_betapply Ts (Const (\<^const_name>\<open>Let\<close>,
  1151                           Type (_, [bound_T, Type (_, [_, body_T])]))
  1151                           Type (_, [bound_T, Type (_, [_, body_T])]))
  1152                    $ t12 $ Abs (s, T, t13'), t2) =
  1152                    $ t12 $ Abs (s, T, t13'), t2) =
  1153     let val body_T' = range_type body_T in
  1153     let val body_T' = range_type body_T in
  1154       Const (\<^const_name>\<open>Let\<close>, bound_T --> (bound_T --> body_T') --> body_T')
  1154       Const (\<^const_name>\<open>Let\<close>, bound_T --> (bound_T --> body_T') --> body_T')
  1179   in aux Ts t handle Same.SAME => t end
  1179   in aux Ts t handle Same.SAME => t end
  1180 
  1180 
  1181 fun discr_term_for_constr hol_ctxt (x as (s, T)) =
  1181 fun discr_term_for_constr hol_ctxt (x as (s, T)) =
  1182   let val dataT = body_type T in
  1182   let val dataT = body_type T in
  1183     if s = \<^const_name>\<open>Suc\<close> then
  1183     if s = \<^const_name>\<open>Suc\<close> then
  1184       Abs (Name.uu, dataT, @{const Not} $ HOLogic.mk_eq (zero_const dataT, Bound 0))
  1184       Abs (Name.uu, dataT, \<^const>\<open>Not\<close> $ HOLogic.mk_eq (zero_const dataT, Bound 0))
  1185     else if length (data_type_constrs hol_ctxt dataT) >= 2 then
  1185     else if length (data_type_constrs hol_ctxt dataT) >= 2 then
  1186       Const (discr_for_constr x)
  1186       Const (discr_for_constr x)
  1187     else
  1187     else
  1188       Abs (Name.uu, dataT, @{const True})
  1188       Abs (Name.uu, dataT, \<^const>\<open>True\<close>)
  1189   end
  1189   end
  1190 
  1190 
  1191 fun discriminate_value (hol_ctxt as {ctxt, ...}) x t =
  1191 fun discriminate_value (hol_ctxt as {ctxt, ...}) x t =
  1192   case head_of t of
  1192   case head_of t of
  1193     Const x' =>
  1193     Const x' =>
  1194     if x = x' then @{const True}
  1194     if x = x' then \<^const>\<open>True\<close>
  1195     else if is_nonfree_constr ctxt x' then @{const False}
  1195     else if is_nonfree_constr ctxt x' then \<^const>\<open>False\<close>
  1196     else s_betapply [] (discr_term_for_constr hol_ctxt x, t)
  1196     else s_betapply [] (discr_term_for_constr hol_ctxt x, t)
  1197   | _ => s_betapply [] (discr_term_for_constr hol_ctxt x, t)
  1197   | _ => s_betapply [] (discr_term_for_constr hol_ctxt x, t)
  1198 
  1198 
  1199 fun nth_arg_sel_term_for_constr (x as (s, T)) n =
  1199 fun nth_arg_sel_term_for_constr (x as (s, T)) n =
  1200   let val (arg_Ts, dataT) = strip_type T in
  1200   let val (arg_Ts, dataT) = strip_type T in
  1378 
  1378 
  1379 (* This function is designed to work for both real definition axioms and
  1379 (* This function is designed to work for both real definition axioms and
  1380    simplification rules (equational specifications). *)
  1380    simplification rules (equational specifications). *)
  1381 fun term_under_def t =
  1381 fun term_under_def t =
  1382   case t of
  1382   case t of
  1383     @{const Pure.imp} $ _ $ t2 => term_under_def t2
  1383     \<^const>\<open>Pure.imp\<close> $ _ $ t2 => term_under_def t2
  1384   | Const (\<^const_name>\<open>Pure.eq\<close>, _) $ t1 $ _ => term_under_def t1
  1384   | Const (\<^const_name>\<open>Pure.eq\<close>, _) $ t1 $ _ => term_under_def t1
  1385   | @{const Trueprop} $ t1 => term_under_def t1
  1385   | \<^const>\<open>Trueprop\<close> $ t1 => term_under_def t1
  1386   | Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t1 $ _ => term_under_def t1
  1386   | Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t1 $ _ => term_under_def t1
  1387   | Abs (_, _, t') => term_under_def t'
  1387   | Abs (_, _, t') => term_under_def t'
  1388   | t1 $ _ => term_under_def t1
  1388   | t1 $ _ => term_under_def t1
  1389   | _ => t
  1389   | _ => t
  1390 
  1390 
  1405       | aux (c as Const (\<^const_name>\<open>Pure.type\<close>, _)) (SOME t) = SOME (lambda c t)
  1405       | aux (c as Const (\<^const_name>\<open>Pure.type\<close>, _)) (SOME t) = SOME (lambda c t)
  1406       | aux _ _ = NONE
  1406       | aux _ _ = NONE
  1407     val (lhs, rhs) =
  1407     val (lhs, rhs) =
  1408       case t of
  1408       case t of
  1409         Const (\<^const_name>\<open>Pure.eq\<close>, _) $ t1 $ t2 => (t1, t2)
  1409         Const (\<^const_name>\<open>Pure.eq\<close>, _) $ t1 $ t2 => (t1, t2)
  1410       | @{const Trueprop} $ (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t1 $ t2) =>
  1410       | \<^const>\<open>Trueprop\<close> $ (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t1 $ t2) =>
  1411         (t1, t2)
  1411         (t1, t2)
  1412       | _ => raise TERM ("Nitpick_HOL.normalized_rhs_of", [t])
  1412       | _ => raise TERM ("Nitpick_HOL.normalized_rhs_of", [t])
  1413     val args = strip_comb lhs |> snd
  1413     val args = strip_comb lhs |> snd
  1414   in fold_rev aux args (SOME rhs) end
  1414   in fold_rev aux args (SOME rhs) end
  1415 
  1415 
  1483 
  1483 
  1484 fun lhs_of_equation t =
  1484 fun lhs_of_equation t =
  1485   case t of
  1485   case t of
  1486     Const (\<^const_name>\<open>Pure.all\<close>, _) $ Abs (_, _, t1) => lhs_of_equation t1
  1486     Const (\<^const_name>\<open>Pure.all\<close>, _) $ Abs (_, _, t1) => lhs_of_equation t1
  1487   | Const (\<^const_name>\<open>Pure.eq\<close>, _) $ t1 $ _ => SOME t1
  1487   | Const (\<^const_name>\<open>Pure.eq\<close>, _) $ t1 $ _ => SOME t1
  1488   | @{const Pure.imp} $ _ $ t2 => lhs_of_equation t2
  1488   | \<^const>\<open>Pure.imp\<close> $ _ $ t2 => lhs_of_equation t2
  1489   | @{const Trueprop} $ t1 => lhs_of_equation t1
  1489   | \<^const>\<open>Trueprop\<close> $ t1 => lhs_of_equation t1
  1490   | Const (\<^const_name>\<open>All\<close>, _) $ Abs (_, _, t1) => lhs_of_equation t1
  1490   | Const (\<^const_name>\<open>All\<close>, _) $ Abs (_, _, t1) => lhs_of_equation t1
  1491   | Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t1 $ _ => SOME t1
  1491   | Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t1 $ _ => SOME t1
  1492   | @{const HOL.implies} $ _ $ t2 => lhs_of_equation t2
  1492   | \<^const>\<open>HOL.implies\<close> $ _ $ t2 => lhs_of_equation t2
  1493   | _ => NONE
  1493   | _ => NONE
  1494 
  1494 
  1495 fun is_constr_pattern _ (Bound _) = true
  1495 fun is_constr_pattern _ (Bound _) = true
  1496   | is_constr_pattern _ (Var _) = true
  1496   | is_constr_pattern _ (Var _) = true
  1497   | is_constr_pattern ctxt t =
  1497   | is_constr_pattern ctxt t =
  1597       |> map (fn (func_t, x) =>
  1597       |> map (fn (func_t, x) =>
  1598                  (constr_case_body ctxt (dataT :: Ts)
  1598                  (constr_case_body ctxt (dataT :: Ts)
  1599                                    (incr_boundvars 1 func_t, x),
  1599                                    (incr_boundvars 1 func_t, x),
  1600                   discriminate_value hol_ctxt x (Bound 0)))
  1600                   discriminate_value hol_ctxt x (Bound 0)))
  1601       |> AList.group (op aconv)
  1601       |> AList.group (op aconv)
  1602       |> map (apsnd (List.foldl s_disj @{const False}))
  1602       |> map (apsnd (List.foldl s_disj \<^const>\<open>False\<close>))
  1603       |> sort (int_ord o apply2 (size_of_term o snd))
  1603       |> sort (int_ord o apply2 (size_of_term o snd))
  1604       |> rev
  1604       |> rev
  1605   in
  1605   in
  1606     if res_T = bool_T then
  1606     if res_T = bool_T then
  1607       if forall (member (op =) [@{const False}, @{const True}] o fst) cases then
  1607       if forall (member (op =) [\<^const>\<open>False\<close>, \<^const>\<open>True\<close>] o fst) cases then
  1608         case cases of
  1608         case cases of
  1609           [(body_t, _)] => body_t
  1609           [(body_t, _)] => body_t
  1610         | [_, (@{const True}, head_t2)] => head_t2
  1610         | [_, (\<^const>\<open>True\<close>, head_t2)] => head_t2
  1611         | [_, (@{const False}, head_t2)] => @{const Not} $ head_t2
  1611         | [_, (\<^const>\<open>False\<close>, head_t2)] => \<^const>\<open>Not\<close> $ head_t2
  1612         | _ => raise BAD ("Nitpick_HOL.optimized_case_def", "impossible cases")
  1612         | _ => raise BAD ("Nitpick_HOL.optimized_case_def", "impossible cases")
  1613       else
  1613       else
  1614         @{const True} |> fold_rev (add_constr_case res_T) cases
  1614         \<^const>\<open>True\<close> |> fold_rev (add_constr_case res_T) cases
  1615     else
  1615     else
  1616       fst (hd cases) |> fold_rev (add_constr_case res_T) (tl cases)
  1616       fst (hd cases) |> fold_rev (add_constr_case res_T) (tl cases)
  1617   end
  1617   end
  1618   |> absdummy dataT
  1618   |> absdummy dataT
  1619 
  1619 
  1894     val j = maxidx_of_term t + 1
  1894     val j = maxidx_of_term t + 1
  1895     val (prems, concl) = Logic.strip_horn t
  1895     val (prems, concl) = Logic.strip_horn t
  1896   in
  1896   in
  1897     Logic.list_implies (prems,
  1897     Logic.list_implies (prems,
  1898         case concl of
  1898         case concl of
  1899           @{const Trueprop} $ (Const (\<^const_name>\<open>HOL.eq\<close>, Type (_, [T, _]))
  1899           \<^const>\<open>Trueprop\<close> $ (Const (\<^const_name>\<open>HOL.eq\<close>, Type (_, [T, _]))
  1900                                $ t1 $ t2) =>
  1900                                $ t1 $ t2) =>
  1901           @{const Trueprop} $ extensional_equal j T t1 t2
  1901           \<^const>\<open>Trueprop\<close> $ extensional_equal j T t1 t2
  1902         | @{const Trueprop} $ t' =>
  1902         | \<^const>\<open>Trueprop\<close> $ t' =>
  1903           @{const Trueprop} $ HOLogic.mk_eq (t', @{const True})
  1903           \<^const>\<open>Trueprop\<close> $ HOLogic.mk_eq (t', \<^const>\<open>True\<close>)
  1904         | Const (\<^const_name>\<open>Pure.eq\<close>, Type (_, [T, _])) $ t1 $ t2 =>
  1904         | Const (\<^const_name>\<open>Pure.eq\<close>, Type (_, [T, _])) $ t1 $ t2 =>
  1905           @{const Trueprop} $ extensional_equal j T t1 t2
  1905           \<^const>\<open>Trueprop\<close> $ extensional_equal j T t1 t2
  1906         | _ => (warning ("Ignoring " ^ quote tag ^ " for non-equation " ^
  1906         | _ => (warning ("Ignoring " ^ quote tag ^ " for non-equation " ^
  1907                          quote (Syntax.string_of_term ctxt t));
  1907                          quote (Syntax.string_of_term ctxt t));
  1908                 raise SAME ()))
  1908                 raise SAME ()))
  1909     |> SOME
  1909     |> SOME
  1910   end
  1910   end
  1951          (filter (fn (cat, _) => cat = Spec_Rules.Inductive orelse
  1951          (filter (fn (cat, _) => cat = Spec_Rules.Inductive orelse
  1952                                  cat = Spec_Rules.Co_Inductive) (Spec_Rules.get ctxt))) subst
  1952                                  cat = Spec_Rules.Co_Inductive) (Spec_Rules.get ctxt))) subst
  1953   end
  1953   end
  1954 
  1954 
  1955 fun ground_theorem_table thy =
  1955 fun ground_theorem_table thy =
  1956   fold ((fn @{const Trueprop} $ t1 =>
  1956   fold ((fn \<^const>\<open>Trueprop\<close> $ t1 =>
  1957             is_ground_term t1 ? Inttab.map_default (hash_term t1, []) (cons t1)
  1957             is_ground_term t1 ? Inttab.map_default (hash_term t1, []) (cons t1)
  1958           | _ => I) o Thm.prop_of o snd) (Global_Theory.all_thms_of thy true) Inttab.empty
  1958           | _ => I) o Thm.prop_of o snd) (Global_Theory.all_thms_of thy true) Inttab.empty
  1959 
  1959 
  1960 fun ersatz_table ctxt =
  1960 fun ersatz_table ctxt =
  1961  #ersatz_table (Data.get (Context.Proof ctxt))
  1961  #ersatz_table (Data.get (Context.Proof ctxt))
  2016     val normal_y = normal_fun $ y_var
  2016     val normal_y = normal_fun $ y_var
  2017     val is_unknown_t = Const (\<^const_name>\<open>is_unknown\<close>, rep_T --> bool_T)
  2017     val is_unknown_t = Const (\<^const_name>\<open>is_unknown\<close>, rep_T --> bool_T)
  2018   in
  2018   in
  2019     [Logic.mk_equals (normal_fun $ sel_a_t, sel_a_t),
  2019     [Logic.mk_equals (normal_fun $ sel_a_t, sel_a_t),
  2020      Logic.list_implies
  2020      Logic.list_implies
  2021          ([@{const Not} $ (is_unknown_t $ normal_x),
  2021          ([\<^const>\<open>Not\<close> $ (is_unknown_t $ normal_x),
  2022            @{const Not} $ (is_unknown_t $ normal_y),
  2022            \<^const>\<open>Not\<close> $ (is_unknown_t $ normal_y),
  2023            equiv_rel $ x_var $ y_var] |> map HOLogic.mk_Trueprop,
  2023            equiv_rel $ x_var $ y_var] |> map HOLogic.mk_Trueprop,
  2024            Logic.mk_equals (normal_x, normal_y)),
  2024            Logic.mk_equals (normal_x, normal_y)),
  2025      Logic.list_implies
  2025      Logic.list_implies
  2026          ([HOLogic.mk_Trueprop (@{const Not} $ (is_unknown_t $ normal_x)),
  2026          ([HOLogic.mk_Trueprop (\<^const>\<open>Not\<close> $ (is_unknown_t $ normal_x)),
  2027            HOLogic.mk_Trueprop (@{const Not} $ HOLogic.mk_eq (normal_x, x_var))],
  2027            HOLogic.mk_Trueprop (\<^const>\<open>Not\<close> $ HOLogic.mk_eq (normal_x, x_var))],
  2028           HOLogic.mk_Trueprop (equiv_rel $ x_var $ normal_x))]
  2028           HOLogic.mk_Trueprop (equiv_rel $ x_var $ normal_x))]
  2029     |> partial ? cons (HOLogic.mk_Trueprop (equiv_rel $ sel_a_t $ sel_a_t))
  2029     |> partial ? cons (HOLogic.mk_Trueprop (equiv_rel $ sel_a_t $ sel_a_t))
  2030   end
  2030   end
  2031 
  2031 
  2032 fun codatatype_bisim_axioms (hol_ctxt as {ctxt, ...}) T =
  2032 fun codatatype_bisim_axioms (hol_ctxt as {ctxt, ...}) T =
  2033   let
  2033   let
  2034     val xs = data_type_constrs hol_ctxt T
  2034     val xs = data_type_constrs hol_ctxt T
  2035     val pred_T = T --> bool_T
  2035     val pred_T = T --> bool_T
  2036     val iter_T = \<^typ>\<open>bisim_iterator\<close>
  2036     val iter_T = \<^typ>\<open>bisim_iterator\<close>
  2037     val bisim_max = @{const bisim_iterator_max}
  2037     val bisim_max = \<^const>\<open>bisim_iterator_max\<close>
  2038     val n_var = Var (("n", 0), iter_T)
  2038     val n_var = Var (("n", 0), iter_T)
  2039     val n_var_minus_1 =
  2039     val n_var_minus_1 =
  2040       Const (\<^const_name>\<open>safe_The\<close>, (iter_T --> bool_T) --> iter_T)
  2040       Const (\<^const_name>\<open>safe_The\<close>, (iter_T --> bool_T) --> iter_T)
  2041       $ Abs ("m", iter_T, HOLogic.eq_const iter_T $ (suc_const iter_T $ Bound 0) $ n_var)
  2041       $ Abs ("m", iter_T, HOLogic.eq_const iter_T $ (suc_const iter_T $ Bound 0) $ n_var)
  2042     val x_var = Var (("x", 0), T)
  2042     val x_var = Var (("x", 0), T)
  2213           val tuple_T = HOLogic.mk_tupleT arg_Ts
  2213           val tuple_T = HOLogic.mk_tupleT arg_Ts
  2214           val j = length arg_Ts
  2214           val j = length arg_Ts
  2215           fun repair_rec j (Const (\<^const_name>\<open>Ex\<close>, T1) $ Abs (s2, T2, t2')) =
  2215           fun repair_rec j (Const (\<^const_name>\<open>Ex\<close>, T1) $ Abs (s2, T2, t2')) =
  2216               Const (\<^const_name>\<open>Ex\<close>, T1)
  2216               Const (\<^const_name>\<open>Ex\<close>, T1)
  2217               $ Abs (s2, T2, repair_rec (j + 1) t2')
  2217               $ Abs (s2, T2, repair_rec (j + 1) t2')
  2218             | repair_rec j (@{const HOL.conj} $ t1 $ t2) =
  2218             | repair_rec j (\<^const>\<open>HOL.conj\<close> $ t1 $ t2) =
  2219               @{const HOL.conj} $ repair_rec j t1 $ repair_rec j t2
  2219               \<^const>\<open>HOL.conj\<close> $ repair_rec j t1 $ repair_rec j t2
  2220             | repair_rec j t =
  2220             | repair_rec j t =
  2221               let val (head, args) = strip_comb t in
  2221               let val (head, args) = strip_comb t in
  2222                 if head = Bound j then
  2222                 if head = Bound j then
  2223                   HOLogic.eq_const tuple_T $ Bound j
  2223                   HOLogic.eq_const tuple_T $ Bound j
  2224                   $ mk_flat_tuple tuple_T args
  2224                   $ mk_flat_tuple tuple_T args
  2226                   t
  2226                   t
  2227               end
  2227               end
  2228           val (nonrecs, recs) =
  2228           val (nonrecs, recs) =
  2229             List.partition (curry (op =) 0 o num_occs_of_bound_in_term j)
  2229             List.partition (curry (op =) 0 o num_occs_of_bound_in_term j)
  2230                            (disjuncts_of body)
  2230                            (disjuncts_of body)
  2231           val base_body = nonrecs |> List.foldl s_disj @{const False}
  2231           val base_body = nonrecs |> List.foldl s_disj \<^const>\<open>False\<close>
  2232           val step_body = recs |> map (repair_rec j)
  2232           val step_body = recs |> map (repair_rec j)
  2233                                |> List.foldl s_disj @{const False}
  2233                                |> List.foldl s_disj \<^const>\<open>False\<close>
  2234         in
  2234         in
  2235           (fold_rev Term.abs (tl xs) (incr_bv (~1, j, base_body))
  2235           (fold_rev Term.abs (tl xs) (incr_bv (~1, j, base_body))
  2236            |> ap_n_split (length arg_Ts) tuple_T bool_T,
  2236            |> ap_n_split (length arg_Ts) tuple_T bool_T,
  2237            Abs ("y", tuple_T, fold_rev Term.abs (tl xs) step_body
  2237            Abs ("y", tuple_T, fold_rev Term.abs (tl xs) step_body
  2238                               |> ap_n_split (length arg_Ts) tuple_T bool_T))
  2238                               |> ap_n_split (length arg_Ts) tuple_T bool_T))
  2364     [] => (case def_props_for_const thy psimp_table x of
  2364     [] => (case def_props_for_const thy psimp_table x of
  2365              [] => (if is_inductive_pred hol_ctxt x then
  2365              [] => (if is_inductive_pred hol_ctxt x then
  2366                       [inductive_pred_axiom hol_ctxt x]
  2366                       [inductive_pred_axiom hol_ctxt x]
  2367                     else case def_of_const thy def_tables x of
  2367                     else case def_of_const thy def_tables x of
  2368                       SOME def =>
  2368                       SOME def =>
  2369                       @{const Trueprop} $ HOLogic.mk_eq (Const x, def)
  2369                       \<^const>\<open>Trueprop\<close> $ HOLogic.mk_eq (Const x, def)
  2370                       |> equationalize_term ctxt "" |> the |> single
  2370                       |> equationalize_term ctxt "" |> the |> single
  2371                     | NONE => [])
  2371                     | NONE => [])
  2372            | psimps => psimps)
  2372            | psimps => psimps)
  2373   | simps => simps
  2373   | simps => simps
  2374 
  2374 
  2375 fun is_equational_fun_surely_complete hol_ctxt x =
  2375 fun is_equational_fun_surely_complete hol_ctxt x =
  2376   case equational_fun_axioms hol_ctxt x of
  2376   case equational_fun_axioms hol_ctxt x of
  2377     [@{const Trueprop} $ (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t1 $ _)] =>
  2377     [\<^const>\<open>Trueprop\<close> $ (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t1 $ _)] =>
  2378     strip_comb t1 |> snd |> forall is_Var
  2378     strip_comb t1 |> snd |> forall is_Var
  2379   | _ => false
  2379   | _ => false
  2380 
  2380 
  2381 (** Type preprocessing **)
  2381 (** Type preprocessing **)
  2382 
  2382