src/HOL/Tools/Sledgehammer/sledgehammer_annotate.ML
author blanchet
Thu, 19 Dec 2013 16:11:20 +0100
changeset 54821 a12796872603
parent 54504 096f7d452164
permissions -rw-r--r--
tuning
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
50263
0b430064296a added comments to new source files
smolkas
parents: 50259
diff changeset
     1
(*  Title:      HOL/Tools/Sledgehammer/sledgehammer_annotate.ML
0b430064296a added comments to new source files
smolkas
parents: 50259
diff changeset
     2
    Author:     Jasmin Blanchette, TU Muenchen
0b430064296a added comments to new source files
smolkas
parents: 50259
diff changeset
     3
    Author:     Steffen Juilf Smolka, TU Muenchen
0b430064296a added comments to new source files
smolkas
parents: 50259
diff changeset
     4
52369
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
     5
Supplements term with a locally minmal, complete set of type constraints.
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
     6
Complete: The constraints suffice to infer the term's types.
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
     7
Minimal: Reducing the set of constraints further will make it incomplete.
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
     8
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
     9
When configuring the pretty printer appropriately, the constraints will show up
52627
smolkas
parents: 52555
diff changeset
    10
as type annotations when printing the term. This allows the term to be printed
smolkas
parents: 52555
diff changeset
    11
and reparsed without a change of types.
52369
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
    12
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
    13
NOTE: Terms should be unchecked before calling annotate_types to avoid awkward
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
    14
syntax.
50263
0b430064296a added comments to new source files
smolkas
parents: 50259
diff changeset
    15
*)
0b430064296a added comments to new source files
smolkas
parents: 50259
diff changeset
    16
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    17
signature SLEDGEHAMMER_ANNOTATE =
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    18
sig
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    19
  val annotate_types : Proof.context -> term -> term
54504
blanchet
parents: 52627
diff changeset
    20
