Definitions on lazy lists #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
This file contains various definitions and proofs on lazy lists.
TODO: move the lazy_list.lean
file from core to mathlib.
Equations
- thunk.decidable_eq a b = have this : a = b ↔ a unit.star() = b unit.star(), from _, _.mpr (_inst_1 (a unit.star()) (b unit.star()))
Isomorphism between strict and lazy lists.
Equations
- lazy_list.list_equiv_lazy_list α = {to_fun := lazy_list.of_list α, inv_fun := lazy_list.to_list α, left_inv := _, right_inv := _}
Equations
- lazy_list.decidable_eq (lazy_list.cons x xs) (lazy_list.cons y ys) = dite (x = y) (λ (h : x = y), lazy_list.decidable_eq._match_1 x xs y ys h (lazy_list.decidable_eq (xs unit.star()) (ys unit.star()))) (λ (h : ¬x = y), decidable.is_false _)
- lazy_list.decidable_eq (lazy_list.cons _x _x_1) lazy_list.nil = decidable.is_false _
- lazy_list.decidable_eq lazy_list.nil (lazy_list.cons _x _x_1) = decidable.is_false _
- lazy_list.decidable_eq lazy_list.nil lazy_list.nil = decidable.is_true lazy_list.decidable_eq._main._proof_1
- lazy_list.decidable_eq._match_1 x xs y ys h (decidable.is_true h2) = have this : xs = ys, from _, decidable.is_true _
- lazy_list.decidable_eq._match_1 x xs y ys h (decidable.is_false h2) = decidable.is_false _
Traversal of lazy lists using an applicative effect.
Equations
Equations
- lazy_list.traversable = {to_functor := {map := lazy_list.traverse monad.to_applicative, map_const := λ (α β : Type u_1), lazy_list.traverse ∘ function.const β}, traverse := lazy_list.traverse}
Equations
- lazy_list.is_lawful_traversable = equiv.is_lawful_traversable' lazy_list.list_equiv_lazy_list lazy_list.is_lawful_traversable._proof_1 lazy_list.is_lawful_traversable._proof_2 lazy_list.is_lawful_traversable._proof_3
init xs
, if xs
non-empty, drops the last element of the list.
Otherwise, return the empty list.
Equations
- (lazy_list.cons x xs).init = let xs' : lazy_list α := xs unit.star() in lazy_list.init._match_1 x (xs unit.star()).init xs'
- lazy_list.nil.init = lazy_list.nil
- lazy_list.init._match_1 x _f_1 (lazy_list.cons _x _x_1) = lazy_list.cons x (λ («_» : unit), _f_1)
- lazy_list.init._match_1 x _f_1 lazy_list.nil = lazy_list.nil
Return the first object contained in the list that satisfies
predicate p
Equations
- lazy_list.find p (lazy_list.cons h t) = ite (p h) (option.some h) (lazy_list.find p (t unit.star()))
- lazy_list.find p lazy_list.nil = option.none
interleave xs ys
creates a list where elements of xs
and ys
alternate.
Equations
- (lazy_list.cons x xs).interleave (lazy_list.cons y ys) = lazy_list.cons x (λ («_» : unit), lazy_list.cons y (λ («_» : unit), (xs unit.star()).interleave (ys unit.star())))
- (lazy_list.cons x xs).interleave lazy_list.nil = lazy_list.cons x xs
- lazy_list.nil.interleave xs = xs
interleave_all (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.
Equations
Monadic bind operation for lazy_list
.
Equations
- (lazy_list.cons x xs).bind f = (f x).append (λ («_» : unit), (xs unit.star()).bind f)
- lazy_list.nil.bind _x = lazy_list.nil
Equations
Try applying function f
to every element of a lazy_list
and
return the result of the first attempt that succeeds.
Equations
- lazy_list.mfirst f (lazy_list.cons x xs) = (f x <|> lazy_list.mfirst f (xs unit.star()))
- lazy_list.mfirst f lazy_list.nil = failure
Membership in lazy lists
Equations
- lazy_list.mem x (lazy_list.cons y ys) = (x = y ∨ lazy_list.mem x (ys unit.star()))
- lazy_list.mem x lazy_list.nil = false
Equations
- lazy_list.has_mem = {mem := lazy_list.mem α}
Equations
- lazy_list.mem.decidable x (lazy_list.cons y ys) = dite (x = y) (λ (h : x = y), decidable.is_true _) (λ (h : ¬x = y), decidable_of_decidable_of_iff (lazy_list.mem.decidable x (ys unit.star())) _)
- lazy_list.mem.decidable x lazy_list.nil = decidable.false
map for partial functions #
Partial map. If f : Π a, p a → β
is a partial function defined on
a : α
satisfying p
, then pmap f l h
is essentially the same as map f l
but is defined only when all members of l
satisfy p
, using the proof
to apply f
.
Equations
- lazy_list.pmap f (lazy_list.cons x xs) H = lazy_list.cons (f x _) (λ («_» : unit), lazy_list.pmap f (xs unit.star()) _)
- lazy_list.pmap f lazy_list.nil H = lazy_list.nil
"Attach" the proof that the elements of l
are in l
to produce a new lazy_list
with the same elements but in the type {x // x ∈ l}
.
Equations
- l.attach = lazy_list.pmap subtype.mk l _