[Agda] `with' in standard functions

Sandro Stucki sandro.stucki at gmail.com
Mon Sep 25 14:32:07 CEST 2017


Hi Sergei,

Here's a solution that uses a with clause in the proof (similar to
that in the definition of `fromBits`) and the `inspect` idiom to keep
track of the result of the with clause. There's also a helper lemma to
dispatch some absurd cases. It's not very elegant, and I'm not sure it
will scale to bigger examples, but I hope it's useful to you anyway.

----
open import Data.Bin
open import Data.Digit
open import Data.Fin renaming (suc to 1+_)
open import Data.List
open import Function
open import Relation.Binary.PropositionalEquality
open ≡-Reasoning
open import Relation.Nullary.Negation

-- A helper: lists of bits ending in `1b` do not convert to `0#`.
fromBits-bs++1≠0 : ∀ bs → fromBits (bs ∷ʳ 1b) ≢ 0#
fromBits-bs++1≠0 []                ()
fromBits-bs++1≠0 (b          ∷ bs) _
  with fromBits (bs ∷ʳ 1b) | inspect fromBits (bs ∷ʳ 1b)
fromBits-bs++1≠0 (zero       ∷ bs) _  | 0#     | [ eq ] = fromBits-bs++1≠0 bs eq
fromBits-bs++1≠0 (1+ zero    ∷ bs) () | 0#     | [ _ ]
fromBits-bs++1≠0 (1+ (1+ ()) ∷ bs) _  | 0#     | _
fromBits-bs++1≠0 (b ∷ bs)          () | bs′ 1# | [ _ ]

fromBits-bs++1 :  fromBits ∘ (_∷ʳ 1b) ≗ _1#
fromBits-bs++1 []                = refl
fromBits-bs++1 (b          ∷ bs)
  with fromBits (bs ∷ʳ 1b) | inspect fromBits (bs ∷ʳ 1b)
fromBits-bs++1 (b          ∷ bs) | bs′ 1# | [ eq ] =
  helper (begin
    bs′ 1#                            ≡⟨ sym eq ⟩
    fromBits (bs ++ (1+ zero) ∷ [])   ≡⟨ fromBits-bs++1 bs ⟩
    bs 1#                             ∎)
  where
    -- Combines injectivity of `_1#` with `cong (_#1 ∘ (b ∷_))`.
    helper : ∀ {b bs₁ bs₂} → bs₁ 1# ≡ bs₂ 1# → (b ∷ bs₁) 1# ≡ (b ∷ bs₂) 1#
    helper refl = refl
fromBits-bs++1 (zero       ∷ bs) | 0#     | [ eq ] =
  contradiction eq ((fromBits-bs++1≠0 bs))
fromBits-bs++1 (1+ zero    ∷ bs) | 0#     | [ eq ] =
  contradiction eq ((fromBits-bs++1≠0 bs))
fromBits-bs++1 (1+ (1+ ()) ∷ bs) | 0#     | _
----

Cheers
/Sandro


On Sun, Sep 24, 2017 at 1:46 PM, Sergei Meshveliani <mechvel at botik.ru> wrote:
> People,
>
> There is a certain problem with user proofs for Standard library
> functions that use `with' or `case_of_'.
> If a function is written without `with' (`with' replaced with calling an
> auxiliary function  aux, and this  aux  is exported from the module),
> then it is much easier to compose various new proofs about it.
>
> But the user cannot change implementation for a standard function.
>
> For example,  Data.Bin  implements
>
> -------------------------
> fromBits : List Bit → Bin
> fromBits []        = 0#
> fromBits (b  ∷ bs) with fromBits bs
> fromBits (b  ∷ bs) | bs′ 1# = (b ∷ bs′) 1#
> fromBits (0b ∷ bs) | 0#     = 0#
> fromBits (1b ∷ bs) | 0#     = [] 1#
> fromBits (⊥b ∷ bs) | _
> -------------------------
>
> I need to prove
>
>           fromBits-bs++1 :  fromBits ∘ (_∷ʳ 1b) ≗ _1#
>
> And find it difficult.
> Then I get free of `with', and a proof becomes plain and easy to
> compose:
>
> --------------------------------------------------
> fromBits-aux : Bit → List Bit → Bin → Bin    -- needs to be exported
>
> fromBits-aux b  bs (bs' 1#) = (b ∷ bs') 1#
> fromBits-aux 0b bs 0#       = 0#
> fromBits-aux 1b bs 0#       = [] 1#
> fromBits-aux ⊥b bs _
>
> fromBits' : List Bit → Bin
> fromBits' []       = 0#
> fromBits' (b ∷ bs) = fromBits-aux b bs (fromBits' bs)
>
>
> fromBits-bs++1 :  fromBits' ∘ (_∷ʳ 1b) ≗ _1#
> fromBits-bs++1 []       =  refl
> fromBits-bs++1 (b ∷ bs) =
>   begin
>     fromBits' (b ∷ (bs ∷ʳ 1b))                        ≡⟨ refl ⟩
>     fromBits-aux b (bs ∷ʳ 1b) (fromBits' (bs ∷ʳ 1b))
>                                     ≡⟨ cong (fromBits-aux b (bs ∷ʳ 1b))
>                                             (fromBits-bs++1 bs)
>>     fromBits-aux b (bs ∷ʳ 1b) (bs 1#)                 ≡⟨ refl ⟩
>     (b ∷ bs) 1#
>> ---------------------------------------------------
>
> Please, what is a way out?
>
> Thanks,
>
> ------
> Sergei
>
>
> _______________________________________________
> Agda mailing list
> Agda at lists.chalmers.se
> https://lists.chalmers.se/mailman/listinfo/agda


More information about the Agda mailing list