Zulip Chat Archive
Stream: lean4
Topic: Properly axiomatizing foreign functions
James Gallicchio (Apr 04 2022 at 19:10):
Currently trying to learn how to build reasonable FFIs (in my case, for not-dynamic arrays).
I came across the definition of USize.ofNat
(here)[https://github.com/leanprover/lean4/blob/da4ad465d0a8a1267268def14af779ea0244f78e/src/Init/Data/UInt.lean#L285] and am a bit confused by it
- The Lean definition mods by the system usize (which I don't think is ever the desired use-case here?)
- I'm pretty sure the C definition panics if the nat can't fit in a usize (which I think is the desired behavior)
Why was this definition chosen instead of making an opaque constant or, at most, an unsafe function which panics on too-large inputs? Right now the behaviors just don't match up, which seems like a recipe for issues
James Gallicchio (Apr 04 2022 at 19:22):
The C definition is across a few places:
https://github.com/leanprover/lean4/blob/35e623fca0b949b373fac42063881f606c7abbe0/src/include/lean/lean.h#L1661
https://github.com/leanprover/lean4/blob/412691c9581138028e9a98e1b7c99dd136cefed8/src/runtime/object.cpp#L1521
and here I get stuck, since I don't know where these definitions came from. Maybe this does actually mod?
James Gallicchio (Apr 04 2022 at 19:37):
Okay, I guess my actual question is whether there's a different function somewhere I can use that unsafe converts Nat
to USize
, panicking if it is too large
Tomas Skrivan (Apr 04 2022 at 20:54):
You can define your own function that does that:
def Nat.toUSize! (n : Nat) : USize :=
if n < USize.size then
n.toUSize
else
panic! s!"Integer {n} is to larget for usize"
#eval (USize.size-1).toUSize! -- PANIC at toUSize doodle:9:4: Integer 18446744073709551616 is to larget for usize
#eval (USize.size).toUSize! -- 18446744073709551615
If you want to have something that is really safe, I would expect to always provide a proof that provided Nat fits to usize
def Nat.toUSizeSafe (n : Nat) (h : n < USize.size) : USize := ⟨n,h⟩
#eval (USize.size - 1).toUSizeSafe (by native_decide)
But I have a feeling I'm misunderstanding your question.
James Gallicchio (Apr 04 2022 at 22:13):
Tomas Skrivan said:
You can define your own function that does that:
Yeah, I can write my own, but was wondering why the disparity on this definition
Mario Carneiro (Apr 04 2022 at 22:38):
I believe it should be possible to bind to those functions directly, but it doesn't seem to be working:
@[extern "lean_usize_of_nat"]
def Nat.toUSize! (n : @& Nat) : USize :=
if n < USize.size then
n.toUSize
else
panic! s!"Integer {n} is to larget for usize"
#eval (USize.size-1).toUSize!
-- could not find native implementation of external declaration 'Nat.toUSize!' (symbols 'l_Nat_toUSize_x21___boxed' or 'l_Nat_toUSize_x21')
#eval (USize.size).toUSize!
Last updated: Dec 20 2023 at 11:08 UTC