I'm self-studying the Semantics course, and met the following proof script in the warmup directory:
Lemma step_deterministic e e' e'' :
step e e' → step e e'' → e' = e''.
Proof.
intros Hstep1 Hstep2.
induction Hstep1 as [ ??? H IH | ??? H IH | | ??? H IH | ??? H IH | ] in e'', Hstep2 |- *.
{ inversion Hstep2; subst.
+ f_equal. by apply IH.
+ exfalso; by eapply no_step_const.
+ exfalso; by eapply no_step_const.
}
{ inversion Hstep2; subst.
+ exfalso; by eapply no_step_const.
+ f_equal. by apply IH.
+ exfalso; by eapply no_step_const.
}
(* you get the idea, let's apply some automation... *)
(* [naive_solver] is a clever automation tactic by [stdpp] that can solve many simple things. *)
all: inversion Hstep2; subst; first [ try exfalso; by eapply no_step_const | naive_solver].
Qed.
What does the part in e''
in induction Hstep1 ... in e''
do? I can understand that we are applying a rule induction on step
, and with in e''
the number of the goals reduces down to the number of the rules rather than the square of it.
I also have another small question---what does ???
do, and what is the intention of putting the trailing |- *
which seems useless?
EDIT: I now understand that induction Hstep1 ... in e'', Hstep2 |- *
is not parsed as induction (Hstep1 ... in e''), Hstep2 |- *
but as induction Hstep1 ... in (e'', Hstep2 |- *)
.
Also, I found that
generalize dependent e''.
induction H_step1; intros.
works as well.
What I still don't understand is the purpose of the |- *
in this specific example.
|-
is a special token used to indicate the premises (before this token) and goals (after this token) in Coq. Soe'', Hstep2 |- *
selects the premisese''
andHstep2
and all goals. $\endgroup$???
lets Coq pick three arbitrary names for the things you have introduced in theinduction
pattern. $\endgroup$induction Hstep1 as ... in (e'', Hstep2 |- *)
? $\endgroup$induction a in b
means doing induction inb
where in your case b is(e'', Hstep 2 |- *)
, i.e., doing induction withine''
andHstep2
as well as all goals. $\endgroup$