src/HOL/Tools/Nitpick/nitpick_hol.ML
changeset 34124 c4628a1dcf75
parent 34123 c4988215a691
child 34126 8a2c5d7aff51
equal deleted inserted replaced
34123:c4988215a691 34124:c4628a1dcf75
    19     max_bisim_depth: int,
    19     max_bisim_depth: int,
    20     boxes: (typ option * bool option) list,
    20     boxes: (typ option * bool option) list,
    21     wfs: (styp option * bool option) list,
    21     wfs: (styp option * bool option) list,
    22     user_axioms: bool option,
    22     user_axioms: bool option,
    23     debug: bool,
    23     debug: bool,
       
    24     binary_ints: bool option,
    24     destroy_constrs: bool,
    25     destroy_constrs: bool,
    25     specialize: bool,
    26     specialize: bool,
    26     skolemize: bool,
    27     skolemize: bool,
    27     star_linear_preds: bool,
    28     star_linear_preds: bool,
    28     uncurry: bool,
    29     uncurry: bool,
    47   val name_sep : string
    48   val name_sep : string
    48   val numeral_prefix : string
    49   val numeral_prefix : string
    49   val skolem_prefix : string
    50   val skolem_prefix : string
    50   val eval_prefix : string
    51   val eval_prefix : string
    51   val original_name : string -> string
    52   val original_name : string -> string
    52   val unbox_type : typ -> typ
    53   val unbit_and_unbox_type : typ -> typ
    53   val string_for_type : Proof.context -> typ -> string
    54   val string_for_type : Proof.context -> typ -> string
    54   val prefix_name : string -> string -> string
    55   val prefix_name : string -> string -> string
    55   val shortest_name : string -> string
    56   val shortest_name : string -> string
    56   val short_name : string -> string
    57   val short_name : string -> string
    57   val shorten_names_in_term : term -> term
    58   val shorten_names_in_term : term -> term
    66   val is_lfp_iterator_type : typ -> bool
    67   val is_lfp_iterator_type : typ -> bool
    67   val is_gfp_iterator_type : typ -> bool
    68   val is_gfp_iterator_type : typ -> bool
    68   val is_fp_iterator_type : typ -> bool
    69   val is_fp_iterator_type : typ -> bool
    69   val is_boolean_type : typ -> bool
    70   val is_boolean_type : typ -> bool
    70   val is_integer_type : typ -> bool
    71   val is_integer_type : typ -> bool
       
    72   val is_bit_type : typ -> bool
       
    73   val is_word_type : typ -> bool
    71   val is_record_type : typ -> bool
    74   val is_record_type : typ -> bool
    72   val is_number_type : theory -> typ -> bool
    75   val is_number_type : theory -> typ -> bool
    73   val const_for_iterator_type : typ -> styp
    76   val const_for_iterator_type : typ -> styp
    74   val nth_range_type : int -> typ -> typ
    77   val nth_range_type : int -> typ -> typ
    75   val num_factors_in_type : typ -> int
    78   val num_factors_in_type : typ -> int
    89   val is_abs_fun : theory -> styp -> bool
    92   val is_abs_fun : theory -> styp -> bool
    90   val is_rep_fun : theory -> styp -> bool
    93   val is_rep_fun : theory -> styp -> bool
    91   val is_constr : theory -> styp -> bool
    94   val is_constr : theory -> styp -> bool
    92   val is_stale_constr : theory -> styp -> bool
    95   val is_stale_constr : theory -> styp -> bool
    93   val is_sel : string -> bool
    96   val is_sel : string -> bool
       
    97   val is_sel_like_and_no_discr : string -> bool
    94   val discr_for_constr : styp -> styp
    98   val discr_for_constr : styp -> styp
    95   val num_sels_for_constr_type : typ -> int
    99   val num_sels_for_constr_type : typ -> int
    96   val nth_sel_name_for_constr_name : string -> int -> string
   100   val nth_sel_name_for_constr_name : string -> int -> string
    97   val nth_sel_for_constr : styp -> int -> styp
   101   val nth_sel_for_constr : styp -> int -> styp
    98   val boxed_nth_sel_for_constr : extended_context -> styp -> int -> styp
   102   val boxed_nth_sel_for_constr : extended_context -> styp -> int -> styp
   159   max_bisim_depth: int,
   163   max_bisim_depth: int,
   160   boxes: (typ option * bool option) list,
   164   boxes: (typ option * bool option) list,
   161   wfs: (styp option * bool option) list,
   165   wfs: (styp option * bool option) list,
   162   user_axioms: bool option,
   166   user_axioms: bool option,
   163   debug: bool,
   167   debug: bool,
       
   168   binary_ints: bool option,
   164   destroy_constrs: bool,
   169   destroy_constrs: bool,
   165   specialize: bool,
   170   specialize: bool,
   166   skolemize: bool,
   171   skolemize: bool,
   167   star_linear_preds: bool,
   172   star_linear_preds: bool,
   168   uncurry: bool,
   173   uncurry: bool,
   305    (@{const_name one_nat_inst.one_nat}, 0),
   310    (@{const_name one_nat_inst.one_nat}, 0),
   306    (@{const_name plus_nat_inst.plus_nat}, 0),
   311    (@{const_name plus_nat_inst.plus_nat}, 0),
   307    (@{const_name minus_nat_inst.minus_nat}, 0),
   312    (@{const_name minus_nat_inst.minus_nat}, 0),
   308    (@{const_name times_nat_inst.times_nat}, 0),
   313    (@{const_name times_nat_inst.times_nat}, 0),
   309    (@{const_name div_nat_inst.div_nat}, 0),
   314    (@{const_name div_nat_inst.div_nat}, 0),
   310    (@{const_name div_nat_inst.mod_nat}, 0),
       
   311    (@{const_name ord_nat_inst.less_nat}, 2),
   315    (@{const_name ord_nat_inst.less_nat}, 2),
   312    (@{const_name ord_nat_inst.less_eq_nat}, 2),
   316    (@{const_name ord_nat_inst.less_eq_nat}, 2),
   313    (@{const_name nat_gcd}, 0),
   317    (@{const_name nat_gcd}, 0),
   314    (@{const_name nat_lcm}, 0),
   318    (@{const_name nat_lcm}, 0),
   315    (@{const_name zero_int_inst.zero_int}, 0),
   319    (@{const_name zero_int_inst.zero_int}, 0),
   316    (@{const_name one_int_inst.one_int}, 0),
   320    (@{const_name one_int_inst.one_int}, 0),
   317    (@{const_name plus_int_inst.plus_int}, 0),
   321    (@{const_name plus_int_inst.plus_int}, 0),
   318    (@{const_name minus_int_inst.minus_int}, 0),
   322    (@{const_name minus_int_inst.minus_int}, 0),
   319    (@{const_name times_int_inst.times_int}, 0),
   323    (@{const_name times_int_inst.times_int}, 0),
   320    (@{const_name div_int_inst.div_int}, 0),
   324    (@{const_name div_int_inst.div_int}, 0),
   321    (@{const_name div_int_inst.mod_int}, 0),
       
   322    (@{const_name uminus_int_inst.uminus_int}, 0),
   325    (@{const_name uminus_int_inst.uminus_int}, 0),
   323    (@{const_name ord_int_inst.less_int}, 2),
   326    (@{const_name ord_int_inst.less_int}, 2),
   324    (@{const_name ord_int_inst.less_eq_int}, 2),
   327    (@{const_name ord_int_inst.less_eq_int}, 2),
   325    (@{const_name Tha}, 1),
   328    (@{const_name Tha}, 1),
   326    (@{const_name Frac}, 0),
   329    (@{const_name Frac}, 0),
   327    (@{const_name norm_frac}, 0)]
   330    (@{const_name norm_frac}, 0)]
   328 val built_in_descr_consts =
   331 val built_in_descr_consts =
   329   [(@{const_name The}, 1),
   332   [(@{const_name The}, 1),
   330    (@{const_name Eps}, 1)]
   333    (@{const_name Eps}, 1)]
   331 val built_in_typed_consts =
   334 val built_in_typed_consts =
   332   [((@{const_name of_nat}, nat_T --> int_T), 0)]
   335   [((@{const_name of_nat}, nat_T --> int_T), 0),
       
   336    ((@{const_name of_nat}, @{typ "unsigned_bit word => signed_bit word"}), 0)]
   333 val built_in_set_consts =
   337 val built_in_set_consts =
   334   [(@{const_name lower_semilattice_fun_inst.inf_fun}, 2),
   338   [(@{const_name lower_semilattice_fun_inst.inf_fun}, 2),
   335    (@{const_name upper_semilattice_fun_inst.sup_fun}, 2),
   339    (@{const_name upper_semilattice_fun_inst.sup_fun}, 2),
   336    (@{const_name minus_fun_inst.minus_fun}, 2),
   340    (@{const_name minus_fun_inst.minus_fun}, 2),
   337    (@{const_name ord_fun_inst.less_eq_fun}, 2)]
   341    (@{const_name ord_fun_inst.less_eq_fun}, 2)]
   338 
   342 
   339 (* typ -> typ *)
   343 (* typ -> typ *)
   340 fun unbox_type (Type (@{type_name fun_box}, Ts)) =
   344 fun unbit_type @{typ "unsigned_bit word"} = nat_T
   341     Type ("fun", map unbox_type Ts)
   345   | unbit_type @{typ "signed_bit word"} = int_T
   342   | unbox_type (Type (@{type_name pair_box}, Ts)) =
   346   | unbit_type @{typ bisim_iterator} = nat_T
   343     Type ("*", map unbox_type Ts)
   347   | unbit_type (Type (s, Ts as _ :: _)) = Type (s, map unbit_type Ts)
   344   | unbox_type (Type (s, Ts)) = Type (s, map unbox_type Ts)
   348   | unbit_type T = T
   345   | unbox_type T = T
   349 fun unbit_and_unbox_type (Type (@{type_name fun_box}, Ts)) =
       
   350     unbit_and_unbox_type (Type ("fun", Ts))
       
   351   | unbit_and_unbox_type (Type (@{type_name pair_box}, Ts)) =
       
   352     Type ("*", map unbit_and_unbox_type Ts)
       
   353   | unbit_and_unbox_type @{typ "unsigned_bit word"} = nat_T
       
   354   | unbit_and_unbox_type @{typ "signed_bit word"} = int_T
       
   355   | unbit_and_unbox_type @{typ bisim_iterator} = nat_T
       
   356   | unbit_and_unbox_type (Type (s, Ts as _ :: _)) =
       
   357     Type (s, map unbit_and_unbox_type Ts)
       
   358   | unbit_and_unbox_type T = T
   346 (* Proof.context -> typ -> string *)
   359 (* Proof.context -> typ -> string *)
   347 fun string_for_type ctxt = Syntax.string_of_typ ctxt o unbox_type
   360 fun string_for_type ctxt = Syntax.string_of_typ ctxt o unbit_and_unbox_type
   348 
   361 
   349 (* string -> string -> string *)
   362 (* string -> string -> string *)
   350 val prefix_name = Long_Name.qualify o Long_Name.base_name
   363 val prefix_name = Long_Name.qualify o Long_Name.base_name
   351 (* string -> string *)
   364 (* string -> string *)
   352 fun shortest_name s = List.last (space_explode "." s) handle List.Empty => ""
   365 fun shortest_name s = List.last (space_explode "." s) handle List.Empty => ""
   399   | is_gfp_iterator_type _ = false
   412   | is_gfp_iterator_type _ = false
   400 val is_fp_iterator_type = is_lfp_iterator_type orf is_gfp_iterator_type
   413 val is_fp_iterator_type = is_lfp_iterator_type orf is_gfp_iterator_type
   401 fun is_boolean_type T = (T = prop_T orelse T = bool_T)
   414 fun is_boolean_type T = (T = prop_T orelse T = bool_T)
   402 val is_integer_type =
   415 val is_integer_type =
   403   member (op =) [nat_T, int_T, @{typ bisim_iterator}] orf is_fp_iterator_type
   416   member (op =) [nat_T, int_T, @{typ bisim_iterator}] orf is_fp_iterator_type
       
   417 fun is_bit_type T = (T = @{typ unsigned_bit} orelse T = @{typ signed_bit})
       
   418 fun is_word_type (Type (@{type_name word}, _)) = true
       
   419   | is_word_type _ = false
   404 val is_record_type = not o null o Record.dest_recTs
   420 val is_record_type = not o null o Record.dest_recTs
   405 (* theory -> typ -> bool *)
   421 (* theory -> typ -> bool *)
   406 fun is_frac_type thy (Type (s, [])) =
   422 fun is_frac_type thy (Type (s, [])) =
   407     not (null (these (AList.lookup (op =) (#frac_types (Data.get thy)) s)))
   423     not (null (these (AList.lookup (op =) (#frac_types (Data.get thy)) s)))
   408   | is_frac_type _ _ = false
   424   | is_frac_type _ _ = false
   451 fun dest_n_tuple_type 1 T = [T]
   467 fun dest_n_tuple_type 1 T = [T]
   452   | dest_n_tuple_type n (Type (_, [T1, T2])) =
   468   | dest_n_tuple_type n (Type (_, [T1, T2])) =
   453     T1 :: dest_n_tuple_type (n - 1) T2
   469     T1 :: dest_n_tuple_type (n - 1) T2
   454   | dest_n_tuple_type _ T =
   470   | dest_n_tuple_type _ T =
   455     raise TYPE ("Nitpick_HOL.dest_n_tuple_type", [T], [])
   471     raise TYPE ("Nitpick_HOL.dest_n_tuple_type", [T], [])
   456 
       
   457 (* (typ * typ) list -> typ -> typ *)
       
   458 fun typ_subst [] T = T
       
   459   | typ_subst ps T =
       
   460     let
       
   461       (* typ -> typ *)
       
   462       fun subst T =
       
   463         case AList.lookup (op =) ps T of
       
   464           SOME T' => T'
       
   465         | NONE => case T of Type (s, Ts) => Type (s, map subst Ts) | _ => T
       
   466     in subst T end
       
   467 
   472 
   468 (* FIXME: Use antiquotation for "code_numeral" below or detect "rep_datatype",
   473 (* FIXME: Use antiquotation for "code_numeral" below or detect "rep_datatype",
   469    e.g., by adding a field to "Datatype_Aux.info". *)
   474    e.g., by adding a field to "Datatype_Aux.info". *)
   470 (* string -> bool *)
   475 (* string -> bool *)
   471 val is_basic_datatype =
   476 val is_basic_datatype =
   620            (AList.lookup (op =) codatatypes co_s |> Option.map snd |> these)
   625            (AList.lookup (op =) codatatypes co_s |> Option.map snd |> these)
   621   end
   626   end
   622   handle TYPE ("dest_Type", _, _) => false
   627   handle TYPE ("dest_Type", _, _) => false
   623 fun is_constr_like thy (s, T) =
   628 fun is_constr_like thy (s, T) =
   624   s = @{const_name FunBox} orelse s = @{const_name PairBox} orelse
   629   s = @{const_name FunBox} orelse s = @{const_name PairBox} orelse
   625   let val (x as (s, T)) = (s, unbox_type T) in
   630   let val (x as (s, T)) = (s, unbit_and_unbox_type T) in
   626     Refute.is_IDT_constructor thy x orelse is_record_constr x
   631     Refute.is_IDT_constructor thy x orelse is_record_constr x
   627     orelse (is_abs_fun thy x andalso is_pure_typedef thy (range_type T))
   632     orelse (is_abs_fun thy x andalso is_pure_typedef thy (range_type T))
   628     orelse s = @{const_name Zero_Rep} orelse s = @{const_name Suc_Rep}
   633     orelse s = @{const_name Zero_Rep} orelse s = @{const_name Suc_Rep}
   629     orelse x = (@{const_name zero_nat_inst.zero_nat}, nat_T)
   634     orelse x = (@{const_name zero_nat_inst.zero_nat}, nat_T)
   630     orelse is_coconstr thy x
   635     orelse is_coconstr thy x
   632 fun is_stale_constr thy (x as (_, T)) =
   637 fun is_stale_constr thy (x as (_, T)) =
   633   is_codatatype thy (body_type T) andalso is_constr_like thy x
   638   is_codatatype thy (body_type T) andalso is_constr_like thy x
   634   andalso not (is_coconstr thy x)
   639   andalso not (is_coconstr thy x)
   635 fun is_constr thy (x as (_, T)) =
   640 fun is_constr thy (x as (_, T)) =
   636   is_constr_like thy x
   641   is_constr_like thy x
   637   andalso not (is_basic_datatype (fst (dest_Type (body_type T))))
   642   andalso not (is_basic_datatype (fst (dest_Type (unbit_type (body_type T)))))
   638   andalso not (is_stale_constr thy x)
   643   andalso not (is_stale_constr thy x)
   639 (* string -> bool *)
   644 (* string -> bool *)
   640 val is_sel = String.isPrefix discr_prefix orf String.isPrefix sel_prefix
   645 val is_sel = String.isPrefix discr_prefix orf String.isPrefix sel_prefix
   641 val is_sel_like_and_no_discr =
   646 val is_sel_like_and_no_discr =
   642   String.isPrefix sel_prefix
   647   String.isPrefix sel_prefix
   884   handle SAME () =>
   889   handle SAME () =>
   885          let
   890          let
   886            val x' as (_, T') =
   891            val x' as (_, T') =
   887              if is_pair_type T then
   892              if is_pair_type T then
   888                let val (T1, T2) = HOLogic.dest_prodT T in
   893                let val (T1, T2) = HOLogic.dest_prodT T in
   889                  (@{const_name Pair}, [T1, T2] ---> T)
   894                  (@{const_name Pair}, T1 --> T2 --> T)
   890                end
   895                end
   891              else
   896              else
   892                datatype_constrs ext_ctxt T |> the_single
   897                datatype_constrs ext_ctxt T |> the_single
   893            val arg_Ts = binder_types T'
   898            val arg_Ts = binder_types T'
   894          in
   899          in
  1213               (Datatype.get_all thy) [] @
  1218               (Datatype.get_all thy) [] @
  1214   map (apsnd length o snd) (#codatatypes (Data.get thy))
  1219   map (apsnd length o snd) (#codatatypes (Data.get thy))
  1215 
  1220 
  1216 (* Proof.context -> term list -> const_table *)
  1221 (* Proof.context -> term list -> const_table *)
  1217 fun const_def_table ctxt ts =
  1222 fun const_def_table ctxt ts =
  1218   table_for (map prop_of o Nitpick_Defs.get) ctxt
  1223   table_for (rev o map prop_of o Nitpick_Defs.get) ctxt
  1219   |> fold (fn (s, t) => Symtab.map_default (s, []) (cons t))
  1224   |> fold (fn (s, t) => Symtab.map_default (s, []) (cons t))
  1220           (map pair_for_prop ts)
  1225           (map pair_for_prop ts)
  1221 (* term list -> const_table *)
  1226 (* term list -> const_table *)
  1222 fun const_nondef_table ts =
  1227 fun const_nondef_table ts =
  1223   fold (fn t => append (map (fn s => (s, t)) (Term.add_const_names t []))) ts []
  1228   fold (fn t => append (map (fn s => (s, t)) (Term.add_const_names t []))) ts []
  1322     list_comb (Bound j, map2 (select_nth_constr_arg thy x (Bound 0))
  1327     list_comb (Bound j, map2 (select_nth_constr_arg thy x (Bound 0))
  1323                              (index_seq 0 (length arg_Ts)) arg_Ts)
  1328                              (index_seq 0 (length arg_Ts)) arg_Ts)
  1324   end
  1329   end
  1325 (* extended_context -> typ -> int * styp -> term -> term *)
  1330 (* extended_context -> typ -> int * styp -> term -> term *)
  1326 fun add_constr_case (ext_ctxt as {thy, ...}) res_T (j, x) res_t =
  1331 fun add_constr_case (ext_ctxt as {thy, ...}) res_T (j, x) res_t =
  1327   Const (@{const_name If}, [bool_T, res_T, res_T] ---> res_T)
  1332   Const (@{const_name If}, bool_T --> res_T --> res_T --> res_T)
  1328   $ discriminate_value ext_ctxt x (Bound 0) $ constr_case_body thy (j, x)
  1333   $ discriminate_value ext_ctxt x (Bound 0) $ constr_case_body thy (j, x)
  1329   $ res_t
  1334   $ res_t
  1330 (* extended_context -> typ -> typ -> term *)
  1335 (* extended_context -> typ -> typ -> term *)
  1331 fun optimized_case_def (ext_ctxt as {thy, ...}) dataT res_T =
  1336 fun optimized_case_def (ext_ctxt as {thy, ...}) dataT res_T =
  1332   let
  1337   let
  1553               else if is_equational_fun ext_ctxt x then
  1558               else if is_equational_fun ext_ctxt x then
  1554                 (Const x, ts)
  1559                 (Const x, ts)
  1555               else case def_of_const thy def_table x of
  1560               else case def_of_const thy def_table x of
  1556                 SOME def =>
  1561                 SOME def =>
  1557                 if depth > unfold_max_depth then
  1562                 if depth > unfold_max_depth then
  1558                   raise LIMIT ("Nitpick_HOL.unfold_defs_in_term",
  1563                   raise TOO_LARGE ("Nitpick_HOL.unfold_defs_in_term",
  1559                                "too many nested definitions (" ^
  1564                                    "too many nested definitions (" ^
  1560                                string_of_int depth ^ ") while expanding " ^
  1565                                    string_of_int depth ^ ") while expanding " ^
  1561                                quote s)
  1566                                    quote s)
  1562                 else if s = @{const_name wfrec'} then
  1567                 else if s = @{const_name wfrec'} then
  1563                   (do_term (depth + 1) Ts (betapplys (def, ts)), [])
  1568                   (do_term (depth + 1) Ts (betapplys (def, ts)), [])
  1564                 else
  1569                 else
  1565                   (do_term (depth + 1) Ts def, ts)
  1570                   (do_term (depth + 1) Ts def, ts)
  1566               | NONE => (Const x, ts)
  1571               | NONE => (Const x, ts)
  1571 fun codatatype_bisim_axioms (ext_ctxt as {thy, ...}) T =
  1576 fun codatatype_bisim_axioms (ext_ctxt as {thy, ...}) T =
  1572   let
  1577   let
  1573     val xs = datatype_constrs ext_ctxt T
  1578     val xs = datatype_constrs ext_ctxt T
  1574     val set_T = T --> bool_T
  1579     val set_T = T --> bool_T
  1575     val iter_T = @{typ bisim_iterator}
  1580     val iter_T = @{typ bisim_iterator}
  1576     val bisim_const = Const (@{const_name bisim}, [iter_T, T, T] ---> bool_T)
  1581     val bisim_const = Const (@{const_name bisim}, iter_T --> T --> T --> bool_T)
  1577     val bisim_max = @{const bisim_iterator_max}
  1582     val bisim_max = @{const bisim_iterator_max}
  1578     val n_var = Var (("n", 0), iter_T)
  1583     val n_var = Var (("n", 0), iter_T)
  1579     val n_var_minus_1 =
  1584     val n_var_minus_1 =
  1580       Const (@{const_name Tha}, (iter_T --> bool_T) --> iter_T)
  1585       Const (@{const_name Tha}, (iter_T --> bool_T) --> iter_T)
  1581       $ Abs ("m", iter_T, HOLogic.eq_const iter_T
  1586       $ Abs ("m", iter_T, HOLogic.eq_const iter_T
  1601     [HOLogic.eq_const bool_T $ (bisim_const $ n_var $ x_var $ y_var)
  1606     [HOLogic.eq_const bool_T $ (bisim_const $ n_var $ x_var $ y_var)
  1602      $ (@{term "op |"} $ (HOLogic.eq_const iter_T $ n_var $ zero_const iter_T)
  1607      $ (@{term "op |"} $ (HOLogic.eq_const iter_T $ n_var $ zero_const iter_T)
  1603         $ (betapplys (optimized_case_def ext_ctxt T bool_T,
  1608         $ (betapplys (optimized_case_def ext_ctxt T bool_T,
  1604                       map case_func xs @ [x_var]))),
  1609                       map case_func xs @ [x_var]))),
  1605      HOLogic.eq_const set_T $ (bisim_const $ bisim_max $ x_var)
  1610      HOLogic.eq_const set_T $ (bisim_const $ bisim_max $ x_var)
  1606      $ (Const (@{const_name insert}, [T, set_T] ---> set_T)
  1611      $ (Const (@{const_name insert}, T --> set_T --> set_T)
  1607         $ x_var $ Const (@{const_name bot_fun_inst.bot_fun}, set_T))]
  1612         $ x_var $ Const (@{const_name bot_fun_inst.bot_fun}, set_T))]
  1608     |> map HOLogic.mk_Trueprop
  1613     |> map HOLogic.mk_Trueprop
  1609   end
  1614   end
  1610 
  1615 
  1611 exception NO_TRIPLE of unit
  1616 exception NO_TRIPLE of unit
  2062        else case strip_comb t2 of
  2067        else case strip_comb t2 of
  2063          (Const (x as (s, T)), args) =>
  2068          (Const (x as (s, T)), args) =>
  2064          let val arg_Ts = binder_types T in
  2069          let val arg_Ts = binder_types T in
  2065            if length arg_Ts = length args
  2070            if length arg_Ts = length args
  2066               andalso (is_constr thy x orelse s = @{const_name Pair}
  2071               andalso (is_constr thy x orelse s = @{const_name Pair}
  2067                        orelse x = dest_Const @{const Suc})
  2072                        orelse x = (@{const_name Suc}, nat_T --> nat_T))
  2068               andalso (not careful orelse not (is_Var t1)
  2073               andalso (not careful orelse not (is_Var t1)
  2069                        orelse String.isPrefix val_var_prefix
  2074                        orelse String.isPrefix val_var_prefix
  2070                                               (fst (fst (dest_Var t1)))) then
  2075                                               (fst (fst (dest_Var t1)))) then
  2071              discriminate_value ext_ctxt x t1 ::
  2076              discriminate_value ext_ctxt x t1 ::
  2072              map3 (sel_eq x t1) (index_seq 0 (length args)) arg_Ts args
  2077              map3 (sel_eq x t1) (index_seq 0 (length args)) arg_Ts args
  2494                      fun app f =
  2499                      fun app f =
  2495                        list_comb (f (),
  2500                        list_comb (f (),
  2496                                   map Bound (length trunk_arg_Ts - 1 downto 0))
  2501                                   map Bound (length trunk_arg_Ts - 1 downto 0))
  2497                    in
  2502                    in
  2498                      List.foldr absdummy
  2503                      List.foldr absdummy
  2499                                 (Const (set_oper, [set_T, set_T] ---> set_T)
  2504                                 (Const (set_oper, set_T --> set_T --> set_T)
  2500                                         $ app pos $ app neg) trunk_arg_Ts
  2505                                         $ app pos $ app neg) trunk_arg_Ts
  2501                    end
  2506                    end
  2502                  else
  2507                  else
  2503                    connective $ pos () $ neg ())
  2508                    connective $ pos () $ neg ())
  2504             end
  2509             end
  2831       let
  2836       let
  2832         val (t1, t2) = pairself (do_term new_Ts old_Ts Neut) (t1, t2)
  2837         val (t1, t2) = pairself (do_term new_Ts old_Ts Neut) (t1, t2)
  2833         val (T1, T2) = pairself (curry fastype_of1 new_Ts) (t1, t2)
  2838         val (T1, T2) = pairself (curry fastype_of1 new_Ts) (t1, t2)
  2834         val T = [T1, T2] |> sort TermOrd.typ_ord |> List.last
  2839         val T = [T1, T2] |> sort TermOrd.typ_ord |> List.last
  2835       in
  2840       in
  2836         list_comb (Const (s0, [T, T] ---> body_type T0),
  2841         list_comb (Const (s0, T --> T --> body_type T0),
  2837                    map2 (coerce_term new_Ts T) [T1, T2] [t1, t2])
  2842                    map2 (coerce_term new_Ts T) [T1, T2] [t1, t2])
  2838       end
  2843       end
  2839     (* string -> typ -> term *)
  2844     (* string -> typ -> term *)
  2840     and do_description_operator s T =
  2845     and do_description_operator s T =
  2841       let val T1 = box_type ext_ctxt InFunLHS (range_type T) in
  2846       let val T1 = box_type ext_ctxt InFunLHS (range_type T) in
  3048         (if member (op =) xs x orelse is_built_in_const fast_descrs x then
  3053         (if member (op =) xs x orelse is_built_in_const fast_descrs x then
  3049            accum
  3054            accum
  3050          else
  3055          else
  3051            let val accum as (xs, _) = (x :: xs, axs) in
  3056            let val accum as (xs, _) = (x :: xs, axs) in
  3052              if depth > axioms_max_depth then
  3057              if depth > axioms_max_depth then
  3053                raise LIMIT ("Nitpick_HOL.axioms_for_term.add_axioms_for_term",
  3058                raise TOO_LARGE ("Nitpick_HOL.axioms_for_term.\
  3054                             "too many nested axioms (" ^ string_of_int depth ^
  3059                                 \add_axioms_for_term",
  3055                             ")")
  3060                                 "too many nested axioms (" ^
       
  3061                                 string_of_int depth ^ ")")
  3056              else if Refute.is_const_of_class thy x then
  3062              else if Refute.is_const_of_class thy x then
  3057                let
  3063                let
  3058                  val class = Logic.class_of_const s
  3064                  val class = Logic.class_of_const s
  3059                  val of_class = Logic.mk_of_class (TVar (("'a", 0), [class]),
  3065                  val of_class = Logic.mk_of_class (TVar (("'a", 0), [class]),
  3060                                                    class)
  3066                                                    class)
  3193             end
  3199             end
  3194 
  3200 
  3195 (* int list -> int list -> typ -> typ *)
  3201 (* int list -> int list -> typ -> typ *)
  3196 fun format_type default_format format T =
  3202 fun format_type default_format format T =
  3197   let
  3203   let
  3198     val T = unbox_type T
  3204     val T = unbit_and_unbox_type T
  3199     val format = format |> filter (curry (op <) 0)
  3205     val format = format |> filter (curry (op <) 0)
  3200   in
  3206   in
  3201     if forall (curry (op =) 1) format then
  3207     if forall (curry (op =) 1) format then
  3202       T
  3208       T
  3203     else
  3209     else
  3232       (if String.isPrefix special_prefix s then
  3238       (if String.isPrefix special_prefix s then
  3233          let
  3239          let
  3234            (* term -> term *)
  3240            (* term -> term *)
  3235            val do_term = map_aterms (fn Const x => fst (do_const x) | t' => t')
  3241            val do_term = map_aterms (fn Const x => fst (do_const x) | t' => t')
  3236            val (x' as (_, T'), js, ts) =
  3242            val (x' as (_, T'), js, ts) =
  3237              AList.find (op =) (!special_funs) (s, unbox_type T) |> the_single
  3243              AList.find (op =) (!special_funs) (s, unbit_and_unbox_type T)
       
  3244              |> the_single
  3238            val max_j = List.last js
  3245            val max_j = List.last js
  3239            val Ts = List.take (binder_types T', max_j + 1)
  3246            val Ts = List.take (binder_types T', max_j + 1)
  3240            val missing_js = filter_out (member (op =) js) (0 upto max_j)
  3247            val missing_js = filter_out (member (op =) js) (0 upto max_j)
  3241            val missing_Ts = filter_indices missing_js Ts
  3248            val missing_Ts = filter_indices missing_js Ts
  3242            (* int -> indexname *)
  3249            (* int -> indexname *)
  3321                            (Const (@{const_name Eps}, (T --> bool_T) --> T))) T)
  3328                            (Const (@{const_name Eps}, (T --> bool_T) --> T))) T)
  3322        else
  3329        else
  3323          let val t = Const (original_name s, T) in
  3330          let val t = Const (original_name s, T) in
  3324            (t, format_term_type thy def_table formats t)
  3331            (t, format_term_type thy def_table formats t)
  3325          end)
  3332          end)
  3326       |>> map_types (typ_subst [(@{typ bisim_iterator}, nat_T)] o unbox_type)
  3333       |>> map_types unbit_and_unbox_type
  3327       |>> shorten_names_in_term |>> shorten_abs_vars
  3334       |>> shorten_names_in_term |>> shorten_abs_vars
  3328   in do_const end
  3335   in do_const end
  3329 
  3336 
  3330 (* styp -> string *)
  3337 (* styp -> string *)
  3331 fun assign_operator_for_const (s, T) =
  3338 fun assign_operator_for_const (s, T) =
  3336   else if original_name s <> s then
  3343   else if original_name s <> s then
  3337     assign_operator_for_const (after_name_sep s, T)
  3344     assign_operator_for_const (after_name_sep s, T)
  3338   else
  3345   else
  3339     "="
  3346     "="
  3340 
  3347 
       
  3348 val binary_int_threshold = 4
       
  3349 
       
  3350 (* term -> bool *)
       
  3351 fun may_use_binary_ints (t1 $ t2) =
       
  3352     may_use_binary_ints t1 andalso may_use_binary_ints t2
       
  3353   | may_use_binary_ints (Const (s, _)) =
       
  3354     not (member (op =) [@{const_name Abs_Frac}, @{const_name Rep_Frac},
       
  3355                         @{const_name Frac}, @{const_name norm_frac},
       
  3356                         @{const_name nat_gcd}, @{const_name nat_lcm}] s)
       
  3357   | may_use_binary_ints (Abs (_, _, t')) = may_use_binary_ints t'
       
  3358   | may_use_binary_ints _ = true
       
  3359 
       
  3360 fun should_use_binary_ints (t1 $ t2) =
       
  3361     should_use_binary_ints t1 orelse should_use_binary_ints t2
       
  3362   | should_use_binary_ints (Const (s, _)) =
       
  3363     member (op =) [@{const_name times_nat_inst.times_nat},
       
  3364                    @{const_name div_nat_inst.div_nat},
       
  3365                    @{const_name times_int_inst.times_int},
       
  3366                    @{const_name div_int_inst.div_int}] s
       
  3367     orelse (String.isPrefix numeral_prefix s andalso
       
  3368             let val n = the (Int.fromString (unprefix numeral_prefix s)) in
       
  3369               n <= ~ binary_int_threshold orelse n >= binary_int_threshold
       
  3370             end)
       
  3371   | should_use_binary_ints (Abs (_, _, t')) = should_use_binary_ints t'
       
  3372   | should_use_binary_ints _ = false
       
  3373 
       
  3374 (* typ -> typ *)
       
  3375 fun binarize_nat_and_int_in_type @{typ nat} = @{typ "unsigned_bit word"}
       
  3376   | binarize_nat_and_int_in_type @{typ int} = @{typ "signed_bit word"}
       
  3377   | binarize_nat_and_int_in_type (Type (s, Ts)) =
       
  3378     Type (s, map binarize_nat_and_int_in_type Ts)
       
  3379   | binarize_nat_and_int_in_type T = T
       
  3380 (* term -> term *)
       
  3381 val binarize_nat_and_int_in_term = map_types binarize_nat_and_int_in_type
       
  3382 
  3341 (* extended_context -> term
  3383 (* extended_context -> term
  3342    -> ((term list * term list) * (bool * bool)) * term *)
  3384    -> ((term list * term list) * (bool * bool)) * term *)
  3343 fun preprocess_term (ext_ctxt as {thy, destroy_constrs, boxes, skolemize,
  3385 fun preprocess_term (ext_ctxt as {thy, binary_ints, destroy_constrs, boxes,
  3344                                   uncurry, ...}) t =
  3386                                   skolemize, uncurry, ...}) t =
  3345   let
  3387   let
  3346     val skolem_depth = if skolemize then 4 else ~1
  3388     val skolem_depth = if skolemize then 4 else ~1
  3347     val (((def_ts, nondef_ts), (got_all_mono_user_axioms, no_poly_user_axioms)),
  3389     val (((def_ts, nondef_ts), (got_all_mono_user_axioms, no_poly_user_axioms)),
  3348          core_t) = t |> unfold_defs_in_term ext_ctxt
  3390          core_t) = t |> unfold_defs_in_term ext_ctxt
  3349                      |> Refute.close_form
  3391                      |> Refute.close_form
  3350                      |> skolemize_term_and_more ext_ctxt skolem_depth
  3392                      |> skolemize_term_and_more ext_ctxt skolem_depth
  3351                      |> specialize_consts_in_term ext_ctxt 0
  3393                      |> specialize_consts_in_term ext_ctxt 0
  3352                      |> `(axioms_for_term ext_ctxt)
  3394                      |> `(axioms_for_term ext_ctxt)
  3353     val maybe_box = exists (not_equal (SOME false) o snd) boxes
  3395     val binarize =
       
  3396       case binary_ints of
       
  3397         SOME false => false
       
  3398       | _ =>
       
  3399         forall may_use_binary_ints (core_t :: def_ts @ nondef_ts) andalso
       
  3400         (binary_ints = SOME true
       
  3401          orelse exists should_use_binary_ints (core_t :: def_ts @ nondef_ts))
       
  3402     val box = exists (not_equal (SOME false) o snd) boxes
  3354     val table =
  3403     val table =
  3355       Termtab.empty |> uncurry
  3404       Termtab.empty |> uncurry
  3356         ? fold (add_to_uncurry_table thy) (core_t :: def_ts @ nondef_ts)
  3405         ? fold (add_to_uncurry_table thy) (core_t :: def_ts @ nondef_ts)
  3357     (* bool -> bool -> term -> term *)
  3406     (* bool -> bool -> term -> term *)
  3358     fun do_rest def core =
  3407     fun do_rest def core =
  3359       uncurry ? uncurry_term table
  3408       binarize ? binarize_nat_and_int_in_term
  3360       #> maybe_box ? box_fun_and_pair_in_term ext_ctxt def
  3409       #> uncurry ? uncurry_term table
       
  3410       #> box ? box_fun_and_pair_in_term ext_ctxt def
  3361       #> destroy_constrs ? (pull_out_universal_constrs thy def
  3411       #> destroy_constrs ? (pull_out_universal_constrs thy def
  3362                             #> pull_out_existential_constrs thy
  3412                             #> pull_out_existential_constrs thy
  3363                             #> destroy_pulled_out_constrs ext_ctxt def)
  3413                             #> destroy_pulled_out_constrs ext_ctxt def)
  3364       #> curry_assms
  3414       #> curry_assms
  3365       #> destroy_universal_equalities
  3415       #> destroy_universal_equalities