added term postprocessor to Nitpick, to provide custom syntax for typedefs
authorblanchet
Thu, 11 Mar 2010 12:22:11 +0100
changeset 35711548d3f16404b
parent 35710 58acd48904bc
child 35712 77aa29bf14ee
child 35731 f139a9bb6501
added term postprocessor to Nitpick, to provide custom syntax for typedefs
src/HOL/Nitpick_Examples/Manual_Nits.thy
src/HOL/Tools/Nitpick/nitpick.ML
src/HOL/Tools/Nitpick/nitpick_hol.ML
src/HOL/Tools/Nitpick/nitpick_model.ML
     1.1 --- a/src/HOL/Nitpick_Examples/Manual_Nits.thy	Thu Mar 11 10:13:24 2010 +0100
     1.2 +++ b/src/HOL/Nitpick_Examples/Manual_Nits.thy	Thu Mar 11 12:22:11 2010 +0100
     1.3 @@ -117,6 +117,19 @@
     1.4  nitpick [show_datatypes, expect = genuine]
     1.5  oops
     1.6  
     1.7 +ML {*
     1.8 +(* Proof.context -> typ -> term -> term *)
     1.9 +fun my_int_postproc _ T (Const _ $ (Const _ $ t1 $ t2)) =
    1.10 +    HOLogic.mk_number T (snd (HOLogic.dest_number t1) - snd (HOLogic.dest_number t2))
    1.11 +  | my_int_postproc _ _ t = t
    1.12 +*}
    1.13 +
    1.14 +setup {* Nitpick.register_term_postprocessor @{typ my_int} my_int_postproc *}
    1.15 +
    1.16 +lemma "add x y = add x x"
    1.17 +nitpick [show_datatypes]
    1.18 +oops
    1.19 +
    1.20  record point =
    1.21    Xcoord :: int
    1.22    Ycoord :: int
     2.1 --- a/src/HOL/Tools/Nitpick/nitpick.ML	Thu Mar 11 10:13:24 2010 +0100
     2.2 +++ b/src/HOL/Tools/Nitpick/nitpick.ML	Thu Mar 11 12:22:11 2010 +0100
     2.3 @@ -8,6 +8,7 @@
     2.4  signature NITPICK =
     2.5  sig
     2.6    type styp = Nitpick_Util.styp
     2.7 +  type term_postprocessor = Nitpick_Model.term_postprocessor
     2.8    type params = {
     2.9      cards_assigns: (typ option * int list) list,
    2.10      maxes_assigns: (styp option * int list) list,
    2.11 @@ -58,6 +59,9 @@
    2.12    val unregister_frac_type : string -> theory -> theory
    2.13    val register_codatatype : typ -> string -> styp list -> theory -> theory
    2.14    val unregister_codatatype : typ -> theory -> theory
    2.15 +  val register_term_postprocessor :
    2.16 +    typ -> term_postprocessor -> theory -> theory
    2.17 +  val unregister_term_postprocessor : typ -> theory -> theory
    2.18    val pick_nits_in_term :
    2.19      Proof.state -> params -> bool -> int -> int -> int -> (term * term) list
    2.20      -> term list -> term -> string * Proof.state
     3.1 --- a/src/HOL/Tools/Nitpick/nitpick_hol.ML	Thu Mar 11 10:13:24 2010 +0100
     3.2 +++ b/src/HOL/Tools/Nitpick/nitpick_hol.ML	Thu Mar 11 12:22:11 2010 +0100
     3.3 @@ -72,9 +72,11 @@
     3.4    val shortest_name : string -> string
     3.5    val short_name : string -> string
     3.6    val shorten_names_in_term : term -> term
     3.7 +  val strict_type_match : theory -> typ * typ -> bool
     3.8    val type_match : theory -> typ * typ -> bool
     3.9    val const_match : theory -> styp * styp -> bool
    3.10    val term_match : theory -> term * term -> bool
    3.11 +  val frac_from_term_pair : typ -> term -> term -> term
    3.12    val is_TFree : typ -> bool
    3.13    val is_higher_order_type : typ -> bool
    3.14    val is_fun_type : typ -> bool
    3.15 @@ -457,6 +459,15 @@
    3.16      const_match thy ((shortest_name s1, T1), (shortest_name s2, T2))
    3.17    | term_match _ (t1, t2) = t1 aconv t2
    3.18  
    3.19 +(* typ -> term -> term -> term *)
    3.20 +fun frac_from_term_pair T t1 t2 =
    3.21 +  case snd (HOLogic.dest_number t1) of
    3.22 +    0 => HOLogic.mk_number T 0
    3.23 +  | n1 => case snd (HOLogic.dest_number t2) of
    3.24 +            1 => HOLogic.mk_number T n1
    3.25 +          | n2 => Const (@{const_name divide}, T --> T --> T)
    3.26 +                  $ HOLogic.mk_number T n1 $ HOLogic.mk_number T n2
    3.27 +
    3.28  (* typ -> bool *)
    3.29  fun is_TFree (TFree _) = true
    3.30    | is_TFree _ = false
     4.1 --- a/src/HOL/Tools/Nitpick/nitpick_model.ML	Thu Mar 11 10:13:24 2010 +0100
     4.2 +++ b/src/HOL/Tools/Nitpick/nitpick_model.ML	Thu Mar 11 12:22:11 2010 +0100
     4.3 @@ -16,9 +16,13 @@
     4.4      show_skolems: bool,
     4.5      show_datatypes: bool,
     4.6      show_consts: bool}
     4.7 +  type term_postprocessor = Proof.context -> typ -> term -> term
     4.8  
     4.9    structure NameTable : TABLE
    4.10  
    4.11 +  val register_term_postprocessor :
    4.12 +    typ -> term_postprocessor -> theory -> theory
    4.13 +  val unregister_term_postprocessor : typ -> theory -> theory
    4.14    val tuple_list_for_name :
    4.15      nut NameTable.table -> Kodkod.raw_bound list -> nut -> int list list
    4.16    val reconstruct_hol_model :
    4.17 @@ -47,6 +51,14 @@
    4.18    show_datatypes: bool,
    4.19    show_consts: bool}
    4.20  
    4.21 +type term_postprocessor = Proof.context -> typ -> term -> term
    4.22 +
    4.23 +structure Data = Theory_Data(
    4.24 +  type T = (typ * term_postprocessor) list
    4.25 +  val empty = []
    4.26 +  val extend = I
    4.27 +  fun merge (ps1, ps2) = AList.merge (op =) (K true) (ps1, ps2))
    4.28 +
    4.29  val unknown = "?"
    4.30  val unrep = "\<dots>"
    4.31  val maybe_mixfix = "_\<^sup>?"
    4.32 @@ -105,6 +117,11 @@
    4.33                | ord => ord)
    4.34             | _ => Term_Ord.fast_term_ord tp
    4.35  
    4.36 +(* typ -> term_postprocessor -> theory -> theory *)
    4.37 +fun register_term_postprocessor T p = Data.map (cons (T, p))
    4.38 +(* typ -> theory -> theory *)
    4.39 +fun unregister_term_postprocessor T = Data.map (AList.delete (op =) T)
    4.40 +
    4.41  (* nut NameTable.table -> KK.raw_bound list -> nut -> int list list *)
    4.42  fun tuple_list_for_name rel_table bounds name =
    4.43    the (AList.lookup (op =) bounds (the_rel rel_table name)) handle NUT _ => [[]]
    4.44 @@ -271,12 +288,25 @@
    4.45    | mk_tuple _ (t :: _) = t
    4.46    | mk_tuple T [] = raise TYPE ("Nitpick_Model.mk_tuple", [T], [])
    4.47  
    4.48 +(* theory -> typ * typ -> bool *)
    4.49 +fun varified_type_match thy (candid_T, pat_T) =
    4.50 +  strict_type_match thy (candid_T, Logic.varifyT pat_T)
    4.51 +(* Proof.context -> typ -> term -> term *)
    4.52 +fun postprocess_term ctxt T =
    4.53 +  let val thy = ProofContext.theory_of ctxt in
    4.54 +    if null (Data.get thy) then
    4.55 +      I
    4.56 +    else
    4.57 +      (T |> AList.lookup (varified_type_match thy) (Data.get thy)
    4.58 +         |> the_default (K (K I))) ctxt T
    4.59 +  end
    4.60 +
    4.61  (* bool -> atom_pool -> (string * string) * (string * string) -> scope
    4.62     -> nut list -> nut list -> nut list -> nut NameTable.table
    4.63     -> KK.raw_bound list -> typ -> typ -> rep -> int list list -> term *)
    4.64  fun reconstruct_term unfold pool ((maybe_name, abs_name), _)
    4.65 -        ({hol_ctxt as {thy, stds, ...}, binarize, card_assigns, bits, datatypes,
    4.66 -          ofs, ...} : scope) sel_names rel_table bounds =
    4.67 +        ({hol_ctxt as {ctxt, thy, stds, ...}, binarize, card_assigns, bits,
    4.68 +          datatypes, ofs, ...} : scope) sel_names rel_table bounds =
    4.69    let
    4.70      val for_auto = (maybe_name = "")
    4.71      (* int list list -> int *)
    4.72 @@ -476,23 +506,11 @@
    4.73                      |> dest_n_tuple (length uncur_arg_Ts)
    4.74                  val t =
    4.75                    if constr_s = @{const_name Abs_Frac} then
    4.76 -                    let
    4.77 -                      val num_T = body_type T
    4.78 -                      (* int -> term *)
    4.79 -                      val mk_num = HOLogic.mk_number num_T
    4.80 -                    in
    4.81 -                      case ts of
    4.82 -                        [Const (@{const_name Pair}, _) $ t1 $ t2] =>
    4.83 -                        (case snd (HOLogic.dest_number t1) of
    4.84 -                           0 => mk_num 0
    4.85 -                         | n1 => case HOLogic.dest_number t2 |> snd of
    4.86 -                                   1 => mk_num n1
    4.87 -                                 | n2 => Const (@{const_name divide},
    4.88 -                                                num_T --> num_T --> num_T)
    4.89 -                                         $ mk_num n1 $ mk_num n2)
    4.90 -                      | _ => raise TERM ("Nitpick_Model.reconstruct_term.\
    4.91 -                                         \term_for_atom (Abs_Frac)", ts)
    4.92 -                    end
    4.93 +                    case ts of
    4.94 +                      [Const (@{const_name Pair}, _) $ t1 $ t2] =>
    4.95 +                      frac_from_term_pair (body_type T) t1 t2
    4.96 +                    | _ => raise TERM ("Nitpick_Model.reconstruct_term.\
    4.97 +                                       \term_for_atom (Abs_Frac)", ts)
    4.98                    else if not for_auto andalso
    4.99                            (is_abs_fun thy constr_x orelse
   4.100                             constr_s = @{const_name Quot}) then
   4.101 @@ -523,6 +541,7 @@
   4.102                    t
   4.103                end
   4.104            end
   4.105 +          |> postprocess_term ctxt T
   4.106      (* (typ * int) list -> int -> rep -> typ -> typ -> typ -> int list
   4.107         -> term *)
   4.108      and term_for_vect seen k R T1 T2 T' js =