Ltac Kind :=
  exploit safe_expr_kind; eauto; simpl; intros X; rewrite <- X in *; clear X.Ltac Rec HR kind C C' :=
  destruct (HR kind (fun x => C(C' x))) as [? | [C'' [a' [D [A B]]]]];
  [eauto | eauto | auto |
   right; exists (fun x => C'(C'' x)); exists a'; rewrite D; auto].Ltac Base :=
  right; exists (fun x => x); econstructor; split; [eauto | simpl; auto].

Theorem progress: forall S, safe S -> (exists r, final_state S r) \/ (exists t, exists S', step S t S').