How do you use boxed closures in FnMut contexts? - closures

How can you use a boxed closure in a context that requires a FnMut type, e.g.
pub fn main() {
for n in (0..10).map(Box::new(|i| i * 2)) {
println!("{}", n);
}
}

As Box implements the Deref trait, you can simply derefence your boxed function:
fn main() {
let boxed_fn = Box::new(|i| i * 2);
for n in (0..10).map(*boxed_fn) {
println!("{}", n);
}
}

Related

How to match exactly one byte using nom?

I want to match exactly one alphabetic character (a-zA-Z) with nom.
I know I can match greedily using take_while! with something like this:
// match one or more alphabetical characters
pub fn alpha_many(input: &[u8]) -> IResult<&[u8], &[u8]> {
take_while!(input, |c| {
(c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a)
})
}
But I can't find how to match only one byte. There is one_of!, but I can't use a closure, I have to pass a whole slice:
// match exactly one alphabetical character
pub fn alpha_one(input: &[u8]) -> IResult<&[u8], u8> {
one_of!(
input,
[
0x41, 0x42, 0x43,
// etc until 0x5a and then from 0x61 to 0x7a
// ...
].as_ref()
)
}
I've come up with this. I'll mark this as the accepted answer tomorrow if nobody comes up with a better solution:
use nom::{self, ErrorKind, IResult, Needed};
/// Alphabetical characters ([RFC5234 appendix B.1])
///
/// [RFC5234 appendix B.1]: https://tools.ietf.org/html/rfc5234#appendix-B.1
///
/// ```no_rust
/// ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
/// ```
pub struct Alpha;
impl Alpha {
/// Return true if the given byte represents an alphabetical character
pub fn is_alpha(c: u8) -> bool {
(c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a)
}
/// Parse one or more alphabetical characters
pub fn parse_many(input: &[u8]) -> IResult<&[u8], &[u8]> {
take_while!(input, Self::is_alpha)
}
/// Parse one alphabetical character
pub fn parse_one(input: &[u8]) -> IResult<&[u8], u8> {
Self::parse_n(input, 1).map(|res| res[0])
}
/// Parse n alphabetical characters
pub fn parse_n(input: &[u8], n: usize) -> IResult<&[u8], &[u8]> {
Self::parse_m_n(input, n, n)
}
/// Parse between m and n alphabetical characters
pub fn parse_m_n(input: &[u8], m: usize, n: usize) -> IResult<&[u8], &[u8]> {
if input.len() < m {
return IResult::Incomplete(Needed::Size(input.len() - m));
}
for i in 0..n {
if !Self::is_alpha(input[i]) {
// We were supposed to have at least m printable bytes
if i < m {
return IResult::Error(error_position!(ErrorKind::ManyMN, &input[..]));
} else {
return IResult::Done(&input[i..], &input[0..i]);
}
}
}
return IResult::Done(&input[n..], &input[0..n]);
}
}

What is the difference between a let-rebinding and a standard assignment?

In Rust, in order to change the value of a mutable variable, what is the difference in let x = 12 or x = 12 in the following sample code?
fn main() {
let mut x: i32 = 8;
{
println!("{}", x);
let x = 12; // what if change to x = 12
println!("{}", x);
}
println!("{}", x);
let x = 42;
println!("{}", x);
}
The output is 8, 12, 8, 42. If I change let x = 12 to x = 12 ...
fn main() {
let mut x: i32 = 8;
{
println!("{}", x);
x = 12;
println!("{}", x);
}
println!("{}", x);
let x = 42;
println!("{}", x);
}
The output is 8, 12, 12, 42.
I understand that Rust uses let to do variable binding, so the let x = 12 is a variable rebinding and the binding is only valid inside a scope. But how to explain the functionality of x = 12 and the corresponding scope? Is that a type of variable binding?
The second let x introduces a second binding that shadows the first one for the rest of the block. That is, there are two variables named x, but you can only access the second one within the block statement after the let x = 12; statement. These two variables don't need to have the same type!
Then, after the block statement, the second x is out of scope, so you access the first x again.
However, if you write x = 12; instead, that's an assignment expression: the value in x is overwritten. This doesn't introduce a new variable, so the type of the value being assigned must be compatible with the variable's type.
This difference is important if you write a loop. For example, consider this function:
fn fibonacci(mut n: u32) -> u64 {
if n == 0 {
return 1;
}
let mut a = 1;
let mut b = 1;
loop {
if n == 1 {
return b;
}
let next = a + b;
a = b;
b = next;
n -= 1;
}
}
This function reassigns variables, so that each iteration of the loop can operate on the values assigned on the preceding iteration.
However, you might be tempted to write the loop like this:
loop {
if n == 1 {
return b;
}
let (a, b) = (b, a + b);
n -= 1;
}
This doesn't work, because the let statement introduces new variables, and these variables will go out of scope before the next iteration begins. On the next iteration, (b, a + b) will still use the original values.

