在 Coq 中使用依赖类型(安全第 n 个函数)

2024-01-29

我正在尝试学习 Coq,但我发现很难从我读到的内容中实现飞跃软件基础 and 依赖类型的认证编程到我自己的用例。

特别是,我想我应该尝试制作一个经过验证的版本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.

这可行,但它提出了两个问题:

  1. 有经验的 Coq 用户会如何写这个?这三个引理真的有必要吗?这是一个用例吗{ | } types?
  2. 如何从其他代码调用此函数,即如何提供所需的证明?

我试过这个:

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 开发通常倾向于使用索引归纳类型来编写这样的代码。这是随后的解决方案矢量库 https://coq.inria.fr/distrib/current/stdlib/Coq.Vectors.Vector.html在 Coq 发行版中。在那里,您可以为向量定义一个索引归纳类型,为有界整数定义另一种索引归纳类型(称为Vector.t and Fin.t分别在标准库中)。一些函数,例如nth,用这种风格编写要简单得多,因为例如,在消除矛盾的情况和进行递归调用时,向量和索引上的模式匹配最终会为您进行一些推理。缺点是 Coq 中的依赖模式匹配不是很直观,有时你必须以奇怪的方式编写函数才能让它们工作。这种方法的另一个问题是,需要重新定义许多适用于列表的函数才能适用于向量。

另一个解决方案是将有界整数定义为 a 的依赖对nat以及该索引是有界的证明,这本质上就是您提到的时候想要的{ | }类型。这是以下方法所遵循的ss反射 http://ssr.msr-inria.inria.fr/~jenkins/current/Ssreflect.fintype.html例如,图书馆(寻找ordinal类型)。定义一个安全的nth函数,他们所做的是定义一个简单的版本,当索引越界时返回一个默认元素,并使用以下证明:n < length l提供默认元素(例如看看tuple http://ssr.msr-inria.inria.fr/~jenkins/current/Ssreflect.tuple.htmlssreflect 库,他们在其中定义长度索引列表,并了解它们如何定义tnth)。优点是更容易将信息更丰富的类型和函数与更简单的变体联系起来。缺点是有些事情变得更难以直接表达:例如,您不能直接在 ssreflect 元组上进行模式匹配。

