Skip to content

Commit 8d418d9

Browse files
committed
added str.at support
1 parent 8d953b3 commit 8d418d9

1 file changed

Lines changed: 53 additions & 8 deletions

File tree

src/smt/parse.rs

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,16 +1393,18 @@ impl SmtParser {
13931393
_ => Err(SmtParseError::unrecog(head)),
13941394
}
13951395
}
1396-
/*(TokenTypes::StrTok(str_token), TokenTypes::Other(val))
1396+
(TokenTypes::StrTok(str_token), TokenTypes::Other(val))
13971397
| (TokenTypes::Other(val), TokenTypes::StrTok(str_token)) => {
1398-
let str_re=Self::strtok_to_re(&str_token)?;
1398+
println!("yipppeeee");
1399+
let str_re = Self::strtok_to_re(&str_token)?;
13991400
let (head, tail) = val.as_pair().ok_or(SmtParseError::unrecog(&val))?;
14001401
let cmd = head.as_symbol().ok_or(SmtParseError::unrecog(head))?;
14011402
match cmd {
1402-
"str.at" => todo!(),
1403+
"str.at" => self.parse_str_at(tail, str_re),
1404+
"str.substr" => self.parse_substr(&val, &str_re),
14031405
_ => Err(SmtParseError::unrecog(head)),
14041406
}
1405-
}*/
1407+
}
14061408
// TODO: remove exhaustive fallback pattern
14071409
_ => {
14081410
if arg1.is_number() && self.is_length_operation(arg2) {
@@ -1421,11 +1423,13 @@ impl SmtParser {
14211423
.as_i64()
14221424
.expect("Should be a number"),
14231425
)
1424-
} else if arg1.is_string() && self.is_substr_operation(arg2) {
1426+
}
1427+
/*else if arg1.is_string() && self.is_substr_operation(arg2) {
14251428
self.parse_substr(arg2, arg1)
14261429
} else if arg2.is_string() && self.is_substr_operation(arg1) {
14271430
self.parse_substr(arg1, arg2)
1428-
} else {
1431+
} */
1432+
else {
14291433
let parsed1 = if arg1.is_string() {
14301434
Self::strtok_to_retok(&self.parse_string_expr(arg1)?)?
14311435
} else {
@@ -1819,8 +1823,9 @@ impl SmtParser {
18191823
fn parse_substr(
18201824
&mut self,
18211825
substr_value: &Value,
1822-
str_value: &Value,
1826+
string_gre: &Rc<GenRegex>,
18231827
) -> Result<Rc<GenRegex>, SmtParseError> {
1828+
println!("{}", substr_value);
18241829
// NB: We discussed the following issue in meeting on 2025-06-11.
18251830
// We should debug the case benchmarks/usr/explicit/substr_sat.smt2
18261831
// and benchmarks/usr/implicit/substr_sat.smt2 to see why we are failing.
@@ -1832,7 +1837,7 @@ impl SmtParser {
18321837
//TODO: the same idea might need to be applied to all equals expressions, not sure though,
18331838
//worth checking out
18341839
//parses expressions of the form (= (str.substr s1 i j) s2)
1835-
let string_gre = self.parse_string_to_gre(str_value)?; //Parse s2
1840+
//let string_gre = self.parse_string_to_gre(str_value)?; //Parse s2
18361841
let args = self.get_args(substr_value)?;
18371842
let big_string_gre = self.parse_string_to_gre(args[1])?; //Parse s1
18381843
let i_len = args[2]
@@ -2356,6 +2361,46 @@ impl SmtParser {
23562361
}
23572362
}
23582363

2364+
fn parse_str_at(
2365+
&mut self,
2366+
args: &Value,
2367+
found_str: Rc<GenRegex>,
2368+
) -> Result<Rc<GenRegex>, SmtParseError> {
2369+
println!("We made it to str.at!!!");
2370+
let arg_vec = self.get_args(args)?;
2371+
if arg_vec.len() != 2 {
2372+
return Err(SmtParseError::unexpected(args, "2 arguments for str.at"));
2373+
}
2374+
let string = Self::strtok_to_re(&self.parse_string_expr(arg_vec[0])?)?;
2375+
let IntToken::Val(index) = self.parse_int_expr(arg_vec[1])? else {
2376+
return Err(SmtParseError::unsupported(arg_vec[1]));
2377+
};
2378+
println!("{},{},{}", string, index, found_str);
2379+
let found_str_constraint1 =
2380+
GenRegex::intersect(&found_str.clone(), &GenRegex::create_sigma());
2381+
let args = [
2382+
GenRegex::caret(index as u64, &GenRegex::create_sigma()),
2383+
found_str.clone(),
2384+
GenRegex::sigma_star(),
2385+
];
2386+
let string_constraint1 =
2387+
GenRegex::intersect(&string.clone(), &GenRegex::concat_many(&args));
2388+
let constraint1 =
2389+
GenRegex::concat(&string_constraint1.clone(), &found_str_constraint1.clone());
2390+
println!("{}", constraint1);
2391+
let constraint2 = GenRegex::concat(
2392+
&GenRegex::intersect(
2393+
&string.clone(),
2394+
&GenRegex::complement(&GenRegex::concat(
2395+
&GenRegex::caret(index as u64, &GenRegex::create_sigma()),
2396+
&GenRegex::sigma_star(),
2397+
)),
2398+
),
2399+
&GenRegex::intersect(&found_str, &GenRegex::epsilon()),
2400+
);
2401+
println!("{}", constraint2);
2402+
Ok(GenRegex::union(&constraint1, &constraint2))
2403+
}
23592404
/*
23602405
Parsing functions with output Int
23612406
*/

0 commit comments

Comments
 (0)