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

时间:2017-10-12 10:43:06

标签: comparison-operators agda

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

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

但是,我希望标准库中有类似内容,所以我不是每次都写不出来。

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

我试图解决的更大问题:

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

1 个答案:

答案 0 :(得分:4)

@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对此答案的评论提出建议:您还可以使用简写⌊_⌋\clL / \clR\lfloor / \rfloor){ {3}}并且无需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 ⌋

另一种方法是使用does this exact pattern matching,它还提供更多信息(例如两个数字之间的差异):

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使用常量值compare