7 datatype direction = Left | Right |
7 datatype direction = Left | Right |
8 val mk_tree : ('a -> term) -> typ -> 'a list -> term |
8 val mk_tree : ('a -> term) -> typ -> 'a list -> term |
9 val dest_tree : term -> term list |
9 val dest_tree : term -> term list |
10 val find_tree : term -> term -> direction list option |
10 val find_tree : term -> term -> direction list option |
11 |
11 |
|
12 val in_set: Proof.context -> direction list -> cterm -> thm |
|
13 val find_in_set: Proof.context -> term -> cterm -> thm |
12 val neq_to_eq_False : thm |
14 val neq_to_eq_False : thm |
13 val distinctTreeProver : Proof.context -> thm -> direction list -> direction list -> thm |
15 val distinctTreeProver : Proof.context -> thm -> direction list -> direction list -> thm |
14 val neq_x_y : Proof.context -> term -> term -> string -> thm option |
16 val neq_x_y : Proof.context -> term -> term -> string -> thm option |
15 val distinctFieldSolver : string list -> solver |
17 val distinctFieldSolver : string list -> solver |
16 val distinctTree_tac : string list -> Proof.context -> int -> tactic |
18 val distinctTree_tac : string list -> Proof.context -> int -> tactic |
186 |> Thm.dest_comb; |
188 |> Thm.dest_comb; |
187 val l = Node_l |> Thm.dest_comb |> #2; |
189 val l = Node_l |> Thm.dest_comb |> #2; |
188 in (x, l) end; |
190 in (x, l) end; |
189 |
191 |
190 in |
192 in |
|
193 |
|
194 fun in_set ctxt ps tree = |
|
195 let |
|
196 val in_set = in_set ctxt |
|
197 val (_, [l, x, _, r]) = Drule.strip_comb tree; |
|
198 val xT = Thm.ctyp_of_cterm x; |
|
199 in |
|
200 (case ps of |
|
201 [] => |
|
202 instantiate ctxt |
|
203 [(Thm.ctyp_of_cterm x_in_set_root, xT)] |
|
204 [(l_in_set_root, l), (x_in_set_root, x), (r_in_set_root, r)] @{thm in_set_root} |
|
205 | Left :: ps' => |
|
206 let |
|
207 val in_set_l = in_set ps' l; |
|
208 val in_set_left' = |
|
209 instantiate ctxt |
|
210 [(Thm.ctyp_of_cterm x_in_set_left, xT)] |
|
211 [(x_in_set_left, x), (r_in_set_left, r)] @{thm in_set_left}; |
|
212 in discharge ctxt [in_set_l] in_set_left' end |
|
213 | Right :: ps' => |
|
214 let |
|
215 val in_set_r = in_set ps' r; |
|
216 val in_set_right' = |
|
217 instantiate ctxt |
|
218 [(Thm.ctyp_of_cterm x_in_set_right, xT)] |
|
219 [(x_in_set_right, x), (l_in_set_right, l)] @{thm in_set_right}; |
|
220 in discharge ctxt [in_set_r] in_set_right' end) |
|
221 end; |
|
222 |
|
223 fun find_in_set ctxt t ct = |
|
224 case find_tree t (Thm.term_of ct) of |
|
225 SOME ps => in_set ctxt ps ct |
|
226 | NONE => raise TERM ("find_in_set", [t, Thm.term_of ct]) |
|
227 |
191 (* |
228 (* |
192 1. First get paths x_path y_path of x and y in the tree. |
229 1. First get paths x_path y_path of x and y in the tree. |
193 2. For the common prefix descend into the tree according to the path |
230 2. For the common prefix descend into the tree according to the path |
194 and lemmas all_distinct_left/right |
231 and lemmas all_distinct_left/right |
195 3. If one restpath is empty use distinct_left/right, |
232 3. If one restpath is empty use distinct_left/right, |
208 val (ps, x_rest, y_rest) = split_common_prefix x_path y_path; |
245 val (ps, x_rest, y_rest) = split_common_prefix x_path y_path; |
209 val dist_subtree_thm = dist_subtree ps dist_thm; |
246 val dist_subtree_thm = dist_subtree ps dist_thm; |
210 val subtree = Thm.cprop_of dist_subtree_thm |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2; |
247 val subtree = Thm.cprop_of dist_subtree_thm |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2; |
211 val (_, [l, _, _, r]) = Drule.strip_comb subtree; |
248 val (_, [l, _, _, r]) = Drule.strip_comb subtree; |
212 |
249 |
213 fun in_set ps tree = |
250 val in_set = in_set ctxt |
214 let |
|
215 val (_, [l, x, _, r]) = Drule.strip_comb tree; |
|
216 val xT = Thm.ctyp_of_cterm x; |
|
217 in |
|
218 (case ps of |
|
219 [] => |
|
220 instantiate ctxt |
|
221 [(Thm.ctyp_of_cterm 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} |
|
223 | Left :: ps' => |
|
224 let |
|
225 val in_set_l = in_set ps' l; |
|
226 val in_set_left' = |
|
227 instantiate ctxt |
|
228 [(Thm.ctyp_of_cterm x_in_set_left, xT)] |
|
229 [(x_in_set_left, x), (r_in_set_left, r)] @{thm in_set_left}; |
|
230 in discharge ctxt [in_set_l] in_set_left' end |
|
231 | Right :: ps' => |
|
232 let |
|
233 val in_set_r = in_set ps' r; |
|
234 val in_set_right' = |
|
235 instantiate ctxt |
|
236 [(Thm.ctyp_of_cterm x_in_set_right, xT)] |
|
237 [(x_in_set_right, x), (l_in_set_right, l)] @{thm in_set_right}; |
|
238 in discharge ctxt [in_set_r] in_set_right' end) |
|
239 end; |
|
240 |
|
241 fun in_set' [] = raise TERM ("distinctTreeProver", []) |
251 fun in_set' [] = raise TERM ("distinctTreeProver", []) |
242 | in_set' (Left :: ps) = in_set ps l |
252 | in_set' (Left :: ps) = in_set ps l |
243 | in_set' (Right :: ps) = in_set ps r; |
253 | in_set' (Right :: ps) = in_set ps r; |
244 |
254 |
245 fun distinct_lr node_in_set Left = |
255 fun distinct_lr node_in_set Left = |