我正在尝试推导出一个交换的单元类型A的AVL树,给定一个可交换的幺半群(A,+,epsilon),其中派生的运算是unionWith +
。 AVL树的等价概念是这样的,如果它们具有相同的toList
图像,则两棵树是相等的。
我一直试图证明unionWith +
是联想的(取决于我的等效概念)。我有交换性和+ -cong作为假设,因为我想在关联性证明中使用它们,但还没有证明它们。
我已将问题与以下代码中的bibble
一词隔离开来:
module Temp
{A : Set}
where
open import Algebra.FunctionProperties
open import Algebra.Structures
import Data.AVL
import Data.Nat.Properties as ℕ-Prop
open import Function
open import Relation.Binary
open import Relation.Binary.PropositionalEquality
open ≡-Reasoning
-- Specialise AVL trees to keys of type ℕ.
module ℕ-AVL
= Data.AVL (const A) (StrictTotalOrder.isStrictTotalOrder ℕ-Prop.strictTotalOrder)
open ℕ-AVL
-- Equivalence of AVL tree normal form (ordered list of key-value pairs).
_≈_ : Tree → Tree → Set
_≈_ = _≡_ on toList
infix 4 _≈_
-- Extend a commutative monoid (A, ⊕, ε) to AVL trees of type A, with union and empty.
comm-monoid-AVL-∪ : {⊕ : Op₂ A} → IsCommutativeMonoid _≈_ (unionWith ⊕) empty
comm-monoid-AVL-∪ {⊕} = record {
isSemigroup = record {
isEquivalence = record { refl = refl; sym = sym; trans = trans }; assoc = assoc; ∙-cong = {!!}
};
identityˡ = λ _ → refl;
comm = comm
} where
_∪_ = unionWith ⊕
postulate comm : Commutative _≈_ _∪_
postulate ∙-cong : _∪_ Preserves₂ _≈_ ⟶ _≈_ ⟶ _≈_
assoc : Associative _≈_ _∪_
assoc (tree (Indexed.leaf l<u)) y z = refl
assoc x (tree (Indexed.leaf l<u)) z =
let bibble : (x ∪ tree (Indexed.leaf l<u)) ∪ z ≈ ((tree (Indexed.leaf l<u)) ∪ x) ∪ z
bibble = ∙-cong (comm x (tree (Indexed.leaf l<u))) refl in
begin
toList ((x ∪ tree (Indexed.leaf l<u)) ∪ z)
≡⟨ bibble ⟩
toList (((tree (Indexed.leaf l<u)) ∪ x) ∪ z)
≡⟨ refl ⟩
toList (x ∪ z)
≡⟨ refl ⟩
toList (x ∪ ((tree (Indexed.leaf l<u)) ∪ z))
∎
assoc x (tree (Indexed.node kv τ₁ τ₂ bal)) z = {!!} -- TODO
在bibble
中,我有z ≈ z
(即refl
)的证据,还有x ∪ tree (Indexed.leaf l<u) ≈ (tree (Indexed.leaf l<u)) ∪ x
(通过交换性)的证明,我相信我应该能够使用∙-cong
得出证明≈参数的并集也是≈。
然而,编译器似乎留下了一些未解析的元变量,不幸的是我并不真正理解如何阅读消息。我只是做错了什么(证据明智),或者我只是需要明确地提出一些论点,或者是什么?
答案 0 :(得分:2)
证明很好,只有编译器需要更多提示。通过统一来填充隐含的争论,虽然它可以做一些很酷的事情,但有时你必须帮助它并将其推向正确的方向。
让我们来看看Preserves₂
:
_Preserves₂_⟶_⟶_ :
∀ {a b c ℓ₁ ℓ₂ ℓ₃} {A : Set a} {B : Set b} {C : Set c} →
(A → B → C) → Rel A ℓ₁ → Rel B ℓ₂ → Rel C ℓ₃ → Set _
_+_ Preserves₂ P ⟶ Q ⟶ R =
∀ {x y u v} → P x y → Q u v → R (x + u) (y + v)
如果我们专注于_+_ = _∪_
和P, Q, R = _≈_
,我们会得到:
∀ {x y u v} → x ≈ y → u ≈ v → (x ∪ u) ≈ (y ∪ v)
有四个隐含的参数,让我们填写其中一些并观察会发生什么:
bibble = ∙-cong
{x = x ∪ tree (Indexed.leaf l<u)}
(comm x (tree (Indexed.leaf l<u)))
refl
不,它还是黄色的。显然,只知道x
是不够的。现在y
:
bibble = ∙-cong
{x = x ∪ tree (Indexed.leaf l<u)}
{y = tree (Indexed.leaf l<u) ∪ x}
(comm x (tree (Indexed.leaf l<u)))
refl
就是这样!明确地给予x
和y
足以让编制者找出u
和v
。
另外,我在这个answer中写了一些关于隐式参数的内容,你可能想要检查一下。
无论如何,“未解决的元”错误消息确实有点可怕(通常不是很有用),我通常做的是这样的:
bibble = ∙-cong
{?} {?} {?} {?}
(comm x (tree (Indexed.leaf l<u)))
refl
也就是说,我只是为所有(或最相关的)隐式参数准备漏洞并逐个填充它们,直到编译器满意为止。