うん、それらの誘導型定義は、読みにくいことができます。
最初の部分である:
Inductive ex (A:Type) (P:A -> Prop) : Prop :=
これは、型自体に関連付けられているものです。だから、あなたがex
を参照してくださいいつでも、それはA
とし、P
を持つことになりますし、ex
はタイプProp
のものであろう。すぐにA
をスキップして、述語であるP
に注目しましょう。したがって、例として「素数である自然数がある」とすると、is_prime
となる可能性があります。nat
(自然数)を引数とし、nat
が素数ならばその証明が存在する可能性があります。
この例では、A
はnat
となります。このチュートリアルでは、A
は言及されていません。なぜなら、Coqは常にそれを推論できるからです。述語が与えられると、Coqは述語の引数の型を調べることによってA
の型を得ることができる。
ここまで要約すると、この例では、タイプはex nat is_prime
となります。これはプライムであるナットが存在すると言っていますが、ナットは何も言いません。 ex nat is_prime
を構築する際には、どちらが必要なのか、「証人」が必要です。そしてそれは、コンストラクタ定義に私たちをリード:
ex_intro : forall x:A, P x -> ex (A:=A) P.
コンストラクタはex_intro
という名前です。ここで難しいのは、コンストラクターにその型のすべてのパラメーターがあることです。したがって、ex_intro
の後にリストされているものになる前に、A
とP
のタイプのものを含める必要があります。これらのパラメータの後
はex_intro
後にリストされているものを来る:x
、述語は証人のために保持している証拠である証人、そしてP x
、です。この例を使用すると、x
は2になり、P x
は(is_prime 2)
という証明になります。
コンストラクタは、構築中のタイプex
のパラメータを指定する必要があります。それは矢印の後に起こっていることです(->
)。これらは、コンストラクタの呼び出しで使用されるパラメータと一致する必要はありませんが、通常は行います。これを達成するために、引数A
はではなく、であり、明示的に渡されます。 (A:=A)
では、のパラメータA
は、コンストラクタの呼び出しでA
と等しいはずです。同様に、P
のex
は、コンストラクタの呼び出しからP
に設定されています。
したがって(prime 2)
タイプのproof_that_2_is_prime
がある場合は、ex_intro is_prime 2 proof_that_2_is_prime
とすることができ、タイプはex nat is_prime
となります。素数である自然数が存在するという私たちの証明です。直接あなたの質問に答えるために
:式forall x:A, P x -> ex (A:=A)
では、x:A
は証人であるとP x
は、証人が真実であることの証明です。式には述語が含まれていません。これは、コンストラクタex_intro
に渡す必要がある型のパラメータの一部であるためです。チュートリアルのパラメータリストにはA
は含まれていません。これはCoqによって推論されるためです。
私はこのディスカッションが私のチュートリアルでは詳細すぎると思った理由を理解してもらいたいと思います。ご質問ありがとうございます。
このような詳細な回答を書く時間をとってくれてありがとう。しかし、私は、矢印の後にあるものについての段落は間違っていると思います。実際、 'A'と' P'は型のパラメータなので、コンストラクタでは選択肢がありません。例えば 'ex_intro:forall x:A、P x - > ex(A:= nat)P'と書くことはできません。ところで、あなたは '(A:= A)'を省略することができます。これは 'Inductive ex:forall A、(A - > Prop) - > Prop'の定義とは異なります。ここでコンストラクタの定義方法が自由になります。 – eponier