end;
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    21
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    22
structure Sledgehammer_Annotate : SLEDGEHAMMER_ANNOTATE =
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    23
struct
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    24
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    25
(* Util *)
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    26
fun post_traverse_term_type' f _ (t as Const (_, T)) s = f t T s
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    27
  | post_traverse_term_type' f _ (t as Free (_, T)) s = f t T s
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    28
  | post_traverse_term_type' f _ (t as Var (_, T)) s = f t T s
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    29
  | post_traverse_term_type' f env (t as Bound i) s = f t (nth env i) s
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    30
  | post_traverse_term_type' f env (Abs (x, T1, b)) s =
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    31
    let
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    32
      val ((b', s'), T2) = post_traverse_term_type' f (T1 :: env) b s
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    33
    in f (Abs (x, T1, b')) (T1 --> T2) s' end
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    34
  | post_traverse_term_type' f env (u $ v) s =
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    35
    let
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    36
      val ((u', s'), Type (_, [_, T])) = post_traverse_term_type' f env u s
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    37
      val ((v', s''), _) = post_traverse_term_type' f env v s'
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    38
    in f (u' $ v') T s'' end
52555
6811291d1869 moved code -> easier debugging
smolkas
parents: 52452
diff changeset
    39
    handle Bind => raise Fail "Sledgehammer_Annotate: post_traverse_term_type'"
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    40
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    41
fun post_traverse_term_type f s t =
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    42
  post_traverse_term_type' (fn t => fn T => fn s => (f t T s, T)) [] t s |> fst
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    43
fun post_fold_term_type f s t =
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    44
  post_traverse_term_type (fn t => fn T => fn s => (t, f t T s)) s t |> snd
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    45
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    46
fun fold_map_atypes f T s =
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    47
  case T of
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    48
    Type (name, Ts) =>
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    49
        let val (Ts, s) = fold_map (fold_map_atypes f) Ts s in
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    50
          (Type (name, Ts), s)
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    51
        end
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    52
  | _ => f T s
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    53
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    54
(** get unique elements of a list **)
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    55
local
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    56
  fun unique' b x [] = if b then [x] else []
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    57
    | unique' b x (y :: ys) =
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    58
      if x = y then unique' false x ys
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    59
      else unique' true y ys |> b ? cons x
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    60
in
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    61
  fun unique ord xs =
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    62
    case sort ord xs of x :: ys => unique' true x ys | [] => []
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    63
end
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    64
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    65
(** Data structures, orders **)
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    66
val indexname_ord = Term_Ord.fast_indexname_ord
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    67
val cost_ord = prod_ord int_ord (prod_ord int_ord int_ord)
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    68
structure Var_Set_Tab = Table(
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    69
  type key = indexname list
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    70
  val ord = list_ord indexname_ord)
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    71
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    72
(* (1) Generalize types *)
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    73
fun generalize_types ctxt t =
52369
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
    74
  let
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
    75
    val erase_types = map_types (fn _ => dummyT)
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
    76
    (* use schematic type variables *)
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
    77
    val ctxt = ctxt |> Proof_Context.set_mode Proof_Context.mode_pattern
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
    78
    val infer_types = singleton (Type_Infer_Context.infer_types ctxt)
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
    79
  in
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
    80
     t |> erase_types |> infer_types
0b395800fdf0 uncheck terms before annotation to avoid awkward syntax
smolkas
parents: 52366
diff changeset
    81
  end
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
    82
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    83
(* (2) match types *)
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    84
fun match_types ctxt t1 t2 =
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    85
  let
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    86
    val thy = Proof_Context.theory_of ctxt
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    87
    val get_types = post_fold_term_type (K cons) []
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    88
  in
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    89
    fold (Sign.typ_match thy) (get_types t1 ~~ get_types t2) Vartab.empty
52627
smolkas
parents: 52555
diff changeset
    90
    handle Type.TYPE_MATCH => raise Fail "Sledgehammer_Annotate: match_types"
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    91
  end
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    92
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    93
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    94
(* (3) handle trivial tfrees  *)
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    95
fun handle_trivial_tfrees ctxt (t', subst) =
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    96
  let
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    97
    val add_tfree_names =
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    98
      snd #> snd #> fold_atyps (fn TFree (x, _) => cons x | _ => I)
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
    99
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   100
    val trivial_tfree_names =
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   101
      Vartab.fold add_tfree_names subst []
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   102
      |> filter_out (Variable.is_declared ctxt)
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   103
      |> unique fast_string_ord
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   104
    val tfree_name_trivial = Ord_List.member fast_string_ord trivial_tfree_names
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   105
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   106
    val trivial_tvar_names =
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   107
      Vartab.fold
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   108
        (fn (tvar_name, (_, TFree (tfree_name, _))) =>
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   109
               tfree_name_trivial tfree_name ? cons tvar_name
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   110
          | _ => I)
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   111
        subst
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   112
        []
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   113
      |> sort indexname_ord
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   114
    val tvar_name_trivial = Ord_List.member indexname_ord trivial_tvar_names
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   115
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   116
    val t' =
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   117
      t' |> map_types
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   118
              (map_type_tvar
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   119
                (fn (idxn, sort) =>
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   120
                  if tvar_name_trivial idxn then dummyT else TVar (idxn, sort)))
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   121
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   122
    val subst =
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   123
      subst |> fold Vartab.delete trivial_tvar_names
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   124
            |> Vartab.map
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   125
               (K (apsnd (map_type_tfree
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   126
                           (fn (name, sort) =>
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   127
                              if tfree_name_trivial name then dummyT
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   128
                              else TFree (name, sort)))))
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   129
  in
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   130
    (t', subst)
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   131
  end
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   132
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   133
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   134
(* (4) Typing-spot table *)
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   135
local
54821
blanchet
parents: 54504
diff changeset
   136
fun key_of_atype (TVar (z, _)) = Ord_List.insert indexname_ord z
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   137
  | key_of_atype _ = I
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   138
fun key_of_type T = fold_atyps key_of_atype T []
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   139
fun update_tab t T (tab, pos) =
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   140
  (case key_of_type T of
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   141
     [] => tab
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   142
   | key =>
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   143
     let val cost = (size_of_typ T, (size_of_term t, pos)) in
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   144
       case Var_Set_Tab.lookup tab key of
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   145
         NONE => Var_Set_Tab.update_new (key, cost) tab
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   146
       | SOME old_cost =>
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   147
         (case cost_ord (cost, old_cost) of
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   148
            LESS => Var_Set_Tab.update (key, cost) tab
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   149
          | _ => tab)
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   150
     end,
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   151
   pos + 1)
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   152
in
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   153
val typing_spot_table =
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   154
  post_fold_term_type update_tab (Var_Set_Tab.empty, 0) #> fst
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   155
end
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   156
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   157
(* (5) Reverse-greedy *)
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   158
fun reverse_greedy typing_spot_tab =
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   159
  let
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   160
    fun update_count z =
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   161
      fold (fn tvar => fn tab =>
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   162
        let val c = Vartab.lookup tab tvar |> the_default 0 in
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   163
          Vartab.update (tvar, c + z) tab
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   164
        end)
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   165
    fun superfluous tcount =
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   166
      forall (fn tvar => the (Vartab.lookup tcount tvar) > 1)
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   167
    fun drop_superfluous (tvars, (_, (_, spot))) (spots, tcount) =
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   168
      if superfluous tcount tvars then (spots, update_count ~1 tvars tcount)
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   169
      else (spot :: spots, tcount)
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   170
    val (typing_spots, tvar_count_tab) =
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   171
      Var_Set_Tab.fold
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   172
        (fn kv as (k, _) => apfst (cons kv) #> apsnd (update_count 1 k))
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   173
        typing_spot_tab ([], Vartab.empty)
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   174
      |>> sort_distinct (rev_order o cost_ord o pairself snd)
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   175
  in fold drop_superfluous typing_spots ([], tvar_count_tab) |> fst end
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   176
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   177
(* (6) Introduce annotations *)
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   178
fun introduce_annotations subst spots t t' =
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   179
  let
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   180
    fun subst_atype (T as TVar (idxn, S)) subst =
54821
blanchet
parents: 54504
diff changeset
   181
        (Envir.subst_type subst T, Vartab.update (idxn, (S, dummyT)) subst)
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   182
      | subst_atype T subst = (T, subst)
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   183
    val subst_type = fold_map_atypes subst_atype
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   184
    fun collect_annot _ T (subst, cp, ps as p :: ps', annots) =
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   185
        if p <> cp then
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   186
          (subst, cp + 1, ps, annots)
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   187
        else
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   188
          let val (T, subst) = subst_type T subst in
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   189
            (subst, cp + 1, ps', (p, T)::annots)
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   190
          end
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   191
      | collect_annot _ _ x = x
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   192
    val (_, _, _, annots) =
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   193
      post_fold_term_type collect_annot (subst, 0, spots, []) t'
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   194
    fun insert_annot t _ (cp, annots as (p, T) :: annots') =
54821
blanchet
parents: 54504
diff changeset
   195
        if p <> cp then (t, (cp + 1, annots)) else (Type.constraint T t, (cp + 1, annots'))
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   196
      | insert_annot t _ x = (t, x)
52110
411db77f96f2 prevent pretty printer from automatically annotating numerals
smolkas
parents: 51877
diff changeset
   197
  in
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   198
    t |> post_traverse_term_type insert_annot (0, rev annots)
52110
411db77f96f2 prevent pretty printer from automatically annotating numerals
smolkas
parents: 51877
diff changeset
   199
      |> fst
411db77f96f2 prevent pretty printer from automatically annotating numerals
smolkas
parents: 51877
diff changeset
   200
  end
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   201
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   202
(* (7) Annotate *)
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   203
fun annotate_types ctxt t =
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   204
  let
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   205
    val t' = generalize_types ctxt t
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   206
    val subst = match_types ctxt t' t
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   207
    val (t', subst) = (t', subst) |> handle_trivial_tfrees ctxt
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   208
    val typing_spots =
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   209
      t' |> typing_spot_table
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   210
         |> reverse_greedy
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   211
         |> sort int_ord
52452
2207825d67f3 ommit trivial tfrees in annotations
smolkas
parents: 52369
diff changeset
   212
  in introduce_annotations subst typing_spots t t' end
50258
1c708d7728c7 put annotate in own structure
smolkas
parents:
diff changeset
   213
54504
blanchet
parents: 52627
diff changeset
   214
end;