src/HOL/Tools/SMT/smt_monomorph.ML
changeset 41212 2781e8c76165
parent 41174 10eb369f8c01
child 41762 00060198de12
equal deleted inserted replaced
41211:1e2e16bc0077 41212:2781e8c76165
    74 
    74 
    75 
    75 
    76 
    76 
    77 (* search for necessary substitutions *)
    77 (* search for necessary substitutions *)
    78 
    78 
    79 fun new_substitutions thy grounds (n, T) subst =
    79 fun new_substitutions thy limit grounds (n, T) subst =
    80   if not (typ_has_tvars T) then [subst]
    80   if not (typ_has_tvars T) then [subst]
    81   else
    81   else
    82     Symtab.lookup_list grounds n
    82     Symtab.lookup_list grounds n
    83     |> map_filter (try (fn U => Sign.typ_match thy (T, U) subst))
    83     |> map_filter (try (fn U => Sign.typ_match thy (T, U) subst))
    84     |> cons subst
    84     |> cons subst
       
    85     |> take limit (* limit the breadth of the search as well as the width *)
    85 
    86 
    86 fun apply_subst grounds consts subst =
    87 fun apply_subst grounds consts subst =
    87   let
    88   let
    88     fun is_new_ground (n, T) = not (typ_has_tvars T) andalso
    89     fun is_new_ground (n, T) = not (typ_has_tvars T) andalso
    89       not (member (op =) (Symtab.lookup_list grounds n) T)
    90       not (member (op =) (Symtab.lookup_list grounds n) T)
    95         |> is_new_ground c ? Symtab.insert_list (op =) c
    96         |> is_new_ground c ? Symtab.insert_list (op =) c
    96         |> pair c
    97         |> pair c
    97       end
    98       end
    98   in fold_map apply_const consts #>> pair subst end
    99   in fold_map apply_const consts #>> pair subst end
    99 
   100 
   100 fun specialize thy all_grounds new_grounds scs =
   101 fun specialize thy limit all_grounds new_grounds scs =
   101   let
   102   let
   102     fun spec (subst, consts) next_grounds =
   103     fun spec (subst, consts) next_grounds =
   103       [subst]
   104       [subst]
   104       |> fold (maps o new_substitutions thy new_grounds) consts
   105       |> fold (maps o new_substitutions thy limit new_grounds) consts
   105       |> rpair next_grounds
   106       |> rpair next_grounds
   106       |-> fold_map (apply_subst all_grounds consts)
   107       |-> fold_map (apply_subst all_grounds consts)
   107   in
   108   in
   108     fold_map spec scs #>> (fn scss =>
   109     fold_map spec scs #>> (fn scss =>
   109     fold (fold (insert (eq_snd (op =)))) scss [])
   110     fold (fold (insert (eq_snd (op =)))) scss [])
   113 
   114 
   114 fun search_substitutions ctxt limit all_grounds new_grounds scss =
   115 fun search_substitutions ctxt limit all_grounds new_grounds scss =
   115   let
   116   let
   116     val thy = ProofContext.theory_of ctxt
   117     val thy = ProofContext.theory_of ctxt
   117     val all_grounds' = Symtab.merge_list (op =) (all_grounds, new_grounds)
   118     val all_grounds' = Symtab.merge_list (op =) (all_grounds, new_grounds)
   118     val spec = specialize thy all_grounds' new_grounds
   119     val spec = specialize thy limit all_grounds' new_grounds
   119     val (scss', new_grounds') = fold_map spec scss Symtab.empty
   120     val (scss', new_grounds') = fold_map spec scss Symtab.empty
   120   in
   121   in
   121     if Symtab.is_empty new_grounds' then scss'
   122     if Symtab.is_empty new_grounds' then scss'
   122     else if limit > 0 then
   123     else if limit > 0 then
   123       search_substitutions ctxt (limit-1) all_grounds' new_grounds' scss'
   124       search_substitutions ctxt (limit-1) all_grounds' new_grounds' scss'