在`with`子句中没有充分评估上下文

时间:2014-02-25 12:10:39

标签: pattern-matching proof agda

我坚持以下证据。

module Temp where

   open import Data.Empty
   open import Data.Fin hiding (compare)
   open import Data.Nat hiding (compare); open import Data.Nat.Properties
   open import Function
   open import Level
   open import Relation.Binary
   open import Relation.Binary.PropositionalEquality

我正在使用自然数Γ解释为上下文, a la / de Bruijn索引,并使用Fin Γ的元素作为标识符。 (出于我的问题的目的,我们不需要将它们理解为上下文和标识符,但它可能有助于直觉。)

重命名是一种上下文态射:

   Ren : Rel ℕ Level.zero
   Ren Γ Γ′ = Fin Γ → Fin Γ′

我现在定义以下两个非常简单的操作。第一个close-var产生一个重命名,它从上下文中删除一个名称,将其映射到剩余上下文中的现有名称。第二个open-var产生一个重命名,反过来,在特定位置的上下文中插入一个新名称。要在上下文中找到插入或删除点,我会在toℕ进行比较,因为我还没有弄清楚如何使用Data.Fin.compare

   open StrictTotalOrder strictTotalOrder
   open DecTotalOrder decTotalOrder renaming (refl to ≤-refl; trans to ≤-trans)
   open import Data.Fin.Props using (bounded)

   close-var : ∀ {Γ} → Fin Γ → Fin (suc Γ) → Fin (suc Γ) → Fin Γ
   close-var _ y z with compare (toℕ y) (toℕ z)
   close-var _ _ zero | tri< () _ _
   close-var _ _ (suc z) | tri< _ _ _ = z
   close-var x _ _ | tri≈ _ _ _ = x
   close-var _ zero _ | tri> _ _ ()
   close-var _ (suc y) z | tri> _ _ z<suc-y = 
      fromℕ≤ (≤-trans z<suc-y (bounded y))

   open-var : ∀ {Γ} → Fin (suc Γ) → Fin Γ → Fin (suc Γ)
   open-var y z with compare (toℕ y) (toℕ z)
   ... | tri< _ _ _ = suc z
   ... | tri≈ _ _ _ = suc z
   ... | tri> _ _ _ = inject₁ z

这些定义中唯一的重要部分是close-var的最后一种情况,它必须从较大的上下文强制转换为较小的上下文。

对于固定参数,从close-varopen-var获得的重命名形成了同构(我很确定)。但是我无法理解以下目标:

   close∘open≡id : ∀ {Γ} (x : Fin Γ) (y : Fin (suc Γ)) (z : Fin Γ) → 
                   (close-var x y ∘ open-var y) z ≡ z
   close∘open≡id _ y z with compare (toℕ y) (toℕ z)
   close∘open≡id _ y z | tri< _ _ _ with compare (toℕ y) (suc (toℕ z))
   close∘open≡id _ _ _ | tri< _ _ _ | tri< _ _ _ = refl
   close∘open≡id _ _ _ | tri< y<z _ _ | tri≈ y≮suc-z _ _ = 
      ⊥-elim (y≮suc-z (≤-step y<z))
   close∘open≡id _ _ _ | tri< y<z _ _ | tri> y≮suc-z _ _ = 
      ⊥-elim (y≮suc-z (≤-step y<z))
   close∘open≡id _ y z | tri≈ _ _ _ with compare (toℕ y) (suc (toℕ z))
   close∘open≡id _ _ _ | tri≈ _ _ _ | tri< _ _ _ = refl
   close∘open≡id _ _ _ | tri≈ _ y≡z _ | tri≈ y≮suc-z _ _ rewrite y≡z = 
      ⊥-elim (y≮suc-z ≤-refl)
   close∘open≡id _ _ _ | tri≈ _ y≡z _ | tri> y≮suc-z _ _ = {!!}
   close∘open≡id _ y z | tri> _ _ _ with compare (toℕ y) (toℕ (inject₁ z))
   close∘open≡id _ _ _ | tri> _ _ _ | tri< _ _ _ = {!!}
   close∘open≡id _ _ _ | tri> _ _ _ | tri≈ _ _ _ = {!!}
   close∘open≡id _ _ _ | tri> _ _ _ | tri> _ _ _ = {!!}

第一种情况应该是不可能的,但我似乎无法使用y≡zy≮suc-z来导出矛盾,正如我在前一种情况中所做的那样。我认为这是因为模式本身是荒谬的,但我不知道如何使Agda相信这一点。

第二个也许是相关的问题是,在剩下的四个目标下看起来并没有出现足够的减少。它们都包含with个模式,例如tri< .a .¬b .¬c。但我期待嵌套的with子句允许足够的执行来消除这些。我做错了什么?

(作为一个完整性检查,很容易验证:

   sub : ∀ {Γ} (x : Fin Γ) (y : Fin (suc Γ)) → Ren Γ Γ
   sub x y = close-var x y ∘ open-var y

   Γ : ℕ
   Γ = 5

   ρ : Ren Γ Γ
   ρ = sub (suc (zero)) (suc (suc (suc zero)))

   ex₁ : ρ zero ≡ zero
   ex₁ = refl

   ex₂ : ρ (suc zero) ≡ suc zero
   ex₂ = refl

   ex₃ : ρ (suc (suc (zero))) ≡ suc (suc zero)
   ex₃ = refl

   ex₄ : ρ (suc (suc (suc (zero)))) ≡ suc (suc (suc zero))
   ex₄ = refl

等等。)

1 个答案:

答案 0 :(得分:2)

嵌套with条款没问题。问题是,在close-var的定义中,您不仅要匹配compare (toℕ y) (toℕ z)的结果,还要匹配参数yz本身。当然,在不确定使用哪个函数方程的情况下,Agda无法减少某些东西。

在第二个洞中,close-var应该在inject₁ z上进行模式匹配,但是你没有(并且不能)。你必须对其进行抽象,然后模式匹配足以说服Agda可以安全地选择一个等式。

close∘open≡id x y z | tri> _ _ _
  with inject₁ z | compare (toℕ y) (toℕ (inject₁ z))
... | tri> _ _ _ | Fin.zero  | tri< () _ _
... | tri> _ _ _ | Fin.suc r | tri< _  _ _ = {!!}  -- goal is r ≡ z

至于第一个洞 - 如果上面的代码没有帮助,只需证明一个简单的引理:

≡→≤ : {x y : ℕ} → x ≡ y → x ≤ y
≡→≤ refl = ≤-refl

然后,你可以通过以下方式得出矛盾:

y≮suc-z (s≤s (≡→≤ y≡z))

(我没有查看StrictTotalOrder记录,但很可能这个引理已经存在了。)