26 |
26 |
27 val neq_to_eq_False = @{thm neq_to_eq_False}; |
27 val neq_to_eq_False = @{thm neq_to_eq_False}; |
28 |
28 |
29 datatype direction = Left | Right; |
29 datatype direction = Left | Right; |
30 |
30 |
31 fun treeT T = Type (@{type_name tree}, [T]); |
31 fun treeT T = Type (\<^type_name>\<open>tree\<close>, [T]); |
32 |
32 |
33 fun mk_tree' e T n [] = Const (@{const_name Tip}, treeT T) |
33 fun mk_tree' e T n [] = Const (\<^const_name>\<open>Tip\<close>, treeT T) |
34 | mk_tree' e T n xs = |
34 | mk_tree' e T n xs = |
35 let |
35 let |
36 val m = (n - 1) div 2; |
36 val m = (n - 1) div 2; |
37 val (xsl,x::xsr) = chop m xs; |
37 val (xsl,x::xsr) = chop m xs; |
38 val l = mk_tree' e T m xsl; |
38 val l = mk_tree' e T m xsl; |
39 val r = mk_tree' e T (n-(m+1)) xsr; |
39 val r = mk_tree' e T (n-(m+1)) xsr; |
40 in |
40 in |
41 Const (@{const_name Node}, treeT T --> T --> HOLogic.boolT--> treeT T --> treeT T) $ |
41 Const (\<^const_name>\<open>Node\<close>, treeT T --> T --> HOLogic.boolT--> treeT T --> treeT T) $ |
42 l $ e x $ @{term False} $ r |
42 l $ e x $ \<^term>\<open>False\<close> $ r |
43 end |
43 end |
44 |
44 |
45 fun mk_tree e T xs = mk_tree' e T (length xs) xs; |
45 fun mk_tree e T xs = mk_tree' e T (length xs) xs; |
46 |
46 |
47 fun dest_tree (Const (@{const_name Tip}, _)) = [] |
47 fun dest_tree (Const (\<^const_name>\<open>Tip\<close>, _)) = [] |
48 | dest_tree (Const (@{const_name Node}, _) $ l $ e $ _ $ r) = dest_tree l @ e :: dest_tree r |
48 | dest_tree (Const (\<^const_name>\<open>Node\<close>, _) $ l $ e $ _ $ r) = dest_tree l @ e :: dest_tree r |
49 | dest_tree t = raise TERM ("dest_tree", [t]); |
49 | dest_tree t = raise TERM ("dest_tree", [t]); |
50 |
50 |
51 |
51 |
52 |
52 |
53 fun lin_find_tree e (Const (@{const_name Tip}, _)) = NONE |
53 fun lin_find_tree e (Const (\<^const_name>\<open>Tip\<close>, _)) = NONE |
54 | lin_find_tree e (Const (@{const_name Node}, _) $ l $ x $ _ $ r) = |
54 | lin_find_tree e (Const (\<^const_name>\<open>Node\<close>, _) $ l $ x $ _ $ r) = |
55 if e aconv x |
55 if e aconv x |
56 then SOME [] |
56 then SOME [] |
57 else |
57 else |
58 (case lin_find_tree e l of |
58 (case lin_find_tree e l of |
59 SOME path => SOME (Left :: path) |
59 SOME path => SOME (Left :: path) |
61 (case lin_find_tree e r of |
61 (case lin_find_tree e r of |
62 SOME path => SOME (Right :: path) |
62 SOME path => SOME (Right :: path) |
63 | NONE => NONE)) |
63 | NONE => NONE)) |
64 | lin_find_tree e t = raise TERM ("find_tree: input not a tree", [t]) |
64 | lin_find_tree e t = raise TERM ("find_tree: input not a tree", [t]) |
65 |
65 |
66 fun bin_find_tree order e (Const (@{const_name Tip}, _)) = NONE |
66 fun bin_find_tree order e (Const (\<^const_name>\<open>Tip\<close>, _)) = NONE |
67 | bin_find_tree order e (Const (@{const_name Node}, _) $ l $ x $ _ $ r) = |
67 | bin_find_tree order e (Const (\<^const_name>\<open>Node\<close>, _) $ l $ x $ _ $ r) = |
68 (case order (e, x) of |
68 (case order (e, x) of |
69 EQUAL => SOME [] |
69 EQUAL => SOME [] |
70 | LESS => Option.map (cons Left) (bin_find_tree order e l) |
70 | LESS => Option.map (cons Left) (bin_find_tree order e l) |
71 | GREATER => Option.map (cons Right) (bin_find_tree order e r)) |
71 | GREATER => Option.map (cons Right) (bin_find_tree order e r)) |
72 | bin_find_tree order e t = raise TERM ("find_tree: input not a tree", [t]) |
72 | bin_find_tree order e t = raise TERM ("find_tree: input not a tree", [t]) |
291 |> Thm.dest_comb |> #2; |
291 |> Thm.dest_comb |> #2; |
292 val [alpha] = ct |> Thm.ctyp_of_cterm |> Thm.dest_ctyp; |
292 val [alpha] = ct |> Thm.ctyp_of_cterm |> Thm.dest_ctyp; |
293 in (dest_TVar (Thm.typ_of alpha), #1 (dest_Var (Thm.term_of ct))) end; |
293 in (dest_TVar (Thm.typ_of alpha), #1 (dest_Var (Thm.term_of ct))) end; |
294 in |
294 in |
295 |
295 |
296 fun subtractProver ctxt (Const (@{const_name Tip}, T)) ct dist_thm = |
296 fun subtractProver ctxt (Const (\<^const_name>\<open>Tip\<close>, T)) ct dist_thm = |
297 let |
297 let |
298 val ct' = dist_thm |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2; |
298 val ct' = dist_thm |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2; |
299 val [alphaI] = #2 (dest_Type T); |
299 val [alphaI] = #2 (dest_Type T); |
300 in |
300 in |
301 Thm.instantiate |
301 Thm.instantiate |
302 ([(alpha, Thm.ctyp_of ctxt alphaI)], |
302 ([(alpha, Thm.ctyp_of ctxt alphaI)], |
303 [((v, treeT alphaI), ct')]) @{thm subtract_Tip} |
303 [((v, treeT alphaI), ct')]) @{thm subtract_Tip} |
304 end |
304 end |
305 | subtractProver ctxt (Const (@{const_name Node}, nT) $ l $ x $ d $ r) ct dist_thm = |
305 | subtractProver ctxt (Const (\<^const_name>\<open>Node\<close>, nT) $ l $ x $ d $ r) ct dist_thm = |
306 let |
306 let |
307 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; |
308 val (_, [cl, _, _, cr]) = Drule.strip_comb ct; |
308 val (_, [cl, _, _, cr]) = Drule.strip_comb ct; |
309 val ps = the (find_tree x (Thm.term_of ct')); |
309 val ps = the (find_tree x (Thm.term_of ct')); |
310 val del_tree = deleteProver ctxt dist_thm ps; |
310 val del_tree = deleteProver ctxt dist_thm ps; |
340 in SOME thm |
340 in SOME thm |
341 end handle Option.Option => NONE); |
341 end handle Option.Option => NONE); |
342 |
342 |
343 fun distinctTree_tac names ctxt = SUBGOAL (fn (goal, i) => |
343 fun distinctTree_tac names ctxt = SUBGOAL (fn (goal, i) => |
344 (case goal of |
344 (case goal of |
345 Const (@{const_name Trueprop}, _) $ |
345 Const (\<^const_name>\<open>Trueprop\<close>, _) $ |
346 (Const (@{const_name Not}, _) $ (Const (@{const_name HOL.eq}, _) $ x $ y)) => |
346 (Const (\<^const_name>\<open>Not\<close>, _) $ (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ x $ y)) => |
347 (case get_fst_success (neq_x_y ctxt x y) names of |
347 (case get_fst_success (neq_x_y ctxt x y) names of |
348 SOME neq => resolve_tac ctxt [neq] i |
348 SOME neq => resolve_tac ctxt [neq] i |
349 | NONE => no_tac) |
349 | NONE => no_tac) |
350 | _ => no_tac)) |
350 | _ => no_tac)) |
351 |
351 |
352 fun distinctFieldSolver names = |
352 fun distinctFieldSolver names = |
353 mk_solver "distinctFieldSolver" (distinctTree_tac names); |
353 mk_solver "distinctFieldSolver" (distinctTree_tac names); |
354 |
354 |
355 fun distinct_simproc names = |
355 fun distinct_simproc names = |
356 Simplifier.make_simproc @{context} "DistinctTreeProver.distinct_simproc" |
356 Simplifier.make_simproc \<^context> "DistinctTreeProver.distinct_simproc" |
357 {lhss = [@{term "x = y"}], |
357 {lhss = [\<^term>\<open>x = y\<close>], |
358 proc = fn _ => fn ctxt => fn ct => |
358 proc = fn _ => fn ctxt => fn ct => |
359 (case Thm.term_of ct of |
359 (case Thm.term_of ct of |
360 Const (@{const_name HOL.eq}, _) $ x $ y => |
360 Const (\<^const_name>\<open>HOL.eq\<close>, _) $ x $ y => |
361 Option.map (fn neq => @{thm neq_to_eq_False} OF [neq]) |
361 Option.map (fn neq => @{thm neq_to_eq_False} OF [neq]) |
362 (get_fst_success (neq_x_y ctxt x y) names) |
362 (get_fst_success (neq_x_y ctxt x y) names) |
363 | _ => NONE)}; |
363 | _ => NONE)}; |
364 |
364 |
365 end; |
365 end; |