如何指示两种 Coq 电感类型尺寸的减小

2023-12-11

我正在尝试定义game组合游戏的归纳型。我想要一个比较方法来判断两个游戏是否相同lessOrEq, greatOrEq, lessOrConf or greatOrConf。然后我可以检查两个游戏是否相等(如果它们都是)lessOrEq and greatOrEq.

但是当我尝试定义用于进行此检查的相互递归方法时,我得到:

错误:无法猜测递减参数fix.

我认为这是因为每次递归调用时只有一个游戏或另一个游戏的大小会减小(但不是两者都会减小)。我如何向 Coq 表明这一点?

这是我的代码。失败的部分是相互递归定义gameCompare, innerGCompare, listGameCompare, gameListCompare.

Inductive game : Set :=
 | gameCons : gamelist -> gamelist -> game
with gamelist : Set :=
 | emptylist : gamelist
 | listCons : game -> gamelist -> gamelist.

Definition side :=
 game -> gamelist.

Definition leftSide (g : game) : gamelist :=
 match g with
  | gameCons gll glr => gll
 end.

Definition rightSide (g : game) : gamelist :=
 match g with
  | gameCons gll glr => glr
 end.

Inductive compare_quest : Set :=
 | lessOrEq : compare_quest
 | greatOrEq : compare_quest
 | lessOrConf : compare_quest
 | greatOrConf : compare_quest.

Definition g1side (c : compare_quest) : side :=
 match c with
  | lessOrEq => leftSide
  | greatOrEq => rightSide
  | lessOrConf => rightSide
  | greatOrConf => leftSide
 end.

Definition g2side (c : compare_quest) : side :=
 match c with 
  | lessOrEq => rightSide
  | greatOrEq => leftSide
  | lessOrConf => leftSide
  | greatOrConf => rightSide
 end.

Definition combiner :=
 Prop -> Prop -> Prop.

Definition compareCombiner (c : compare_quest) : combiner :=
 match c with
  | lessOrEq => and
  | greatOrEq => and
  | lessOrConf => or
  | greatOrConf => or
 end.

Definition nextCompare (c : compare_quest) : compare_quest :=
 match c with
  | lessOrEq => lessOrConf
  | greatOrEq => greatOrConf
  | lessOrConf => lessOrEq
  | greatOrConf => greatOrEq
 end.

Definition cbn_init (cbn : combiner) : Prop :=
 ~ (cbn False True).

Fixpoint gameCompare (c : compare_quest) (g1 : game) (g2 : game) : Prop :=
 innerGCompare (nextCompare c) (compareCombiner c) g1 (g1side c g1) g2 (g2side c g2)
with innerGCompare (next_c : compare_quest) (cbn : combiner)
      (g1 : game) (g1s : gamelist) (g2 : game) (g2s : gamelist) : Prop :=
 cbn (listGameCompare next_c cbn g1s g2) (gameListCompare next_c cbn g1 g2s)
with listGameCompare (c : compare_quest) (cbn : combiner) (g1s : gamelist) (g2 : game) : Prop :=
 match g1s with
  | emptylist => cbn_init cbn
  | listCons g1s_car g1s_cdr => cbn (gameCompare c g1s_car g2) (listGameCompare c cbn g1s_cdr g2)
 end
with gameListCompare (c : compare_quest) (cbn : combiner) (g1 : game) (g2s : gamelist) : Prop :=
 match g2s with
  | emptylist => cbn_init cbn
  | listCons g2s_car g2s_cdr => cbn (gameCompare c g1 g2s_car) (gameListCompare c cbn g1 g2s_cdr)
 end.

Definition game_eq (g1 : game) (g2 : game) : Prop :=
 (gameCompare lessOrEq g1 g2) /\ (gameCompare greatOrEq g1 g2).

您可能可以采取多种措施来解决此问题。我无法真正理解您的代码想要做什么,所以也许有比我要提到的更有效的方法。

你可以做的一件事就是定义gameCompare作为(可能是相互的)归纳关系而不是函数。我不知道你对 Coq 有多熟悉,所以我不会详细解释这一点,因为答案会太大,但是在定义诸如以下概念时,归纳关系比函数提供了更大的灵活性gameCompare。有关如何定义归纳关系的更多信息,可以查看Benjamin Pierce的书软件基础.

这种方法的一个缺点是,与函数不同,归纳关系并不真正计算任何东西。这使得它们有时更难使用。特别是,您不能像简化函数调用那样简化归纳命题。

另一种可能更容易应用于您的问题的方法是向函数添加一个“时间”数字参数,该参数随着每次递归调用而减少。这使得函数很容易终止。然后,为了使其工作,您只需确保使用足够大的“时间”参数进行初始调用。以下是如何执行此操作的示例:

