3

I have a proof script with a section that looks like this:

  - destruct (IHx1 _ _ H3). subst. destruct (IHx2 _ _ H7). congruence.
  - destruct (IHx1 _ _ H6). congruence.
  - destruct (IHx1 _ _ H3). subst. destruct (IHx2 _ _ H7). congruence.
  - destruct (IHx1 _ _ H6). congruence.
  - destruct (IHx  _ _ H2). congruence.
  - destruct (IHx  _ _ H5). congruence.
  - destruct (IHx  _ _ H2). congruence.
  - destruct (IHx  _ _ H8). congruence.
  - destruct (IHx  _ _ H8). congruence.
  - destruct (IHx  _ _ H8). congruence.
  - destruct (IHx  _ _ H8). congruence.
  - destruct (IHx  _ _ H7). congruence.
  - destruct (IHx  _ _ H4). congruence.
  - destruct (IHx1 _ _ H8). congruence.
  - destruct (IHx1 _ _ H5). subst. destruct (IHx2 _ _ H9).

It seems like it would be a choice candidate for using ; to solve cleanly, unfortunately the hypotheses are all over the place. How can I collapse the various sub-proofs together?

Carl Patenaude Poulin
  • 6,238
  • 5
  • 24
  • 46

1 Answers1

2

The cases where we have only one induction hypothesis can be solved using the following piece of Ltac (see the manual, chapter 9):

match goal with
  IH : forall st2 s2, ?c / ?st \\ s2 / st2 -> _,
  H : ?c / ?st \\ _ / _
  |- _ => now destruct (IH  _ _ H)
end

Where variables prefixed with question marks, e.g. ?c, ?st, etc. are pattern-matching metavariables, commas separate hypotheses and the turnstile symbol (|-) separates the hypotheses from the goal. Here we are looking for an induction hypothesis IH and a compatible hypothesis H so we could apply IH to H. The ?c / ?st part ensures IH and H are compatible.

The subgoals with two induction hypotheses can be solved analogously:

match goal with
  IH1 : forall st2 s2, ?c1 / ?st \\ s2 / st2 -> _,
  IH2 : forall st2 s2, ?c2 / _ \\ s2 / st2 -> _,
  H1 : ?c1 / ?st \\ _ / ?st'',
  H2 : ?c2 / ?st'' \\ _ / st2
  |- _ => now destruct (IH1  _ _ H1); subst; destruct (IH2 _ _ H2)
end

Of course, if you want you can bind names to those custom tactics, use tactical with them and so on:

Ltac solve1 :=
  try match goal with
        IH : forall st2 s2, ?c / ?st || s2 / st2 -> _,
        H : ?c / ?st || _ / _
        |- _ => now destruct (IH  _ _ H)
      end.
Anton Trunov
  • 15,074
  • 2
  • 23
  • 43