Functional programming 如何在Agda中定义除法运算符?

Functional programming 如何在Agda中定义除法运算符?,functional-programming,agda,dependent-type,Functional Programming,Agda,Dependent Type,我想除以两个自然数。我做了这样的函数 _/_ : N -> N -> frac m / one = m / one (suc m) / n = ?? I dont know what to write here. 请帮忙。除法通常被定义为迭代减法,需要一个稍微不寻常的归纳原则。例如,正如@gallais所说,可以显式地使用基础良好的递归,但我不喜欢这种方法,因为它完全不可读 此数据类型 record Is {α} {A : Set α} (x : A) : Set α

我想除以两个自然数。我做了这样的函数

_/_ : N -> N -> frac
m / one = m / one
(suc m) / n = ??        I dont know what to write here.

请帮忙。

除法通常被定义为迭代减法,需要一个稍微不寻常的归纳原则。例如,

正如@gallais所说,可以显式地使用基础良好的递归,但我不喜欢这种方法,因为它完全不可读

此数据类型

record Is {α} {A : Set α} (x : A) : Set α where
  ¡ = x
open Is

! : ∀ {α} {A : Set α} -> (x : A) -> Is x
! _ = _
允许将值提升到类型级别,例如,您可以定义类型安全
pred
功能:

pred⁺ : ∀ {n} -> Is (suc n) -> ℕ
pred⁺ = pred ∘ ¡
然后

打字检查,而

fail : pred⁺ (! 0) ≡ 0
fail = refl
没有。可以用相同的方式定义减法和正减数(以确保良好的基础):

_-⁺_ : ∀ {m} -> ℕ -> Is (suc m) -> ℕ
n -⁺ im = n ∸ ¡ im
然后使用我描述的东西,你可以重复地从一个数字中减去另一个数字,直到差值小于第二个数字:

lem : ∀ {n m} {im : Is (suc m)} -> m < n -> n -⁺ im <′ n
lem {suc n} {m} (s≤s _) = s≤′s (≤⇒≤′ (n∸m≤n m n))

iter-sub : ∀ {m} -> ℕ -> Is (suc m) -> List ℕ
iter-sub n im = calls (λ n -> n -⁺ im) <-well-founded lem (_≤?_ (¡ im)) n
div⁺然后是简单的

_div⁺_ : ∀ {m} -> ℕ -> Is (suc m) -> ℕ
n div⁺ im = length (iter-sub n im)
以及类似于
Data.Nat.DivMod
模块中的版本(仅不含
Mod
部分):

一些测试:

test-3 : map (λ n -> n div 3)
           (0 ∷ 1 ∷ 2 ∷ 3 ∷ 4 ∷ 5 ∷ 6 ∷ 7 ∷ 8 ∷ 9 ∷ [])
         ≡ (0 ∷ 0 ∷ 0 ∷ 1 ∷ 1 ∷ 1 ∷ 2 ∷ 2 ∷ 2 ∷ 3 ∷ [])
test-3 = refl
但是,请注意,标准库中的版本还包含坚固性证明:

property  : dividend ≡ toℕ remainder + quotient * divisor
全部

_div_ : ℕ -> (m : ℕ) {_ : False (m ≟ 0)} -> ℕ
n div  0      = λ{()}
n div (suc m) = n div⁺ (! (suc m))
test-3 : map (λ n -> n div 3)
           (0 ∷ 1 ∷ 2 ∷ 3 ∷ 4 ∷ 5 ∷ 6 ∷ 7 ∷ 8 ∷ 9 ∷ [])
         ≡ (0 ∷ 0 ∷ 0 ∷ 1 ∷ 1 ∷ 1 ∷ 2 ∷ 2 ∷ 2 ∷ 3 ∷ [])
test-3 = refl
property  : dividend ≡ toℕ remainder + quotient * divisor