/- Copyright (c) 2018 Simon Hudon. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Simon Hudon ! This file was ported from Lean 3 source module data.lazy_list.basic ! leanprover-community/mathlib commit 1f0096e6caa61e9c849ec2adbd227e960e9dff58 ! Please do not edit these lines, except to modify the commit id ! if you have ported upstream changes. -/ import Mathlib.Control.Traversable.Equiv import Mathlib.Control.Traversable.Instances import Mathlib.Data.LazyList /-! ## Definitions on lazy lists This file contains various definitions and proofs on lazy lists. TODO: move the `LazyList.lean` file from core to mathlib. -/ universe u namespace Thunk -- Porting note: `Thunk.pure` appears to do the same thing. #align thunk.mk Thunk.pure -- Porting note: Added `Thunk.ext` to get `ext` tactic to work. @[ext] theorem ext {α :α: Type uType u} {Type u: Type (u+1)aa: Thunk αb : Thunkb: Thunk αα} (eq :α: Type ua.get =a: Thunk αb.get) :b: Thunk αa =a: Thunk αb :=b: Thunk αGoals accomplished! 🐙Goals accomplished! 🐙instance {instance: {α : Type u} → [inst : DecidableEq α] → DecidableEq (Thunk α)α :α: Type uType u} [DecidableEqType u: Type (u+1)α] : DecidableEq (Thunkα: Type uα) :=α: Type uGoals accomplished! 🐙DecidableEq (Thunk α)DecidableEq (Thunk α)Goals accomplished! 🐙Goals accomplished! 🐙Goals accomplished! 🐙Goals accomplished! 🐙DecidableEq (Thunk α)DecidableEq (Thunk α)end Thunk namespace LazyList open Function /-- Isomorphism between strict and lazy lists. -/ def listEquivLazyList (Goals accomplished! 🐙α :α: Type ?u.652Type _) : ListType _: Type (?u.652+1)α ≃ LazyListα: Type ?u.652α where toFun := LazyList.ofList invFun := LazyList.toList right_inv :=α: Type ?u.652Goals accomplished! 🐙α: Type ?u.652Function.RightInverse toList ofListα: Type ?u.652Function.RightInverse toList ofListα: Type ?u.652Function.RightInverse toList ofListGoals accomplished! 🐙α: Type ?u.652Function.RightInverse toList ofListGoals accomplished! 🐙α: Type ?u.652Function.RightInverse toList ofListleft_inv :=Goals accomplished! 🐙Goals accomplished! 🐙α: Type ?u.652LeftInverse toList ofListα: Type ?u.652LeftInverse toList ofListα: Type ?u.652LeftInverse toList ofListGoals accomplished! 🐙α: Type ?u.652LeftInverse toList ofList#align lazy_list.list_equiv_lazy_list LazyList.listEquivLazyList -- Porting note: Added a name to make the recursion work. instanceGoals accomplished! 🐙decidableEq {decidableEq: {α : Type u} → [inst : DecidableEq α] → DecidableEq (LazyList α)α :α: Type uType u} [DecidableEqType u: Type (u+1)α] : DecidableEq (LazyListα: Type uα) | nil, nil => isTrue rfl | consα: Type ux xs, consx: αy ys => ify: αh :h: ?m.2121x =x: αy then matchy: αdecidableEq xs.get ys.get with | isFalse h2 =>decidableEq: {α : Type u} → [inst : DecidableEq α] → DecidableEq (LazyList α)Goals accomplished! 🐙| isTrue h2 =>Goals accomplished! 🐙Goals accomplished! 🐙elseGoals accomplished! 🐙Goals accomplished! 🐙| nil, cons _ _ =>Goals accomplished! 🐙Goals accomplished! 🐙| cons _ _, nil =>Goals accomplished! 🐙Goals accomplished! 🐙/-- Traversal of lazy lists using an applicative effect. -/ protected defGoals accomplished! 🐙traverse {m :Type u →Type u: Type (u+1)Type u} [Applicative m] {Type u: Type (u+1)αα: Type uβ :β: Type uType u} (Type u: Type (u+1)f :f: α → m βα → mα: Type uβ) : LazyListβ: Type uα → m (LazyListα: Type uβ) | LazyList.nil => pure LazyList.nil | LazyList.consβ: Type ux xs => LazyList.cons <$>x: αff: α → m βx <*> Thunk.pure <$> xs.get.x: αtraversef #align lazy_list.traverse LazyList.traversef: α → m βinstance : Traversable LazyList where map := @LazyList.traverse Id _ traverse := @LazyList.traverseinstance: Traversable LazyListinstance :instance: IsLawfulTraversable LazyListIsLawfulTraversable LazyList :=IsLawfulTraversable: (t : Type ?u.20080 → Type ?u.20080) → [inst : Traversable t] → Type (?u.20080+1)Goals accomplished! 🐙
h₀∀ {α β : Type ?u.20081} (f : α → β), Functor.map f = Equiv.map listEquivLazyList f
h₁
h₂∀ {F : Type ?u.20081 → Type ?u.20081} [inst : Applicative F] [inst_1 : LawfulApplicative F] {α β : Type ?u.20081} (f : α → F β), traverse f = Equiv.traverse listEquivLazyList f
h₀∀ {α β : Type ?u.20081} (f : α → β), Functor.map f = Equiv.map listEquivLazyList f
h₁
h₂∀ {F : Type ?u.20081 → Type ?u.20081} [inst : Applicative F] [inst_1 : LawfulApplicative F] {α β : Type ?u.20081} (f : α → F β), traverse f = Equiv.traverse listEquivLazyList fF✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f✝: α✝ → F✝ β✝
h₂
h₀
h₁F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f✝: α✝ → F✝ β✝
h₂F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f✝: α✝ → F✝ β✝
x✝: LazyList α✝
h₂.htraverse f✝ x✝ = Equiv.traverse listEquivLazyList f✝ x✝
h₀.hf✝ <$> x✝ = Equiv.map listEquivLazyList f✝ x✝
h₁.hF✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f✝: α✝ → F✝ β✝
x✝: LazyList α✝
h₂.htraverse f✝ x✝ = Equiv.traverse listEquivLazyList f✝ x✝F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
h₂.htraverse f xs = Equiv.traverse listEquivLazyList f xs
h₀.hf <$> xs = Equiv.map listEquivLazyList f xs
h₁.hF✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
h₂.htraverse f xs = Equiv.traverse listEquivLazyList f xs
h₀.h.nilf <$> nil = Equiv.map listEquivLazyList f nilGoals accomplished! 🐙Goals accomplished! 🐙α✝, β✝: Type ?u.20081
f: α✝ → β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), f <$> fn✝ a = Equiv.map listEquivLazyList f (fn✝ a)
h₀.h.mk.eqThunk.get (Thunk.pure (LazyList.traverse f (Thunk.get { fn := fn✝ }))) = Thunk.get { fn := fun x => ofList (List.map f (toList (Thunk.get { fn := fn✝ }))) }α✝, β✝: Type ?u.20081
f: α✝ → β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), f <$> fn✝ a = Equiv.map listEquivLazyList f (fn✝ a)
h₀.h.mk.eqThunk.get (Thunk.pure (LazyList.traverse f (Thunk.get { fn := fn✝ }))) = Thunk.get { fn := fun x => ofList (List.map f (toList (Thunk.get { fn := fn✝ }))) }Goals accomplished! 🐙
h₁.h
h₁.hF✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
h₂.htraverse f xs = Equiv.traverse listEquivLazyList f xs
h₁.h
h₁.hGoals accomplished! 🐙
h₁.hGoals accomplished! 🐙
h₁.hα✝, β✝: Type ?u.20081
f: β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), LazyList.traverse (const α✝ f) (fn✝ a) = ofList (const α✝ f <$> toList (fn✝ a))
h₁.h.mkThunk.pure (LazyList.traverse (const α✝ f) (Thunk.get { fn := fn✝ })) = { fn := fun x => ofList (List.map (const α✝ f) (toList (Thunk.get { fn := fn✝ }))) }α✝, β✝: Type ?u.20081
f: β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), LazyList.traverse (const α✝ f) (fn✝ a) = ofList (const α✝ f <$> toList (fn✝ a))
h₁.h.mkThunk.pure (LazyList.traverse (const α✝ f) (Thunk.get { fn := fn✝ })) = { fn := fun x => ofList (List.map (const α✝ f) (toList (Thunk.get { fn := fn✝ }))) }α✝, β✝: Type ?u.20081
f: β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), LazyList.traverse (const α✝ f) (fn✝ a) = ofList (const α✝ f <$> toList (fn✝ a))
h₁.h.mkThunk.pure (LazyList.traverse (const α✝ f) (Thunk.get { fn := fn✝ })) = { fn := fun x => ofList (List.map (const α✝ f) (toList (Thunk.get { fn := fn✝ }))) }Goals accomplished! 🐙F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
h₂.htraverse f xs = Equiv.traverse listEquivLazyList f xsF✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
h₂.htraverse f xs = Equiv.traverse listEquivLazyList f xsF✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
h₂.hLazyList.traverse f xs = ofList <$> List.traverse f (toList xs)F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
h₂.htraverse f xs = Equiv.traverse listEquivLazyList f xsF✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
h₂.h.nilLazyList.traverse f nil = ofList <$> List.traverse f (toList nil)F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
hd✝: α✝
tl: Thunk (LazyList α✝)
ih: ?m.23299 tl
h₂.h.consLazyList.traverse f (cons hd✝ tl) = ofList <$> List.traverse f (toList (cons hd✝ tl))F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), LazyList.traverse f (fn✝ a) = ofList <$> List.traverse f (toList (fn✝ a))
h₂.h.mk?m.23299 { fn := fn✝ }F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
h₂.htraverse f xs = Equiv.traverse listEquivLazyList f xsF✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
h₂.h.nilLazyList.traverse f nil = ofList <$> List.traverse f (toList nil)F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
h₂.h.nilLazyList.traverse f nil = ofList <$> List.traverse f (toList nil)F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
hd✝: α✝
tl: Thunk (LazyList α✝)
ih: ?m.23299 tl
h₂.h.consLazyList.traverse f (cons hd✝ tl) = ofList <$> List.traverse f (toList (cons hd✝ tl))F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), LazyList.traverse f (fn✝ a) = ofList <$> List.traverse f (toList (fn✝ a))
h₂.h.mk?m.23299 { fn := fn✝ }F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
h₂.h.nilLazyList.traverse f nil = pure (ofList [])F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
h₂.h.nilLazyList.traverse f nil = pure (ofList [])F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
h₂.h.nilLazyList.traverse f nil = ofList <$> List.traverse f (toList nil)Goals accomplished! 🐙F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
h₂.htraverse f xs = Equiv.traverse listEquivLazyList f xsF✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
hd✝: α✝
tl: Thunk (LazyList α✝)
ih: ?m.23299 tl
h₂.h.consLazyList.traverse f (cons hd✝ tl) = ofList <$> List.traverse f (toList (cons hd✝ tl))F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
hd✝: α✝
tl: Thunk (LazyList α✝)
ih: ?m.23299 tl
h₂.h.consLazyList.traverse f (cons hd✝ tl) = ofList <$> List.traverse f (toList (cons hd✝ tl))F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), LazyList.traverse f (fn✝ a) = ofList <$> List.traverse f (toList (fn✝ a))
h₂.h.mk?m.23299 { fn := fn✝ }F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
hd✝: α✝
tl: Thunk (LazyList α✝)
ih, this: LazyList.traverse f (Thunk.get tl) = ofList <$> List.traverse f (toList (Thunk.get tl))
h₂.h.consLazyList.traverse f (cons hd✝ tl) = ofList <$> List.traverse f (toList (cons hd✝ tl))F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
hd✝: α✝
tl: Thunk (LazyList α✝)
ih: ?m.23299 tl
h₂.h.consLazyList.traverse f (cons hd✝ tl) = ofList <$> List.traverse f (toList (cons hd✝ tl))F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
hd✝: α✝
tl: Thunk (LazyList α✝)
ih, this: LazyList.traverse f (Thunk.get tl) = ofList <$> List.traverse f (toList (Thunk.get tl))
h₂.h.consF✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
hd✝: α✝
tl: Thunk (LazyList α✝)
ih: ?m.23299 tl
h₂.h.consLazyList.traverse f (cons hd✝ tl) = ofList <$> List.traverse f (toList (cons hd✝ tl))F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
hd✝: α✝
tl: Thunk (LazyList α✝)
ih, this: LazyList.traverse f (Thunk.get tl) = ofList <$> List.traverse f (toList (Thunk.get tl))
h₂.h.consF✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
hd✝: α✝
tl: Thunk (LazyList α✝)
ih, this: LazyList.traverse f (Thunk.get tl) = ofList <$> List.traverse f (toList (Thunk.get tl))
h₂.h.consGoals accomplished! 🐙F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
h₂.htraverse f xs = Equiv.traverse listEquivLazyList f xsF✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), LazyList.traverse f (fn✝ a) = ofList <$> List.traverse f (toList (fn✝ a))
h₂.h.mkLazyList.traverse f (Thunk.get { fn := fn✝ }) = ofList <$> List.traverse f (toList (Thunk.get { fn := fn✝ }))F✝: Type ?u.20081 → Type ?u.20081
inst✝¹: Applicative F✝
inst✝: LawfulApplicative F✝
α✝, β✝: Type ?u.20081
f: α✝ → F✝ β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), LazyList.traverse f (fn✝ a) = ofList <$> List.traverse f (toList (fn✝ a))
h₂.h.mkLazyList.traverse f (Thunk.get { fn := fn✝ }) = ofList <$> List.traverse f (toList (Thunk.get { fn := fn✝ }))/-- `init xs`, if `xs` non-empty, drops the last element of the list. Otherwise, return the empty list. -/ def init {Goals accomplished! 🐙α} : LazyListα: Type ?u.25676α → LazyListα: ?m.25672α | LazyList.nil => LazyList.nil | LazyList.consα: ?m.25672x xs => letx: αxs' := xs.get matchxs': ?m.25718xs' with | LazyList.nil => LazyList.nil | LazyList.cons _ _ => LazyList.consxs': ?m.25718x (initx: αxs') #align lazy_list.init LazyList.init /-- Return the first object contained in the list that satisfies predicate `p` -/ defxs': ?m.25718find {find: {α : Type ?u.34584} → (p : α → Prop) → [inst : DecidablePred p] → LazyList α → Option αα} (α: ?m.34566p :p: α → Propα →α: ?m.34566Prop) [DecidablePredProp: Typep] : LazyListp: α → Propα → Optionα: ?m.34566α | nil => none | consα: ?m.34566h t => ifh: αpp: α → Proph then someh: αh else t.get.h: αfindfind: {α : Type ?u.34584} → (p : α → Prop) → [inst : DecidablePred p] → LazyList α → Option αp #align lazy_list.findp: α → PropLazyList.find /-- `interleave xs ys` creates a list where elements of `xs` and `ys` alternate. -/ def interleave {LazyList.find: {α : Type u_1} → (p : α → Prop) → [inst : DecidablePred p] → LazyList α → Option αα} : LazyListα: ?m.42506α → LazyListα: ?m.42506α → LazyListα: ?m.42506α | LazyList.nil,α: ?m.42506xs =>xs: LazyList αxs |xs: LazyList αa@(LazyList.cons _ _), LazyList.nil =>a: LazyList αa | LazyList.consa: LazyList αx xs, LazyList.consx: αy ys => LazyList.consy: αx (LazyList.consx: αy (interleave xs.get ys.get)) #align lazy_list.interleave LazyList.interleave /-- `interleaveAll (xs::ys::zs::xss)` creates a list where elements of `xs`, `ys` and `zs` and the rest alternate. Every other element of the resulting list is taken from `xs`, every fourth is taken from `ys`, every eighth is taken from `zs` and so on. -/ def interleaveAll {y: αα} : List (LazyListα: ?m.52562α) → LazyListα: ?m.52562α | [] => LazyList.nil |α: ?m.52562x :: xs => interleavex: LazyList αx (interleaveAll xs) #align lazy_list.interleave_all LazyList.interleaveAll /-- Monadic bind operation for `LazyList`. -/ protected def bind {x: LazyList ααα: Type ?u.52848β} : LazyListβ: ?m.52844α → (α: ?m.52841α → LazyListα: ?m.52841β) → LazyListβ: ?m.52844β | LazyList.nil, _ => LazyList.nil | LazyList.consβ: ?m.52844x xs,x: αf => (f: α → LazyList βff: α → LazyList βx).append (xs.get.bindx: αf) #align lazy_list.bind LazyList.bind /-- Reverse the order of a `LazyList`. It is done by converting to a `List` first because reversal involves evaluating all the list and if the list is all evaluated, `List` is a better representation for it than a series of thunks. -/ def reverse {f: α → LazyList βα} (α: ?m.61942xs : LazyListxs: LazyList αα) : LazyListα: ?m.61942α := ofListα: ?m.61942xs.toList.reverse #align lazy_list.reverse LazyList.reverse instance : Monad LazyList where pure := @LazyList.singleton bind := @LazyList.bind -- Porting note: Added `Thunk.pure` to definition. theoremxs: LazyList αappend_nil {append_nil: ∀ {α : Type u_1} (xs : LazyList α), append xs (Thunk.pure nil) = xsα} (α: Type u_1xs : LazyListxs: LazyList αα) :α: ?m.62775xs.append (Thunk.pure LazyList.nil) =xs: LazyList αxs :=xs: LazyList αGoals accomplished! 🐙append xs (Thunk.pure nil) = xsappend xs (Thunk.pure nil) = xsα: Type u_1
nilappend nil (Thunk.pure nil) = nilGoals accomplished! 🐙append xs (Thunk.pure nil) = xsGoals accomplished! 🐙append xs (Thunk.pure nil) = xs#align lazy_list.append_nilGoals accomplished! 🐙LazyList.append_nil theoremLazyList.append_nil: ∀ {α : Type u_1} (xs : LazyList α), append xs (Thunk.pure nil) = xsappend_assoc {α} (α: Type u_1xsxs: LazyList αysys: LazyList αzs : LazyListzs: LazyList αα) : (α: ?m.63484xs.appendxs: LazyList αys).appendys: LazyList αzs =zs: LazyList αxs.append (xs: LazyList αys.appendys: LazyList αzs) :=zs: LazyList αGoals accomplished! 🐙Goals accomplished! 🐙Goals accomplished! 🐙#align lazy_list.append_assoc LazyList.append_assoc -- Porting note: Rewrote proof of `append_bind`. theoremGoals accomplished! 🐙append_bind {append_bind: ∀ {α : Type u_1} {β : Type u_2} (xs : LazyList α) (ys : Thunk (LazyList α)) (f : α → LazyList β), LazyList.bind (append xs ys) f = append (LazyList.bind xs f) { fn := fun x => LazyList.bind (Thunk.get ys) f }αα: Type u_1β} (β: Type u_2xs : LazyListxs: LazyList αα) (ys : Thunk (LazyListα: ?m.66428α)) (α: ?m.66428f :f: α → LazyList βα → LazyListα: ?m.66428β) : (β: ?m.66431xs.append ys).bindxs: LazyList αf = (f: α → LazyList βxs.bindxs: LazyList αf).append (ys.get.bindf: α → LazyList βf) :=f: α → LazyList βGoals accomplished! 🐙LazyList.bind (append xs ys) f = append (LazyList.bind xs f) { fn := fun x => LazyList.bind (Thunk.get ys) f }LazyList.bind (append xs ys) f = append (LazyList.bind xs f) { fn := fun x => LazyList.bind (Thunk.get ys) f }LazyList.bind (append nil ys) f = append (LazyList.bind nil f) { fn := fun x => LazyList.bind (Thunk.get ys) f }LazyList.bind (append xs ys) f = append (LazyList.bind xs f) { fn := fun x => LazyList.bind (Thunk.get ys) f }Goals accomplished! 🐙LazyList.bind (append xs ys) f = append (LazyList.bind xs f) { fn := fun x => LazyList.bind (Thunk.get ys) f }LazyList.bind (append xs ys) f = append (LazyList.bind xs f) { fn := fun x => LazyList.bind (Thunk.get ys) f }α: Type u_1
β: Type u_2
xs✝: LazyList α
ys: Thunk (LazyList α)
f: α → LazyList β
x: α
xs: Thunk (LazyList α)append (f x) { fn := fun x => LazyList.bind (append (Thunk.fn xs ()) ys) f } = append (append (f x) { fn := fun x => LazyList.bind (Thunk.fn xs ()) f }) { fn := fun x => LazyList.bind (Thunk.fn ys ()) f }α: Type u_1
β: Type u_2
xs✝: LazyList α
ys: Thunk (LazyList α)
f: α → LazyList β
x: α
xs: Thunk (LazyList α)
this: LazyList.bind (append (Thunk.get xs) ys) f = append (LazyList.bind (Thunk.get xs) f) { fn := fun x => LazyList.bind (Thunk.get ys) f }append (f x) { fn := fun x => LazyList.bind (append (Thunk.fn xs ()) ys) f } = append (append (f x) { fn := fun x => LazyList.bind (Thunk.fn xs ()) f }) { fn := fun x => LazyList.bind (Thunk.fn ys ()) f }α: Type u_1
β: Type u_2
xs✝: LazyList α
ys: Thunk (LazyList α)
f: α → LazyList β
x: α
xs: Thunk (LazyList α)
this: LazyList.bind (append (Thunk.fn xs ()) ys) f = append (LazyList.bind (Thunk.fn xs ()) f) { fn := fun x => LazyList.bind (Thunk.fn ys ()) f }append (f x) { fn := fun x => LazyList.bind (append (Thunk.fn xs ()) ys) f } = append (append (f x) { fn := fun x => LazyList.bind (Thunk.fn xs ()) f }) { fn := fun x => LazyList.bind (Thunk.fn ys ()) f }α: Type u_1
β: Type u_2
xs✝: LazyList α
ys: Thunk (LazyList α)
f: α → LazyList β
x: α
xs: Thunk (LazyList α)
this: LazyList.bind (append (Thunk.fn xs ()) ys) f = append (LazyList.bind (Thunk.fn xs ()) f) { fn := fun x => LazyList.bind (Thunk.fn ys ()) f }append (f x) { fn := fun x => LazyList.bind (append (Thunk.fn xs ()) ys) f } = append (append (f x) { fn := fun x => LazyList.bind (Thunk.fn xs ()) f }) { fn := fun x => LazyList.bind (Thunk.fn ys ()) f }α: Type u_1
β: Type u_2
xs✝: LazyList α
ys: Thunk (LazyList α)
f: α → LazyList β
x: α
xs: Thunk (LazyList α)
this: LazyList.bind (append (Thunk.fn xs ()) ys) f = append (LazyList.bind (Thunk.fn xs ()) f) { fn := fun x => LazyList.bind (Thunk.fn ys ()) f }append (f x) { fn := fun x => append (LazyList.bind (Thunk.fn xs ()) f) { fn := fun x => LazyList.bind (Thunk.fn ys ()) f } } = append (append (f x) { fn := fun x => LazyList.bind (Thunk.fn xs ()) f }) { fn := fun x => LazyList.bind (Thunk.fn ys ()) f }α: Type u_1
β: Type u_2
xs✝: LazyList α
ys: Thunk (LazyList α)
f: α → LazyList β
x: α
xs: Thunk (LazyList α)
this: LazyList.bind (append (Thunk.fn xs ()) ys) f = append (LazyList.bind (Thunk.fn xs ()) f) { fn := fun x => LazyList.bind (Thunk.fn ys ()) f }append (f x) { fn := fun x => LazyList.bind (append (Thunk.fn xs ()) ys) f } = append (append (f x) { fn := fun x => LazyList.bind (Thunk.fn xs ()) f }) { fn := fun x => LazyList.bind (Thunk.fn ys ()) f }α: Type u_1
β: Type u_2
xs✝: LazyList α
ys: Thunk (LazyList α)
f: α → LazyList β
x: α
xs: Thunk (LazyList α)
this: LazyList.bind (append (Thunk.fn xs ()) ys) f = append (LazyList.bind (Thunk.fn xs ()) f) { fn := fun x => LazyList.bind (Thunk.fn ys ()) f }append (f x) { fn := fun x => append (LazyList.bind (Thunk.fn xs ()) f) { fn := fun x => LazyList.bind (Thunk.fn ys ()) f } } = append (f x) { fn := fun x => append (LazyList.bind (Thunk.fn xs ()) f) { fn := fun x => LazyList.bind (Thunk.fn ys ()) f } }#align lazy_list.append_bindGoals accomplished! 🐙LazyList.append_bindLazyList.append_bind: ∀ {α : Type u_1} {β : Type u_2} (xs : LazyList α) (ys : Thunk (LazyList α)) (f : α → LazyList β), LazyList.bind (append xs ys) f = append (LazyList.bind xs f) { fn := fun x => LazyList.bind (Thunk.get ys) f }instance : LawfulMonad LazyList :=instance: LawfulMonad LazyListLawfulMonad.mk' (bind_pure_comp :=LawfulMonad.mk': ∀ (m : Type ?u.76390 → Type ?u.76389) [inst : Monad m], (∀ {α : Type ?u.76390} (x : m α), id <$> x = x) → (∀ {α β : Type ?u.76390} (x : α) (f : α → m β), pure x >>= f = f x) → (∀ {α β γ : Type ?u.76390} (x : m α) (f : α → m β) (g : β → m γ), x >>= f >>= g = x >>= fun x => f x >>= g) → autoParam (∀ {α β : Type ?u.76390} (x : α) (y : m β), Functor.mapConst x y = const β x <$> y) _auto✝ → autoParam (∀ {α β : Type ?u.76390} (x : m α) (y : m β), (SeqLeft.seqLeft x fun x => y) = do let a ← x let _ ← y pure a) _auto✝¹ → autoParam (∀ {α β : Type ?u.76390} (x : m α) (y : m β), (SeqRight.seqRight x fun x => y) = do let _ ← x y) _auto✝² → autoParam (∀ {α β : Type ?u.76390} (f : α → β) (x : m α), (do let y ← x pure (f y)) = f <$> x) _auto✝³ → autoParam (∀ {α β : Type ?u.76390} (f : m (α → β)) (x : m α), (do let x_1 ← f x_1 <$> x) = Seq.seq f fun x_1 => x) _auto✝⁴ → LawfulMonad mGoals accomplished! 🐙(LazyList.bind xs fun y => cons (f y) (Thunk.pure nil)) = LazyList.traverse f xs
nil(LazyList.bind nil fun y => cons (f y) (Thunk.pure nil)) = LazyList.traverse f nil
cons(LazyList.bind (cons hd✝ tl✝) fun y => cons (f y) (Thunk.pure nil)) = LazyList.traverse f (cons hd✝ tl✝)α✝, β✝: Type ?u.76377
f: α✝ → β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), (LazyList.bind (fn✝ a) fun y => cons (f y) (Thunk.pure nil)) = LazyList.traverse f (fn✝ a)
mk?m.77774 { fn := fn✝ }
nil(LazyList.bind nil fun y => cons (f y) (Thunk.pure nil)) = LazyList.traverse f nil
nil(LazyList.bind nil fun y => cons (f y) (Thunk.pure nil)) = LazyList.traverse f nil
cons(LazyList.bind (cons hd✝ tl✝) fun y => cons (f y) (Thunk.pure nil)) = LazyList.traverse f (cons hd✝ tl✝)α✝, β✝: Type ?u.76377
f: α✝ → β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), (LazyList.bind (fn✝ a) fun y => cons (f y) (Thunk.pure nil)) = LazyList.traverse f (fn✝ a)
mk?m.77774 { fn := fn✝ }Goals accomplished! 🐙
cons(LazyList.bind (cons hd✝ tl✝) fun y => cons (f y) (Thunk.pure nil)) = LazyList.traverse f (cons hd✝ tl✝)
cons(LazyList.bind (cons hd✝ tl✝) fun y => cons (f y) (Thunk.pure nil)) = LazyList.traverse f (cons hd✝ tl✝)α✝, β✝: Type ?u.76377
f: α✝ → β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), (LazyList.bind (fn✝ a) fun y => cons (f y) (Thunk.pure nil)) = LazyList.traverse f (fn✝ a)
mk?m.77774 { fn := fn✝ }
conscons (f hd✝) { fn := fun x => append (Thunk.get (Thunk.pure nil)) { fn := fun x => LazyList.bind (Thunk.get tl✝) fun y => cons (f y) (Thunk.pure nil) } } = Seq.seq (cons (f hd✝)) fun x => Thunk.pure (LazyList.traverse f (Thunk.get tl✝))
conscons (f hd✝) { fn := fun x => append (Thunk.get (Thunk.pure nil)) { fn := fun x => LazyList.bind (Thunk.get tl✝) fun y => cons (f y) (Thunk.pure nil) } } = Seq.seq (cons (f hd✝)) fun x => Thunk.pure (LazyList.traverse f (Thunk.get tl✝))
cons(LazyList.bind (cons hd✝ tl✝) fun y => cons (f y) (Thunk.pure nil)) = LazyList.traverse f (cons hd✝ tl✝)Goals accomplished! 🐙α✝, β✝: Type ?u.76377
f: α✝ → β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), (LazyList.bind (fn✝ a) fun y => cons (f y) (Thunk.pure nil)) = LazyList.traverse f (fn✝ a)
mk{ fn := fun x => append (Thunk.get (Thunk.pure nil)) { fn := fun x => LazyList.bind (Thunk.get { fn := fn✝ }) fun y => cons (f y) (Thunk.pure nil) } } = (fun x => Thunk.pure (LazyList.traverse f (Thunk.get { fn := fn✝ }))) ()α✝, β✝: Type ?u.76377
f: α✝ → β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), (LazyList.bind (fn✝ a) fun y => cons (f y) (Thunk.pure nil)) = LazyList.traverse f (fn✝ a)
mk{ fn := fun x => append (Thunk.get (Thunk.pure nil)) { fn := fun x => LazyList.bind (Thunk.get { fn := fn✝ }) fun y => cons (f y) (Thunk.pure nil) } } = (fun x => Thunk.pure (LazyList.traverse f (Thunk.get { fn := fn✝ }))) ()α✝, β✝: Type ?u.76377
f: α✝ → β✝
xs: LazyList α✝
fn✝: Unit → LazyList α✝
ih: ∀ (a : Unit), (LazyList.bind (fn✝ a) fun y => cons (f y) (Thunk.pure nil)<