How can I write a builder that stores a Path?

The Path argument could be immediately converted into a PathBuf, but that seems inefficient. There has to be some way of keeping just a Path, right?
use std::{fs::File, path::Path};
struct Foo {
a: Option<File>,
b: Option<File>,
}
struct FooBuilder<'a> {
a: Option<&'a Path>,
b: Option<&'a Path>,
}
impl<'a> FooBuilder<'a> {
fn new() -> FooBuilder<'a> {
FooBuilder { a: None, b: None }
}
fn a<P: AsRef<Path> + 'a>(&'a mut self, a: P) -> &mut FooBuilder<'a> {
self.a = Some(a.as_ref());
self
}
fn b<P: AsRef<Path> + 'a>(&'a mut self, b: P) -> &mut FooBuilder<'a> {
self.b = Some(b.as_ref());
self
}
fn done(&self) -> Foo {
Foo {
a: match self.a {
Some(path) => Some(File::open(path).unwrap()),
None => None,
},
b: match self.b {
Some(path) => Some(File::open(path).unwrap()),
None => None,
},
}
}
}
fn main() {
let path1 = Path::new("1");
let path2 = Path::new("2");
let _foo = FooBuilder::new().a(path1).b(path2).done();
}
error[E0597]: `a` does not live long enough
--> src/main.rs:19:23
|
13 | impl<'a> FooBuilder<'a> {
| -- lifetime `'a` defined here
...
19 | self.a = Some(a.as_ref());
| --------------^----------
| | |
| | borrowed value does not live long enough
| assignment requires that `a` is borrowed for `'a`
20 | self
21 | }
| - `a` dropped here while still borrowed
error[E0597]: `b` does not live long enough
--> src/main.rs:24:23
|
13 | impl<'a> FooBuilder<'a> {
| -- lifetime `'a` defined here
...
24 | self.b = Some(b.as_ref());
| --------------^----------
| | |
| | borrowed value does not live long enough
| assignment requires that `b` is borrowed for `'a`
25 | self
26 | }
| - `b` dropped here while still borrowed
This works:
use std::{fs::File, path::Path};
struct Foo {
a: Option<File>,
}
struct FooBuilder<'a> {
a: Option<&'a Path>,
}
impl<'a> FooBuilder<'a> {
fn new() -> FooBuilder<'a> {
FooBuilder { a: None }
}
fn a<P>(&mut self, a: &'a P) -> &mut FooBuilder<'a>
where
P: AsRef<Path> + ?Sized,
{
self.a = Some(a.as_ref());
self
}
fn build(&self) -> Foo {
Foo {
a: self.a.map(|path| File::open(path).unwrap()),
}
}
}
fn main() {
let path1 = Path::new("1");
let _foo = FooBuilder::new().a(path1).build();
}
Let's focus on the a method:
fn a<P>(&mut self, a: &'a P) -> &mut FooBuilder<'a>
where
P: AsRef<Path> + ?Sized,
This method accepts a reference to a type that implements AsRef<Path>. That means that we can get a reference to a Path with the same lifetime as the parameter. The other change is to make the Sized bound optional for the type via ?. This means that we can have a reference to something that we don't know how big it is. This is fine as we will know how big the reference itself is.
Let's compare this to your original version:
fn a<P: AsRef<Path> + 'a>(&'a mut self, a: P) -> &mut FooBuilder<'a> {
self.a = Some(a.as_ref());
self
}
Here, the a parameter is passed-by-value into the method a. When you call as_ref, you are implicitly calling it on a reference to the item that is on the stack frame of the method call. The referred-to item will be dropped at the end of the method call, which means that the reference would become invalid. That is the reasoning behind the error: `a` does not live long enough error you were getting.
I also used Option::map to clean up the build method. I renamed it to build because builders should generally have a build method, unless there's a more obvious verb to use (like open).
See also:
What does the question mark mean in a type parameter bound?

