Zulip Chat Archive
Stream: lean4
Topic: Making a RungeKutta 4
Miguel Raz Guzmán Macedo (Jun 17 2021 at 05:44):
Hello all!
I'm trying to dive again into Lean4.
I was inspired by this post to make a functional RungeKutta4 function https://www.johndcook.com/blog/2016/06/02/ode-solver-as-a-functional-fold/
So far, I have this:
import Data
def rk (t, y) t' : (t', y):= do
let h := t' - t
let k1 := f t y
let k2 := f (t + 0.5*h) (y + 0.5*h*k1)
let k3 := f (t + 0.5*h) (y + 0.5*h*k2)
let k4 := f (t + 1.0*h) (y + 1.0*h*k3)
return (t', y + h*(k1 + 2.0*k2 + 2.0*k3 + k4)/6.0)
def f (t y : Float) : Float := (t^2 - y*2) * sin y
#eval f 0.1 0.2
#eval foldl rk (0.0, -1.0) #[0.01, 0.03, 0.04, 0.06]
My problems are the following:
- I don't know how to import
sin
- I don't know how to use
foldl
- I don't know how to use the unit testing facilities
Miguel Raz Guzmán Macedo (Jun 17 2021 at 05:44):
Please ping if you are answering, thanks!
Mario Carneiro (Jun 17 2021 at 06:20):
Does that import Data
line actually work for you? I'm getting unknown package Data
but that might be my setup
Mario Carneiro (Jun 17 2021 at 06:24):
This works:
def rk (f : Float → Float → Float) : Float × Float → Float → Float × Float
| (t, y), t' =>
let h := t' - t
let k1 := f t y
let k2 := f (t + 0.5*h) (y + 0.5*h*k1)
let k3 := f (t + 0.5*h) (y + 0.5*h*k2)
let k4 := f (t + 1.0*h) (y + 1.0*h*k3)
return (t', y + h*(k1 + 2.0*k2 + 2.0*k3 + k4)/6.0)
def f (t y : Float) : Float := (t^2 - y*2) * y.sin
#eval f 0.1 0.2
#eval Array.foldl (rk f) (init := (0.0, -1.0)) #[0.01, 0.03, 0.04, 0.06]
Mario Carneiro (Jun 17 2021 at 06:25):
if you want to open sin
instead of using projection notation, you can do this
open Float (sin)
open Array (foldl)
def f (t y : Float) : Float := (t^2 - y*2) * sin y
#eval f 0.1 0.2
#eval foldl (rk f) (init := (0.0, -1.0)) #[0.01, 0.03, 0.04, 0.06]
Mario Carneiro (Jun 17 2021 at 06:26):
foldl
takes its arguments in the opposite order, so you can either use named arguments like init :=
here or else swap the arguments
Mario Carneiro (Jun 17 2021 at 06:31):
and in case you are wondering why you are getting -1.1099
instead of -0.9527
like the blog post, it's because your definition of f
uses y*2
instead of y^2
Miguel Raz Guzmán Macedo (Jun 17 2021 at 15:04):
Thanks a ton @Mario Carneiro , super helpful as always.
Miguel Raz Guzmán Macedo (Jun 17 2021 at 15:05):
Next question: do I _need_ to specify the type signature of rk
that explicitly?
Mario Carneiro (Jun 17 2021 at 20:13):
You still have to say that f
is a function because lean does not try to guess if a function is dependent or not, but other than that you can do without all the types
def rk (f : _ → _ → _) := fun (t, y) t' =>
let h := t' - t
let k1 := f t y
let k2 := f (t + 0.5*h) (y + 0.5*h*k1)
let k3 := f (t + 0.5*h) (y + 0.5*h*k2)
let k4 := f (t + 1.0*h) (y + 1.0*h*k3)
(t', y + h*(k1 + 2.0*k2 + 2.0*k3 + k4)/6.0)
Mario Carneiro (Jun 17 2021 at 20:15):
the return
is not necessary and is bad for type inference
Mario Carneiro (Jun 17 2021 at 20:15):
@Miguel Raz Guzmán Macedo
Miguel Raz Guzmán Macedo (Jun 17 2021 at 20:20):
Oooh, those are very useful tips, thanks a lot! I didn't know about return
.
Mario Carneiro (Jun 17 2021 at 20:25):
Normally you would use return
in a do
block, although it's not necessary at the last statement
Mario Carneiro (Jun 17 2021 at 20:26):
If you are just creating lets then you don't need do
Miguel Raz Guzmán Macedo (Jun 17 2021 at 20:26):
Ok, Gotcha.
Mario Carneiro (Jun 17 2021 at 20:27):
lean 4 has where
syntax as well, but it doesn't seem to work with local variables introduced by pattern matching
Mario Carneiro (Jun 17 2021 at 20:30):
def rk (f : _ → _ → _) t y t' :=
(t', y + h*(k1 + 2.0*k2 + 2.0*k3 + k4)/6.0)
where
h := t' - t
k1 := f t y
k2 := f (t + 0.5*h) (y + 0.5*h*k1)
k3 := f (t + 0.5*h) (y + 0.5*h*k2)
k4 := f (t + 1.0*h) (y + 1.0*h*k3)
Miguel Raz Guzmán Macedo (Jun 17 2021 at 20:30):
@Mario Carneiro nice, I had only seen the where
for structs and types, so I didn't know how to use it.
Miguel Raz Guzmán Macedo (Jun 17 2021 at 20:51):
Hmmm - I can't get the final line to work - here is all my code:
open Float (sin)
open Array (foldl)
def rk (f : _ → _ → _) t y t' :=
(t', y + h*(k1 + 2.0*k2 + 2.0*k3 + k4)/6.0)
where
h := t' - t
k1 := f t y
k2 := f (t + 0.5*h) (y + 0.5*h*k1)
k3 := f (t + 0.5*h) (y + 0.5*h*k2)
k4 := f (t + 1.0*h) (y + 1.0*h*k3)
def f (t y : Float) : Float := (t^2 - y^2) * sin y
#eval f 0.1 0.2
#eval foldl rk (init := (0.0, -1.0)) #[0.01, 0.03, 0.04, 0.06]
Mario Carneiro (Jun 17 2021 at 21:02):
the last version changes the type of rk
, so you would have to use uncurry (rk f)
instead of rk
in the eval line
Miguel Raz Guzmán Macedo (Jun 17 2021 at 21:24):
#eval foldl uncurry (rk f) (init := (0.0, -1.0)) #[0.01, 0.03, 0.04, 0.06]
Am I missing an export?
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:33):
The manual really needs some updating.
Mario Carneiro (Jun 17 2021 at 23:33):
(uncurry (rk f))
needs to be in parentheses since otherwise you are passing uncurry
and (rk f)
separately to foldl
; also uncurry
probably doesn't exist in lean 4 yet
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:33):
I keep wanting a Lean4 by example
guide
Mario Carneiro (Jun 17 2021 at 23:33):
that's called the lean 4 source code ATM :upside_down:
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:34):
Even looking at the source code is not too helpful - how do you navigate when you want to see what a function does?
Mario Carneiro (Jun 17 2021 at 23:34):
ctrl-click
Mario Carneiro (Jun 17 2021 at 23:34):
Use vscode with the lean 4 extension to look at the lean 4 sources
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:35):
I'm used to searching for unit tests, but I don't think Lean4 has a good system for that.
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:35):
@Mario Carneiro I have Lean3 installed in VSCode and Lean4 on Emacs, and that's after a few days of battle with the nix stuff.
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:35):
I don't really get how to keep the installations separate.
Mario Carneiro (Jun 17 2021 at 23:35):
There are unit tests in lean 4 but not enough to be usable as an example guide
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:36):
thanks for your patience, sorry for being a newbie :(
Mario Carneiro (Jun 17 2021 at 23:36):
I have the lean 4 extension disabled by default and enabled on specific workspaces (like the lean4 repo)
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:36):
Oh that's nice.
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:37):
I just want a little package that I can make little examples for.
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:37):
Like exercism.
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:37):
And start to benchmark different solutions.
Mario Carneiro (Jun 17 2021 at 23:37):
I ran into some issues with lean files getting misinterpreted as lean4 if I don't selectively enable the extension
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:37):
Understandable.
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:38):
@Mario Carneiro A bit besides the point, but how likely is Lean5 to completely change Lean4 semantics? Do you find much transition pain from Lean3 to Lean4?
Mario Carneiro (Jun 17 2021 at 23:38):
I have no idea whether lean 5 will exist or what it will do
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:39):
@Mario Carneiro hoo boy.
Mario Carneiro (Jun 17 2021 at 23:39):
there is a lot of transition pain from lean 3 to lean 4, but working on fixing that is literally in my job description at the moment
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:39):
@Mario Carneiro Oh neat - where at?
Mario Carneiro (Jun 17 2021 at 23:40):
microsoft research
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:40):
Oh neat, so I guess there's at least 3 people working on Lean4 now? Kudos!
Mario Carneiro (Jun 17 2021 at 23:41):
heh, I'm not on the core team, but my spirit is
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:41):
Neat.
Mario Carneiro (Jun 17 2021 at 23:42):
I'm working with Daniel Selsam on the mathport tool
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:42):
@Mario Carneiro Neat!
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:42):
Wait, which extension is the good Lean4 extension?
Mario Carneiro (Jun 17 2021 at 23:43):
mhuisi.lean4 I think
Mario Carneiro (Jun 17 2021 at 23:44):
no wait, it's leanprover.lean4 now
Mario Carneiro (Jun 17 2021 at 23:46):
By the way, it's easy to write uncurry yourself:
def uncurry (f : α → β → γ) : α × β → γ | (a, b) => f a b
#eval Array.foldl (uncurry (rk f)) (init := (0.0, -1.0)) #[0.01, 0.03, 0.04, 0.06]
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:47):
Oh neat.
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:47):
Ugh, I'm stuck in elan hell again.
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:51):
Alright, not worth my sanity to fight this package manager today. thanks though!
Miguel Raz Guzmán Macedo (Jun 17 2021 at 23:54):
That uncurry doesn't work btw
Mario Carneiro (Jun 17 2021 at 23:56):
full example:
def rk (f : _ → _ → _) t y t' :=
(t', y + h*(k1 + 2.0*k2 + 2.0*k3 + k4)/6.0)
where
h := t' - t
k1 := f t y
k2 := f (t + 0.5*h) (y + 0.5*h*k1)
k3 := f (t + 0.5*h) (y + 0.5*h*k2)
k4 := f (t + 1.0*h) (y + 1.0*h*k3)
def f (t y : Float) : Float := (t^2 - y^2) * y.sin
#eval f 0.1 0.2
def uncurry (f : α → β → γ) : α × β → γ | (a, b) => f a b
#eval Array.foldl (uncurry (rk f)) (init := (0.0, -1.0)) #[0.01, 0.03, 0.04, 0.06]
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:39):
@Mario Carneiro mmmmm nope, not on my leanprover/lean4:4.0.0
version.
Mario Carneiro (Jun 18 2021 at 00:40):
What's the error? I use nightly
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:44):
@Mario Carneiro unknown declaration '_eval', failed to synthesize instance.
Mario Carneiro (Jun 18 2021 at 00:45):
What does #check
give in place of #eval
?
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:45):
#check
is green
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:45):
it says:
Mario Carneiro (Jun 18 2021 at 00:46):
what instance was failed to synthesize?
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:46):
foldl (uncurry (rk f)) (0.0 sorryAx Float) #[num1, num2, num3, num4] 0
Mario Carneiro (Jun 18 2021 at 00:46):
Oh, it's probably Repr Float
Mario Carneiro (Jun 18 2021 at 00:46):
oh wait that looks bad
Mario Carneiro (Jun 18 2021 at 00:47):
where did num1
come from?
Mario Carneiro (Jun 18 2021 at 00:47):
are you using the code as written?
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:47):
Sorry, I got lazy. The full array is:
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:47):
#[ 1e-2, 3e-2, 4e-2, 6e-2]
Mario Carneiro (Jun 18 2021 at 00:48):
Could you post the code as written and the output as printed?
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:49):
here ya go
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:49):
Mario Carneiro (Jun 18 2021 at 00:50):
oh, that makes a lot more sense with the comma
Mario Carneiro (Jun 18 2021 at 00:50):
it's saying -1.0
has an instance problem
Mario Carneiro (Jun 18 2021 at 00:50):
so it's probably missing Neg Float
Mario Carneiro (Jun 18 2021 at 00:51):
and that probably happened some time after 4.0.0 (which is pretty old)
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:51):
OK, if I swap -1.0 -> 1.0
Everything works!
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:51):
:tada:
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:51):
I ... don't know how to update the Lean4 here.
Mario Carneiro (Jun 18 2021 at 00:51):
elan update leanprover/lean4:nightly
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:51):
I tried to elan update
but I got a 404 download error.
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:52):
Oh what... now it's downloading.
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:52):
Must've mixed up some flags.
Mario Carneiro (Jun 18 2021 at 00:53):
Also, the failed to synthesize instance message should say more about the missing instance if you look at the error detail
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:55):
Well, I don't get any output in the #eval 2+2
now :confused:
Mario Carneiro (Jun 18 2021 at 00:55):
maybe restart the editor
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:55):
(This is Lean4 in Doom emacs.)
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:55):
Lemme do that restart.
Miguel Raz Guzmán Macedo (Jun 18 2021 at 00:59):
Hmm no luck.
Miguel Raz Guzmán Macedo (Jun 18 2021 at 01:11):
You know what? The easiest way to set this up is just using the TBA gitpod setup by @Sebastian Ullrich .
Mario Carneiro (Jun 18 2021 at 01:19):
Oh, you also have to update the extension
Mario Carneiro (Jun 18 2021 at 01:20):
the communication protocol also changes by lean version
Last updated: Dec 20 2023 at 11:08 UTC