Fixpoint gameSize (g : game) : nat :=
  match g with
    | gameCons gl1 gl2 => 1 + gameListSize gl1 + gameListSize gl2
  end

with gameListSize (gl : gamelist) : nat :=
  match gl with
    | emptylist => 1
    | listCons g gl => 1 + gameSize g + gameListSize gl
  end.

Definition gameCompareTime (g1 g2 : game) : nat :=
  gameSize g1 + gameSize g2.

Fixpoint gameCompareAux (time : nat) (c : compare_quest) (g1 : game) (g2 : game) : Prop :=
  match time with
    | O => True
    | S time =>
      compareCombiner c
                      (listGameCompare time
                                       (nextCompare c)
                                       (compareCombiner c)
                                       (g1side c g1)
                                       g2)
                      (gameListCompare time
                                       (nextCompare c)
                                       (compareCombiner c)
                                       g1
                                       (g2side c g2))
  end

with listGameCompare (time : nat) (c : compare_quest) (cbn : combiner) (g1s : gamelist) (g2 : game) : Prop :=
  match time with
    | 0 => True
    | S time =>
      match g1s with
        | emptylist => cbn_init cbn
        | listCons g1s_car g1s_cdr => cbn (gameCompareAux time c g1s_car g2) (listGameCompare time c cbn g1s_cdr g2)
      end
  end

with gameListCompare (time : nat) (c : compare_quest) (cbn : combiner) (g1 : game) (g2s : gamelist) : Prop :=
  match time with
    | 0 => True
    | S time =>
      match g2s with
        | emptylist => cbn_init cbn
        | listCons g2s_car g2s_cdr => cbn (gameCompareAux time c g1 g2s_car) (gameListCompare time c cbn g1 g2s_cdr)
      end
  end.

Definition gameCompare c g1 g2 :=
  gameCompareAux (gameCompareTime g1 g2) c g1 g2.

Definition game_eq (g1 : game) (g2 : game) : Prop :=
 (gameCompare lessOrEq g1 g2) /\ (gameCompare greatOrEq g1 g2).

The gameCompareTime函数计算两个游戏的大小总和,这似乎是调用树深度的合理界限gameCompareAux。请注意,我已经内联了innerGCompare,因为这使得边界更容易计算。当时间结束时(即模式匹配的 0 分支),我们返回一个任意值(True,在本例中),因为我们将给函数足够的时间让它在到达这种情况之前完成。

这种方法的优点是相对容易实现。缺点是证明任何关于gameCompare需要你推理gameCompareAux并明确终止时间,这可能非常繁琐。

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

