src/HOL/Tools/Nitpick/nitpick_model.ML
changeset 55888 cac1add157e8
parent 55725 9d605a21d7ec
child 55889 6bfbec3dff62
equal deleted inserted replaced
55887:25bd4745ee38 55888:cac1add157e8
   354         | t => t
   354         | t => t
   355       end
   355       end
   356   in index_seq 0 card |> map nth_value_of_type |> sort nice_term_ord end
   356   in index_seq 0 card |> map nth_value_of_type |> sort nice_term_ord end
   357 and reconstruct_term maybe_opt unfold pool
   357 and reconstruct_term maybe_opt unfold pool
   358         (wacky_names as ((maybe_name, abs_name), _))
   358         (wacky_names as ((maybe_name, abs_name), _))
   359         (scope as {hol_ctxt as {thy, ctxt, stds, ...}, binarize, card_assigns,
   359         (scope as {hol_ctxt as {thy, ctxt, ...}, binarize, card_assigns, bits,
   360                    bits, datatypes, ofs, ...})
   360                    datatypes, ofs, ...})
   361         atomss sel_names rel_table bounds =
   361         atomss sel_names rel_table bounds =
   362   let
   362   let
   363     val for_auto = (maybe_name = "")
   363     val for_auto = (maybe_name = "")
   364     fun value_of_bits jss =
   364     fun value_of_bits jss =
   365       let
   365       let
   505       | term_for_atom seen @{typ prop} _ j k =
   505       | term_for_atom seen @{typ prop} _ j k =
   506         HOLogic.mk_Trueprop (term_for_atom seen bool_T bool_T j k)
   506         HOLogic.mk_Trueprop (term_for_atom seen bool_T bool_T j k)
   507       | term_for_atom _ @{typ bool} _ j _ =
   507       | term_for_atom _ @{typ bool} _ j _ =
   508         if j = 0 then @{const False} else @{const True}
   508         if j = 0 then @{const False} else @{const True}
   509       | term_for_atom seen T _ j k =
   509       | term_for_atom seen T _ j k =
   510         if T = nat_T andalso is_standard_datatype thy stds nat_T then
   510         if T = nat_T then
   511           HOLogic.mk_number nat_T j
   511           HOLogic.mk_number nat_T j
   512         else if T = int_T then
   512         else if T = int_T then
   513           HOLogic.mk_number int_T (int_for_atom (k, 0) j)
   513           HOLogic.mk_number int_T (int_for_atom (k, 0) j)
   514         else if is_fp_iterator_type T then
   514         else if is_fp_iterator_type T then
   515           HOLogic.mk_number nat_T (k - j - 1)
   515           HOLogic.mk_number nat_T (k - j - 1)
   516         else if T = @{typ bisim_iterator} then
   516         else if T = @{typ bisim_iterator} then
   517           HOLogic.mk_number nat_T j
   517           HOLogic.mk_number nat_T j
   518         else case datatype_spec datatypes T of
   518         else case datatype_spec datatypes T of
   519           NONE => nth_atom thy atomss pool for_auto T j
   519           NONE => nth_atom thy atomss pool for_auto T j
   520         | SOME {deep = false, ...} => nth_atom thy atomss pool for_auto T j
   520         | SOME {deep = false, ...} => nth_atom thy atomss pool for_auto T j
   521         | SOME {co, standard, constrs, ...} =>
   521         | SOME {co, constrs, ...} =>
   522           let
   522           let
   523             fun tuples_for_const (s, T) =
   523             fun tuples_for_const (s, T) =
   524               tuple_list_for_name rel_table bounds (ConstName (s, T, Any))
   524               tuple_list_for_name rel_table bounds (ConstName (s, T, Any))
   525             fun cyclic_atom () =
   525             fun cyclic_atom () =
   526               nth_atom thy atomss pool for_auto (Type (cyclic_type_name (), []))
   526               nth_atom thy atomss pool for_auto (Type (cyclic_type_name (), []))
   551             val sel_jsss = map tuples_for_const sel_xs
   551             val sel_jsss = map tuples_for_const sel_xs
   552             val arg_jsss =
   552             val arg_jsss =
   553               map (map_filter (fn js => if hd js = real_j then SOME (tl js)
   553               map (map_filter (fn js => if hd js = real_j then SOME (tl js)
   554                                         else NONE)) sel_jsss
   554                                         else NONE)) sel_jsss
   555             val uncur_arg_Ts = binder_types constr_T
   555             val uncur_arg_Ts = binder_types constr_T
   556             val maybe_cyclic = co orelse not standard
       
   557           in
   556           in
   558             if maybe_cyclic andalso not (null seen) andalso
   557             if co andalso not (null seen) andalso
   559                member (op =) (seen |> unfold ? (fst o split_last)) (T, j) then
   558                member (op =) (seen |> unfold ? (fst o split_last)) (T, j) then
   560               cyclic_var ()
   559               cyclic_var ()
   561             else if constr_s = @{const_name Word} then
   560             else if constr_s = @{const_name Word} then
   562               HOLogic.mk_number
   561               HOLogic.mk_number
   563                   (if T = @{typ "unsigned_bit word"} then nat_T else int_T)
   562                   (if T = @{typ "unsigned_bit word"} then nat_T else int_T)
   564                   (value_of_bits (the_single arg_jsss))
   563                   (value_of_bits (the_single arg_jsss))
   565             else
   564             else
   566               let
   565               let
   567                 val seen = seen |> maybe_cyclic ? cons (T, j)
   566                 val seen = seen |> co ? cons (T, j)
   568                 val ts =
   567                 val ts =
   569                   if length arg_Ts = 0 then
   568                   if length arg_Ts = 0 then
   570                     []
   569                     []
   571                   else
   570                   else
   572                     map3 (fn Ts => term_for_rep true seen Ts Ts) arg_Ts arg_Rs
   571                     map3 (fn Ts => term_for_rep true seen Ts Ts) arg_Ts arg_Rs
   585                            constr_s = @{const_name Quot}) then
   584                            constr_s = @{const_name Quot}) then
   586                     Const (abs_name, constr_T) $ the_single ts
   585                     Const (abs_name, constr_T) $ the_single ts
   587                   else
   586                   else
   588                     list_comb (Const constr_x, ts)
   587                     list_comb (Const constr_x, ts)
   589               in
   588               in
   590                 if maybe_cyclic then
   589                 if co then
   591                   let val var = cyclic_var () in
   590                   let val var = cyclic_var () in
   592                     if unfold andalso not standard andalso
   591                     if exists_subterm (curry (op =) var) t then
   593                        length seen = 1 andalso
       
   594                        exists_subterm
       
   595                            (fn Const (s, _) =>
       
   596                                String.isPrefix (cyclic_const_prefix ()) s
       
   597                              | t' => t' = var) t then
       
   598                       subst_atomic [(var, cyclic_atom ())] t
       
   599                     else if exists_subterm (curry (op =) var) t then
       
   600                       if co then
   592                       if co then
   601                         Const (@{const_name The}, (T --> bool_T) --> T)
   593                         Const (@{const_name The}, (T --> bool_T) --> T)
   602                         $ Abs (cyclic_co_val_name (), T,
   594                         $ Abs (cyclic_co_val_name (), T,
   603                                Const (@{const_name HOL.eq}, T --> T --> bool_T)
   595                                Const (@{const_name HOL.eq}, T --> T --> bool_T)
   604                                $ Bound 0 $ abstract_over (var, t))
   596                                $ Bound 0 $ abstract_over (var, t))
   874       else
   866       else
   875         t1 = t2
   867         t1 = t2
   876     end
   868     end
   877 
   869 
   878 fun reconstruct_hol_model {show_datatypes, show_skolems, show_consts}
   870 fun reconstruct_hol_model {show_datatypes, show_skolems, show_consts}
   879         ({hol_ctxt = {thy, ctxt, max_bisim_depth, boxes, stds, wfs, user_axioms,
   871         ({hol_ctxt = {thy, ctxt, max_bisim_depth, boxes, wfs, user_axioms,
   880                       debug, whacks, binary_ints, destroy_constrs, specialize,
   872                       debug, whacks, binary_ints, destroy_constrs, specialize,
   881                       star_linear_preds, total_consts, needs, tac_timeout,
   873                       star_linear_preds, total_consts, needs, tac_timeout,
   882                       evals, case_names, def_tables, nondef_table, nondefs,
   874                       evals, case_names, def_tables, nondef_table, nondefs,
   883                       simp_table, psimp_table, choice_spec_table, intro_table,
   875                       simp_table, psimp_table, choice_spec_table, intro_table,
   884                       ground_thm_table, ersatz_table, skolems, special_funs,
   876                       ground_thm_table, ersatz_table, skolems, special_funs,
   890     val pool = Unsynchronized.ref []
   882     val pool = Unsynchronized.ref []
   891     val (wacky_names as (_, base_step_names), ctxt) =
   883     val (wacky_names as (_, base_step_names), ctxt) =
   892       add_wacky_syntax ctxt
   884       add_wacky_syntax ctxt
   893     val hol_ctxt =
   885     val hol_ctxt =
   894       {thy = thy, ctxt = ctxt, max_bisim_depth = max_bisim_depth, boxes = boxes,
   886       {thy = thy, ctxt = ctxt, max_bisim_depth = max_bisim_depth, boxes = boxes,
   895        stds = stds, wfs = wfs, user_axioms = user_axioms, debug = debug,
   887        wfs = wfs, user_axioms = user_axioms, debug = debug, whacks = whacks,
   896        whacks = whacks, binary_ints = binary_ints,
   888        binary_ints = binary_ints, destroy_constrs = destroy_constrs,
   897        destroy_constrs = destroy_constrs, specialize = specialize,
   889        specialize = specialize, star_linear_preds = star_linear_preds,
   898        star_linear_preds = star_linear_preds, total_consts = total_consts,
   890        total_consts = total_consts, needs = needs, tac_timeout = tac_timeout,
   899        needs = needs, tac_timeout = tac_timeout, evals = evals,
   891        evals = evals, case_names = case_names, def_tables = def_tables,
   900        case_names = case_names, def_tables = def_tables,
       
   901        nondef_table = nondef_table, nondefs = nondefs, simp_table = simp_table,
   892        nondef_table = nondef_table, nondefs = nondefs, simp_table = simp_table,
   902        psimp_table = psimp_table, choice_spec_table = choice_spec_table,
   893        psimp_table = psimp_table, choice_spec_table = choice_spec_table,
   903        intro_table = intro_table, ground_thm_table = ground_thm_table,
   894        intro_table = intro_table, ground_thm_table = ground_thm_table,
   904        ersatz_table = ersatz_table, skolems = skolems,
   895        ersatz_table = ersatz_table, skolems = skolems,
   905        special_funs = special_funs, unrolled_preds = unrolled_preds,
   896        special_funs = special_funs, unrolled_preds = unrolled_preds,
   958                 (map (Syntax.pretty_term ctxt) (all_values card typ) @
   949                 (map (Syntax.pretty_term ctxt) (all_values card typ) @
   959                  (if fun_from_pair complete false then []
   950                  (if fun_from_pair complete false then []
   960                   else [Pretty.str (unrep ())]))]))
   951                   else [Pretty.str (unrep ())]))]))
   961     fun integer_datatype T =
   952     fun integer_datatype T =
   962       [{typ = T, card = card_of_type card_assigns T, co = false,
   953       [{typ = T, card = card_of_type card_assigns T, co = false,
   963         standard = true, self_rec = true, complete = (false, false),
   954         self_rec = true, complete = (false, false), concrete = (true, true),
   964         concrete = (true, true), deep = true, constrs = []}]
   955         deep = true, constrs = []}]
   965       handle TYPE ("Nitpick_HOL.card_of_type", _, _) => []
   956       handle TYPE ("Nitpick_HOL.card_of_type", _, _) => []
   966     val (codatatypes, datatypes) =
   957     val (codatatypes, datatypes) =
   967       datatypes |> filter #deep |> List.partition #co
   958       datatypes |> filter #deep |> List.partition #co
   968                 ||> append (integer_datatype int_T
   959                 ||> append (integer_datatype nat_T @ integer_datatype int_T)
   969                             |> is_standard_datatype thy stds nat_T
       
   970                                ? append (integer_datatype nat_T))
       
   971     val block_of_datatypes =
   960     val block_of_datatypes =
   972       if show_datatypes andalso not (null datatypes) then
   961       if show_datatypes andalso not (null datatypes) then
   973         [Pretty.big_list ("Datatype" ^ plural_s_for_list datatypes ^ ":")
   962         [Pretty.big_list ("Datatype" ^ plural_s_for_list datatypes ^ ":")
   974                          (map pretty_for_datatype datatypes)]
   963                          (map pretty_for_datatype datatypes)]
   975       else
   964       else