src/HOL/Tools/Nitpick/nitpick.ML
changeset 33566 1c62ac4ef6d1
parent 33292 affe60b3d864
parent 33561 ab01b72715ef
child 33568 532b915afa14
equal deleted inserted replaced
33300:939ca97f5a11 33566:1c62ac4ef6d1
    21     debug: bool,
    21     debug: bool,
    22     verbose: bool,
    22     verbose: bool,
    23     overlord: bool,
    23     overlord: bool,
    24     user_axioms: bool option,
    24     user_axioms: bool option,
    25     assms: bool,
    25     assms: bool,
    26     coalesce_type_vars: bool,
    26     merge_type_vars: bool,
    27     destroy_constrs: bool,
    27     destroy_constrs: bool,
    28     specialize: bool,
    28     specialize: bool,
    29     skolemize: bool,
    29     skolemize: bool,
    30     star_linear_preds: bool,
    30     star_linear_preds: bool,
    31     uncurry: bool,
    31     uncurry: bool,
    86   debug: bool,
    86   debug: bool,
    87   verbose: bool,
    87   verbose: bool,
    88   overlord: bool,
    88   overlord: bool,
    89   user_axioms: bool option,
    89   user_axioms: bool option,
    90   assms: bool,
    90   assms: bool,
    91   coalesce_type_vars: bool,
    91   merge_type_vars: bool,
    92   destroy_constrs: bool,
    92   destroy_constrs: bool,
    93   specialize: bool,
    93   specialize: bool,
    94   skolemize: bool,
    94   skolemize: bool,
    95   star_linear_preds: bool,
    95   star_linear_preds: bool,
    96   uncurry: bool,
    96   uncurry: bool,
   173     val timer = Timer.startRealTimer ()
   173     val timer = Timer.startRealTimer ()
   174     val thy = Proof.theory_of state
   174     val thy = Proof.theory_of state
   175     val ctxt = Proof.context_of state
   175     val ctxt = Proof.context_of state
   176     val {cards_assigns, maxes_assigns, iters_assigns, bisim_depths, boxes,
   176     val {cards_assigns, maxes_assigns, iters_assigns, bisim_depths, boxes,
   177          monos, wfs, sat_solver, blocking, falsify, debug, verbose, overlord,
   177          monos, wfs, sat_solver, blocking, falsify, debug, verbose, overlord,
   178          user_axioms, assms, coalesce_type_vars, destroy_constrs, specialize,
   178          user_axioms, assms, merge_type_vars, destroy_constrs, specialize,
   179          skolemize, star_linear_preds, uncurry, fast_descrs, peephole_optim,
   179          skolemize, star_linear_preds, uncurry, fast_descrs, peephole_optim,
   180          tac_timeout, sym_break, sharing_depth, flatten_props, max_threads,
   180          tac_timeout, sym_break, sharing_depth, flatten_props, max_threads,
   181          show_skolems, show_datatypes, show_consts, evals, formats,
   181          show_skolems, show_datatypes, show_consts, evals, formats,
   182          max_potential, max_genuine, check_potential, check_genuine, batch_size,
   182          max_potential, max_genuine, check_potential, check_genuine, batch_size,
   183          ...} =
   183          ...} =
   185     val state_ref = Unsynchronized.ref state
   185     val state_ref = Unsynchronized.ref state
   186     (* Pretty.T -> unit *)
   186     (* Pretty.T -> unit *)
   187     val pprint =
   187     val pprint =
   188       if auto then
   188       if auto then
   189         Unsynchronized.change state_ref o Proof.goal_message o K
   189         Unsynchronized.change state_ref o Proof.goal_message o K
   190         o curry Pretty.blk 0 o cons (Pretty.str "") o single
   190         o Pretty.chunks o cons (Pretty.str "") o single
   191         o Pretty.mark Markup.hilite
   191         o Pretty.mark Markup.hilite
   192       else
   192       else
   193         priority o Pretty.string_of
   193         priority o Pretty.string_of
   194     (* (unit -> Pretty.T) -> unit *)
   194     (* (unit -> Pretty.T) -> unit *)
   195     fun pprint_m f = () |> not auto ? pprint o f
   195     fun pprint_m f = () |> not auto ? pprint o f
   218                     Logic.mk_conjunction_list (neg_t :: orig_assm_ts)
   218                     Logic.mk_conjunction_list (neg_t :: orig_assm_ts)
   219                   else
   219                   else
   220                     neg_t
   220                     neg_t
   221     val (assms_t, evals) =
   221     val (assms_t, evals) =
   222       assms_t :: evals
   222       assms_t :: evals
   223       |> coalesce_type_vars ? coalesce_type_vars_in_terms
   223       |> merge_type_vars ? merge_type_vars_in_terms
   224       |> hd pairf tl
   224       |> hd pairf tl
   225     val original_max_potential = max_potential
   225     val original_max_potential = max_potential
   226     val original_max_genuine = max_genuine
   226     val original_max_genuine = max_genuine
   227 (*
   227 (*
   228     val _ = priority ("*** " ^ Syntax.string_of_term ctxt orig_t)
   228     val _ = priority ("*** " ^ Syntax.string_of_term ctxt orig_t)
   281                                      nondef_ts))
   281                                      nondef_ts))
   282     val _ = List.app (ignore o Term.type_of) (core_t :: def_ts @ nondef_ts)
   282     val _ = List.app (ignore o Term.type_of) (core_t :: def_ts @ nondef_ts)
   283             handle TYPE (_, Ts, ts) =>
   283             handle TYPE (_, Ts, ts) =>
   284                    raise TYPE ("Nitpick.pick_them_nits_in_term", Ts, ts)
   284                    raise TYPE ("Nitpick.pick_them_nits_in_term", Ts, ts)
   285 
   285 
       
   286     val core_u = nut_from_term thy fast_descrs (!special_funs) Eq core_t
       
   287     val def_us = map (nut_from_term thy fast_descrs (!special_funs) DefEq)
       
   288                      def_ts
       
   289     val nondef_us = map (nut_from_term thy fast_descrs (!special_funs) Eq)
       
   290                         nondef_ts
       
   291     val (free_names, const_names) =
       
   292       fold add_free_and_const_names (core_u :: def_us @ nondef_us) ([], [])
       
   293     val (sel_names, nonsel_names) =
       
   294       List.partition (is_sel o nickname_of) const_names
       
   295     val would_be_genuine = got_all_user_axioms andalso none_true wfs
       
   296 (*
       
   297     val _ = List.app (priority o string_for_nut ctxt)
       
   298                      (core_u :: def_us @ nondef_us)
       
   299 *)
       
   300 
   286     val unique_scope = forall (equal 1 o length o snd) cards_assigns
   301     val unique_scope = forall (equal 1 o length o snd) cards_assigns
   287     (* typ -> bool *)
   302     (* typ -> bool *)
   288     fun is_free_type_monotonic T =
   303     fun is_free_type_monotonic T =
   289       unique_scope orelse
   304       unique_scope orelse
   290       case triple_lookup (type_match thy) monos T of
   305       case triple_lookup (type_match thy) monos T of
   296         SOME (SOME b) => b
   311         SOME (SOME b) => b
   297       | _ =>
   312       | _ =>
   298         not (is_pure_typedef thy T) orelse is_univ_typedef thy T
   313         not (is_pure_typedef thy T) orelse is_univ_typedef thy T
   299         orelse is_number_type thy T
   314         orelse is_number_type thy T
   300         orelse formulas_monotonic ext_ctxt T def_ts nondef_ts core_t
   315         orelse formulas_monotonic ext_ctxt T def_ts nondef_ts core_t
       
   316     fun is_datatype_shallow T =
       
   317       not (exists (equal T o domain_type o type_of) sel_names)
   301     val Ts = ground_types_in_terms ext_ctxt (core_t :: def_ts @ nondef_ts)
   318     val Ts = ground_types_in_terms ext_ctxt (core_t :: def_ts @ nondef_ts)
   302              |> sort TermOrd.typ_ord
   319              |> sort TermOrd.typ_ord
   303     val (all_dataTs, all_free_Ts) =
   320     val (all_dataTs, all_free_Ts) =
   304       List.partition (is_integer_type orf is_datatype thy) Ts
   321       List.partition (is_integer_type orf is_datatype thy) Ts
   305     val (mono_dataTs, nonmono_dataTs) =
   322     val (mono_dataTs, nonmono_dataTs) =
   324                     end)
   341                     end)
   325       else
   342       else
   326         ()
   343         ()
   327     val mono_Ts = mono_dataTs @ mono_free_Ts
   344     val mono_Ts = mono_dataTs @ mono_free_Ts
   328     val nonmono_Ts = nonmono_dataTs @ nonmono_free_Ts
   345     val nonmono_Ts = nonmono_dataTs @ nonmono_free_Ts
   329 
   346     val shallow_dataTs = filter is_datatype_shallow mono_dataTs
   330 (*
   347 (*
   331     val _ = priority "Monotonic datatypes:"
   348     val _ = priority "Monotonic datatypes:"
   332     val _ = List.app (priority o string_for_type ctxt) mono_dataTs
   349     val _ = List.app (priority o string_for_type ctxt) mono_dataTs
   333     val _ = priority "Nonmonotonic datatypes:"
   350     val _ = priority "Nonmonotonic datatypes:"
   334     val _ = List.app (priority o string_for_type ctxt) nonmono_dataTs
   351     val _ = List.app (priority o string_for_type ctxt) nonmono_dataTs
   336     val _ = List.app (priority o string_for_type ctxt) mono_free_Ts
   353     val _ = List.app (priority o string_for_type ctxt) mono_free_Ts
   337     val _ = priority "Nonmonotonic free types:"
   354     val _ = priority "Nonmonotonic free types:"
   338     val _ = List.app (priority o string_for_type ctxt) nonmono_free_Ts
   355     val _ = List.app (priority o string_for_type ctxt) nonmono_free_Ts
   339 *)
   356 *)
   340 
   357 
   341     val core_u = nut_from_term thy fast_descrs (!special_funs) Eq core_t
       
   342     val def_us = map (nut_from_term thy fast_descrs (!special_funs) DefEq)
       
   343                      def_ts
       
   344     val nondef_us = map (nut_from_term thy fast_descrs (!special_funs) Eq)
       
   345                         nondef_ts
       
   346     val (free_names, const_names) =
       
   347       fold add_free_and_const_names (core_u :: def_us @ nondef_us) ([], [])
       
   348     val nonsel_names = filter_out (is_sel o nickname_of) const_names
       
   349     val would_be_genuine = got_all_user_axioms andalso none_true wfs
       
   350 (*
       
   351     val _ = List.app (priority o string_for_nut ctxt)
       
   352                      (core_u :: def_us @ nondef_us)
       
   353 *)
       
   354     val need_incremental = Int.max (max_potential, max_genuine) >= 2
   358     val need_incremental = Int.max (max_potential, max_genuine) >= 2
   355     val effective_sat_solver =
   359     val effective_sat_solver =
   356       if sat_solver <> "smart" then
   360       if sat_solver <> "smart" then
   357         if need_incremental andalso
   361         if need_incremental andalso
   358            not (sat_solver mem Kodkod_SAT.configured_sat_solvers true) then
   362            not (sat_solver mem Kodkod_SAT.configured_sat_solvers true) then
   776         val unsat =
   780         val unsat =
   777           fold (fn scope =>
   781           fold (fn scope =>
   778                    case scope_count (do_filter (!generated_problems)) scope of
   782                    case scope_count (do_filter (!generated_problems)) scope of
   779                      0 => I
   783                      0 => I
   780                    | n =>
   784                    | n =>
   781                      if scope_count (do_filter (these (!checked_problems)))
   785                      scope_count (do_filter (these (!checked_problems)))
   782                                     scope = n then
   786                                  scope = n
   783                        Integer.add 1
   787                      ? Integer.add 1) (!generated_scopes) 0
   784                      else
       
   785                        I) (!generated_scopes) 0
       
   786       in
   788       in
   787         "Nitpick " ^ did_so_and_so ^
   789         "Nitpick " ^ did_so_and_so ^
   788         (if is_some (!checked_problems) andalso total > 0 then
   790         (if is_some (!checked_problems) andalso total > 0 then
   789            " after checking " ^
   791            " after checking " ^
   790            string_of_int (Int.min (total - 1, unsat)) ^ " of " ^
   792            string_of_int (Int.min (total - 1, unsat)) ^ " of " ^
   812           run_batches (j + 1) n (if max_genuine > 0 then batches else []) z
   814           run_batches (j + 1) n (if max_genuine > 0 then batches else []) z
   813         end
   815         end
   814 
   816 
   815     val _ = scopes := all_scopes ext_ctxt sym_break cards_assigns maxes_assigns
   817     val _ = scopes := all_scopes ext_ctxt sym_break cards_assigns maxes_assigns
   816                                  iters_assigns bisim_depths mono_Ts nonmono_Ts
   818                                  iters_assigns bisim_depths mono_Ts nonmono_Ts
       
   819                                  shallow_dataTs
   817     val batches = batch_list batch_size (!scopes)
   820     val batches = batch_list batch_size (!scopes)
   818     val outcome_code =
   821     val outcome_code =
   819       (run_batches 0 (length batches) batches (max_potential, max_genuine, 0)
   822       (run_batches 0 (length batches) batches (max_potential, max_genuine, 0)
   820        handle Exn.Interrupt => do_interrupted ())
   823        handle Exn.Interrupt => do_interrupted ())
   821       handle TimeLimit.TimeOut =>
   824       handle TimeLimit.TimeOut =>