[Agda] Making ≡ proofs more manageable

Twan van Laarhoven twanvl at gmail.com
Mon Jan 13 15:10:47 CET 2014


It looks like you can split up this proof as

   goal = cong-mkParser \i₀ a₀ m₀ kf ks →
          cong-runParser x i₀ (A ε) m₀ \i₁ a₁ m₃ _ _ →
          subgoal

where cong-mkParser asserts something like

    ∀ {f g} : (∀ i a m kf ks → f i a m kf ks ≡ g i a m kf ks)
            → mkParser f ≡ mkParser g

and similarly for runParser. Or you could assume extensionality and use 
Relation.Binary.ProposionalEquality.cong. In general when only a few bits 
change, you can write this as

    cong (\x -> constant-stuff x) (equality-of-changing-parts)

Or perhaps cong₂ if more than one thing changes.


Twan

On 13/01/14 09:30, Mateusz Kowalczyk wrote:
> Hello,
>
> I'm modelling Haskell's Attoparsec behaviour and I currently need to
> prove its associativity, that is ‘x <> y <> z ≡ x <> (y <> z)’ where
> _<>_ is a helper I used to define _∙_ in the record.
>
> I'm not going to bog you down with details unless you ask but just
> know that a lot of original functions look like
>
>> plus :: (Monoid t) => Parser t a -> Parser t a -> Parser t a
>> plus a b = Parser $ \i0 a0 m0 kf ks ->
>>             let kf' i1 a1 m1 _ _ = addS i0 a0 m0 i1 a1 m1 $
>>                                    \ i2 a2 m2 -> runParser b i2 a2 m2 kf ks
>>                 ks' i1 a1 m1 = ks i1 (a0 <> a1) m1
>>             in  noAdds i0 a0 m0 $ \i2 a2 m2 -> runParser a i2 a2 m2  kf' ks'
>
> and I replicate this behaviour. An upside is that once my Agda program
> checks out, I'll have some confidence that the Attoparsec's method
> works. The problem I'm having right now is that Agda is now asking me
> for such inconvenient looking proofs as
>
>> Goal: mkParser
>>        (λ {.r} i₀ a₀ m₀ kf ks →
>>           Parser.runParser x i₀ (A ε) m₀
>>           (λ i₁ a₁ m₃ _ _ →
>>              Parser.runParser y (I (unI i₀ ∙ unA a₁)) (A (ε ∙ unA a₁))
>>              (m₀ .Data.Agdoparsec.Internal.Types.More._.<> m₃)
>>              (λ i₂ a₂ m₄ _ _ →
>>                 Parser.runParser z (I (unI i₀ ∙ unA a₂)) (A (unA a₀ ∙ unA a₂))
>>                 (m₀ .Data.Agdoparsec.Internal.Types.More._.<> m₄) kf ks)
>>              (λ i₂ a₂ → ks i₂ (A (unA a₀ ∙ unA a₂))))
>>           (λ i₁ a₁ → ks i₁ (A (unA a₀ ∙ (ε ∙ unA a₁)))))
>>>>        mkParser
>>        (λ {.r} i₀ a₀ m₀ kf ks →
>>           Parser.runParser x i₀ (A ε) m₀
>>           (λ i₁ a₁ m₃ _ _ →
>>              Parser.runParser y (I (unI i₀ ∙ unA a₁)) (A ε)
>>              (m₀ .Data.Agdoparsec.Internal.Types.More._.<> m₃)
>>              (λ i₂ a₂ m₄ _ _ →
>>                 Parser.runParser z (I ((unI i₀ ∙ unA a₁) ∙ unA a₂))
>>                 (A ((unA a₀ ∙ unA a₁) ∙ unA a₂))
>>                 ((m₀ .Data.Agdoparsec.Internal.Types.More._.<> m₃)
>>                  .Data.Agdoparsec.Internal.Types.More._.<> m₄)
>>                 kf ks)
>>              (λ i₂ a₂ → ks i₂ (A ((unA a₀ ∙ unA a₁) ∙ unA a₂))))
>>           (λ i₁ a₁ → ks i₁ (A (unA a₀ ∙ unA a₁))))
>
> Is there any way to make proofs of such form more manageable? Any
> tricks? It's fairly clear that the meat of the proof is just down to
> showing a few bits inside of this rather large goal type. Perhaps
> there's a method to get those in an easier manner rather than retyping
> the whole thing at each step of the proof.
>
> --
> Mateusz K.
> _______________________________________________
> Agda mailing list
> Agda at lists.chalmers.se
> https://lists.chalmers.se/mailman/listinfo/agda
>



More information about the Agda mailing list