Coq で単純型付けされたラムダ計算を形式化する演習を行っており、Ltac を使用して証明を自動化したいと考えています。進行定理を証明しながら:
Theorem progress : forall t T,
empty |-- t \in T -> value t \/ exists t', t ==> t'.
このLtacコードを思いつきました:
Ltac progress_when_stepping :=
(* right, because progress statement places stepping on the right of \/ *)
right;
(* use induction hypotheses *)
repeat
match goal with
| [ H : _ -> value _ \/ exists _, ?t1 ==> _ |- exists _, ?C ?t1 _ ==> _ ] =>
induction H; auto
| [ H : _ -> value _ \/ exists _, ?t2 ==> _, H0 : value ?t1 |-
exists _, ?C ?t1 ?t2 ==> _ ] =>
induction H; auto
| [ H : _ -> value _ \/ exists _, ?t1 ==> _ |- exists _, ?C ?t1 ==> _ ] =>
induction H; auto
end.
==>
(スモールステップセマンティクスによる) 評価の単一ステップを示します。各一致ケースの意図は次のとおりです。
- コンストラクターの最初の項がステップするという仮説がある場合、任意のバイナリコンストラクターに一致します。
- コンストラクターのステップの 2 番目の項とコンストラクターの最初の項が既に値であるという仮説がある場合、任意のバイナリコンストラクターに一致します。
- コンストラクターの項がステップするという仮説がある場合、任意の単項コンストラクターに一致します。
ただし、このコードの動作を見ると、3 番目のケースもバイナリコンストラクターと一致しているように見えます。実際に単項コンストラクターのみに一致するように制限するにはどうすればよいですか?