まず、スタイルについて議論させてください。関数 CompStrings を次のように記述できます。
Fixpoint CompStrings' (sa : string) (sb : string) {struct sb}: bool :=
match sa, sb with
| EmptyString, EmptyString => true
| EmptyString, _
| _, EmptyString => false
| String a sa', String b sb'=> CompStrings sa' sb'
end.
読みやすいと思います。疑わしい場合に備えて、これがあなたのものと同じであることの証明を次に示します。
Theorem CompStrings'ok: forall sa sb, CompStrings sa sb = CompStrings' sa sb.
Proof.
intros. destruct sa, sb; simpl; reflexivity.
Qed.
さて、これは二重の答えになります。最初に、証明の方向性を示します。次に、自分で試してみる前に読まないことをお勧めする完全な証拠を示します.
length
まず、あなたがそれを提供しなかったので、私はこの定義を仮定しました:
Fixpoint length (s: string): nat :=
match s with
| EmptyString => O
| String _ rest => S (length rest)
end.
そして、Eq_nat も持っていなかったので、長さが命題的に等しいことを証明し始めました。Eq_nat に適応するのはかなり簡単です。
Lemma Eq_length' : forall (s1 s2 : string),
CompStrings s1 s2 = true ->
length s1 = length s2.
Proof.
induction s1.
(* TODO *)
Admitted.
それではスタートです!帰納的なデータ型 string に関するプロパティを証明したいとします。事は、場合分けで進めたいのですが、destruct
sだけでは終わらないのです。これが、 で進める理由induction
です。つまり、ことif s1 is the EmptyString, then the property holds
、およびことを証明する必要がありますif the property holds for a substring, then it holds for the string with one character added
。2 つのケースは非常に単純です。それぞれのケースで、s2 のケース分析 (つまり、 を使用destruct
) によって進めることができます。
intros s1 s2 C.
する前に私がしなかったことに注意してくださいinduction s1.
。s2
これが非常に重要な理由は 1 つあります。それを行うと (試してみてください!)、帰納仮説は、特定の について量化されるのではなく、特定の について話すため、制約が強すぎます。帰納法による証明を始めると、これは注意が必要です。したがって、この証明を続けるようにしてください。
Lemma Eq_length'_will_fail : forall (s1 s2 : string),
CompStrings s1 s2 = true ->
length s1 = length s2.
Proof.
intros s1 s2 C. induction s1.
(* TODO *)
Admitted.
最終的には、特定の について話しているため、帰納仮説を目標に適用できないことがわかりますs2
。
この 2 つの演習を試していただければ幸いです。
行き詰まっている場合は、最初の目標を証明する 1 つの方法を次に示します。
カンニングしないでください!:)
Lemma Eq_length' : forall (s1 s2 : string),
CompStrings s1 s2 = true ->
length s1 = length s2.
Proof.
induction s1.
intros s2 C. destruct s2. reflexivity. inversion C.
intros s2 C. destruct s2. inversion C. simpl in *. f_equal.
exact (IHs1 _ C).
Qed.
それをわかりやすい言葉で言えば:
最後のステップでは、 を証明する方法がたくさんあることに注意してくださいS (length rest1) = S (length rest2)
。f_equal.
そのうちの 1 つは、コンストラクターのパラメーター間のペアワイズ等価性を証明するように要求するwhich を使用しています。rewrite (IHs1 _ C).
また、その目標に対して再帰性を使用することもできます。
これがこの特定の目標を解決するだけでなく、帰納法による証明を最初に理解するのに役立つことを願っています!
これを締めくくるために、ここに 2 つの興味深いリンクがあります。
これは帰納法の基本を示しています (「リストに関する帰納法」の段落を参照してください)。
これは、帰納仮説を一般化する理由と方法を私よりもよく説明しています。誘導を開始する前に、タクティック を使用して をゴールにintros s1 s2 C.
戻すことで、私が行ったゴールを解決する方法を学びます。s2
generalize (dependent)
一般的に、本全体を読むことをお勧めします。テンポが遅く、非常に教訓的です。