22 if P x then (x :: ins, outs) else (ins, x :: outs) |
22 if P x then (x :: ins, outs) else (ins, x :: outs) |
23 end; |
23 end; |
24 |
24 |
25 fun ALLGOALS_SKIP skip tac st = |
25 fun ALLGOALS_SKIP skip tac st = |
26 let fun doall n = if n = skip then all_tac else tac n THEN doall (n - 1) |
26 let fun doall n = if n = skip then all_tac else tac n THEN doall (n - 1) |
27 in doall (nprems_of st) st end; |
27 in doall (Thm.nprems_of st) st end; |
28 |
28 |
29 fun THEN_ALL_NEW_SKIP skip tac1 tac2 i st = |
29 fun THEN_ALL_NEW_SKIP skip tac1 tac2 i st = |
30 st |> (tac1 i THEN (fn st' => |
30 st |> (tac1 i THEN (fn st' => |
31 Seq.INTERVAL tac2 (i + skip) (i + nprems_of st' - nprems_of st) st')); |
31 Seq.INTERVAL tac2 (i + skip) (i + Thm.nprems_of st' - Thm.nprems_of st) st')); |
32 |
32 |
33 fun DELETE_PREMS_AFTER skip tac i st = |
33 fun DELETE_PREMS_AFTER skip tac i st = |
34 let |
34 let |
35 val n = nth (prems_of st) (i - 1) |> Logic.strip_assums_hyp |> length; |
35 val n = nth (Thm.prems_of st) (i - 1) |> Logic.strip_assums_hyp |> length; |
36 in |
36 in |
37 (THEN_ALL_NEW_SKIP skip tac (REPEAT_DETERM_N n o eresolve0_tac [thin_rl])) i st |
37 (THEN_ALL_NEW_SKIP skip tac (REPEAT_DETERM_N n o eresolve0_tac [thin_rl])) i st |
38 end; |
38 end; |
39 |
39 |
40 fun coinduction_tac ctxt raw_vars opt_raw_thm prems = HEADGOAL (SUBGOAL_CASES (fn (goal, _, _) => |
40 fun coinduction_tac ctxt raw_vars opt_raw_thm prems = HEADGOAL (SUBGOAL_CASES (fn (goal, _, _) => |
54 Object_Logic.rulify_tac ctxt THEN' |
54 Object_Logic.rulify_tac ctxt THEN' |
55 Method.insert_tac prems THEN' |
55 Method.insert_tac prems THEN' |
56 Object_Logic.atomize_prems_tac ctxt THEN' |
56 Object_Logic.atomize_prems_tac ctxt THEN' |
57 DELETE_PREMS_AFTER skip (Subgoal.FOCUS (fn {concl, context = ctxt, params, prems, ...} => |
57 DELETE_PREMS_AFTER skip (Subgoal.FOCUS (fn {concl, context = ctxt, params, prems, ...} => |
58 let |
58 let |
59 val vars = raw_vars @ map (term_of o snd) params; |
59 val vars = raw_vars @ map (Thm.term_of o snd) params; |
60 val names_ctxt = ctxt |
60 val names_ctxt = ctxt |
61 |> fold Variable.declare_names vars |
61 |> fold Variable.declare_names vars |
62 |> fold Variable.declare_thm (raw_thm :: prems); |
62 |> fold Variable.declare_thm (raw_thm :: prems); |
63 val thm_concl = Thm.cprop_of raw_thm |> strip_imp_concl; |
63 val thm_concl = Thm.cprop_of raw_thm |> strip_imp_concl; |
64 val (rhoTs, rhots) = Thm.match (thm_concl, concl) |
64 val (rhoTs, rhots) = Thm.match (thm_concl, concl) |
65 |>> map (apply2 typ_of) |
65 |>> map (apply2 Thm.typ_of) |
66 ||> map (apply2 term_of); |
66 ||> map (apply2 Thm.term_of); |
67 val xs = hd (Thm.prems_of raw_thm) |> HOLogic.dest_Trueprop |> strip_comb |> snd |
67 val xs = hd (Thm.prems_of raw_thm) |> HOLogic.dest_Trueprop |> strip_comb |> snd |
68 |> map (subst_atomic_types rhoTs); |
68 |> map (subst_atomic_types rhoTs); |
69 val raw_eqs = map (fn x => (x, AList.lookup op aconv rhots x |> the)) xs; |
69 val raw_eqs = map (fn x => (x, AList.lookup op aconv rhots x |> the)) xs; |
70 val ((names, ctxt), Ts) = map_split (apfst fst o dest_Var o fst) raw_eqs |
70 val ((names, ctxt), Ts) = map_split (apfst fst o dest_Var o fst) raw_eqs |
71 |>> (fn names => Variable.variant_fixes names names_ctxt) ; |
71 |>> (fn names => Variable.variant_fixes names names_ctxt) ; |
72 val eqs = |
72 val eqs = |
73 @{map 3} (fn name => fn T => fn (_, rhs) => |
73 @{map 3} (fn name => fn T => fn (_, rhs) => |
74 HOLogic.mk_eq (Free (name, T), rhs)) |
74 HOLogic.mk_eq (Free (name, T), rhs)) |
75 names Ts raw_eqs; |
75 names Ts raw_eqs; |
76 val phi = eqs @ map (HOLogic.dest_Trueprop o prop_of) prems |
76 val phi = eqs @ map (HOLogic.dest_Trueprop o Thm.prop_of) prems |
77 |> try (Library.foldr1 HOLogic.mk_conj) |
77 |> try (Library.foldr1 HOLogic.mk_conj) |
78 |> the_default @{term True} |
78 |> the_default @{term True} |
79 |> Ctr_Sugar_Util.list_exists_free vars |
79 |> Ctr_Sugar_Util.list_exists_free vars |
80 |> Term.map_abs_vars (Variable.revert_fixed ctxt) |
80 |> Term.map_abs_vars (Variable.revert_fixed ctxt) |
81 |> fold_rev Term.absfree (names ~~ Ts) |
81 |> fold_rev Term.absfree (names ~~ Ts) |
102 let |
102 let |
103 val (init, last) = funpow_yield (p + e - 1) HOLogic.conj_elim inv; |
103 val (init, last) = funpow_yield (p + e - 1) HOLogic.conj_elim inv; |
104 val inv_thms = init @ [last]; |
104 val inv_thms = init @ [last]; |
105 val eqs = take e inv_thms; |
105 val eqs = take e inv_thms; |
106 fun is_local_var t = |
106 fun is_local_var t = |
107 member (fn (t, (_, t')) => t aconv (term_of t')) params t; |
107 member (fn (t, (_, t')) => t aconv (Thm.term_of t')) params t; |
108 val (eqs, assms') = filter_in_out (is_local_var o lhs_of_eq o prop_of) eqs; |
108 val (eqs, assms') = |
|
109 filter_in_out (is_local_var o lhs_of_eq o Thm.prop_of) eqs; |
109 val assms = assms' @ drop e inv_thms |
110 val assms = assms' @ drop e inv_thms |
110 in |
111 in |
111 HEADGOAL (Method.insert_tac (assms @ case_prems)) THEN |
112 HEADGOAL (Method.insert_tac (assms @ case_prems)) THEN |
112 Ctr_Sugar_General_Tactics.unfold_thms_tac ctxt eqs |
113 Ctr_Sugar_General_Tactics.unfold_thms_tac ctxt eqs |
113 end)) ctxt)))]) |
114 end)) ctxt)))]) |
114 end) ctxt) THEN' |
115 end) ctxt) THEN' |
115 K (prune_params_tac ctxt)) |
116 K (prune_params_tac ctxt)) |
116 #> Seq.maps (fn st => |
117 #> Seq.maps (fn st => |
117 CASES (Rule_Cases.make_common (Proof_Context.theory_of ctxt, prop_of st) cases) all_tac st) |
118 CASES (Rule_Cases.make_common (Proof_Context.theory_of ctxt, Thm.prop_of st) cases) all_tac st) |
118 end)); |
119 end)); |
119 |
120 |
120 local |
121 local |
121 |
122 |
122 val ruleN = "rule" |
123 val ruleN = "rule" |