从mathcomp的ssralg

时间:2017-08-09 16:20:36

标签: coq ssreflect

为问题设置了一点:符号`_i被定义为序列的第i个分量,但也意味着是多项式的第i个系数。以下代码输出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包含构造函数PoszNegz

标题 https://github.com/math-comp/math-comp/blob/master/mathcomp/algebra/poly.v 通知我们Poly s是一个多项式,其序列来自序列s。它还说p`_i是多项式p的第i个系数。我希望以下代码输出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中恢复int_Ring的值? int_Ring的打包方式看起来不太可能,因为构造函数不引用元素。但是,int_ZmodType也是如此。作为参考,这些类型在

中定义

https://github.com/math-comp/math-comp/blob/master/mathcomp/algebra/ssralg.v

2 个答案:

答案 0 :(得分:3)

这并没有完全回答这个问题,但我设法证明系数确实是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.

编辑:正如下面的评论中所解释的,存在这个事实的简单证据。

答案 1 :(得分:2)

这是您的代码的一个版本:

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来定义的,idP又是insub的案例分析定义的,这是一个不透明的引理!当一个不透明的术语妨碍时,Coq的减少会被卡住。 (如果你很好奇,这里发生的是idP正在使用+测试多项式的前导系数是否确实与零不同,如果是,则使用该事实建立多项式。)

问题是ssreflect中的许多定义都没有在逻辑内完全计算。这是由于两个原因。一个是性能:通过允许一切完全减少,我们可以使类型检查更慢。另一个是ssreflect是为了方便推理而量身定制的,因此许多定义并不是最有效的。开发CoqEAL库是为了将具有更好计算行为的定义连接到更易于推理的定义,例如ssreflect;不幸的是,我不知道该项目是否仍在维护中。