将排序列表与大小类型合并

2024-01-10

假设我们有一个排序列表的数据类型,具有与证明无关的排序见证。我们将使用 Agda 的实验性大小类型功能,这样我们就有希望在数据类型上获得一些递归函数来通过 Agda 的终止检查器。

{-# OPTIONS --sized-types #-}

open import Relation.Binary
open import Relation.Binary.PropositionalEquality as P

module ListMerge
   {???? ℓ}
   (A : Set ????)
   {_<_ : Rel A ℓ}
   (isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_) where

   open import Level
   open import Size

   data SortedList (l u : A) : {ι : _} → Set (???? ⊔ ℓ) where
      [] : {ι : _} → .(l < u) → SortedList l u {↑ ι}
      _∷[_]_ : {ι : _} (x : A) → .(l < x) → (xs : SortedList x u {ι}) → 
               SortedList l u {↑ ι}

现在,人们想要在这样的数据结构上定义的一个经典函数是merge,它接受两个排序列表,并输出一个完全包含输入列表元素的排序列表。

   open IsStrictTotalOrder isStrictTotalOrder

   merge : ∀ {l u} → SortedList l u → SortedList l u → SortedList l u
   merge xs ([] _) = xs
   merge ([] _) ys = ys
   merge (x ∷[ l<x ] xs) (y ∷[ l<y ] ys) with compare x y
   ... | tri< _ _ _ = x ∷[ l<x ] (merge xs (y ∷[ _ ] ys))
   merge (x ∷[ l<x ] xs) (.x ∷[ _ ] ys) | tri≈ _ P.refl _ = 
      x ∷[ l<x ] (merge xs ys)
   ... | tri> _ _ _ = y ∷[ l<y ] (merge (x ∷[ _ ] xs) ys)

这个函数看起来没什么害处,只是要让 Agda 相信它是完整的可能很棘手。事实上,如果没有任何显式的大小索引,该函数将无法进行终止检查。一种选择是将函数拆分为两个相互递归的定义 https://stackoverflow.com/questions/17910737/termination-check-on-list-merge。这是可行的,但给定义和相关证明增加了一定量的冗余。

但同样,我不确定是否可以明确给出大小索引,以便merge有 Agda 会接受的签名。这些幻灯片 http://www2.tcs.ifi.lmu.de/~abel/appsemTalk.ps.gz%E2%80%8E讨论mergesort明确地;那里给出的签名表明以下内容应该有效:

   merge′ : ∀ {l u} → {ι : _} → SortedList l u {ι} → 
                      {ι′ : _} → SortedList l u {ι′} → SortedList l u
   merge′ xs ([] _) = xs
   merge′ ([] _) ys = ys
   merge′ (x ∷[ l<x ] xs) (y ∷[ l<y ] ys) with compare x y
   ... | tri< _ _ _ = x ∷[ l<x ] (merge′ xs (y ∷[ _ ] ys))
   merge′ (x ∷[ l<x ] xs) (.x ∷[ _ ] ys) | tri≈ _ P.refl _ = 
      x ∷[ l<x ] (merge′ xs ys)
   ... | tri> _ _ _ = y ∷[ l<y ] (merge' (x ∷[ _ ] xs) ys)

这里我们所做的是允许输入具有任意(和不同)的大小,并指定输出的大小为 ∞。

不幸的是,有了这个签名,Agda 抱怨说.ι != ∞ of type Size、检查身体时xs定义的第一个子句。我并不声称非常了解大小类型,但我的印象是任何大小 ι 都会与 ∞ 统一。也许自这些幻灯片编写以来,大小类型的语义已经发生了变化。

那么,我的场景是针对哪种大小的类型的用例吗?如果是这样,我应该如何使用它们?如果尺寸类型在这里不合适,为什么第一个版本merge上面不是终止检查,因为以下是 https://stackoverflow.com/questions/17910737/termination-check-on-list-merge:

open import Data.Nat
open import Data.List
open import Relation.Nullary

merge : List ℕ → List ℕ → List ℕ
merge (x ∷ xs) (y ∷ ys) with x ≤? y
... | yes p = x ∷ merge xs (y ∷ ys)
... | _     = y ∷ merge (x ∷ xs) ys 
merge xs ys = xs ++ ys

有趣的是,您的第一个版本实际上是正确的。我提到 Agda 启用了一些额外的规则,考虑到Size,其中之一是↑ ∞ ≡ ∞。顺便说一句,您可以通过以下方式确认:

↑inf : ↑ ∞ ≡ ∞
↑inf = refl

好吧,这促使我调查其他规则是什么。我在 Andreas Abel 的关于尺寸类型的幻灯片中找到了其余的内容(可以找到here http://www2.tcs.ifi.lmu.de/~abel/talkAIM2008Sendai.pdf):

  • ↑ ∞ ≡ ∞
  • i ≤ ↑ i ≤ ∞
  • T {i} <: T {↑ i} <: T {∞}

The <:关系是子类型关系,您可能从面向对象语言中知道它。还有一个与这种关系相关的规则,即包容 rule:

Γ ⊢ x : A   Γ ⊢ A <: B
────────────────────── (sub)
      Γ ⊢ x : B

所以,如果你有一个价值观x类型的A你知道A是一个子类型B,你可以治疗x作为类型B以及。这看起来很奇怪,因为遵循大小类型的子类型规则,您应该能够处理类型的值SortedList l u {ι} as SortedList l u.

所以我做了一些挖掘并发现了这个错误报告 http://code.google.com/p/agda/issues/detail?id=701。事实上,问题只是 Agda 无法正确识别大小,并且规则不会触发。我所需要做的就是重写定义SortedList to:

data SortedList (l u : A) : {ι : Size} → Set (???? ⊔ ℓ) where
  -- ...

就是这样!


作为附录,这是我用于测试的代码:

data ℕ : {ι : _} → Set where         -- does not work
-- data ℕ : {ι : Size} → Set where   -- works
  zero : ∀ {ι} →         ℕ {↑ ι}
  suc  : ∀ {ι} → ℕ {ι} → ℕ {↑ ι}

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

将排序列表与大小类型合并 的相关文章

  • R 中的混合合并 - 下标解决方案?

    Note 我从第一次发布时更改了示例 我的第一个例子过于简单 无法捕捉到真正的问题 我有两个数据框 它们在一列中以不同的方式排序 我想匹配一列 然后合并第二列中的值 第二列需要保持相同的顺序 所以我有这个 state lt c IA IA
  • 使用 df.merge 填充 df 中的新列给出奇怪的匹配

    我刚刚发现导致此问题的 2 个问题 请参阅下面的解决方案 我想基于另一个数据帧在我的数据帧 df 中创建一个新列 基本上 df2 包含我想要插入 df 的更新信息 为了复制我的真实情况 gt 1m 行 我将用简单的列填充两个随机 df 我使
  • gridview中如何合并两个单元格

    我在 gridview 中有一些数据 格式如下 A B 1 2 adeel 3 4 sml 现在我想将该行与 B 列下的空单元格合并 我该怎么做 您可以使用 layout columnSpan 或 layout rowSpan 根据需要使对
  • 按时间合并 pandas 数据框和另一列

    我有两个熊猫数据框 我正在尝试将它们组合成一个数据框 我是这样设置它们的 a date 1 1 2015 00 00 1 1 2015 00 15 1 1 2015 00 30 num 1 2 3 b date 1 1 2015 01 15
  • 条件合并表

    我有 2 张桌子 Time X1 8 1 2013 56 9 1 2013 14 10 1 2013 8 11 1 2013 4 12 1 2013 78 Time X2 8 1 2013 42 9 1 2013 44 10 1 2013
  • 使用 git 在整个文件上“接受他们的”或“接受我的”的简单工具

    我不需要可视化合并工具 而且我也不想必须 vi 冲突文件并手动在 HEAD 我的 和导入的更改 他们的 之间进行选择 大多数时候 我要么想要他们的所有更改 要么想要我的所有更改 通常这是因为我的更改使其上升并通过拉动返回给我 但可能在各个地
  • 合并 Pandas Dataframe:如何添加列和替换值

    我有一个数据帧 df1 并想要合并其他 许多 数据帧 df2 以便 合并发生在匹配的 多 索引上 如果缺失 将创建新列 如果列已存在 则替换值 正确的 pandas 操作是什么以及使用什么参数 我查看了 concat join merge
  • 基于多列值的重复键的两个大型 Pandas DataFrame 的条件合并/连接 - Python

    我来自 R 老实说 这是使用 R data tables 在一行中完成的最简单的事情 并且对于大型数据表来说 该操作也相当快 但是我真的很难用Python实现它 前面提到的用例都不适合我的应用程序 当前的主要问题是 Python 解决方案中
  • PHP 按值合并数组以获得 2 个不同的数组值

    我尝试将两个不同的数组合并为一个数组 有人可以帮我吗 我有这样的数组 0 Array 2 rank 579 id 1 1 Array 4 rank 251 id 2 0 Array 2 size S rank 251 1 Array 15
  • 如何有效地合并两个 BST?

    如何合并两个二叉搜索树并保持BST的性质 如果我们决定从树中取出每个元素并将其插入到另一个元素中 则此方法的复杂度将为O n1 log n2 where n1是树的节点数 比如T1 我们已经拆分了 并且n2是另一棵树的节点数 比如T2 执行
  • 连接两个 Git 存储库的历史记录?

    我有一个旧的 Git 存储库 请调用它app 然后 一年后 我想从头开始重建应用程序 所以我创建了一个新的存储库 称之为app 2 现在 我意识到我应该创建一个新分支或其他东西 而不是一个新的存储库 因为我想移动app 2在之上app然后摆
  • Python:合并嵌套列表

    初学者在这里 我有 2 个要合并的嵌套列表 list1 a b c d e f g h list2 p q r s t u v w 我正在寻找的输出是 list3 a p q b c r s d e t f g h u v w 这可以在没有
  • R模糊字符串匹配根据匹配的字符串返回特定列

    我有两个大型数据集 一个大约有 50 万条记录 另一个大约有 7 万条记录 这些数据集有地址 我想匹配较小数据集中的任何地址是否存在于大数据集中 正如您所想象的那样 地址可以用不同的方式和不同的情况 拼写等来书写 此外 如果只写到建筑物级别
  • 与 data.table 合并时防止重复列

    我有两个数据表 它们的列名部分相似 dfA lt read table text A B C D E F G iso year matchcode 1 0 1 1 1 0 1 0 NLD 2010 NLD2010 2 1 0 0 0 1 0
  • 如何在 cygwin 下配置 Mercurial 以使用 WinMerge 进行合并?

    当 Mercurial 在 cygwin 下运行时 弄清楚如何生成有点棘手WinMerge http winmerge org 来解决合并冲突 我怎样才能做到这一点 诀窍是 cygwin 路径与 Windows 路径不同 因此您需要一个小脚
  • 在ansible中合并字典

    我目前正在构建一个使用 ansible 安装 PHP 的角色 并且在合并字典时遇到一些困难 我尝试了多种方法来做到这一点 但我无法让它像我想要的那样工作 A vars file my default values key value my
  • 当重复的行具有不同的值时,如何将 DataFrame 上的重复行合并为一行

    我有一个DataFrame像下面这样 ID NAME TEL 1 TEL 2 TEL 3 1 John 123456 754987 465317 1 John 465987 465987 1 John 546783 2 Robert 264
  • 根据不平凡的标准有效合并两个数据帧

    正在接听这个问题 https stackoverflow com questions 18821862 data selection error 18823432 18823432昨晚 我花了一个小时试图找到一个没有增长的解决方案data
  • 默认情况下 git merge -Xignore-space-change

    我该如何设置该选项ignore space change对于所有合并使用git config 我也许可以使用别名merge 但因为我希望该设置应用于git stash pop git stash apply git pull and git
  • Rails/Ruby 合并两个具有相同键、不同值的哈希值

    我有两个想要合并的哈希值 它们看起来像这样 Hello gt 3 Hi gt 43 Hola gt 43 第二个哈希看起来像 Hello gt 4 Hi gt 2 Bonjour gt 2 我想合并这两个哈希数组 使结果看起来像 Hello

随机推荐