Reputation: 309
The standard library's AVL tree implementation uses dependent pairs to store key-value pairs. I have two such pairs whose keys (k
and k′
) I have shown to be equal (k≡k′
). They also contain the same value (v
). I'd like to prove that the pairs are equal. Here's the goal:
open import Agda.Primitive
open import Data.Nat
open import Data.Nat.Properties
open import Data.Product
open import Relation.Binary.PropositionalEquality
open import Data.AVL.Indexed <-strictTotalOrder
module Repro (ℓ : Level) (V : Value ℓ) where
Val = Value.family V
V≈ = Value.respects V
proof : (k k′ : ℕ) → (v : Val k) → (k≡k′ : k ≡ k′) → (k , v) ≡ (k′ , V≈ k≡k′ v)
proof k k′ v k≡k′ = {!!}
I tried rewriting with k≡k′
, which turns k
on the LHS into k′
and k≡k′
on the RHS into refl
. That's where I get stuck. I feel like I'm missing something obvious, as this seems a pretty basic thing to do.
(As an exercise, I'm trying to prove the standard library's AVL tree insertion correct. Hence my recent obsession with its AVL tree code.)
Update
Hmm. Maybe this isn't as trivial as I thought, at least without knowing more about V
. After all, what I currently know is that:
There's a way to turn a value of type Val k
into a value of type Val k′
- by way of V≈
.
That V≈ refl
takes a Val foo
and returns a Val foo
.
What I don't know at this point is that V≈ refl
is the identity function, which seems to be what I'd need to do my proof.
Update II
If, for example, I knew that V≈
was actually subst Val
, then my proof would be:
proof′ : (k k′ : ℕ) → (v : Val k) → (k≡k′ : k ≡ k′) → (k , v) ≡ (k′ , subst Val k≡k′ v)
proof′ k k′ v k≡k′ rewrite k≡k′ = cong (k′ ,_) refl
So, I guess my question ultimately is:
Can I complete my original proof with what I have?
If not, then what property do I need V≈
to have to complete my original proof (i.e., to "restrict it to functions that are like subst
")?
Update III
I am providing more context in response to MrO's comment. Instead of stripping down my actual proof, I'll provide something even simpler. Let's prove a special case of AVL tree insertion, which leads to the same problem that I'm facing in the general case.
Let's prove that inserting a value v
for key k
into an empty tree and then looking up the value for key k
yields the value v
that we inserted.
Let's get set up:
open import Agda.Primitive using (Level)
open import Data.Maybe using (just)
open import Data.Nat using (ℕ)
open import Data.Nat.Properties using (<-strictTotalOrder ; <-cmp)
open import Data.Product using (proj₂)
open import Function using () renaming (const to constᶠ)
open import Relation.Binary using (tri< ; tri≈ ; tri>)
open import Relation.Binary.PropositionalEquality using (_≡_ ; refl )
open import Relation.Nullary.Negation using (contradiction)
open import Data.AVL.Indexed <-strictTotalOrder
module Simple {ℓ : Level} (V : Value ℓ) where
private
Val = Value.family V
V≈ = Value.respects V
Now, a function to create an empty tree:
make-empty : ∀ {l u} → l <⁺ u → Tree V l u 0
make-empty = leaf
And the proof:
proof : ∀ {l u} (k : ℕ) (v : Val k) (l<u : l <⁺ u) (l<k<u : l < k < u) →
lookup k (proj₂ (insertWith k (constᶠ v) (make-empty l<u) l<k<u)) l<k<u ≡ just v
proof k v l<u l<k<u with <-cmp k k
... | tri< _ p _ = contradiction refl p
... | tri> _ p _ = contradiction refl p
... | tri≈ _ p _ rewrite p = {!!}
The goal that I'm trying to fill in is just (V≈ refl v) ≡ just v
.
Upvotes: 0
Views: 187
Reputation: 1347
You could postulate, or take as a module parameter, the fact that V≈
leaves the value unchanged, as follows:
postulate lemma : ∀ {k k′} {v : Val k} → (k≡k′ : k ≡ k′) → v ≡ subst _ (sym k≡k′) (V≈ k≡k′ v)
After that, your proof becomes:
proof : (k k′ : ℕ) → (v : Val k) → (k≡k′ : k ≡ k′) → (k , v) ≡ (k′ , V≈ k≡k′ v)
proof k ._ _ refl = cong (k ,_) (lemma refl)
Upvotes: 1