隐式参数并将函数应用于固定大小向量的尾部

时间:2012-11-21 11:29:43

标签: agda dependent-type

我编写了一个Agda函数applyPrefix,将固定大小的向量函数应用于较长向量的初始部分,其中向量大小mn和{ {1}}可能会隐含。这是定义以及辅助函数k

split

我需要一个对称函数split : ∀ {A m n} → Vec A (n + m) → (Vec A n) × (Vec A m) split {_} {_} {zero} xs = ( [] , xs ) split {_} {_} {suc _} (x ∷ xs) with split xs ... | ( ys , zs ) = ( (x ∷ ys) , zs ) applyPrefix : ∀ {A n m k} → (Vec A n → Vec A m) → Vec A (n + k) → Vec A (m + k) applyPrefix f xs with split xs ... | ( ys , zs ) = f ys ++ zs ,它将固定大小的向量函数应用于较长向量的尾部。

applyPostfix

正如applyPostfix ∀ {A n m k} → (Vec A n → Vec A m) → Vec A (k + n) → Vec A (k + m) applyPostfix {k = k} f xs with split {_} {_} {k} xs ... | ( ys , zs ) = ys ++ (f zs) 的定义已经显示的那样,applyPrefix - 参数在使用k时不能保持隐含。例如:

applyPostfix

有没有人知道一种技术,如何实现change2 : {A : Set} → Vec A 2 → Vec A 2 change2 ( x ∷ y ∷ [] ) = (y ∷ x ∷ [] ) changeNpre : {A : Set}{n : ℕ} → Vec A (2 + n) → Vec A (2 + n) changeNpre = applyPrefix change2 changeNpost : {A : Set}{n : ℕ} → Vec A (n + 2) → Vec A (n + 2) changeNpost = applyPost change2 -- does not work; n has to be provided ,以便在使用applyPostfixk - 参数可能保持隐含?

我所做的是校对/编程:

applyPostfix

并在定义lem-plus-comm : (n m : ℕ) → (n + m) ≡ (m + n) 时使用该引理:

applyPostfix

不幸的是,这没有用,因为我使用postfixApp2 : ∀ {A}{n m k : ℕ} → (Vec A n → Vec A m) → Vec A (k + n) → Vec A (k + m) postfixApp2 {A} {n} {m} {k} f xs rewrite lem-plus-comm n k | lem-plus-comm k n | lem-plus-comm k m | lem-plus-comm m k = reverse (drop {n = n} (reverse xs)) ++ f (reverse (take {n = n} (reverse xs))) - 参数来调用引理: - (

如何避免k明确?也许我应该在矢量上使用snoc-View?

1 个答案:

答案 0 :(得分:6)

您可以做的是postfixApp2applyPrefix相同的类型。

问题的根源是,只有n已知,自然数p + q才能与p统一。这是因为+是通过第一个参数的归纳来定义的。

所以这个有效(我在+使用标准库版本的交换性):

+-comm = comm
  where
    open IsCommutativeSemiring isCommutativeSemiring
    open IsCommutativeMonoid +-isCommutativeMonoid

postfixApp2 : {A : Set} {n m k : ℕ}
            → (Vec A n → Vec A m)
            → Vec A (n + k) → Vec A (m + k)
postfixApp2 {A} {n} {m} {k} f xs rewrite +-comm n k | +-comm m k =
  applyPostfix {k = k} f xs

是的,我在这里重复使用原来的applyPostfix,并通过重写两次给它一个不同的类型。

并测试:

changeNpost : {A : Set} {n : ℕ} → Vec A (2 + n) → Vec A (2 + n)
changeNpost = postfixApp2 change2

test : changeNpost (1 ∷ 2 ∷ 3 ∷ 4 ∷ []) ≡ 1 ∷ 2 ∷ 4 ∷ 3 ∷ []
test = refl