在 mathcomp 的 ssralg 中从 int_Ring 类型中提取整数
Extracting integer from int_Ring type in mathcomp's ssralg
问题的一些设置:符号 `_i
被定义为序列的 i-th 分量,但也意味着 i-th 系数一个多项式。以下代码输出 Negz 2 : int_ZmodType
:
From mathcomp Require Import all_ssreflect.
From mathcomp Require Import all_algebra.
Open Scope ring_scope.
Definition my_seq := [:: Posz 4; Negz 2].
Eval compute in my_seq`_1.
my_seq
的类型是seq int
。类型 int
具有构造函数 Posz
和 Negz
.
的header
https://github.com/math-comp/math-comp/blob/master/mathcomp/algebra/poly.v
告诉我们 Poly s
是一个系数来自序列 s
的多项式。它还表示 p`_i
是多项式 p
的 i-th 系数。我希望以下代码输出 Negz 2
:
Definition my_polynomial := Poly my_seq.
Eval compute in my_polynomial`_1.
结果项不是 Negz 2
,尽管它确实具有类型 int_Ring
。多项式有一个序列构造函数 polyseq
。事实上,polyseq my_polynomial
的类型是 seq int_Ring
。然而,做 Eval compute in (polyseq my_polynomial)`_1.
会产生同样的混乱。
在从具体类型 int
到 int_Ring
的转换中,整数的值是否丢失了?或者,有没有办法从 int_Ring
恢复 int
的值? int_Ring
的打包方式,看起来不太可能,因为构造函数不引用元素。但是,int_ZmodType
也是如此。作为参考,这些类型在
中定义
https://github.com/math-comp/math-comp/blob/master/mathcomp/algebra/ssralg.v
这是您的代码的一个版本:
From mathcomp Require Import all_ssreflect.
From mathcomp Require Import all_algebra.
Open Scope ring_scope.
Definition my_seq := [:: Posz 4; Negz 2].
Definition my_poly := @Polynomial _ my_seq erefl.
Compute my_poly`_1.
此版本没有使用库中定义的更简单的 Poly
包装函数,而是直接调用 polynomial
的构造函数。如果你看一下这种类型的定义,你会发现多项式只是一个包含多项式系数序列的记录,加上一个布尔等式的证明,断言这个序列的最后一个元素(前导系数)不为零。 (上面表达式中的第二个参数是 true = true
的证明,根据计算规则,Coq 将其理解为 (last 1 polyseq != 0) = true
的证明。)你可以手动检查那里没有什么能阻止我们计算的表达式减少,所以 Coq 能够找出答案。
要看你原来的尝试有什么问题,我们得稍微展开一下。我在这里按顺序包含了相关定义,扩展了一些符号:
Poly s := foldr cons_poly (polyC 0)
polyC c := insubd poly_nil [:: c]
(* from eqtype.v *)
insubd {T : Type} {P : pred T} {sT : subType T P} u0 (x : T) : sT :=
odflt u0 (insub x)
insub {T : Type} {P : pred T} {sT : subType T P} (x : T) : option sT
:= if @idP (P x) is ReflectT Px then @Some sT (Sub x Px) else None
这里我们找到了罪魁祸首:Poly
是根据 insub
定义的,而 insub
又是由 idP
上的案例分析定义的,这是一个不透明的引理!当一个不透明的术语妨碍时,Coq 的归约就会停滞不前。 (如果你很好奇,这里发生的是 insub
正在测试,使用 idP
,多项式的前导系数是否确实不为零,如果是,则使用该事实构建多项式。)
问题在于 ssreflect 中的许多定义并未在逻辑内部进行完全计算。这是由于两个原因。一是性能:通过允许一切都完全减少,我们可以使类型检查慢得多。另外一个就是ssreflect是为了方便推理而剪裁的,所以很多定义并不是最高效的。 CoqEAL 库的开发是为了将具有更好计算行为的定义与更容易推理的定义联系起来,例如 ssreflect;不幸的是,我不知道该项目是否还在维护。
这并没有完全回答问题,但我设法证明了系数确实是Negz 2
。我在这里给出证明以供记录。请注意,我对 ssreflect 一点都不熟悉,所以可能会有更好更自然的方法来做到这一点。
From mathcomp Require Import all_ssreflect.
From mathcomp Require Import all_algebra.
Open Scope ring_scope.
Definition my_seq := [:: Posz 4; Negz 2].
Eval compute in my_seq`_1.
Definition my_polynomial := Poly my_seq.
Example test : my_polynomial `_1 = Negz 2.
Proof.
cbn.
rewrite 2!polyseq_cons. cbn.
rewrite 2!size_polyC. cbn.
rewrite polyseqC. cbn. reflexivity.
Qed.
编辑:如以下评论所述,存在更简单的证据证明这一事实。
问题的一些设置:符号 `_i
被定义为序列的 i-th 分量,但也意味着 i-th 系数一个多项式。以下代码输出 Negz 2 : int_ZmodType
:
From mathcomp Require Import all_ssreflect.
From mathcomp Require Import all_algebra.
Open Scope ring_scope.
Definition my_seq := [:: Posz 4; Negz 2].
Eval compute in my_seq`_1.
my_seq
的类型是seq int
。类型 int
具有构造函数 Posz
和 Negz
.
的header
https://github.com/math-comp/math-comp/blob/master/mathcomp/algebra/poly.v
告诉我们 Poly s
是一个系数来自序列 s
的多项式。它还表示 p`_i
是多项式 p
的 i-th 系数。我希望以下代码输出 Negz 2
:
Definition my_polynomial := Poly my_seq.
Eval compute in my_polynomial`_1.
结果项不是 Negz 2
,尽管它确实具有类型 int_Ring
。多项式有一个序列构造函数 polyseq
。事实上,polyseq my_polynomial
的类型是 seq int_Ring
。然而,做 Eval compute in (polyseq my_polynomial)`_1.
会产生同样的混乱。
在从具体类型 int
到 int_Ring
的转换中,整数的值是否丢失了?或者,有没有办法从 int_Ring
恢复 int
的值? int_Ring
的打包方式,看起来不太可能,因为构造函数不引用元素。但是,int_ZmodType
也是如此。作为参考,这些类型在
https://github.com/math-comp/math-comp/blob/master/mathcomp/algebra/ssralg.v
这是您的代码的一个版本:
From mathcomp Require Import all_ssreflect.
From mathcomp Require Import all_algebra.
Open Scope ring_scope.
Definition my_seq := [:: Posz 4; Negz 2].
Definition my_poly := @Polynomial _ my_seq erefl.
Compute my_poly`_1.
此版本没有使用库中定义的更简单的 Poly
包装函数,而是直接调用 polynomial
的构造函数。如果你看一下这种类型的定义,你会发现多项式只是一个包含多项式系数序列的记录,加上一个布尔等式的证明,断言这个序列的最后一个元素(前导系数)不为零。 (上面表达式中的第二个参数是 true = true
的证明,根据计算规则,Coq 将其理解为 (last 1 polyseq != 0) = true
的证明。)你可以手动检查那里没有什么能阻止我们计算的表达式减少,所以 Coq 能够找出答案。
要看你原来的尝试有什么问题,我们得稍微展开一下。我在这里按顺序包含了相关定义,扩展了一些符号:
Poly s := foldr cons_poly (polyC 0)
polyC c := insubd poly_nil [:: c]
(* from eqtype.v *)
insubd {T : Type} {P : pred T} {sT : subType T P} u0 (x : T) : sT :=
odflt u0 (insub x)
insub {T : Type} {P : pred T} {sT : subType T P} (x : T) : option sT
:= if @idP (P x) is ReflectT Px then @Some sT (Sub x Px) else None
这里我们找到了罪魁祸首:Poly
是根据 insub
定义的,而 insub
又是由 idP
上的案例分析定义的,这是一个不透明的引理!当一个不透明的术语妨碍时,Coq 的归约就会停滞不前。 (如果你很好奇,这里发生的是 insub
正在测试,使用 idP
,多项式的前导系数是否确实不为零,如果是,则使用该事实构建多项式。)
问题在于 ssreflect 中的许多定义并未在逻辑内部进行完全计算。这是由于两个原因。一是性能:通过允许一切都完全减少,我们可以使类型检查慢得多。另外一个就是ssreflect是为了方便推理而剪裁的,所以很多定义并不是最高效的。 CoqEAL 库的开发是为了将具有更好计算行为的定义与更容易推理的定义联系起来,例如 ssreflect;不幸的是,我不知道该项目是否还在维护。
这并没有完全回答问题,但我设法证明了系数确实是Negz 2
。我在这里给出证明以供记录。请注意,我对 ssreflect 一点都不熟悉,所以可能会有更好更自然的方法来做到这一点。
From mathcomp Require Import all_ssreflect.
From mathcomp Require Import all_algebra.
Open Scope ring_scope.
Definition my_seq := [:: Posz 4; Negz 2].
Eval compute in my_seq`_1.
Definition my_polynomial := Poly my_seq.
Example test : my_polynomial `_1 = Negz 2.
Proof.
cbn.
rewrite 2!polyseq_cons. cbn.
rewrite 2!size_polyC. cbn.
rewrite polyseqC. cbn. reflexivity.
Qed.
编辑:如以下评论所述,存在更简单的证据证明这一事实。