简要背景:我正在使用de Bruijn索引实现上下文和重命名,然后使用“未定义”名称扩展这些概念,写成ε。未定义的名称引起Γ中名称的部分顺序,以及Γ和Γ'之间的重命名。在重命名(get
)中查找名称以及以特定方式反转put
的相关函数get
会产生(相当简单的)Galois连接。这是精简的代码:
module Temp where
open import Relation.Binary
open import Data.Fin using (Fin; zero; suc)
open import Data.Maybe renaming (nothing to ε; just to [_]) hiding (map)
open import Data.Nat using (ℕ; zero; suc)
open import Data.Product
open import Function
open import Relation.Binary.PropositionalEquality
-- Pointed version of Fin, with ε indicating an undefined name.
Name : ℕ → Set
Name = Maybe ∘ Fin
-- The type of names below x.
data ↓_ {Γ} : Name Γ → Set where
ε : {x : Name Γ} → ↓ x
[_] : (x : Fin Γ) → ↓ [ x ]
-- A proof that two upper-bounded names are related.
data _≤_ {Γ} : {x : Name Γ} → ↓ x → ↓ x → Set where
ε : {x : Name Γ} {x : ↓ x} → ε ≤ x
[_] : (x : Fin Γ) → [ x ] ≤ [ x ]
≤-refl : ∀ {Γ} {y : Name Γ} → Reflexive (_≤_ {x = y})
≤-refl {x = ε} = ε
≤-refl {x = [ x ]} = [ x ]
-- Functorial action of suc on a name.
suc⁺₀ : ∀ {Γ} → Name Γ → Name (suc Γ)
suc⁺₀ ε = ε
suc⁺₀ [ x ] = [ suc x ]
-- Lifting of suc⁺₀ to down-sets.
suc⁺ : ∀ {Γ} {x : Name Γ} → ↓ x → ↓ suc⁺₀ x
suc⁺ ε = ε
suc⁺ [ x ] = [ suc x ]
-- A renaming from Γ Γ′.
data Ren : ℕ → ℕ → Set where
[] : ∀ {Γ} → Ren zero Γ
_∷_ : ∀ {Γ Γ′} → Name Γ′ → Ren Γ Γ′ → Ren (suc Γ) Γ′
-- The type of renamings below ρ.
data Ren-↓_ : ∀ {Γ Γ′} → Ren Γ Γ′ → Set where
[] : ∀ {Γ} → Ren-↓ ([] {Γ})
_∷_ : ∀ {Γ Γ′} {x : Name Γ′} {ρ : Ren Γ Γ′} →
↓ x → Ren-↓ ρ → Ren-↓ (x ∷ ρ)
-- Least renaming below ρ.
Ren-ε : ∀ {Γ Γ′} {ρ : Ren Γ Γ′} → Ren-↓ ρ
Ren-ε {ρ = []} = []
Ren-ε {ρ = _ ∷ _} = ε ∷ Ren-ε
-- Interpret a renaming as a function.
get₀ : ∀ {Γ Γ′} → Ren Γ Γ′ × Name Γ → Name Γ′
get₀ (_ , ε) = ε
get₀ (x ∷ _ , [ zero ]) = x
get₀ (_ ∷ ρ , [ suc y ]) = get₀ (ρ , [ y ])
-- Lift get₀ to down-sets.
get : ∀ {Γ Γ′} {ρ : Ren Γ Γ′} {x : Name Γ} →
Ren-↓ ρ × ↓ x → ↓ get₀ (ρ , x)
get (_ , ε) = ε
get (x ∷ _ , [ zero ]) = x
get ( _ ∷ ρ , [ suc x ]) = get (ρ , [ x ])
-- Lower adjoint of get.
put : ∀ {Γ Γ′} {ρ : Ren Γ Γ′} (x : Name Γ) →
↓ get₀ (ρ , x) → Ren-↓ ρ × ↓ x
put ε ε = Ren-ε , ε
put {ρ = _ ∷ _} [ zero ] ε = Ren-ε , ε
put {ρ = ._ ∷ _} [ zero ] [ x ] = [ x ] ∷ Ren-ε , [ zero ]
put {ρ = _ ∷ _} [ suc x ] u = map (_∷_ ε) suc⁺ (put [ x ] u)
这就是设置。我现在要做的是表明get
和put
形成了伽罗瓦联系。实现这一目标的一种方法是证明每个函数都是单调的,而且它们的两个复合函数,一个是通货膨胀,另一个是通货紧缩。这一切都很好,除了我试图证明get∘put
复合材料是通货膨胀时会遇到困难:
id≤get∘put : ∀ {Γ Γ′} {ρ : Ren Γ Γ′} (x : Name Γ)
(u : ↓ get₀ (ρ , x)) → u ≤ get (put x u)
id≤get∘put ε ε = ε
id≤get∘put {ρ = _ ∷ _} [ zero ] ε = ε
id≤get∘put {ρ = ._ ∷ _} [ zero ] [ _ ] = ≤-refl
id≤get∘put {ρ = y ∷ ρ} [ suc x ] u
with put [ x ] u | id≤get∘put {ρ = ρ} [ x ] u
... | ρ′ , x′ | u′ = {!!}
在我的上下文中,我从函数的递归调用中得到u ≤ get (ρ′ , x′)
。我希望能够用它来推导出目标,即u ≤ get (ε ∷ ρ′ , suc⁺ x′)
。直观地说,这应该很简单,因为在x'
中查找ρ′
应该与查找x'
中ρ′
的后续版本相同。事实上,应该很容易证明get (ρ′ , x′)
等于get (ε ∷ ρ′ , suc⁺ x′)
。
但如果我试图说出相应的引理:
-- Not typeable, because ≡ requires homogeneous types?
postulate
not-ok : ∀ {Γ Γ′} {ρ : Ren Γ Γ′} {x : Name Γ}
(ρ′ : Ren-↓ ρ) (x′ : ↓ x) → get (ρ′ , x′) ≡ get (ε ∷ ρ′ , suc⁺ x′)
然后Agda抱怨,因为get
的两次调用(get₀
提升到下调)有不同的类型。这是因为get
的类型提到了由get₀
计算的值。
但是,这两个调用并没有“真正”有不同的类型,因为我可以证明以下引理:
-- This is related to the lemma I want, but not quite it.
ok : ∀ {Γ Γ′} (ρ₀ : Ren Γ Γ′) (x₀ : Name Γ) →
get₀ (ρ₀ , x₀) ≡ get₀ (ε ∷ ρ₀ , suc⁺₀ x₀)
ok _ ε = refl
ok (_ ∷ _) [ zero ] = refl
ok (_ ∷ ρ) [ suc x ] = ok ρ [ x ]
我还没有在Agda中使用异构平等,说实话我真的不知道如何使用它。它能让我说出我需要的引理吗?
答案 0 :(得分:3)
事实上,应该很容易证明get(ρ',x')等于得到(ε∷ρ',suc⁺x')。
首先,Agda没有看到这种平等的原因是,对于一般形式x'的参数,函数suc⁺不会减少。这是因为你对suc⁺模式的定义与参数相匹配,看它是ε还是[_]。因此,最简单的方法是通过x'上的模式匹配为Agda提供有关参数的更多信息,这样make⁺x'可以减少:
id≤get∘put {ρ = y ∷ ρ} [ suc x ] u
with put [ x ] u | id≤get∘put {ρ = ρ} [ x ] u
... | ρ′ , ε | u′ = u′
... | ρ′ , [ ._ ] | u′ = u′
通过这种额外的模式匹配,u'的类型进一步减少到预期的类型,一切正常。
在你的引理中没有问题,你有一个非常类似的问题,可以通过分别为x =ε或x = [_]分别说明引理来解决。
使用异构平等是您可能还会探索解决问题的一个选项,但我预计它会比这里提出的选项更难。