The parameter for this question is an example of "merging sorted lists" from this earlier question .
{-
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 {↑ ι}
As before, I use size types so that Agda can determine that the following function is mergeending:
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)
What I'm trying to do is prove the following associativity theorem:
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)
Cases where at least one list is []easy to follow by definition, but I will include them for completeness.
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 ( ), , , , " " , , rewrite , inspect.
, , compare x y compare y z, inspect:
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′ , ?