Z3 C++ API expression predicate operator overload does not have unsigned operation

I was looking at document of class expr of Z3 C++ API from following link
http://research.microsoft.com/en-us/um/redmond/projects/z3/classz3_1_1expr.html.
I found that for predicate operator such us ">" , ">=" and "<=", for bit vector it only performed signed operation. For example in operator ">=", source code is
{
check_context(a, b);
Z3_ast r;
if (a.is_arith() && b.is_arith()) {
r = Z3_mk_ge(a.ctx(), a, b);
}
else if (a.is_bv() && b.is_bv()) {
r =Z3_mk_bvsge(a.ctx(), a, b);//This statement only did signed version, there actually is a Z3_mk_bvuge in C API
}
else {
assert(false);
}
a.check_error();
return expr(a.ctx(), r);
}
Does this mean if I want to distinguish between signed and unsigned operation I can only use C API?
The z++.h file contains definitions (shorthands) for using the unsigned bit-vector operations, for example:
/**
\brief unsigned less than or equal to operator for bitvectors.
*/
inline expr ule(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvule(a.ctx(), a, b)); }

How to find out if a z3_ast corresponds to a clause?

I am using Z3 with c api. Is it possible to find out if a given Z3_ast variable corresponds to a clause like or_b1_b2 bellow?
Z3_ast or_b1_b2 = mk_binary_or(c,mk_bool_var(c,"b1"),mk_bool_var(c,"b2"));
Thank you
Yes, The Z3 API provides several functions for inspecting/traversing ASTs.
The Z3 API is minimalist, but it has all necessary ingredients for writing function such as: is_propositional_variable, is_literal, and is_clause. Here is an example:
// Return true if the given ast is an application of the given kind
int is_app_of(Z3_context c, Z3_ast a, Z3_decl_kind k) {
if (Z3_get_ast_kind(c, a) != Z3_APP_AST)
return 0;
return Z3_get_decl_kind(c, Z3_get_app_decl(c, Z3_to_app(c, a))) == k;
}
// Return true if the given ast is an OR.
int is_or(Z3_context c, Z3_ast a) {
return is_app_of(c, a, Z3_OP_OR);
}
// Return true if the given ast is a NOT.
int is_not(Z3_context c, Z3_ast a) {
return is_app_of(c, a, Z3_OP_NOT);
}
// Return true if the given ast is an application of an unintepreted symbol.
int is_uninterp(Z3_context c, Z3_ast a) {
return is_app_of(c, a, Z3_OP_UNINTERPRETED);
}
// Return true if the given ast is a uninterpreted constant.
// That is, it is application (with zero arguments) of an uninterpreted symbol.
int is_uninterp_const(Z3_context c, Z3_ast a) {
return is_uninterp(c, a) && Z3_get_app_num_args(c, Z3_to_app(c, a)) == 0;
}
// Return true if the given ast has Boolean sort (aka type).
int has_bool_sort(Z3_context c, Z3_ast a) {
return Z3_get_sort_kind(c, Z3_get_sort(c, a)) == Z3_BOOL_SORT;
}
// Return true if the given ast is a "propositional variable".
// That is, it has Boolean sort and it is uninterpreted.
int is_propositional_var(Z3_context c, Z3_ast a) {
return is_uninterp_const(c, a) && has_bool_sort(c, a);
}
// Return true if the given ast is a "literal".
// That is, it is a "propositional variable" or the negation of a propositional variable.
int is_literal(Z3_context c, Z3_ast a) {
if (is_propositional_var(c, a))
return 1;
if (is_not(c, a))
return is_propositional_var(c, Z3_get_app_arg(c, Z3_to_app(c, a), 0));
return 0;
}
// Return true if the given ast is a "clause".
// That is, it is a literal, or a disjuction (OR) of literals.
int is_clause(Z3_context c, Z3_ast a) {
if (is_literal(c, a)) {
return 1; // unit clause
}
else if (is_or(c, a)) {
unsigned num;
unsigned i;
num = Z3_get_app_num_args(c, Z3_to_app(c, a));
for (i = 0; i < num; i++) {
if (!is_literal(c, Z3_get_app_arg(c, Z3_to_app(c, a), i)))
return 0;
}
return 1;
}
else {
return 0;
}
}

Resources