Coq:使用子类型时卡住

Coq:使用子类型时卡住,coq,Coq,我有以下定义:(正整数作为nat子类型的定义) 我该怎么解决这个问题呢?你对Z_pos_mult的定义太复杂了。它依赖于依赖模式匹配 从一开始。我建议使用这种依赖模式匹配仅用于证明,而不用于定义 From Coq Require Import Arith. Local Coercion is_true : bool >-> Sortclass. Definition Z_pos: Set := {n : nat | 0 <? n }. Definition Z_pos__N

我有以下定义:(正整数作为nat子类型的定义)


我该怎么解决这个问题呢?

你对Z_pos_mult的定义太复杂了。它依赖于依赖模式匹配 从一开始。我建议使用这种依赖模式匹配仅用于证明,而不用于定义

From Coq Require Import Arith.
Local Coercion is_true : bool >-> Sortclass.

Definition Z_pos: Set := {n : nat | 0 <? n }.

Definition Z_pos__N (p: Z_pos): nat := proj1_sig p.

Definition Z_pos_mult : Z_pos -> Z_pos -> Z_pos.
  intros [x xpos%Nat.ltb_lt] [y ypos%Nat.ltb_lt].
  refine (exist  _ (x * y) _).
  now apply Nat.ltb_lt, Nat.mul_pos_pos.
Defined.

Lemma compat: forall p q: Z_pos, Z_pos__N (Z_pos_mult p q) = Z_pos__N p * Z_pos__N q.
Proof. now intros [x xpos] [y ypos]. Qed.
这是另一个定义。并不是说它在进行任何证明之前修复了返回值

Definition Z_pos_mult (p q : Z_pos) : Z_pos.
exists (Z_pos__N p * Z_pos__N q).
destruct p as [p ph]; destruct q as [q qh].
unfold Z_pos_filter in ph, qh |- *; simpl.
destruct (p =? 0) eqn: ph'; try discriminate.
destruct (q =? 0) eqn: qh'; try discriminate.
rewrite beq_nat_false_iff in ph'.
rewrite beq_nat_false_iff in qh'.
destruct (p * q =? 0) eqn:pqh'; auto.
rewrite beq_nat_true_iff in pqh'.
destruct p; destruct q; try solve[discriminate | case ph'; auto | case qh'; auto].
Defined.
有了这个定义,你要求的证据就很容易写了

Lemma compat: forall p q: Z_pos, Z_pos__N (Z_pos_mult p q) = Z_pos__N p * Z_pos__N q.
Proof.
intros [p ph] [q qh]; unfold Z_pos_mult; simpl; auto.
Qed.

原则上,您的代码的证明也是可能的,但这非常困难。

以下是我将如何在vanilla Coq中进行验证。我想我们仍然可以调整定义

From Coq Require Import Arith.
Local Coercion is_true : bool >-> Sortclass.

Definition Z_pos: Set := {n : nat | 0 <? n }.

Definition Z_pos__N (p: Z_pos): nat := proj1_sig p.

Definition Z_pos_mult : Z_pos -> Z_pos -> Z_pos.
  intros [x xpos%Nat.ltb_lt] [y ypos%Nat.ltb_lt].
  refine (exist  _ (x * y) _).
  now apply Nat.ltb_lt, Nat.mul_pos_pos.
Defined.

Lemma compat: forall p q: Z_pos, Z_pos__N (Z_pos_mult p q) = Z_pos__N p * Z_pos__N q.
Proof. now intros [x xpos] [y ypos]. Qed.
来自Coq的
需要导入算术。
本地强制是正确的:bool>->Sortclass。

定义Z_pos:Set:={n:nat | 0IMHO以原始形式回答这个问题是在提倡一种有问题的风格。我认为这类数字的乘法应该是基类型的乘法;并且证明应该仅仅遵循投影的内射性,就像在mathcomp中所做的那样


总的来说,如果非完全不透明的证明在缩减后出现在你的术语中,你会遇到很多问题。

你能解释一下“局部强制”和“Sortclass”是什么意思吗?我已经看到了,但我不能清楚地理解它的意思。这个声明意味着无论Coq在哪里期望一个命题(具有sort
Prop
,因此
Sortclass
),但您提供了一个布尔值,系统将插入
is_true
强制以进行表达式类型检查。
is_true b
is
b=true
根据定义。因此,您真正拥有的是
0老实说,我对这样的子集表示法或模式匹配一无所知,我只是模仿了另一篇文章中看到的内容,所以我不明白是什么造成了差异。你能解释一下我对Z_pos___mult的定义和你的定义有什么不同吗?还有…学习这些东西有什么好的参考吗?我已经遵循了,但我认为这还不够。我想看一些例子和练习。谢谢。我知道一开始你复制别人的做法。对于你来说,应该不需要测试Z_pos_filter是否满意,所以你应该返回值。这也是其他答案所建议的。如果你先返回值,然后证明它是正的,那么就没有困难了。我将试着澄清困难t在后面的答案中,我们比较了这两种风格。我试图先给出这个值,然后证明它在中的存在,但它无法简化。你能告诉我问题出在哪里吗?你所说的“有问题的风格”和“从投影的内射性出发”是什么意思?后者是指特鲁诺夫答案中的方法吗?
From Coq Require Import Arith.
Local Coercion is_true : bool >-> Sortclass.

Definition Z_pos: Set := {n : nat | 0 <? n }.

Definition Z_pos__N (p: Z_pos): nat := proj1_sig p.

Definition Z_pos_mult : Z_pos -> Z_pos -> Z_pos.
  intros [x xpos%Nat.ltb_lt] [y ypos%Nat.ltb_lt].
  refine (exist  _ (x * y) _).
  now apply Nat.ltb_lt, Nat.mul_pos_pos.
Defined.

Lemma compat: forall p q: Z_pos, Z_pos__N (Z_pos_mult p q) = Z_pos__N p * Z_pos__N q.
Proof. now intros [x xpos] [y ypos]. Qed.