equal
deleted
inserted
replaced
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' |