I'm new to Coq and to learn formal semantics I'm following the book Software Foundations. Currently I'm in the chapter: https://softwarefoundations.cis.upenn.edu/lf-current/Imp.html. Where it defines the commands for a simple imperative language. As an exercise I've tried to add a repeat command to the language defined as follows:
Inductive ceval : com -> state -> state -> Prop :=
(* ...same as in the book *)
| E_RepeatTrue : forall st st' b c,
[ c, st ] ~> st' ->
beval st' b = true ->
[ repeat c until b end, st ] ~> st'
| E_RepeatFalse : forall st st' st'' b c,
[ c, st ] ~> st'' ->
beval st'' b = false ->
[ repeat c until b end, st'' ] ~> st' ->
[ repeat c until b end, st ] ~> st'
where "'[' c ',' st ']' '~>' st'" := (ceval c st st').
But I'm stuck trying to prove that the command repeat c until b end
is equivalent to c; while ~b do c end
, in the following sense:
Definition cequiv (c1 c2 : com) : Prop :=
forall (st st' : state),
([ c1, st ] ~> st') <-> ([ c2, st ] ~> st').
I defined the theorem in Coq as follows:
Theorem repeat_equiv_while : forall b c,
cequiv <{repeat c until b end}> <{c; while ~b do c end}>.
Proof.
intros.
split; intros.
- inversion H; subst.
+ apply E_Concat with st'. assumption.
apply E_WhileFalse. apply bev_not_true_iff_false.
rewrite <- H5. apply bev_negb_involutive.
+ (* infinite loop? *)
admit.
- inversion H. subst.
inversion H5. subst.
+ apply E_RepeatTrue. assumption.
apply bev_not_true_iff_false in H6.
rewrite <- H6. symmetry.
apply bev_negb_involutive.
+ admit.
Admitted.
I've managed to prove the cases where the evaluation ends in the next step but when I try to prove the other case I get stuck in a loop. I would like to apply the induction hypothesis to solve it, but I don't know how to do it. I think maybe dependent induction can help me but I couldn't manage to prove it either using it.