Zulip Chat Archive

Stream: new members

Topic: pattern matching prevents `refl` proof from working


David Renshaw (Dec 29 2021 at 15:02):

How can I prove the break_into_words_def lemma below? It works if I redefine everything to not use pattern matching, but I would prefer not to do that.

import data.stream.defs

variable {α : Type}

-- I want to be able to rewrite applications of this function.
-- I expect to be able to use `refl` to reduce it.

def break_into_words :
   (stream )  -- word lengths
   (stream α)  -- original sequence
   (stream (list α)) -- sequence of words
 := function.curry
     (stream.corec
       (λ lengths, a'⟩, stream.take (lengths.head) a')
       (λ lengths, a'⟩, lengths.tail, stream.drop (lengths.head) a'⟩))

#eval (stream.take 4 (break_into_words id id))
-- [[], [0], [1, 2], [3, 4, 5]]

lemma break_into_words_def
    (b : stream )
    (a : stream α)
    (n : )
   : break_into_words b a n =
    ((λ lengths, a'⟩, stream.take (lengths.head) a') : stream  × stream α  list α)
    ((@stream.iterate (stream  × stream α) (λ lengths, a'⟩,
                     lengths.tail, stream.drop (lengths.head) a'⟩) b,a⟩) n) :=
begin
  refl -- I expect this to work, but it does not.
end


-- If I don't use any pattern matching, then it works as expected:

def break_into_words' :
   (stream )  -- word lengths
   (stream α)  -- original sequence
   (stream (list α)) -- sequence of words
 := function.curry
     (stream.corec
       (λ x, stream.take (x.fst.head) x.snd)
       (λ x, x.fst.tail, stream.drop (x.fst.head) x.snd⟩))

#eval (stream.take 4 (break_into_words' id id))
-- [[], [0], [1, 2], [3, 4, 5]]

lemma break_into_words_def'
    (b : stream )
    (a : stream α)
    (n : )
   : break_into_words' b a n =
    ((λ x, stream.take (x.fst.head) x.snd) : stream  × stream α  list α)
    ((@stream.iterate (stream  × stream α) (λ x,
                     x.fst.tail, stream.drop (x.fst.head) x.snd⟩) b,a⟩) n) :=
begin
  refl -- does work
end

Kyle Miller (Dec 29 2021 at 15:23):

One trick is to do cases on the arguments that participate in pattern matching first. This can "unstick" the reduction involved in a refl proof. (I haven't checked if it works here.)

Kyle Miller (Dec 29 2021 at 15:25):

Oh, this doesn't seem to apply here, sorry.

Patrick Johnson (Dec 29 2021 at 16:49):

lemma break_into_words_def
  (b : stream )
  (a : stream α)
  (n : ) :
  break_into_words b a n =
  ((λ lengths, a'⟩, stream.take (lengths.head) a') :
  stream  × stream α  list α)
  ((@stream.iterate (stream  × stream α) (λ lengths, a'⟩,
  lengths.tail, stream.drop (lengths.head) a'⟩) b, a⟩) n) :=
begin
  convert_to
    (function.curry (stream.corec
    (λ x, stream.take (x.fst.head) x.snd)
    (λ x, x.fst.tail, stream.drop (x.fst.head) x.snd⟩)) :
    stream   stream α  stream (list α)) b a n =
    (((λ x, stream.take (x.fst.head) x.snd) : stream  × stream α  list α)
    ((@stream.iterate (stream  × stream α) (λ x,
    x.fst.tail, stream.drop (x.fst.head) x.snd⟩) b, a⟩) n)),
  { rw break_into_words, congr; ext a, b; refl },
  { simp_rw prod_rec },
  refl,
end

David Renshaw (Dec 29 2021 at 17:31):

@Patrick Johnson what is prod_rec? I don't see that anywhere in mathlib or core lean.

Patrick Johnson (Dec 29 2021 at 17:34):

Sorry, I edited the post, but that lemma somehow disappeared. Fixed.

David Renshaw (Dec 29 2021 at 17:34):

Thanks!

David Renshaw (Dec 29 2021 at 17:35):

I still don't understand why this isn't a direct definitional equality, though.


Last updated: Dec 20 2023 at 11:08 UTC