值得注意的另一点是,通常使用布尔属性比归纳定义的属性更容易,因为计算和简化消除了对某些引理的需要。因此,当使用布尔版本时<, Coq 不会区分以下证明0 < 0 = true and false = true,或之间的证明S n < length (x :: l) = true和一个证明n < length l = true,这意味着您可以直接在定义中使用这些证明nth无需用辅助引理来按摩它们。不幸的是,Coq 标准库在许多情况下倾向于使用归纳定义的类型而不是布尔计算,而在这些情况下它们没有用处,例如定义<. The ss反射 http://ssr.msr-inria.inria.fr另一方面,库更多地使用布尔计算来定义属性,使其更适合这种编程风格。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Coq 中使用依赖类型(安全第 n 个函数) 的相关文章

  • 如何切换到 Coq 的特定版本——尤其是在使用 Opam 管理 Coq 版本时?

    我目前使用的是标准方式 可能通过网站 安装的标准方式 但我想用tcoq 我相信我已经正确安装了它 因为我有一个 bin 文件 并且所有常见的 Coq 内容似乎都在那里 pinno gamepad tcoq ls bin coq tex co
  • Coq Proof Assistant 中依赖类型的问题

    考虑以下简单的表达语言 Inductive Exp Set EConst nat gt Exp EVar nat gt Exp EFun nat gt list Exp gt Exp 及其格式良好的谓词 Definition Env lis
  • Coq 平等实现

    我正在编写一种玩具语言 其中 AST 中的节点可以有任意数量的子节点 Num has 0 Arrow有 2 个 等等 您可以致电这些接线员 此外 AST 中可能只有一个节点被 聚焦 我们对数据类型进行索引Z如果它有焦点 或者H如果没有 我需
  • Ltac:通过回溯重复策略 n 次

    假设我有一个像这样的策略 取自 HaysTac 它搜索一个参数来专门化一个特定的假设 Ltac find specialize in H multimatch goal with v gt specialize H v end 然而 我想写
  • 匹配中的冗余子句

    当我运行以下脚本时 Definition inv a Prop Prop match a with False gt True True gt False end 我收到 错误 该子句是多余的 知道为什么会发生这种情况吗 谢谢 马库斯 这件
  • Coq - 在 if ... then ... else 中使用 Prop (True | False)

    我对 Coq 有点陌生 我正在尝试实现插入排序的通用版本 我正在实现一个以比较器作为参数的模块 该 Comparator 实现了比较运算符 如 is eq is le is neq 等 在插入排序中 为了插入 我必须比较输入列表中的两个元素
  • 如何有效地查找 Coq 中定义标识符的位置?

    在大多数 IDE 或文本编辑器中 您可以右键单击某个术语 它会将您带到定义该术语的文件 CoqIDE好像没有这个 所以我一直在做coqdoc myfile v html 然后转到生成的 HTML 文档 但该文件中唯一可点击的术语是针对 Co
  • Coq 中的程序定点和函数有什么区别?

    它们似乎有相似的目的 到目前为止我注意到的一个区别是Program Fixpoint将接受复合措施 例如 measure length l1 length l2 Function似乎拒绝这一点并且只会允许 measure length l1
  • 证明匹配语句

    为了解决一个练习 我有以下代表整数的定义 Inductive bin Type Zero bin Twice bin gt bin TwiceOne bin gt bin 这个想法是 Twice x is 2 x 两次一x is 2 x 1
  • 将假设中的 ~exists 转换为 forall

    我陷入了假设的境地 exists k k lt n 1 f k f n 2 并希望将其转换为等效的 我希望如此 假设forall k k lt n 1 gt f k lt gt f n 2 这是一个小例子 Require Import Co
  • Prop 和 Type 的不同归纳原理

    我注意到 Coq 综合了关于 Prop 和 Type 等式的不同归纳原理 有人对此有解释吗 平等定义为 Inductive eq A Type x A A gt Prop eq refl x x 与之相关的归纳原理有以下类型 eq ind
  • 如何在构造微积分中提取Sigma的第二个元素?

    我尝试这样做 A gt B A gt gt t r gt x a gt B x gt r gt r gt t B t A x A gt y B x gt x x A gt y B x gt y 请注意 由于该函数返回的值取决于 sigma
  • Coq 中的案例分析证明

    我试图证明关于以下函数的命题 Program Fixpoint division m nat n nat measure m nat match lt nat 0 n with false gt 0 true gt match leq na
  • 在 Coq 中查找 ++ 等定义和符号

    我们如何获得这些符号的定义 类型 例如 or of List 我努力了 Search Search Search SearchAbout and Check Check Check 然而它们都不起作用 SearchAbout 确实显示了一些
  • 在 Coq 中,“if then else”允许非布尔第一个参数?

    我读过一些教程if a then b else c代表match a with true gt b false gt c end 然而 很奇怪的是 前者不检查类型a 而后者当然确保a是一个布尔值 例如 Coq lt Check if nil
  • Coq案例分析和函数返回子集类型的重写

    我正在做一个关于使用子集类型编写经过认证的函数的简单练习 想法是先写一个前驱函数 pred forall n n nat n gt 0 m nat S m n 1 然后使用这个定义给定一个函数 pred2 forall n n nat n
  • 我如何编写行为类似于“破坏...作为”的策略?

    在coq中 destruct https coq inria fr distrib current refman Reference Manual010 html hevea tactic65策略有一个接受 连接析取引入模式 的变体 该模式
  • 为什么较新的依赖类型语言没有采用 SSReflect 的方法?

    我在 Coq 的 SSReflect 扩展中发现了两个约定 它们似乎特别有用 但我还没有看到它们在较新的依赖类型语言 Lean Agda Idris 中得到广泛采用 首先 可能的谓词被表示为布尔返回函数而不是归纳定义的数据类型 默认情况下
  • 在 Coq 模块系统中导入 与包含

    确切的语义是什么Include M1在另一个模块中 比如 M 这与做有什么不同Import M1在模块 M 内 更准确地说 以下命令的语义是什么 Module Type M M1 lt M2 lt M3 总结这两个白话命令的语义 命令Inc
  • Coq:多个构造函数的单一表示法

    是否可以在 Coq 中为多个构造函数定义单一符号 如果构造函数的参数类型不同 则可以从中推断出它们 一个最小的 非 工作示例 Inductive A Set a b c C gt A d D gt A with C Set c1 c2 wi