如何指示两种 Coq 电感类型尺寸的减小 的相关文章

  • 在 C# 中比较两个结构体的值

    我不是在寻找返回 bool 的两个结构的比较 我想知道是否有一种方法可以获取两个结构的哪些字段 相同的结构 但可能不同的值 是不同的 基本上我想要一种更简单的方法来执行以下操作 public class Diff public String
  • Coq QArith 除以零就是零,为什么?

    我注意到在 Coq 的有理数定义中 零的倒数被定义为零 通常 除以零是没有明确定义 合法 允许的 Require Import QArith Lemma inv zero is zero 0 0 Proof unfold Qeq refle
  • C# 没有边界检查的 byte[] 比较

    我正在寻找性能高效的方法来比较两个 byte 是否相等 大小超过 1 MB 因此每个数组元素的开销应最小化 我的目标是超越SequenceEqual http msdn microsoft com en us library bb34856
  • c#:动作无与伦比?

    我正在尝试比较两个操作 与 的比较总是返回 false 就像 Equals 方法一样 即使它是同一个实例 我的问题是 这真的不可能还是我做错了 干杯 交流电 你做错了 如果我相信你 当你说 即使它是同一个实例 时 那么以下代码通过执行LIN
  • 测试“0”、“-0”、“0.0”、“00”时的 PHP 和 Perl 行为

    当 PHP Perl 测试一个值时 我遇到了这个有趣的行为 print 0 Yes No gt No print 00 Yes No gt Yes print 0 0 Yes No gt Yes print 0 Yes No gt Yes
  • 在 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
  • 将目录树表示为递归列表

    我被某项任务困住了 我想要的是一个函数 给定目录路径 它将返回递归列表作为输出 输出的格式应为 myList dir subdir subdir fullFilePath 所以基本上我想将目录树表示为某个列表 我获取了所有文件 获取了每个文
  • LINQ:通过使不同类型的集合可转换/可比较来使用 .Except() ?

    给定两个不同类型的列表 是否可以使这些类型可以相互转换或相互比较 例如使用 TypeConverter 或类似的 以便 LINQ 查询可以比较它们 我在 SO 上看到过其他类似的问题 但没有任何迹象表明可以使类型之间可以相互转换来解决问题
  • 确定一个数字是否是十的倍数或在一组特定范围内

    我的程序中有一些需要的循环 我可以写出伪代码 但我不完全确定如何逻辑地编写它们 I need if num is a multiple of 10 do this if num is within 11 20 31 40 51 60 71
  • SQL 多列大于表达式

    看到以下与游标分页结果相关的 SQL 但无法找到有关其部分工作原理的更多信息 SELECT b FROM books b WHERE b name id gt select b2 name b2 id from books b2 where
  • 我可以将 pandas.dataframe.isin() 与数字容差参数一起使用吗?

    我事先查看了以下帖子 有没有办法将 DataFrame isin 与近似因子或容差值一起使用 或者还有其他方法可以吗 如果列中的值位于一组值列表中 则过滤数据框行 https stackoverflow com questions 1206
  • 用于 PHP 开发的 Eclipse PDT 与 NetBeans [已关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 对于 PHP 开发 Eclipse PDT 与 NetBeans 相比如何 我刚刚买了一台装有 Windows 7 的新电脑 我开始设置
  • 如何处理 Coq 中 Program Fixpoint 生成的非常大的项?

    我试图在 Coq 中定义并证明正确的函数 该函数可以有效地比较两个排序列表 由于它并不总是在结构较小的项上递归 第一个或第二个列表较小 Fixpoint不会接受它 所以我尝试使用Program Fixpoint反而 当尝试使用策略证明函数的
  • 如何在Prolog中编写cmp_list/3函数?

    Write a predicate cmp list 3 the first 2 arguments are 2 lists and the last one is Comparison which means ge lt le or gt
  • 为什么 std::sort 将元素与其自身进行比较

    正如题主所说 为什么下面的代码将某些元素与它们自身进行比较 include
  • 为什么使用“==”或“is”比较字符串有时会产生不同的结果?

    两个字符串变量设置为相同的值 s1 s2总是返回True but s1 is s2有时返回False 如果我打开 Python 解释器并执行相同的操作is对比一下 成功了 gt gt gt s1 text gt gt gt s2 text
  • Python:比较字符串与重音字符不起作用

    我对 python 很陌生 我正在尝试从另一个列表中删除一个列表中出现的文件 这些列表是通过在 mac 和 windows 上重定向 ll R 生成的 但自从使用其他 python 脚本进行了一些处理 合并 排序等 某些文件名带有重音符号和
  • 比较 Swift 中的 AnyObjects,无需将它们转换为特定类型

    尝试使用 Equatable 协议中定义的 运算符来比较 AnyObject 类型的两个对象会导致 Swift 中出现编译错误 有没有人找到一种方法来比较这些对象 而不知道可用于向下转换的对象的真实类型 这个问题的背景是我有一个字典 Dic
  • 比较 Lua 中的日期

    我有一个带有日期表的变量 如下所示 table day number 15 year number 2015 month number 2 如何获取当前日期与上述日期之间的天数 非常感谢 您可以使用os time 将表转换为秒并获取当前时间
  • 从时间列表中查找最接近的时间

    所以 这是场景 我有一个带有创建时间的文件 我想从该文件的创建时间最接近或相等的时间列表中选择一个时间 完成此操作的最佳方法是什么 var closestTime listOfTimes OrderBy t gt Math Abs t fi

随机推荐

  • 如何删除数据框列的标题

    我想出了一个像这样的数据框 我想知道我们如何更改或删除 id 和 date 因为它们只是索引和列的名称 id col1 col2 clo3 date 2000 01 03 55 500000 NaN NaN 2000 01 04 52 81
  • 使用 ImageMagick 将 PDF 转换为 PNG 或 JPEG 非常非常慢

    我有一个使用 PHP 和 ImageMagick 的 PDF 到 PNG 转换脚本 但我遇到了转换速度问题 我知道它是有效的 因为对于非常小的 PDF 转换所需的时间并不是那么长 但是对于 250kb 文件 实际上仍然不是那么大 转换需要超
  • 如何控制winform mschart图例文本对齐c#?

    如何设置图表图例对象中的文本对齐方式 我尝试过使用 myChartName Legends mySeriesName Alignment stringAlignment Near 没有效果 我还尝试创建自定义图例项目 同样没有效果 文本始终
  • FirefoxDriver webdriver.load.strategy 不稳定 findelements 从错误页面获取元素

    我在一个应用程序中使用 FirefoxDriver 该应用程序可以快速浏览几个相似但不相同的页面 为了加快执行速度 我需要使用 FF 我将 webdriver load strategy 属性设置为 不稳定 这确实通过不完全加载页面来加快速
  • python groupby 行为?

    gt gt from itertools import groupby gt gt keyfunc lambda x x gt 500 gt gt obj dict groupby range 1000 keyfunc gt gt list
  • 哪一种是表单验证的正确方法? Colander 的模式验证还是 Deform 的表单验证?

    我刚刚开始使用Pyramid对于我的一个项目 我有一种情况 我需要验证表单字段输入 方法是获取该表单字段值并进行 Web 服务调用来断言该值的正确性 例如 有一个字段称为您银行的 CUSTOMER ID 我需要将其 单独 作为输入 并通过进
  • TKinter 中的阿拉伯语文本

    我正在创建一个带有文本的窗口 我想在文本中使用阿拉伯语 root Tk root title Alram root geometry 1500x600 msg Message root bg red text The main interf
  • 使用递归函数反转字符串

    我目前正在学习 C 我无法通过这个练习 我必须创建一个递归函数来反转string1 into string2 这是我的代码 我将非常感谢您的帮助 include
  • 以编程方式访问 Windows 8.1 中最常用的应用程序

    Windows 8 1 开始菜单提供了可按最常用排序的应用程序列表 Windows 按钮 gt 向下箭头 gt 应用程序 按最常用排序 有没有办法以编程方式获取这些应用程序的列表按这个顺序在 C 中 如果不是按照这个顺序 至少是 Windo
  • 如何使用 Tuple/Array/Vector 从 Python (ctypes) 调用 PARI/GP?

    我想打电话PARI GP来自Python 我需要使用ellisdivisible E P n Q 帕里的功能 请参阅此链接中第 441 页的第 3 15 35 号功能 所以我必须传递 2 个向量或数组 例如 E ellinit 0 1 1
  • Spring MVC 和登录重定向

    我有一个网络应用程序 当用户单击个人资料链接时 如果他没有登录 我想将他重定向到登录页面 然后当他登录时 我会将他发送回他所拥有的链接原来点击了 在这种情况下 他的个人资料 我已经完成了将他重定向到登录页面的部分 但我试图找出如何记住他的初
  • Android 导航组件 - 更改根片段?

    假设我有片段 a gt b gt c 但 a 是启动画面 所以我希望 b 成为堆栈中的第一个片段并永远抛出 a 所以当我是 b 时然后按 后退 系统按钮 我关闭应用程序 在SupportFragmentManager中 我使用了replac
  • 以气流用户身份运行气流进程和气流网络服务器

    Problem 我正在 GCP 上设置 Google Compute Engine 虚拟机airflow安装在其上 我现在正在尝试整合airflow with systemd按照以下说明http airflow readthedocs io
  • 如何在 Android 的聊天或消息应用程序中发送表情符号(图像、笑脸)?

    如何发送在编辑文本中一起编写的文本和表情符号 图像 不是默认表情符号 资源文件夹中的图像 以发送该编辑文本中出现的消息和聊天 p s 我正在邮件或消息正文中发送这些图像 我正在尝试以下代码 public class MainActivity
  • 如何在Javascript中实时输出到控制台?

    在 Javascript 中 当您编写如下代码时 计算机似乎会首先完成整个循环 100 000 次 可能需要一两秒 然后一次转储控制台中的所有 100 000 行射击 我怎样才能使计算机每次通过循环一次更新控制台一行 为了澄清 我实际上希望
  • 如何在 Ruby 中进行高级字符串比较?

    我正在尝试比较两段字符串 其输出必须是相似度的百分比 我尝试过使用diff方法和一些Natural Language Processing tools 在红宝石中是否有更好的方法来做到这一点 您可能想为此尝试 Levenshtein 字符串
  • R 使用 lapply 保存绘图

    我有一个名为的模型对象列表allAR1 对于每个模型对象 我需要使用tsdiag函数生成诊断图 然后将该图保存到文件夹中 我正在尝试使用 jpeg lapply 和 dev off 的组合来应用tsdiag每个模型 然后将生成的图保存为图像
  • JNA:找不到指定的程序

    我试图了解 JNA 的工作原理 因此我决定使用 spotify API libspotify 0 0 7 我设法正确加载我的 dll 但看起来我的代码没有找到 API 中定义的任何方法 这是我的代码 我的主要文件 public class
  • 组菜单项可以工作,但不显示复选标记

    我有一个带有溢出菜单的工作应用程序 菜单中的所有代码都有效 但在我单击可单击的分组菜单项后 没有显示复选标记 我是否在做一些根本性错误的事情 我认为 Android 系统会自动显示复选标记 并且系统会为我执行此操作 Android知道它是在
  • 如何指示两种 Coq 电感类型尺寸的减小

    我正在尝试定义game组合游戏的归纳型 我想要一个比较方法来判断两个游戏是否相同lessOrEq greatOrEq lessOrConf or greatOrConf 然后我可以检查两个游戏是否相等 如果它们都是 lessOrEq and