如何将 Agda 中的两个自然数与标准库(如 N -> N -> Bool)进行比较?

How to compare two natural numbers in Agda with standard library (like N -> N -> Bool)?

我可以通过手动编写比较器来比较两个自然数:

is-≤ : ℕ → ℕ → Bool
is-≤ zero _ = true
is-≤ (suc _) zero = false
is-≤ (suc x) (suc y) = is-≤ x y

不过,我希望标准库中有类似的东西,所以我不会每次都这样写。

我能够找到 _≤_ 运算符 in Data.Nat,但它是一个参数化类型,基本上包含 "proof" 一个特定数字小于另一个(类似于 _≡_).有没有办法使用它或其他东西来理解哪个数字小于另一个"in runtime"(例如return对应Bool)?

我要解决的更大问题:

  1. 作为我作业的一部分,我正在编写一个 readNat : List Char → Maybe (ℕ × List Char) 函数。它尝试从列表的开头读取自然数;稍后将成为 sscanf.
  2. 的一部分
  3. 我想实现 digit : Char → Maybe ℕ 辅助函数来解析单个十进制数字。
  4. 为了这样做,我想比较 primCharToNat cprimCharToNat '0'primCharToNat '1' 并决定是 return None 还是 (primCharToNat c) ∸ (primCharToNat '0')

@gallais 在评论中建议的解决方案:

open import Data.Nat using (ℕ; _≤?_)
open import Data.Bool using (Bool)
open import Relation.Nullary using (Dec)

is-≤ : ℕ → ℕ → Bool
is-≤ a b with a ≤? b
... | Dec.yes _ = Bool.true
... | Dec.no _ = Bool.false

这里我们匹配一个证明 _≤_ 是可以使用 with 子句判定的。人们可以在更复杂的功能中类似地使用它。

@user3237465 在对此答案的评论中提出的建议:您还可以使用 shorthand ⌊_⌋\clL/\clR\lfloor/\rfloor) 其中 does this exact pattern matching 并消除对 is-≤:

的需要
open import Data.Nat using (ℕ; _≤?_)
open import Data.Bool using (Bool)
open import Relation.Nullary.Decidable using (⌊_⌋)

is-≤ : ℕ → ℕ → Bool
is-≤ a b = ⌊ a ≤? b ⌋

另一种方法是使用compare,它也提供了更多信息(例如两个数字之间的差异):

open import Data.Nat using (ℕ; compare)
open import Data.Bool using (Bool)
open import Relation.Nullary using (Dec)

is-≤' : ℕ → ℕ → Bool
is-≤' a b with compare a b
... | Data.Nat.greater _ _ = Bool.false
... | _ = Bool.true

is-≤3' : ℕ → Bool
is-≤3' a with 3 | compare a 3
... | _ | Data.Nat.greater _ _ = Bool.false
... | _ | _ = Bool.true

请注意,由于某种原因,compare使用常数值