随机推荐

  • 通过 Powershell 在 IIS 7.5 中启用模拟

    我希望有人可以提供帮助 我正在尝试在 IIS 7 的身份验证会话下启用 ASP Net 模拟 我已使用以下命令启用了其他部分 Set WebConfigurationProperty filter system WebServer secu
  • 在 Perl 中启动非等待后台进程

    我有一个 Perl 脚本 需要在后台启动另一个进程并退出 而不等待其他脚本完成 StackOverflow 上有很多线程介绍如何在 Perl 中等待或如何不等待其他编程语言 但我似乎找不到 Perl 的正确答案 我已经阅读了相当多的内容 并
  • 为什么 foreach %dopar% 每增加一个节点就会变慢?

    我编写了一个简单的矩阵乘法来测试网络的多线程 并行化功能 我注意到计算速度比预期慢得多 The Test很简单 乘以 2 个矩阵 4096x4096 并返回计算时间 矩阵和结果都不被存储 计算时间并非微不足道 50 90 秒 具体取决于您的
  • 如何向枚举添加多个属性?

    我有一个名为的 SQL 查找表客户信用解决计划行动类型我想转换为enum questions tagged enum in c questions tagged c 23 非常基本的要求 对吧 正确的 我的桌子 现在enum questio
  • co_await 似乎不是最理想的?

    我有一个异步函数 void async foo A a B b C c function
  • IE11框架通知栏保存按钮

    在装有 MS Excel 2010 和 IE11 的 64 位系统上 我使用此代码自动从网站下载过程 hWnd FindWindowEx IE hWnd 0 Frame Notification Bar vbNullString If hW
  • 如何将文件读入整数数组

    在我的应用程序文档文件夹中 我有一个文件 我试图将其逐字节读入数组UInt8其中每个元素代表一个字节 我该怎么做呢 该文件恰好名为 Q1 dat 这是我不成功的尝试 func readArray gt Int if let arrayPat
  • 使用 angular2 显示/隐藏密码文本

    我想根据用户点击显示 隐藏密码文本 但我收到以下错误消息 export class App password secret show false ContentChild ShowHideInput input ShowHideInput
  • 同一手臂上不同类型的模式匹配

    我想知道当两个或多个不同的枚举类型具有相同的数据成员或相同的函数时 是否有一种方法可以简化以下模式匹配臂 如果没有 最好解释一下原因 UPDATE 根据要求提供我想要的更准确的示例 请原谅我将数据成员访问与函数混淆 struct Point
  • Hibernate 验证器:@Email 接受ask@stackoverflow 为有效吗?

    我正在使用 Email用于验证电子邮件地址的注释 我遇到的问题是它接受诸如ask stackoverflow作为有效的电子邮件地址 我想这是因为他们想支持 Intranet 地址 但我似乎找不到标志 所以它确实检查扩展名 我真的需要切换到
  • 将 ListView 绑定到 ListProperty

    在tornadoFX中是否可以将ListView绑定到ListProperty 我有一个如下所示的 ViewModel class MyVm ItemViewModel
  • 使用带有 nginx 的 React 路由器应用程序获取 404 [重复]

    这个问题在这里已经有答案了 我有一个反应前端应用程序 它使用反应路由器来创建不同的路线 在开发服务器上它工作正常 但是当我构建项目时 它给我 404 同时直接使用不同的路由访问它 网站完美打开xyz net 当我尝试使用以下命令访问它时 它
  • 使用 ssh 访问存储库

    昨天我发现了 git 这样的东西的存在 我需要使用 ssh 访问远程存储库 我使用了命令 git clone email protected cdn cgi l email protection email protected cdn cg
  • 用于创建事件处理程序存根的 Visual Studio 键盘快捷键

    当您在设计视图中编辑简单页面时 只需双击相关事件即可在大多数组件上添加事件 这将完成绑定并在代码隐藏中为您生成函数声明 在页面复杂的大型项目中 设计视图可能会非常慢 有没有一种方法可以直接从代码快速生成代码隐藏存根 aspx source
  • linq Last() 如何确定最后一项?

    我不明白 Current 如何可以为 null 而 LINQ 函数 Last 可以返回一个对象 我认为 Last 使用 GetEnumerator 并一直持续到 current null 并返回对象 然而 正如您所看到的 第一个 GetEn
  • 如果值匹配,则自动比较 2 个 csv 文件的值,将第二个 csv 读入 DataFrame

    我已将 Excel 导入到数据框中 它看起来像这样 然后我使用代码根据 tx id 对这些数据进行分组 并使用 tx id 的名称创建单独的 csv 这给了我这样的数据 3e6737ae c3af 4d19 a645 d17fc73dbb7
  • Java 基准测试 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我们正在使用 perlbench pybench 和 php bench 等标准基准测试工具对 Per
  • 从 commons.lang 迁移 StringEscapeUtils.escapeSql

    我已经开始将 commons lang 2 迁移到 commons lang3 根据https commons apache org proper commons lang article3 0 html https commons apa
  • XSLT 复制除 1 个元素之外的所有节点

  • 在 Coq 中使用依赖类型(安全第 n 个函数)

    我正在尝试学习 Coq 但我发现很难从我读到的内容中实现飞跃软件基础 and 依赖类型的认证编程到我自己的用例 特别是 我想我应该尝试制作一个经过验证的版本nth列表上的函数 我设法写了这个 Require Import Arith Req