【发布时间】:2023-04-04 22:32:01
【问题描述】:
此问题的设置与此 earlier question 中的“排序列表合并”示例相同。
{-# OPTIONS --sized-types #-}
open import Relation.Binary
open import Relation.Binary.PropositionalEquality as P hiding (trans)
module ListMerge
{???? ℓ}
(A : Set ????)
{_<_ : Rel A ℓ}
(isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_) where
open import Data.Product
open import Data.Unit
open import Level
open import Size
data SortedList (l u : A) : {ι : Size} → Set (???? ⊔ ℓ) where
[] : {ι : _} → .(l < u) → SortedList l u {↑ ι}
_∷[_]_ : {ι : _} (x : A) → .(l < x) → (xs : SortedList x u {ι}) →
SortedList l u {↑ ι}
和以前一样,我使用了调整大小的类型,以便 Agda 可以确定以下 merge 函数终止:
open IsStrictTotalOrder isStrictTotalOrder
merge : ∀ {l u} → {ι : _} → SortedList l u {ι} →
{ι′ : _} → SortedList l u {ι′} → SortedList l u
merge xs ([] _) = xs
merge ([] _) ys = ys
merge (x ∷[ l<x ] xs) (y ∷[ l<y ] ys) with compare x y
... | tri< _ _ _ = x ∷[ l<x ] (merge xs (y ∷[ _ ] ys))
merge (x ∷[ l<x ] xs) (.x ∷[ _ ] ys) | tri≈ _ P.refl _ =
x ∷[ l<x ] (merge xs ys)
... | tri> _ _ _ = y ∷[ l<y ] (merge (x ∷[ _ ] xs) ys)
我要做的是证明以下结合性定理:
assoc : ∀ {l u} → {ι₁ : _} → (x : SortedList l u {ι₁}) →
{ι₂ : _} → (y : SortedList l u {ι₂}) →
{ι₃ : _} → (z : SortedList l u {ι₃}) →
merge (merge x y) z ≡ merge x (merge y z)
根据定义,至少有一个列表是[] 的情况很容易理解,但为了完整起见,我将它们包括在内。
assoc ([] _) ([] _) ([] _) = P.refl
assoc ([] _) ([] _) (_ ∷[ _ ] _) = P.refl
assoc ([] _) (_ ∷[ _ ] _) ([] _) = P.refl
assoc (_ ∷[ _ ] _) ([] _) ([] _) = P.refl
assoc ([] _) (y ∷[ _ ] _) (z ∷[ _ ] _) with compare y z
assoc ([] _) (y ∷[ _ ] ys) (.y ∷[ _ ] zs) | tri≈ _ P.refl _ = P.refl
... | tri< _ _ _ = P.refl
... | tri> _ _ _ = P.refl
assoc (x ∷[ _ ] _) ([] _) (z ∷[ _ ] _) with compare x z
assoc (x ∷[ _ ] xs) ([] _) (.x ∷[ _ ] zs) | tri≈ _ P.refl _ = P.refl
... | tri< _ _ _ = P.refl
... | tri> _ _ _ = P.refl
assoc (x ∷[ _ ] _) (y ∷[ _ ] _) ([] _) with compare x y
assoc (x ∷[ _ ] xs) (.x ∷[ _ ] ys) ([] _) | tri≈ _ P.refl _ = P.refl
... | tri< _ _ _ = P.refl
... | tri> _ _ _ = P.refl
但是,我在尝试证明剩余案例时遇到了困难,该案例有很多子案例。特别是,我不知道如何在顶层下方的证明上下文中“重用”诸如compare x y ≡ tri< .a .¬b .¬c 之类的事实(例如,不引入辅助引理)。
我知道inspect(类固醇)成语提到here,并且已经取得了一些成功,但我的问题似乎是我想“重用”相关事实的上下文当我使用rewrite 来简化我使用inspect 保存的等式时,尚未建立。
因此,例如在以下子案例中,我可以使用以下 inspect 调用来捕获 compare x y 和 compare y z 的值:
assoc (x ∷[ _ ] _) (y ∷[ _ ] _) (z ∷[ _ ] _)
with compare x y | compare y z
| P.inspect (hide (compare x) y) unit
| P.inspect (hide (compare y) z) unit
然后rewrite 简化:
assoc {l} {u} (x ∷[ l<x ] xs) (y ∷[ _ ] ys) (.y ∷[ _ ] zs)
| tri< _ _ _ | tri≈ _ P.refl _ | P.[ eq ] | P.[ eq′ ] rewrite eq | eq′ =
但我认为rewrite 只会影响当时处于活动状态的目标。特别是,如果在证明的主体中我使用cong 转换到允许更多减少的嵌套上下文,我可能会暴露那些不会被重写的比较的新出现。 (请参阅下面的{!!} 了解我的意思。)我对减少的确切方式的理解有点模糊,因此我欢迎对此进行任何更正或澄清。
begin
x ∷[ _ ] merge (merge xs (y ∷[ _ ] ys)) (y ∷[ _ ] zs)
≡⟨ P.cong (λ xs → x ∷[ l<x ] xs) (assoc xs (y ∷[ _ ] ys) (y ∷[ _ ] zs)) ⟩
x ∷[ _ ] merge xs (merge (y ∷[ _ ] ys) (y ∷[ _ ] zs))
≡⟨ P.cong (λ xs′ → x ∷[ _ ] merge xs xs′)
{merge (y ∷[ _ ] ys) (y ∷[ _ ] zs)} {y ∷[ _ ] merge ys zs} {!!} ⟩
x ∷[ _ ] merge xs (y ∷[ _ ] merge ys zs)
∎ where open import Relation.Binary.EqReasoning (P.setoid (SortedList l u))
(cong 的隐含参数需要在这里明确说明。)
当我把光标放在洞里时,我可以看到目标(有点意译)是
merge (y ∷[ _ ] ys) (y ∷[ _ ] zs) | compare y y ≡ y ∷[ _ ] merge ys zs
尽管之前有rewrite eq′。此外,在我的上下文中,我有
eq′ : compare y y ≡ tri≈ .¬a refl .¬c
这似乎正是我需要允许减少以取得进展以便refl 将完成证明案例。
这是剩余子案例的占位符。
assoc (x ∷[ _ ] _) (_ ∷[ _ ] _) (z ∷[ _ ] _) | _ | _ | _ | _ = {!!}
我在这里有点不自信;我不知道我是否在类固醇上滥用inspect,完全以错误的方式进行证明,或者只是愚蠢。
有没有办法使用上下文中的eq′ 等价来允许继续进行缩减?
【问题讨论】:
-
据我所知,你不能。您必须再次对
compare y y进行模式匹配,并显示其他两种情况不会发生。 -
好的,谢谢。我想我可以明白为什么会这样,尽管它大大提高了样板的水平。看来我也必须复制
inspect (hide (compare y) z)代码;即使我已经消除了不可能的情况,我也不能只是rewrite使用上下文中已有的信息而不会得到格式不正确的脱糖 (w != compare y z of type Tri (y < z) (y ≡ z) (z < y) when checking that the type ... of the generated with function is well-formed)。 -
事实上,我根本不需要
inspect的那些嵌套使用(参见下面的引理),因此没有出现特定问题。
标签: pattern-matching proof reduction agda equivalence