Нужно ли мне неоднородное равенство?

Краткая предыстория: я реализую контексты и переименования, используя индексы де Брейна, а затем расширяю эти понятия с помощью «неопределенного» имени, написанного ε. Неопределенное имя индуцирует частичный порядок имен в Γ, а также переименований между Γ и Γ '. Поиск имени в переименовании (get) и связанной функции put, которая инвертирует get определенным образом, приводит к (довольно тривиальной) связи Галуа. Вот урезанный код:

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, и, честно говоря, я действительно не знаю, как его использовать. Позволит ли это сформулировать нужную мне лемму?


person Roly    schedule 11.05.2014    source источник


Ответы (1)


На самом деле должно быть легко показать, что get (ρ ′, x ′) равно get (ε ∷ ρ ′, suc x ′).

Во-первых, причина того, что Agda не видит этого равенства, состоит в том, что функции success не сводятся для аргумента общего вида x '. Это связано с тем, что ваше определение шаблона success совпадает с аргументом, чтобы узнать, является ли он ε или [_]. Итак, самый простой способ пойти дальше - предоставить Agda дополнительную информацию об аргументе путем сопоставления с образцом на x ', так что su x ′ может уменьшить:

id≤get∘put {ρ = y ∷ ρ} [ suc x ] u
   with put [ x ] u | id≤get∘put {ρ = ρ} [ x ] u
... | ρ′ , ε | u′ = u′
... | ρ′ , [ ._ ] | u′ = u′

С этим дополнительным сопоставлением с образцом тип u 'сокращается до ожидаемого типа, и все работает.

В вашей лемме not-ok у вас есть очень похожая проблема, которую проще всего решить, сформулировав лемму отдельно для x = ε или x = [_].

Работа с неоднородным равенством - это вариант, который вы также можете изучить, чтобы решить вашу проблему, но я ожидаю, что это будет сложнее, чем варианты, предлагаемые здесь.

person Dominique Devriese    schedule 11.05.2014
comment
Хорошо, в этом есть смысл. Спасибо. Мне нужно привыкнуть к более внимательному чтению кода целей, чтобы определить, когда что-то может быть недостаточно оценено! Итак, я отложу неоднородное равенство на другой день (и оставлю название вопроса как есть, поскольку теперь оно кажется вполне подходящим). - person Roly; 11.05.2014