88 (* Wrapper around Thm.instantiate. The type instiations of instTs are applied to |
88 (* Wrapper around Thm.instantiate. The type instiations of instTs are applied to |
89 * the right hand sides of insts |
89 * the right hand sides of insts |
90 *) |
90 *) |
91 fun instantiate instTs insts = |
91 fun instantiate instTs insts = |
92 let |
92 let |
93 val instTs' = map (fn (T, U) => (dest_TVar (typ_of T), typ_of U)) instTs; |
93 val instTs' = map (fn (T, U) => (dest_TVar (Thm.typ_of T), Thm.typ_of U)) instTs; |
94 fun substT x = (case AList.lookup (op =) instTs' x of NONE => TVar x | SOME T' => T'); |
94 fun substT x = (case AList.lookup (op =) instTs' x of NONE => TVar x | SOME T' => T'); |
95 fun mapT_and_recertify ct = |
95 fun mapT_and_recertify ct = |
96 let |
96 let |
97 val thy = theory_of_cterm ct; |
97 val thy = Thm.theory_of_cterm ct; |
98 in (cterm_of thy (Term.map_types (Term.map_type_tvar substT) (term_of ct))) end; |
98 in (Thm.cterm_of thy (Term.map_types (Term.map_type_tvar substT) (Thm.term_of ct))) end; |
99 val insts' = map (apfst mapT_and_recertify) insts; |
99 val insts' = map (apfst mapT_and_recertify) insts; |
100 in Thm.instantiate (instTs, insts') end; |
100 in Thm.instantiate (instTs, insts') end; |
101 |
101 |
102 fun tvar_clash ixn S S' = |
102 fun tvar_clash ixn S S' = |
103 raise TYPE ("Type variable has two distinct sorts", [TVar (ixn, S), TVar (ixn, S')], []); |
103 raise TYPE ("Type variable has two distinct sorts", [TVar (ixn, S), TVar (ixn, S')], []); |
131 fun naive_cterm_first_order_match (t, ct) env = |
131 fun naive_cterm_first_order_match (t, ct) env = |
132 let |
132 let |
133 fun mtch (env as (tyinsts, insts)) = |
133 fun mtch (env as (tyinsts, insts)) = |
134 fn (Var (ixn, T), ct) => |
134 fn (Var (ixn, T), ct) => |
135 (case AList.lookup (op =) insts ixn of |
135 (case AList.lookup (op =) insts ixn of |
136 NONE => (naive_typ_match (T, typ_of (ctyp_of_term ct)) tyinsts, (ixn, ct) :: insts) |
136 NONE => |
|
137 (naive_typ_match (T, Thm.typ_of (Thm.ctyp_of_term ct)) tyinsts, (ixn, ct) :: insts) |
137 | SOME _ => env) |
138 | SOME _ => env) |
138 | (f $ t, ct) => |
139 | (f $ t, ct) => |
139 let val (cf, ct') = Thm.dest_comb ct; |
140 let val (cf, ct') = Thm.dest_comb ct; |
140 in mtch (mtch env (f, cf)) (t, ct') end |
141 in mtch (mtch env (f, cf)) (t, ct') end |
141 | _ => env; |
142 | _ => env; |
142 in mtch env (t, ct) end; |
143 in mtch env (t, ct) end; |
143 |
144 |
144 |
145 |
145 fun discharge prems rule = |
146 fun discharge prems rule = |
146 let |
147 let |
147 val thy = theory_of_thm (hd prems); |
148 val thy = Thm.theory_of_thm (hd prems); |
148 val (tyinsts,insts) = |
149 val (tyinsts,insts) = |
149 fold naive_cterm_first_order_match (prems_of rule ~~ map cprop_of prems) ([], []); |
150 fold naive_cterm_first_order_match (Thm.prems_of rule ~~ map Thm.cprop_of prems) ([], []); |
150 |
151 |
151 val tyinsts' = |
152 val tyinsts' = |
152 map (fn (v, (S, U)) => (ctyp_of thy (TVar (v, S)), ctyp_of thy U)) tyinsts; |
153 map (fn (v, (S, U)) => |
|
154 (Thm.ctyp_of thy (TVar (v, S)), Thm.ctyp_of thy U)) tyinsts; |
153 val insts' = |
155 val insts' = |
154 map (fn (idxn, ct) => (cterm_of thy (Var (idxn, typ_of (ctyp_of_term ct))), ct)) insts; |
156 map (fn (idxn, ct) => |
|
157 (Thm.cterm_of thy (Var (idxn, Thm.typ_of (Thm.ctyp_of_term ct))), ct)) insts; |
155 val rule' = Thm.instantiate (tyinsts', insts') rule; |
158 val rule' = Thm.instantiate (tyinsts', insts') rule; |
156 in fold Thm.elim_implies prems rule' end; |
159 in fold Thm.elim_implies prems rule' end; |
157 |
160 |
158 local |
161 local |
159 |
162 |
160 val (l_in_set_root, x_in_set_root, r_in_set_root) = |
163 val (l_in_set_root, x_in_set_root, r_in_set_root) = |
161 let |
164 let |
162 val (Node_l_x_d, r) = |
165 val (Node_l_x_d, r) = |
163 cprop_of @{thm in_set_root} |
166 Thm.cprop_of @{thm in_set_root} |
164 |> Thm.dest_comb |> #2 |
167 |> Thm.dest_comb |> #2 |
165 |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |> Thm.dest_comb; |
168 |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |> Thm.dest_comb; |
166 val (Node_l, x) = Node_l_x_d |> Thm.dest_comb |> #1 |> Thm.dest_comb; |
169 val (Node_l, x) = Node_l_x_d |> Thm.dest_comb |> #1 |> Thm.dest_comb; |
167 val l = Node_l |> Thm.dest_comb |> #2; |
170 val l = Node_l |> Thm.dest_comb |> #2; |
168 in (l,x,r) end; |
171 in (l,x,r) end; |
169 |
172 |
170 val (x_in_set_left, r_in_set_left) = |
173 val (x_in_set_left, r_in_set_left) = |
171 let |
174 let |
172 val (Node_l_x_d, r) = |
175 val (Node_l_x_d, r) = |
173 cprop_of @{thm in_set_left} |
176 Thm.cprop_of @{thm in_set_left} |
174 |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |
177 |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |
175 |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |> Thm.dest_comb; |
178 |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |> Thm.dest_comb; |
176 val x = Node_l_x_d |> Thm.dest_comb |> #1 |> Thm.dest_comb |> #2; |
179 val x = Node_l_x_d |> Thm.dest_comb |> #1 |> Thm.dest_comb |> #2; |
177 in (x, r) end; |
180 in (x, r) end; |
178 |
181 |
179 val (x_in_set_right, l_in_set_right) = |
182 val (x_in_set_right, l_in_set_right) = |
180 let |
183 let |
181 val (Node_l, x) = |
184 val (Node_l, x) = |
182 cprop_of @{thm in_set_right} |
185 Thm.cprop_of @{thm in_set_right} |
183 |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |
186 |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |
184 |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |
187 |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |
185 |> Thm.dest_comb |> #1 |> Thm.dest_comb |> #1 |
188 |> Thm.dest_comb |> #1 |> Thm.dest_comb |> #1 |
186 |> Thm.dest_comb; |
189 |> Thm.dest_comb; |
187 val l = Node_l |> Thm.dest_comb |> #2; |
190 val l = Node_l |> Thm.dest_comb |> #2; |
205 (case p of Left => @{thm all_distinct_left} | Right => @{thm all_distinct_right}) |
208 (case p of Left => @{thm all_distinct_left} | Right => @{thm all_distinct_right}) |
206 in dist_subtree ps (discharge [thm] rule) end; |
209 in dist_subtree ps (discharge [thm] rule) end; |
207 |
210 |
208 val (ps, x_rest, y_rest) = split_common_prefix x_path y_path; |
211 val (ps, x_rest, y_rest) = split_common_prefix x_path y_path; |
209 val dist_subtree_thm = dist_subtree ps dist_thm; |
212 val dist_subtree_thm = dist_subtree ps dist_thm; |
210 val subtree = cprop_of dist_subtree_thm |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2; |
213 val subtree = Thm.cprop_of dist_subtree_thm |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2; |
211 val (_, [l, _, _, r]) = Drule.strip_comb subtree; |
214 val (_, [l, _, _, r]) = Drule.strip_comb subtree; |
212 |
215 |
213 fun in_set ps tree = |
216 fun in_set ps tree = |
214 let |
217 let |
215 val (_, [l, x, _, r]) = Drule.strip_comb tree; |
218 val (_, [l, x, _, r]) = Drule.strip_comb tree; |
216 val xT = ctyp_of_term x; |
219 val xT = Thm.ctyp_of_term x; |
217 in |
220 in |
218 (case ps of |
221 (case ps of |
219 [] => |
222 [] => |
220 instantiate |
223 instantiate |
221 [(ctyp_of_term x_in_set_root, xT)] |
224 [(Thm.ctyp_of_term x_in_set_root, xT)] |
222 [(l_in_set_root, l), (x_in_set_root, x), (r_in_set_root, r)] @{thm in_set_root} |
225 [(l_in_set_root, l), (x_in_set_root, x), (r_in_set_root, r)] @{thm in_set_root} |
223 | Left :: ps' => |
226 | Left :: ps' => |
224 let |
227 let |
225 val in_set_l = in_set ps' l; |
228 val in_set_l = in_set ps' l; |
226 val in_set_left' = |
229 val in_set_left' = |
227 instantiate |
230 instantiate |
228 [(ctyp_of_term x_in_set_left, xT)] |
231 [(Thm.ctyp_of_term x_in_set_left, xT)] |
229 [(x_in_set_left, x), (r_in_set_left, r)] @{thm in_set_left}; |
232 [(x_in_set_left, x), (r_in_set_left, r)] @{thm in_set_left}; |
230 in discharge [in_set_l] in_set_left' end |
233 in discharge [in_set_l] in_set_left' end |
231 | Right :: ps' => |
234 | Right :: ps' => |
232 let |
235 let |
233 val in_set_r = in_set ps' r; |
236 val in_set_r = in_set ps' r; |
234 val in_set_right' = |
237 val in_set_right' = |
235 instantiate |
238 instantiate |
236 [(ctyp_of_term x_in_set_right, xT)] |
239 [(Thm.ctyp_of_term x_in_set_right, xT)] |
237 [(x_in_set_right, x), (l_in_set_right, l)] @{thm in_set_right}; |
240 [(x_in_set_right, x), (l_in_set_right, l)] @{thm in_set_right}; |
238 in discharge [in_set_r] in_set_right' end) |
241 in discharge [in_set_r] in_set_right' end) |
239 end; |
242 end; |
240 |
243 |
241 fun in_set' [] = raise TERM ("distinctTreeProver", []) |
244 fun in_set' [] = raise TERM ("distinctTreeProver", []) |
284 let |
287 let |
285 val ct = |
288 val ct = |
286 @{thm subtract_Tip} |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |
289 @{thm subtract_Tip} |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |
287 |> Thm.dest_comb |> #2; |
290 |> Thm.dest_comb |> #2; |
288 val [alpha] = ct |> Thm.ctyp_of_term |> Thm.dest_ctyp; |
291 val [alpha] = ct |> Thm.ctyp_of_term |> Thm.dest_ctyp; |
289 in (alpha, #1 (dest_Var (term_of ct))) end; |
292 in (alpha, #1 (dest_Var (Thm.term_of ct))) end; |
290 in |
293 in |
291 |
294 |
292 fun subtractProver (Const (@{const_name Tip}, T)) ct dist_thm = |
295 fun subtractProver (Const (@{const_name Tip}, T)) ct dist_thm = |
293 let |
296 let |
294 val ct' = dist_thm |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2; |
297 val ct' = dist_thm |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2; |
295 val thy = theory_of_cterm ct; |
298 val thy = Thm.theory_of_cterm ct; |
296 val [alphaI] = #2 (dest_Type T); |
299 val [alphaI] = #2 (dest_Type T); |
297 in |
300 in |
298 Thm.instantiate |
301 Thm.instantiate |
299 ([(alpha, ctyp_of thy alphaI)], |
302 ([(alpha, Thm.ctyp_of thy alphaI)], |
300 [(cterm_of thy (Var (v, treeT alphaI)), ct')]) @{thm subtract_Tip} |
303 [(Thm.cterm_of thy (Var (v, treeT alphaI)), ct')]) @{thm subtract_Tip} |
301 end |
304 end |
302 | subtractProver (Const (@{const_name Node}, nT) $ l $ x $ d $ r) ct dist_thm = |
305 | subtractProver (Const (@{const_name Node}, nT) $ l $ x $ d $ r) ct dist_thm = |
303 let |
306 let |
304 val ct' = dist_thm |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2; |
307 val ct' = dist_thm |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2; |
305 val (_, [cl, _, _, cr]) = Drule.strip_comb ct; |
308 val (_, [cl, _, _, cr]) = Drule.strip_comb ct; |
306 val ps = the (find_tree x (term_of ct')); |
309 val ps = the (find_tree x (Thm.term_of ct')); |
307 val del_tree = deleteProver dist_thm ps; |
310 val del_tree = deleteProver dist_thm ps; |
308 val dist_thm' = discharge [del_tree, dist_thm] @{thm delete_Some_all_distinct}; |
311 val dist_thm' = discharge [del_tree, dist_thm] @{thm delete_Some_all_distinct}; |
309 val sub_l = subtractProver (term_of cl) cl (dist_thm'); |
312 val sub_l = subtractProver (Thm.term_of cl) cl (dist_thm'); |
310 val sub_r = |
313 val sub_r = |
311 subtractProver (term_of cr) cr |
314 subtractProver (Thm.term_of cr) cr |
312 (discharge [sub_l, dist_thm'] @{thm subtract_Some_all_distinct_res}); |
315 (discharge [sub_l, dist_thm'] @{thm subtract_Some_all_distinct_res}); |
313 in discharge [del_tree, sub_l, sub_r] @{thm subtract_Node} end; |
316 in discharge [del_tree, sub_l, sub_r] @{thm subtract_Node} end; |
314 |
317 |
315 end; |
318 end; |
316 |
319 |
317 fun distinct_implProver dist_thm ct = |
320 fun distinct_implProver dist_thm ct = |
318 let |
321 let |
319 val ctree = ct |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2; |
322 val ctree = ct |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2; |
320 val sub = subtractProver (term_of ctree) ctree dist_thm; |
323 val sub = subtractProver (Thm.term_of ctree) ctree dist_thm; |
321 in @{thm subtract_Some_all_distinct} OF [sub, dist_thm] end; |
324 in @{thm subtract_Some_all_distinct} OF [sub, dist_thm] end; |
322 |
325 |
323 fun get_fst_success f [] = NONE |
326 fun get_fst_success f [] = NONE |
324 | get_fst_success f (x :: xs) = |
327 | get_fst_success f (x :: xs) = |
325 (case f x of |
328 (case f x of |