Zulip Chat Archive
Stream: lean4
Topic: IO Mutable Array
dudubao2007 (Jun 23 2022 at 05:43):
Is there an O(1) random-access and random-modification Array in the IO Monad in Lean 4 like C's array and Haskell's IOArray?
Marc Huisinga (Jun 23 2022 at 05:45):
Array
is that if you are using it linearly (you can check this e.g. via dbgTraceIfShared
)
Marc Huisinga (Jun 23 2022 at 05:46):
Or more explicitly: If the reference count is 1, Lean will update arrays in-place.
dudubao2007 (Jun 23 2022 at 06:02):
I'm sorry that I can't understand that. o(╥﹏╥)o
For example, I want to count the primes from 1 to n using Euler's sieve.
How can I write that just like in the procedural style?
Marc Huisinga (Jun 23 2022 at 06:14):
Here's a more simple example:
def mapa [Inhabited α] (xs : Array α) (f : α → α) : Array α := Id.run do
let mut xs := xs
for i in [0:xs.size] do
xs := dbgTraceIfShared "this will print something if xs has rc > 1" xs
xs := xs.set! i (f xs[i])
return xs
def foo (init n : Nat) : Nat := Id.run do
let mut xs := #[]
for i in [0:n] do
xs := xs.push init
xs := dbgTraceIfShared "this will print something if xs has rc > 1" xs
xs := mapa xs (· + 1)
return xs[0]
#eval foo 3 100000
Marc Huisinga (Jun 23 2022 at 06:16):
mapa
will mutate the array in-place if xs
has a reference count of 1 (i.e. it is not shared).
dudubao2007 (Jun 23 2022 at 06:24):
I see. Thank you a lot! :heart:
dudubao2007 (Jun 23 2022 at 07:20):
def euler (n : Nat) : Nat := Id.run do
let mut ip := Array.mk <| [false, false] ++ List.replicate (n-1) true
let mut prime := #[]
let mut cnt := 0
for i in [2:n+1] do
if ip[i] then
cnt := cnt + 1
prime := prime.push i
for j in [0:cnt] do
if i * prime[j] > n then break
ip := ip.set! (i * prime[j]) false
if i % prime[j] == 0 then break
return cnt
#eval euler 1000000
Sorry to bother.
Is it a normal phenomenon that calculating euler 10^6 takes 4 secs and euler 10^7 causes stack overflow?
Henrik Böving (Jun 23 2022 at 07:22):
You are using eval instead of compiling your code so you shouldn't expect too good of a performance yeah
dudubao2007 (Jun 23 2022 at 07:34):
Oh :joy: , thank you. It takes 0.3 secs to calculate euler 10^6. However, it stills causes stack overflow to calculate euler 10^7.
Marc Huisinga (Jun 23 2022 at 07:37):
That might be List.replicate
Henrik Böving (Jun 23 2022 at 07:38):
Yeah, also note that using Array.mk
on a List adds an additional O(n)
to your runtime since the array consructor has to iterate over the list.
dudubao2007 (Jun 23 2022 at 07:39):
Should I use "push"?
Henrik Böving (Jun 23 2022 at 07:39):
If you want to achieve as much performance as possible you should simply not use List
at all.
Mauricio Collares (Jun 23 2022 at 07:40):
I guess the question is "What is the fastest way of creating an array with N elements, all equal to some value V"?
dudubao2007 (Jun 23 2022 at 07:42):
Yes. :+1: :smiley:
Marc Huisinga (Jun 23 2022 at 07:42):
Try mkArray (n-1) true
Marc Huisinga (Jun 23 2022 at 07:44):
I.e. #[false, false] ++ mkArray (n-1) true
or with less copying
let mut ip := mkArray (n+1) true
ip := ip.set! 0 false
ip := ip.set! 1 false
dudubao2007 (Jun 23 2022 at 07:51):
Thanks. I have trouble finding suitable library functions. Is there a way to search a library function by its type(like Haskell's Hoogle)?
dudubao2007 (Jun 23 2022 at 07:53):
Marc Huisinga said:
I.e.
#[false, false] ++ mkArray (n-1) true
or with less copyinglet mut ip := mkArray (n+1) true ip := ip.set! 0 false ip := ip.set! 1 false
It only takes 0.18 secs to calc euler 10^6. Thank you! :big_smile:
Henrik Böving (Jun 23 2022 at 07:55):
There is #find
which is made for proof search but I guess it could also find regular functions, apart from that we only have search by name here right now: https://leanprover-community.github.io/mathlib4_docs/ getting a hoogle like thing working is definitely on my List as well at some point but it would require an actual Lean backend instead of just generating HTML via Lean which is a whole different complexity class.
Marc Huisinga (Jun 23 2022 at 08:05):
Note that you need Mathlib4 for #find
Last updated: Dec 20 2023 at 11:08 UTC