別の答えは差別的な部分に焦点を当てていますが、私はマニュアルプルーフに焦点を当てます。あなたは試してみました:注意とコックを使用して、私はしばしば不快になるべきである何
Lemma l2: A=B -> False.
apply (fun e:(A=B) => match e with end).
Defined.
は、コックは、それが内部的にうまく型付けされた用語に書き換え、不明確な定義を受け入れることです。 Coqはそれ自身をいくつか追加しているので、あまり冗長ではありません。しかし、一方で、Coqは入力したものとは異なる用語を操作します。
これはあなたの証拠の場合です。当然、e
のパターンマッチングには、eq
タイプの単一のコンストラクタであるコンストラクタeq_refl
が必要です。ここでCoqは平等に人が住んでいないことを検出し、コードを修正する方法を理解しますが、入力したものは適切なパターンマッチングではありません。
二つの成分は、ここで何が起こっているかを理解するのに役立ちます。
eq
- の定義フルパターンマッチング構文を、
as
、in
とreturn
用語
まずとともに、 eq
の定義を見ることができます。
Inductive eq {A : Type} (x : A) : A -> Prop := eq_refl : x = x.
この定義は、より自然な(いずれにしても、より対称的)ように見えることに注意してください。
Inductive eq {A : Type} : A -> A -> Prop := eq_refl : forall (x:A), x = x.
これはeq
は、最初の定義ではなく秒で定義されていることは本当に重要です。特に、私たちの問題については、重要なことは、x = y
ではx
がパラメータであり、y
はインデックスであることです。つまり、x
はすべてのコンストラクターで一定ですが、y
は各コンストラクターで異なる可能性があります。タイプVector.t
と同じ違いがあります。要素を追加すると、ベクトルの要素の型は変更されません。そのため、要素として実装されます。しかし、そのサイズは変わる可能性があるため、インデックスとして実装されています。
ここで、パターンマッチングの拡張構文を見てみましょう。ここで私が理解していることを簡単に説明します。より安全な情報の参照を躊躇しないでください(https://coq.inria.fr/refman/Reference-Manual020.html)。 return
句を使用すると、ブランチごとに異なる戻り値の型を指定できます。この節では、一致した単語と型インデックスをそれぞれバインドする、パターンマッチングの句のas
とin
節で定義されている変数を使用できます。 return
句は、各ブランチのコンテキストで解釈され、このコンテキストを使用してas
とin
の変数を置換し、ブランチを1つずつタイプチェックし、外部視点からmatch
を入力するために使用されます。
Definition test n :=
match n as n0 return (match n0 with | 0 => nat | S _ => bool end) with
| 0 => 17
| _ => true
end.
n
の値に応じて、我々は同じ型を返すされていません。
はここas
句と不自然な例です。 test
のタイプはforall n : nat, match n with | 0 => nat | S _ => bool end
です。しかし、Coqがどのような場合に一致するかを決めることができれば、タイプを単純化することができます。例:ここでは
Definition test2 n : bool := test (S n).
、コックはn
が何であれ、test
に与えられたS n
はタイプbool
のものとしてつながる、ということを知っています。
同等性については、今回はin
節を使用して同様のことを行うことができます。
Definition test3 (e:A=B) : False :=
match e in (_ = c) return (match c with | B => False | _ => True end) with
| eq_refl => I
end.
ここでは何が起こっていますか?本質的には、Coqタイプは、match
とmatch
のブランチを別々にチェックします。eq_refl
の場合、c
は(パラメータと同じ値のインデックスをインスタンス化するeq_refl
という定義のため)A
に等しいので、タイプTrue
、ここではI
の値が返されました。しかし、外部から見ると、c
はB
(e
はA=B
なので)、return
はmatch
がFalse
という値を返していると主張しています。 test2
で見たタイプのパターンマッチングを単純化するCoqの機能をここで使用します。他のケースではB
よりTrue
を使用しましたが、特にTrue
は必要ありません。 eq_refl
ブランチで何かを返すことができるような、いくつかの居住型が必要です。
Coqによって生成された奇妙な用語に戻ると、Coqによって使用される方法は類似していますが、この例では確かに複雑です。特に、Coqは、役に立たないタイプや用語が必要な場合に、idProp
が住むタイプIDProp
を使用することがよくあります。これらは上に使用されたTrue
とI
に対応しています。
最後に、coq-clubに関する議論をlinkで行いました。これは、拡張パターンマッチングがCoqでどのようにタイプされているかを理解するのに役立ちました。
非常に詳しい説明。ありがとう。 – eponier
上記の最後の言葉は「差別化」を明示的にする最短の方法だと言えますか? – Cryptostasis
@Cryptostasis私はできると思います。 (fun H:A = B => [上記の項])を使用して、(fun H:A = B => H in(_ = y) と一致するyを返します。| A => True | B => False end | eq_refl => I end) '。 –