Add support for parsing negative solution values#46
Conversation
This commit adds support for solutions that contain negative integers. Additionally fixes typos in comments.
|
Thanks for opening the issue and draft PR. I think I'd prefer adding methods to extract Something like impl Context {
// Existing
pub fn get(&self, expr: SExpr) -> SExprData { ... }
// New
pub fn get_atom(&self, expr: SExpr) -> Option<&str> { ... }
pub fn get_str(&self, expr: SExpr) -> Option<&str> { ... }
pub fn get_list(&self, expr: SExpr) -> Option<&[SExpr]> { ... }
pub fn get_u8(&self, expr: SExpr) -> Option<u8> { ... }
pub fn get_u16(&self, expr: SExpr) -> Option<u16> { ... }
// etc...
pub fn get_i8(&self, expr: SExpr) -> Option<i8> { ... }
pub fn get_i16(&self, expr: SExpr) -> Option<i16> { ... }
// etc...
}And maybe also |
I implemented your proposed interface in daa988e. I have chosen not to implement Let me know what you think about the implementation |
fitzgen
left a comment
There was a problem hiding this comment.
Thanks!
One nitpick below before we can merge this plus another optional thing that you can take or leave
src/sexpr.rs
Outdated
| return x; | ||
| } | ||
|
|
||
| (prefix.to_owned() + a).parse::<$ty>().ok() |
There was a problem hiding this comment.
I think this is fine to land as-is, but ideally we would avoid the .to_owned() here and the allocation it implies, and instead always parse the integer as the unsigned version at that width and then negate it if necessary.
Something like
fn try_parse_t(a: &str, radix: u32, negative: bool) -> Option<Self> {
let unsigned = <$unsigned_ty>::from_str_radix(a, radix).ok()?;
let signed = <$signed_ty>::try_from(unsigned).ok()?;
if negative {
signed.checked_neg()
} else {
Some(signed)
}
}If you don't feel up for tackling that in this PR, would you mind filing a follow-up issue for this change?
There was a problem hiding this comment.
I agree that the allocation is unnecessary here. But maybe this is a more compact version:
fn try_parse_t(a: &str, negate: bool) -> Option<Self> {
let x = if let Some(a) = a.strip_prefix("#x") {
<$ty>::from_str_radix(a, 16).ok()?
} else if let Some(a) = a.strip_prefix("#b") {
<$ty>::from_str_radix(a , 2).ok()?
} else {
a.parse::<$ty>().ok()?
};
if negate {
return x.checked_neg();
}
Some(x)
}Added in 9b1ca34
fitzgen
left a comment
There was a problem hiding this comment.
Looks great modulo one final nitpick
Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com>
|
Fixed it :) |
fitzgen
left a comment
There was a problem hiding this comment.
Thanks! And thanks for going through multiple iterations of this PR
Description
This PR would add support for solutions that contain negative integers.
Currently, the problem with negative solutions is that the SMT solver will return for example
(x (- 2))a solution tox < 0. When callingget, this solution will be parsed into anSExprData::List. Callingtry_from_intwill then return always return the errorNotAnAtom.This PR introduces a new variant of
SExprData, which is a special case ofSExprData::List, which is returned for lists that contain exactly two atoms , where the first one is either+or-.Additionally it fixes typos in comments.
Minimal Test