equal
deleted
inserted
replaced
6 Coinduction method that avoids some boilerplate compared to coinduct. |
6 Coinduction method that avoids some boilerplate compared to coinduct. |
7 *) |
7 *) |
8 |
8 |
9 signature COINDUCTION = |
9 signature COINDUCTION = |
10 sig |
10 sig |
11 val coinduction_tac: term list -> thm option -> thm list -> int -> context_tactic |
11 val coinduction_context_tactic: term list -> thm option -> thm list -> int -> context_tactic |
|
12 val coinduction_tac: Proof.context -> term list -> thm option -> thm list -> int -> tactic |
12 end; |
13 end; |
13 |
14 |
14 structure Coinduction : COINDUCTION = |
15 structure Coinduction : COINDUCTION = |
15 struct |
16 struct |
16 |
17 |
35 val n = nth (Thm.prems_of st) (i - 1) |> Logic.strip_assums_hyp |> length; |
36 val n = nth (Thm.prems_of st) (i - 1) |> Logic.strip_assums_hyp |> length; |
36 in |
37 in |
37 (THEN_ALL_NEW_SKIP skip tac (REPEAT_DETERM_N n o eresolve0_tac [thin_rl])) i st |
38 (THEN_ALL_NEW_SKIP skip tac (REPEAT_DETERM_N n o eresolve0_tac [thin_rl])) i st |
38 end; |
39 end; |
39 |
40 |
40 fun coinduction_tac raw_vars opt_raw_thm prems = |
41 fun coinduction_context_tactic raw_vars opt_raw_thm prems = |
41 CONTEXT_SUBGOAL (fn (goal, i) => fn (ctxt, st) => |
42 CONTEXT_SUBGOAL (fn (goal, i) => fn (ctxt, st) => |
42 let |
43 let |
43 val lhs_of_eq = HOLogic.dest_Trueprop #> HOLogic.dest_eq #> fst; |
44 val lhs_of_eq = HOLogic.dest_Trueprop #> HOLogic.dest_eq #> fst; |
44 fun find_coinduct t = |
45 fun find_coinduct t = |
45 Induct.find_coinductP ctxt t @ |
46 Induct.find_coinductP ctxt t @ |
115 K (prune_params_tac ctxt)) i) st |
116 K (prune_params_tac ctxt)) i) st |
116 |> Seq.maps (fn st' => |
117 |> Seq.maps (fn st' => |
117 CONTEXT_CASES (Rule_Cases.make_common ctxt (Thm.prop_of st') cases) all_tac (ctxt, st')) |
118 CONTEXT_CASES (Rule_Cases.make_common ctxt (Thm.prop_of st') cases) all_tac (ctxt, st')) |
118 end); |
119 end); |
119 |
120 |
|
121 fun coinduction_tac ctxt x1 x2 x3 x4 = |
|
122 Method.NO_CONTEXT_TACTIC ctxt (coinduction_context_tactic x1 x2 x3 x4); |
|
123 |
|
124 |
120 local |
125 local |
121 |
126 |
122 val ruleN = "rule" |
127 val ruleN = "rule" |
123 val arbitraryN = "arbitrary" |
128 val arbitraryN = "arbitrary" |
124 fun single_rule [rule] = rule |
129 fun single_rule [rule] = rule |
151 val _ = |
156 val _ = |
152 Theory.setup |
157 Theory.setup |
153 (Method.setup @{binding coinduction} |
158 (Method.setup @{binding coinduction} |
154 (arbitrary -- Scan.option coinduct_rule >> |
159 (arbitrary -- Scan.option coinduct_rule >> |
155 (fn (arbitrary, opt_rule) => fn _ => fn facts => |
160 (fn (arbitrary, opt_rule) => fn _ => fn facts => |
156 Seq.DETERM (coinduction_tac arbitrary opt_rule facts 1))) |
161 Seq.DETERM (coinduction_context_tactic arbitrary opt_rule facts 1))) |
157 "coinduction on types or predicates/sets"); |
162 "coinduction on types or predicates/sets"); |
158 |
163 |
159 end; |
164 end; |
160 |
165 |
161 end; |
166 end; |