Reputation: 1232
Let's say I have a lemma about a simple inductively-defined set:
inductive_set foo :: "'a ⇒ 'a list set" for x :: 'a where
"[] ∈ foo x" | "[x] ∈ foo x"
lemma "⋀x y. y ∈ foo x ⟹ qux x y ⟹ baz x y"
(It's important to me that the "⋀x y" bit stays, because the lemma is actually stating the state of my proof in the middle of a long apply chain.)
I'm having trouble starting the proof of this lemma. I would like to proceed by rule induction.
I tried writing
apply (induct rule: foo.induct)
but that doesn't work: the induct
method fails. I find I can get around this by fixing x
and y
explicitly, and then invoking the induct
method, like so:
proof -
fix x :: 'a
fix y :: "'a list"
assume "y ∈ foo x" and "qux x y"
thus "baz x y"
apply (induct rule: foo.induct)
oops
However, since I'm actually in the middle of an apply chain, I would rather not enter a structured proof block.
I tried using the induct_tac
method instead, but unfortunately induct_tac
does not apply the foo.induct
rule in the way I would like. If I type
apply (induct_tac rule: foo.induct, assumption)
then the first subgoal is
⋀x y. y ∈ foo x ⟹ qux x y ⟹ baz x []
which is not what I want: I wanted qux x []
instead of qux x y
. The induct
method got this right, but had other problems, discussed above.
Upvotes: 1
Views: 719
Reputation: 981
If you first transform your goal to look like this:
⋀x y. y ∈ foo x ⟹ qux x y ⟶ baz x []
then apply (induct_tac rule: foo.induct)
will instantiate the induction rule in the way that you want. (It will also leave the object-level implications in the resulting goals, to which you will need to apply (rule impI)
.)
The induct
method does these extra steps dealing with implications automatically, which is one of its major advantages.
On the other hand, induct_tac rule: foo.induct
doesn't do anything more than apply (rule foo.induct)
. (In general, induct_tac
can match the variables you specify, and automatically choose an induction rule based on their types, but you're not taking advantage of those features here.)
I think your best option is to go ahead and use a proof block at the end of your apply chain. If you are worried that all the fix
, assume
and show
statements are too verbose, then you can use the little-advertised case goaln
feature:
apply ...
apply ...
proof -
case goal1 thus ?case
apply induct
...
qed
Upvotes: 4