生病/改写desugaring

时间:2014-01-20 10:48:43

标签: pattern-matching proof equations agda

背景是按键排序的有限地图的数据类型,如previous question中所述:

open import Function
open import Relation.Binary renaming (IsEquivalence to IsEq)
open import Relation.Binary.PropositionalEquality as P using (_≡_)

module Data.Temp
   {k v ℓ ℓ′}
   {Key : Set k}
   (Value : Set v)
   {_<_ : Rel Key ℓ}
   (isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_)
   where

   open import Algebra.FunctionProperties
   open import Data.Product
   open IsStrictTotalOrder isStrictTotalOrder
   open import Level

   KV : Set (k ⊔ v)
   KV = Key × Value

   -- Adapted from the sorted lists presented in Why Dependent Types Matter (Altenkirch, Mcbride & McKinna).
   -- The lower bound is not tight.
   data FiniteMap (l : Key) : Set (k ⊔ v ⊔ ℓ) where
      [] : FiniteMap l
      _∷[_]_ : (kv : KV) → let k = proj₁ kv in l < k → (m : FiniteMap k) → FiniteMap l

   infixr 3 _∷[_]_

   -- Split into two definitions to help the termination checker.
   unionWith : ∀ {l} → Op₂ Value → Op₂ (FiniteMap l)
   unionWith′ : ∀ {l} → Op₂ Value → (kv : KV) → let k = proj₁ kv in l < k → FiniteMap k → Op₁ (FiniteMap l)

   unionWith _ [] [] = []
   unionWith _ [] m = m
   unionWith _ m [] = m
   unionWith ∙ (k , v ∷[ k<l ] m) (k′ , v′ ∷[ k′<l ] m′) with compare k k′
   ... | tri< k<k′ _ _ = k , v ∷[ k<l ] unionWith ∙ m (k′ , v′ ∷[ k<k′ ] m′)
   ... | tri≈ _ k≡k′ _ rewrite P.sym k≡k′ = k , (v ⟨ ∙ ⟩ v′) ∷[ k<l ] unionWith ∙ m m′
   ... | tri> _ _ k′<k = k′ , v′ ∷[ k′<l ] unionWith′ ∙ (k , v) k′<k m m′

   unionWith′ _ (k , v) l<k m [] = k , v ∷[ l<k ] m
   unionWith′ ∙ (k , v) l<k m (k′ , v′ ∷[ k′<l ] m′) with compare k k′
   ... | tri< k<k′ _ _ = k , v ∷[ l<k ] unionWith ∙ m (k′ , v′ ∷[ k<k′ ] m′)
   ... | tri≈ _ k≡k′ _ rewrite P.sym k≡k′ = k , (v ⟨ ∙ ⟩ v′) ∷[ l<k ] unionWith ∙ m m′
   ... | tri> _ _ k′<k = k′ , v′ ∷[ k′<l ] unionWith′ ∙ (k , v) k′<k m m′

我现在有兴趣证明这种类型构造函数在A上保留任何可交换的幺半群结构,其中有限映射的幺半群运算是unionWith ∙(其中∙是底层幺半群的可交换运算)。我应该指出,虽然unionWith ∙显然可以清除地图中嵌入的边界,但我还不确定它是否“在鼻子上”,即考虑边界。 / p>

所以,除了这个警告之外,我遇到了一条错误消息,试图在我的尝试证明中说明一个精确的目标。这是证明的骨架,有问题的位被注释掉:

comm : ∀ {l} (∙ : Op₂ Value) → Commutative _≡_ ∙ → 
                               Commutative _≡_ (unionWith {l} ∙)
comm ∙ _ [] [] = P.refl
comm ∙ _ [] (_ ∷[ _ ] _) = P.refl
comm ∙ _ (_ ∷[ _ ] _) [] = P.refl
comm {l} ∙ _ (k , v ∷[ k<l ] m) (k′ , v′ ∷[ k′<l ] m′) with compare k k′
... | tri< _ _ _ = {!!}
... | tri≈ _ k≡k′ _ {- rewrite P.sym k≡k′ -} = {!!}
... | tri> _ _ _ = {!!}

这是我希望能够为k≡k′案例插入的精确目标:

  begin
     k , (v ⟨ ∙ ⟩ v′) ∷[ l<k ] unionWith ∙ m m′
  ≡⟨ ? ⟩
     unionWith ∙ (k′ , v′ ∷[ k′<l ] m′) (k , v ∷[ k<l ] m)
  ∎ where
     open import Relation.Binary.EqReasoning (P.setoid (FiniteMap l))

但是为了做好打字,我需要k≡k'。根据{{​​1}}的定义,我想在上面的代码中插入注释掉的unionWith

不幸的是,我收到了一条相当令人讨厌的错误消息:

rewrite P.sym k≡k′

讨论了k′ != w of type Key when checking that the type [scary stuff] ≡ (unionWith Value isStrictTotalOrder ∙ (w , v′ ∷[ k′<l ] m′) (k₁ , v₁ ∷[ k<l ] m) | compare w k₁) of the generated with function is well-formed. 错误消息的质量问题here。当然,错误信息的质量不是我直接关注的问题,但它并没有帮助我理解我是否在这里做错了。

我是否以大致正确的方式进行,即使用withwith来改进我的背景,以便我可以开始证明特定情况? (来自this question,我认为答案可能是肯定的。)如果是这样,是什么导致了这个问题呢?

1 个答案:

答案 0 :(得分:0)

我将回答我自己的问题,因为我似乎不理解如何正确使用with条款。在k≡k'的情况下,我需要为两个有限映射再次给出完整模式,而不是仅通过“...”重用现有模式。然后我可以将.k代替k,并将类型k≡k'的值与refl匹配(以证明.k)。

然后我精确的目标类型检查(此版本已经在合适的lCommutative _≡_ ∙的范围内):

     comm′ : Commutative (unionWith ∙)
     comm′ [] [] = P.refl
     comm′ [] (_ ∷[ _ ] _) = P.refl
     comm′ (_ ∷[ _ ] _) [] = P.refl
     comm′ (k , _ ∷[ _ ] _) (k′ , _ ∷[ _ ] _) with compare k k′
     ... | tri< _ _ _ = {!!}
     comm′ (k , v ∷[ k<l ] m) (.k , v′ ∷[ k′<l ] m′) | tri≈ _ P.refl _ =
       begin
           k , (v ⟨ ∙ ⟩ v′) ∷[ k<l ] unionWith ∙ m m′
        ≡⟨ {!!} ⟩
           unionWith ∙ (k , v′ ∷[ k′<l ] m′) (k , v ∷[ k<l ] m)
        ∎
     ... | tri> _ _ _ = {!!}

人们认为原始问题仍然有用吗?我可以删除它。