Termination check on unionWith

后端 未结 2 843
醉话见心
醉话见心 2021-01-24 06:51

I\'m having a problem with termination checking, very similar to the one described in this question and also this Agda bug report/feature request.

The problem is convinc

相关标签:
2条回答
  • 2021-01-24 07:35

    Here's an alternative based on sized types, based on the answer to this later question. You can pick up the Data.Extended-key module from here, or you can tweak the code below so that it uses Data.AVL.Extended-key from the standard library instead.

    Preamble:

    {-# OPTIONS --sized-types #-}
    
    open import Relation.Binary renaming (IsStrictTotalOrder to IsSTO)
    open import Relation.Binary.PropositionalEquality as P using (_≡_)
    
    -- A list of (key, value) pairs, sorted by key in strictly descending order.
    module Temp
       {                                                                    
    0 讨论(0)
  • 2021-01-24 07:39

    It seems the first solution proposed for the earlier list-merge question does indeed work here, but only under Agda version 2.3.3+. Here's the full version, with a slightly nicer syntax for ∷.

    data FiniteMap (l : Key) : Set (k ⊔ v ⊔ ℓ) where
       [] : FiniteMap l
       _∷[_]_ : (kv : KV) → let k = proj₁ kv in l < k → (m : FiniteMap k) → FiniteMap l
    
    -- Split into two definitions to help the termination checker.
    unionWith : ∀ {l} → Op₂ Value → Op₂ (FiniteMap l)
    unionWith′ : ∀ {l} → Op₂ Value → (kv : KV) → let k = proj₁ kv in l < k → FiniteMap k → Op₁ (FiniteMap l)
    
    unionWith _ [] [] = []
    unionWith _ [] m = m
    unionWith _ m [] = m
    unionWith _⊕_ ((k , v) ∷[ k<l ] m) ((k′ , v′) ∷[ k′<l ] m′) with compare k k′
    ... | tri< k<k′ _ _ = (k , v) ∷[ k<l ] (unionWith _⊕_ m ((k′ , v′) ∷[ k<k′ ] m′))
    ... | tri≈ _ k≡k′ _ rewrite P.sym k≡k′ = (k , v ⊕ v′) ∷[ k<l ] (unionWith _⊕_ m m′)
    ... | tri> _ _ k′<k = (k′ , v′) ∷[ k′<l ] (unionWith′ _⊕_ (k , v) k′<k m m′)
    
    unionWith′ _ (k , v) l<k m [] = (k , v) ∷[ l<k ] m
    unionWith′ _⊕_ (k , v) l<k m ((k′ , v′) ∷[ k′<l ] m′) with compare k k′
    ... | tri< k<k′ _ _ = (k , v) ∷[ l<k ] (unionWith _⊕_ m ((k′ , v′) ∷[ k<k′ ] m′))
    ... | tri≈ _ k≡k′ _ rewrite P.sym k≡k′ = (k , v ⊕ v′) ∷[ l<k ] (unionWith _⊕_ m m′)
    ... | tri> _ _ k′<k = (k′ , v′) ∷[ k′<l ] (unionWith′ _⊕_ (k , v) k′<k m m′)
    
    0 讨论(0)
提交回复
热议问题