From c264b08cfb9beb5fe34d872b02a8f4cd1e12d45e Mon Sep 17 00:00:00 2001 From: Ryan Lahfa Date: Tue, 16 Apr 2024 23:30:47 +0200 Subject: compiler: map `core::option::Option::take` to identity function `take` in a pure functional model is the identity function and everything related to borrow checking is handled by the forward/backward mechanism. Signed-off-by: Ryan Lahfa --- compiler/ExtractBuiltin.ml | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'compiler') diff --git a/compiler/ExtractBuiltin.ml b/compiler/ExtractBuiltin.ml index a9b939b5..3e96c320 100644 --- a/compiler/ExtractBuiltin.ml +++ b/compiler/ExtractBuiltin.ml @@ -290,6 +290,9 @@ let builtin_funs () : (pattern * bool list option * builtin_fun_info) list = mk_fun "core::slice::{[@T]}::len" (Some (backend_choice "slice::len" "Slice::len")) None; + mk_fun "core::option::{core::option::Option<@T>}::take" + (Some (backend_choice "option::take" "Option::take")) + None; mk_fun "alloc::vec::{alloc::vec::Vec<@T, alloc::alloc::Global>}::new" (Some "alloc::vec::Vec::new") None; mk_fun "alloc::vec::{alloc::vec::Vec<@T, @A>}::push" None @@ -515,6 +518,7 @@ let builtin_fun_effects = "alloc::vec::{alloc::vec::Vec<@T, @A>}::len"; "core::mem::replace"; "core::mem::take"; + "core::option::{core::option::Option<@T>}::take"; "core::clone::impls::{core::clone::Clone}::clone"; "alloc::vec::{alloc::vec::Vec<@T, alloc::alloc::Global>}::with_capacity"; "core::slice::{[@T]}::reverse"; -- cgit v1.3.1 From 18484e28ef7b13b95dc3af0b1e34c2181e1778e5 Mon Sep 17 00:00:00 2001 From: Ryan Lahfa Date: Wed, 17 Apr 2024 00:01:34 +0200 Subject: compiler: map `core::mem::swap` to the pure swap In the pure functional model, `swap` is mostly about borrow checking and should simplify to the pure swap in our backends. Other backends than Lean are not done in this commit. Signed-off-by: Ryan Lahfa --- backends/lean/Base/Primitives/Base.lean | 2 ++ compiler/ExtractBuiltin.ml | 2 ++ tests/lean/External/FunsExternal_Template.lean | 6 ------ 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'compiler') diff --git a/backends/lean/Base/Primitives/Base.lean b/backends/lean/Base/Primitives/Base.lean index 62546ac3..94134d86 100644 --- a/backends/lean/Base/Primitives/Base.lean +++ b/backends/lean/Base/Primitives/Base.lean @@ -132,6 +132,8 @@ def Result.attach {α: Type} (o : Result α): Result { x : α // o = ok x } := @[simp] def core.mem.replace (a : Type) (x : a) (_ : a) : a × a := (x, x) /- [core::option::Option::take] -/ @[simp] def Option.take (T: Type) (self: Option T): Option T × Option T := (self, .none) +/- [core::mem::swap] -/ +@[simp] def core.mem.swap (T: Type) (a b: T): T × T := (b, a) /-- Aeneas-translated function -- useful to reduce non-recursive definitions. Use with `simp [ aeneas ]` -/ diff --git a/compiler/ExtractBuiltin.ml b/compiler/ExtractBuiltin.ml index 3e96c320..531f1d8b 100644 --- a/compiler/ExtractBuiltin.ml +++ b/compiler/ExtractBuiltin.ml @@ -287,6 +287,7 @@ let builtin_funs () : (pattern * bool list option * builtin_fun_info) list = in [ mk_fun "core::mem::replace" None None; + mk_fun "core::mem::swap" None None; mk_fun "core::slice::{[@T]}::len" (Some (backend_choice "slice::len" "Slice::len")) None; @@ -517,6 +518,7 @@ let builtin_fun_effects = "alloc::vec::{alloc::vec::Vec<@T, alloc::alloc::Global>}::new"; "alloc::vec::{alloc::vec::Vec<@T, @A>}::len"; "core::mem::replace"; + "core::mem::swap"; "core::mem::take"; "core::option::{core::option::Option<@T>}::take"; "core::clone::impls::{core::clone::Clone}::clone"; diff --git a/tests/lean/External/FunsExternal_Template.lean b/tests/lean/External/FunsExternal_Template.lean index 38151dc9..f0e771f7 100644 --- a/tests/lean/External/FunsExternal_Template.lean +++ b/tests/lean/External/FunsExternal_Template.lean @@ -6,12 +6,6 @@ import External.Types open Primitives open external -/- [core::mem::swap]: - Source: '/rustc/d59363ad0b6391b7fc5bbb02c9ccf9300eef3753/library/core/src/mem/mod.rs', lines 726:0-726:42 - Name pattern: core::mem::swap -/ -axiom core.mem.swap - (T : Type) : T → T → State → Result (State × (T × T)) - /- [core::num::nonzero::{core::num::nonzero::NonZeroU32#14}::new]: Source: '/rustc/d59363ad0b6391b7fc5bbb02c9ccf9300eef3753/library/core/src/num/nonzero.rs', lines 79:16-79:57 Name pattern: core::num::nonzero::{core::num::nonzero::NonZeroU32}::new -/ -- cgit v1.3.1 From 8b1fd2477148d5c7174b5175074d480b1cb2cf06 Mon Sep 17 00:00:00 2001 From: Ryan Lahfa Date: Tue, 16 Apr 2024 23:49:47 +0200 Subject: compiler: map `core::option::Option::is_none` to `Option.isNone` Our backend already have support for `isNone`, we just map it and filter out passing the actual type as it can be inferred via implicit types. Other backends than Lean are not done in this commit. Signed-off-by: Ryan Lahfa --- compiler/ExtractBuiltin.ml | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'compiler') diff --git a/compiler/ExtractBuiltin.ml b/compiler/ExtractBuiltin.ml index 531f1d8b..c59825d1 100644 --- a/compiler/ExtractBuiltin.ml +++ b/compiler/ExtractBuiltin.ml @@ -294,6 +294,9 @@ let builtin_funs () : (pattern * bool list option * builtin_fun_info) list = mk_fun "core::option::{core::option::Option<@T>}::take" (Some (backend_choice "option::take" "Option::take")) None; + mk_fun "core::option::{core::option::Option<@T>}::is_none" + (Some (backend_choice "option::is_none" "Option::isNone")) + (Some [ false ]); mk_fun "alloc::vec::{alloc::vec::Vec<@T, alloc::alloc::Global>}::new" (Some "alloc::vec::Vec::new") None; mk_fun "alloc::vec::{alloc::vec::Vec<@T, @A>}::push" None @@ -521,6 +524,7 @@ let builtin_fun_effects = "core::mem::swap"; "core::mem::take"; "core::option::{core::option::Option<@T>}::take"; + "core::option::{core::option::Option<@T>}::is_none"; "core::clone::impls::{core::clone::Clone}::clone"; "alloc::vec::{alloc::vec::Vec<@T, alloc::alloc::Global>}::with_capacity"; "core::slice::{[@T]}::reverse"; -- cgit v1.3.1 From 5f2a388d1ff039cde0d78daaba58c191b404405e Mon Sep 17 00:00:00 2001 From: Ryan Lahfa Date: Wed, 24 Apr 2024 10:47:26 +0200 Subject: compiler: introduce Lean-only translations On the long run, all backends will not have equivalent or equal support for extraction. This introduces a function to filter out some Lean-only definitions in our various arrays of core functions. Signed-off-by: Ryan Lahfa --- compiler/ExtractBuiltin.ml | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'compiler') diff --git a/compiler/ExtractBuiltin.ml b/compiler/ExtractBuiltin.ml index c59825d1..c6827bbe 100644 --- a/compiler/ExtractBuiltin.ml +++ b/compiler/ExtractBuiltin.ml @@ -47,6 +47,10 @@ let flatten_name (name : string list) : string = | FStar | Coq | HOL4 -> String.concat "_" name | Lean -> String.concat "." name +(** Utility for Lean-only definitions **) +let mk_lean_only (funs : 'a list) : 'a list = + match !backend with Lean -> funs | _ -> [] + let () = assert (split_on_separator "x::y::z" = [ "x"; "y"; "z" ]); assert (split_on_separator "x.y.z" = [ "x"; "y"; "z" ]) @@ -287,16 +291,9 @@ let builtin_funs () : (pattern * bool list option * builtin_fun_info) list = in [ mk_fun "core::mem::replace" None None; - mk_fun "core::mem::swap" None None; mk_fun "core::slice::{[@T]}::len" (Some (backend_choice "slice::len" "Slice::len")) None; - mk_fun "core::option::{core::option::Option<@T>}::take" - (Some (backend_choice "option::take" "Option::take")) - None; - mk_fun "core::option::{core::option::Option<@T>}::is_none" - (Some (backend_choice "option::is_none" "Option::isNone")) - (Some [ false ]); mk_fun "alloc::vec::{alloc::vec::Vec<@T, alloc::alloc::Global>}::new" (Some "alloc::vec::Vec::new") None; mk_fun "alloc::vec::{alloc::vec::Vec<@T, @A>}::push" None @@ -445,6 +442,21 @@ let builtin_funs () : (pattern * bool list option * builtin_fun_info) list = (fun ty -> "core::clone::impls::{core::clone::Clone<" ^ ty ^ ">}::clone") (fun ty -> "core.clone.Clone" ^ StringUtils.capitalize_first_letter ty ^ ".clone") + (* Lean-only definitions *) + @ mk_lean_only + [ + (* `backend_choice` first parameter is for non-Lean backends + By construction, we cannot write down that parameter in the output + in this list + *) + mk_fun "core::mem::swap" None None; + mk_fun "core::option::{core::option::Option<@T>}::take" + (Some (backend_choice "" "Option::take")) + None; + mk_fun "core::option::{core::option::Option<@T>}::is_none" + (Some (backend_choice "" "Option::isNone")) + (Some [ false ]); + ] let mk_builtin_funs_map () = let m = @@ -521,16 +533,19 @@ let builtin_fun_effects = "alloc::vec::{alloc::vec::Vec<@T, alloc::alloc::Global>}::new"; "alloc::vec::{alloc::vec::Vec<@T, @A>}::len"; "core::mem::replace"; - "core::mem::swap"; "core::mem::take"; - "core::option::{core::option::Option<@T>}::take"; - "core::option::{core::option::Option<@T>}::is_none"; "core::clone::impls::{core::clone::Clone}::clone"; "alloc::vec::{alloc::vec::Vec<@T, alloc::alloc::Global>}::with_capacity"; "core::slice::{[@T]}::reverse"; "alloc::vec::{core::ops::deref::Deref>}::deref"; ] @ int_funs + @ mk_lean_only + [ + "core::mem::swap"; + "core::option::{core::option::Option<@T>}::take"; + "core::option::{core::option::Option<@T>}::is_none"; + ] in let no_fail_no_state_funs = List.map -- cgit v1.3.1