我试图在Vec上实现rotate
函数,它将每个元素n
位置向左移动,循环播放。我可以使用splitAt
来实现该功能。这是一幅草图:
open import Data.Nat
open import Data.Nat.DivMod
open import Data.Fin
open import Data.Vec
open import Relation.Nullary.Decidable
open import Relation.Binary.PropositionalEquality
rotateLeft : {A : Set} -> {w : ℕ} -> {w≢0 : False (w ≟ 0)} -> ℕ -> Vec A w -> Vec A w
rotateLeft {A} {w} n vec =
let parts = splitAt (toℕ (n mod w)) {n = ?} vec
in ?
问题是splitAt
需要两个输入m
和n
,因此矢量的大小为m + n
。由于此处向量的大小为w
,因此我需要找到k
k + toℕ (n mod w) = w
。我无法找到任何标准功能。最好的方法是什么?
如果k = n mod w
向我提供了k < w
的证明,那么我可以尝试实现一个函数diff : ∀ {k w} -> k < w -> ∃ (λ a : Nat) -> a + k = w
,这可能会有所帮助。另一种可能性是仅接收a
和b
作为输入,而不是移位的位和矢量的大小,但我不确定这是最好的接口。
我已实施以下内容:
add-diff : (a : ℕ) -> (b : Fin (suc a)) -> toℕ b + (a ℕ-ℕ b) ≡ a
add-diff zero zero = refl
add-diff zero (suc ())
add-diff (suc a) zero = refl
add-diff (suc a) (suc b) = cong suc (aaa a b)
现在我只需要∀ {n m} -> n mod m < m
。
答案 0 :(得分:1)
这是我想出的。
open import Data.Vec
open import Data.Nat
open import Data.Nat.DivMod
open import Data.Fin hiding (_+_)
open import Data.Product
open import Relation.Binary.PropositionalEquality
open import Data.Nat.Properties using (+-comm)
difference : ∀ m (n : Fin m) → ∃ λ o → m ≡ toℕ n + o
difference zero ()
difference (suc m) zero = suc m , refl
difference (suc m) (suc n) with difference m n
difference (suc m) (suc n) | o , p1 = o , cong suc p1
rotate-help : ∀ {A : Set} {m} (n : Fin m) → Vec A m → Vec A m
rotate-help {A} {m = m} n vec with difference m n
... | o , p rewrite p with splitAt (toℕ n) vec
... | xs , ys , _ = subst (Vec A) (+-comm o (toℕ n)) (ys ++ xs)
rotate : ∀ {A : Set} {m} (n : ℕ) → Vec A m → Vec A m
rotate {m = zero} n v = v
rotate {m = suc m} n v = rotate-help (n mod suc m) v
答案 1 :(得分:1)
在与IRC的adamse交谈后,我想出了这个:
<form id="contact">
<label>
Name
<input type="text" name="name" id="name" required>
</label>
<label>
Email Address
<input type="email" name="email" id="email" required>
</label>
<button type="submit">Submit</button>
</form>
哪个优于他的实现(部分是因为我还在学习Agda的语法,所以我选择只使用函数),但是有效。我相信现在我应该回归更精致的类型。 (不能够感谢他!)
答案 2 :(得分:1)
对于您的最后一个问题k < w
,自k = toℕ (n mod w)
起,您可以使用bounded
中的Data.Fin.Properties
:
bounded : ∀ {n} (i : Fin n) → toℕ i ℕ< n