4

I'm having some troubles in Coq when trying to perform case analysis on the result of a function (which returns an inductive type). When using the usual tactics, like elim, induction, destroy, etc, the information gets lost.

I'll put an example:

We first have a function like so:

Definition f(n:nat): bool := (* definition *)

Now, imagine we are at this step in the proof of a specific theorem:

n: nat
H: f n = other_stuff
------
P (f n )

When I apply a tactic, like let's say, induction (f n), this happens:

Subgoal 1
n:nat
H: true = other_stuff
------
P true

Subgoal 2
n:nat
H: false = other_stuff
------
P false

However, what I want is something like this instead:

Subgoal 1
n:nat
H: true = other_stuff
H1: f n = true
------
P true

Subgoal 2
n:nat
H: false = other_stuff
H1: f n = false 
------
P false

In the way it actually works, I lose information, specially I lose any information about f n. In the problems I work with, I need to use the information that f n = true or f n = false, to use with other hypothesis, etc. Is there a way to do the 2nd option? I tried using stuff like cut(f n = false \/ f n = true) but it becomes very tiresome, specially when I have several of these "special" inductions in a row. I want to know if there is something that basically works exactly like the cut above, but with fewer tactics/proofs

gonzaw
  • 771
  • 4
  • 17

1 Answers1

4

The issue is that you perform induction on a constructed term, not a single variable. Keeping the information in your case has been proved to be a very difficult problem.

The usual work-around is to abstract your constructed term using the remember tactic. I don't have the exact syntax in mind right now but you should try something like

remember (f n) as Fn. (* this introduces an equality HeqFn : Fn = f n *)
revert f n HeqFn. (* this is useful in many cases, but not mandatory *)
induction Fn; intros; subst in *.

Hope it helps, V.

Vinz
  • 5,997
  • 1
  • 31
  • 52
  • Thanks! It did work for me, but I had to do it like this: `remember (f n) as Fn.` followed by `induction Fn.` With that it did induction over Fn (in this case one subgoal for `true` and one for `false` ), but in HeqFn kept the information about (f n), either `HeqFn : true = f n` or `HeqFn : false = f n`. Cheers! (Edit: `revert f n HeqFn` was not necessary for me. Dunno if you should keep it in the answer or not) – gonzaw Dec 13 '13 at 18:52
  • Nice to know, I always had to use `revert` in my experiences. It is good to have feedback from other users :D Thanks ! – Vinz Dec 16 '13 at 08:24
  • I tried revert, but that only changed something from "H |- G" to "|- H-> G" (i.e reverse of intro). Dunno how that is really useful in this scenario :P – gonzaw Dec 16 '13 at 18:29
  • It becomes useful when you have a term a little more complex than `f n`, e.g. with other variables/parameters. If you need the induction hypothesis to be really strong, you might need to revert these variables/parameters (which forces you to revert the equality as well). I just realize that it was my case, and thus why I always reverted the equality. – Vinz Dec 19 '13 at 08:52
  • 1
    I am usually using 'case_eq' tactics instead of 'destruct' in situations like this. – krokodil Aug 28 '15 at 01:26