- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试学习 Coq,但我发现很难从我在《软件基础》和《依赖类型认证编程》中读到的内容过渡到我自己的内容用例。
特别是,我想尝试制作 nth
的验证版本列表上的函数。我设法写了这个:
Require Import Arith.
Require Import List.
Import ListNotations.
Lemma zltz: 0 < 0 -> False.
Proof.
intros. contradict H. apply Lt.lt_irrefl.
Qed.
Lemma nltz: forall n: nat, n < 0 -> False.
Proof.
intros. contradict H. apply Lt.lt_n_0.
Qed.
Lemma predecessor_proof: forall {X: Type} (n: nat) (x: X) (xs: list X),
S n < length (x::xs) -> n < length xs.
Proof.
intros. simpl in H. apply Lt.lt_S_n. assumption.
Qed.
Fixpoint safe_nth {X: Type} (n: nat) (xs: list X): n < length xs -> X :=
match n, xs with
| 0, [] => fun pf: 0 < length [] => match zltz pf with end
| S n', [] => fun pf: S n' < length [] => match nltz (S n') pf with end
| 0, x::_ => fun _ => x
| S n', x::xs' => fun pf: S n' < length (x::xs') => safe_nth n' xs' (predecessor_proof n' x xs' pf)
end.
这可行,但它提出了两个问题:
{ | }
的用例吗?类型?我尝试过这个:
Require Import NPeano.
Eval compute in if ltb 2 (length [1; 2; 3]) then safe_nth 2 [1; 2; 3] ??? else 0.
但是当然,除非我弄清楚要为 ???
写什么,否则这不会起作用。部分。我尝试输入 (2 < length [1; 2; 3])
但有类型 Prop
而不是输入 2 < length [1; 2; 3]
。我可以编写并证明该特定类型的引理,并且这是有效的。但一般的解决方案是什么?
最佳答案
我认为对于做这类事情的最佳方法是什么没有达成共识。
我相信 Coq 开发通常倾向于使用索引归纳类型来编写这样的代码。这是 vector library 后面的解决方案在 Coq 发行版中。在那里,您可以为向量定义一种索引归纳类型,为有界整数定义另一种索引归纳类型(在标准库中分别称为 Vector.t
和 Fin.t
)。一些函数,如nth
,用这种风格编写要简单得多,因为例如,在消除矛盾的情况和进行递归调用时,向量和索引上的模式匹配最终会为您进行一些推理。缺点是 Coq 中的依赖模式匹配不是很直观,有时你必须以奇怪的方式编写函数才能让它们工作。这种方法的另一个问题是,需要重新定义许多适用于列表的函数才能适用于向量。
另一个解决方案是将有界整数定义为 nat
的依赖对。以及该索引有界的证明,这本质上就是您提到 { | }
时所追求的。类型。这是 ssreflect 遵循的方法。例如,库(查找 ordinal
类型)。定义一个安全nth
函数,他们所做的就是定义一个简单的版本,当索引越界时返回一个默认元素,并使用 n < length l
的证明提供该默认元素(例如查看 ssreflect 的 tuple 库,它们在其中定义长度索引列表,并了解它们如何定义 tnth
)。优点是更容易将信息更丰富的类型和函数与更简单的变体联系起来。缺点是有些事情变得更难以直接表达:例如,您无法直接对 ssreflect 元组进行模式匹配。
值得注意的另一点是,通常使用 bool 属性比归纳定义的属性更容易,因为计算和简化消除了对某些引理的需要。因此,当使用 <
的 bool 版本时,Coq 不会区分 0 < 0 = true
的证明和false = true
,或 S n < length (x :: l) = true
的证明之间以及 n < length l = true
的证明,这意味着您可以直接在 nth
的定义中使用这些证明无需用辅助引理来按摩它们。不幸的是,Coq 标准库在许多情况下倾向于使用归纳定义的类型而不是 bool 计算,而 bool 计算在这些情况下并没有什么用处,例如定义 <
。 ssreflect另一方面,库更多地使用 bool 计算来定义属性,使其更适合这种编程风格。
关于coq - 在 Coq 中使用依赖类型(安全第 n 个函数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27637949/
我正在尝试理解 Coq 定理: Theorem thm0 : UseCl Pos (PredVP (UsePN john_PN) walk_V) -> UseCl Pos
编辑 Require Import Bool List ZArith. Variable A: Type. Inductive error := | Todo. Induc
我试图在 Coq 中证明以下引理: Lemma not_eq_S2: forall m n, S m <> S n -> m <> n. 这似乎很容易,但我不知道如何完成证明。有人可以帮帮我吗? 谢谢
我想查看我的证明中使用的所有公理。 获取此类信息的最简单方法是什么? 我将使用哪些命令、脚本或工具? 我对所有公理或所有使用过的公理感兴趣。 最佳答案 你应该使用 Print Assumptions
我想以某种方式限制在归纳定义中允许什么样的输入构造函数。说我想说定义二进制数如下: Inductive bin : Type := | O : bin | D : bin -> bin |
Coq 标准库中是否有对自然数进行欧几里德除法的函数?我一直无法找到一个。如果没有,那么从数学上讲,是否有理由不应该有一个? 我想要这个的原因是因为我试图将一个列表分成两个较小的列表。我希望一个列表的
我在将参数传递给 coq 中的产品类型时遇到问题。我有一个看起来像这样的定义, Definition bar (a:Type) := a->Type. 我需要定义一个函数,它接收“a”和“ba
这是本在线类(class)中出现的证明https://softwarefoundations.cis.upenn.edu/plf-current/StlcProp.html#lab222 . Proo
在命题和谓词演算中证明了数十个引理后(有些比其他的更具挑战性,但通常仍然可以在 intro-apply-destruct 自动驾驶仪上证明)我从 ~forall 开始打了一个并立即被捕获。显然,我缺乏
我正在学习命题逻辑和推理规则。析取三段论规则指出,如果我们的前提中有(P 或 Q),并且也有(非 P);然后我们可以到达Q。 我一生都无法弄清楚如何在 Coq 中做到这一点。假设我有: H : A \
从 Coq 引用手册 (8.5p1) 来看,我的印象是 revert是 intro 的倒数,但 generalize 也是如此在某种程度上。例如,revert和 generalize dependen
假设我知道某些自然数是好的。我知道 1 很好,如果 n 很好,那么 3n 就是,如果 n 很好,那么 n+5 就是,这些只是构造好数字的方法。在我看来,这在 Coq 中的充分形式化是 Inductiv
通常在 Coq 中,我发现自己在做以下事情:我有证明目标,例如: some_constructor a c d = some_constructor b c d 而我真的只需要证明a = b因为无论如
我希望能够为不同的归纳定义定义相同的 Coq 符号,并根据参数的类型区分这些符号。 这是一个最小的例子: Inductive type : Type := | TBool : type. Induct
有没有办法对 Coq 的类型类使用递归?例如,在为列表定义显示时,如果您想调用 show递归列表函数,那么你将不得不使用这样的固定点: Require Import Strings.String. R
假设我有一个解决某种引理的奇特策略: Ltac solveFancy := some_preparation; repeat (first [important_step1 | importa
我是 Coq 的新手。我注意到可以使用在 Coq 中定义空集 Inductive Empty_set : Set :=. 是否也可以将函数从空集定义为另一个通用集/类型? 如果是这样怎么办? 最佳答案
有人能给我一个 Coq 中存在实例化和存在泛化的简单例子吗?当我想证明exists x, P ,其中 P是一些 Prop使用 x ,我经常想命名x (如 x0 或类似的),并操纵 P。这可以是 Coq
我见过很多在功能上相互重叠的 Coq 策略。 例如,当您在假设中有确切的结论时,您可以使用 assumption , apply , exact , trivial ,也许还有其他人。其他示例包括 d
我需要使用标准库中称为 Coq.Arith.PeanoNat ( https://coq.inria.fr/library/Coq.Arith.PeanoNat.html ) 的部分。 我尝试过导入整
我是一名优秀的程序员,十分优秀!