@@ -365,7 +365,9 @@ impl<'a> EncoderCtx<'a> {
365365 BinOp :: Eq => self . encode_eq ( left, right) ,
366366 BinOp :: Ne => {
367367 let eq = self . encode_eq ( left, right) ?;
368- let eq_bool = eq. as_bool ( ) . unwrap ( ) ;
368+ let eq_bool = eq. as_bool ( ) . ok_or_else ( || {
369+ SymbolicError :: Encoding ( "!= comparison: equality did not produce Bool" . into ( ) )
370+ } ) ?;
369371 Ok ( Dynamic :: from_ast ( & eq_bool. not ( ) ) )
370372 }
371373 BinOp :: Lt => {
@@ -859,10 +861,15 @@ impl<'a> EncoderCtx<'a> {
859861 VarKind :: ExplodedSet { .. } => {
860862 let one = Int :: from_i64 ( 1 ) ;
861863 let zero = Int :: from_i64 ( 0 ) ;
862- let terms: Vec < Int > = vars
863- . iter ( )
864- . map ( |v| v. as_bool ( ) . unwrap ( ) . ite ( & one, & zero) )
865- . collect ( ) ;
864+ let mut terms = Vec :: with_capacity ( vars. len ( ) ) ;
865+ for v in vars {
866+ let b = v. as_bool ( ) . ok_or_else ( || {
867+ SymbolicError :: Encoding (
868+ "set length: expected Bool Z3 variable for set element" . into ( ) ,
869+ )
870+ } ) ?;
871+ terms. push ( b. ite ( & one, & zero) ) ;
872+ }
866873 Ok ( Dynamic :: from_ast ( & Int :: add ( & terms) ) )
867874 }
868875 VarKind :: ExplodedDict { key_lo, key_hi, .. } => {
@@ -967,10 +974,15 @@ impl<'a> EncoderCtx<'a> {
967974 let z3_vars = & self . step_vars [ step] [ * idx] ;
968975 let one = Int :: from_i64 ( 1 ) ;
969976 let zero = Int :: from_i64 ( 0 ) ;
970- let terms: Vec < Int > = z3_vars
971- . iter ( )
972- . map ( |v| v. as_bool ( ) . unwrap ( ) . ite ( & one, & zero) )
973- . collect ( ) ;
977+ let mut terms = Vec :: with_capacity ( z3_vars. len ( ) ) ;
978+ for v in z3_vars {
979+ let b = v. as_bool ( ) . ok_or_else ( || {
980+ SymbolicError :: Encoding (
981+ "set len: expected Bool Z3 variable" . into ( ) ,
982+ )
983+ } ) ?;
984+ terms. push ( b. ite ( & one, & zero) ) ;
985+ }
974986 Ok ( Dynamic :: from_ast ( & Int :: add ( & terms) ) )
975987 }
976988 VarKind :: ExplodedSeq { .. } => {
@@ -1078,7 +1090,11 @@ impl<'a> EncoderCtx<'a> {
10781090 if let Some ( concrete_elem) = self . try_concrete_int ( elem) {
10791091 let offset = ( concrete_elem - lo) as usize ;
10801092 let result = if offset < z3_vars. len ( ) {
1081- z3_vars[ offset] . as_bool ( ) . unwrap ( )
1093+ z3_vars[ offset] . as_bool ( ) . ok_or_else ( || {
1094+ SymbolicError :: Encoding (
1095+ "set membership: expected Bool for set element" . into ( ) ,
1096+ )
1097+ } ) ?
10821098 } else {
10831099 Bool :: from_bool ( false )
10841100 } ;
@@ -1087,7 +1103,11 @@ impl<'a> EncoderCtx<'a> {
10871103 } else {
10881104 let elem_z3 = self . encode_int ( elem) ?;
10891105 let result = Self :: build_ite_chain ( & elem_z3, z3_vars, lo) ?;
1090- let result_bool = result. as_bool ( ) . unwrap ( ) ;
1106+ let result_bool = result. as_bool ( ) . ok_or_else ( || {
1107+ SymbolicError :: Encoding (
1108+ "set membership: ITE chain did not produce Bool" . into ( ) ,
1109+ )
1110+ } ) ?;
10911111 let final_val = if negate {
10921112 result_bool. not ( )
10931113 } else {
@@ -1328,7 +1348,11 @@ impl<'a> EncoderCtx<'a> {
13281348 if let Some ( concrete_elem) = self . try_concrete_int ( elem) {
13291349 let offset = ( concrete_elem - lo) as usize ;
13301350 let result = if offset < set_vars. len ( ) {
1331- set_vars[ offset] . as_bool ( ) . unwrap ( )
1351+ set_vars[ offset] . as_bool ( ) . ok_or_else ( || {
1352+ SymbolicError :: Encoding (
1353+ "nested set membership: expected Bool" . into ( ) ,
1354+ )
1355+ } ) ?
13321356 } else {
13331357 Bool :: from_bool ( false )
13341358 } ;
@@ -1337,7 +1361,11 @@ impl<'a> EncoderCtx<'a> {
13371361 } else {
13381362 let elem_z3 = self . encode_int ( elem) ?;
13391363 let result = Self :: build_ite_chain ( & elem_z3, set_vars, lo) ?;
1340- let result_bool = result. as_bool ( ) . unwrap ( ) ;
1364+ let result_bool = result. as_bool ( ) . ok_or_else ( || {
1365+ SymbolicError :: Encoding (
1366+ "nested set membership: ITE chain did not produce Bool" . into ( ) ,
1367+ )
1368+ } ) ?;
13411369 let final_val = if negate {
13421370 result_bool. not ( )
13431371 } else {
@@ -1370,7 +1398,12 @@ impl<'a> EncoderCtx<'a> {
13701398 let z3_vars: Vec < Dynamic > =
13711399 flags. iter ( ) . map ( |b| Dynamic :: from_ast ( b) ) . collect ( ) ;
13721400 let result = Self :: build_ite_chain ( & elem_z3, & z3_vars, lo) ?;
1373- let result_bool = result. as_bool ( ) . unwrap ( ) ;
1401+ let result_bool = result. as_bool ( ) . ok_or_else ( || {
1402+ SymbolicError :: Encoding (
1403+ "set expression membership: ITE chain did not produce Bool"
1404+ . into ( ) ,
1405+ )
1406+ } ) ?;
13741407 let final_val = if negate {
13751408 result_bool. not ( )
13761409 } else {
@@ -1673,8 +1706,12 @@ impl<'a> EncoderCtx<'a> {
16731706
16741707 let mut conjuncts = Vec :: new ( ) ;
16751708 // len equality
1676- let l_len = l_vars[ 0 ] . as_int ( ) . unwrap ( ) ;
1677- let r_len = r_vars[ 0 ] . as_int ( ) . unwrap ( ) ;
1709+ let l_len = l_vars[ 0 ] . as_int ( ) . ok_or_else ( || {
1710+ SymbolicError :: Encoding ( "seq equality: left seq len is not Int" . into ( ) )
1711+ } ) ?;
1712+ let r_len = r_vars[ 0 ] . as_int ( ) . ok_or_else ( || {
1713+ SymbolicError :: Encoding ( "seq equality: right seq len is not Int" . into ( ) )
1714+ } ) ?;
16781715 conjuncts. push ( l_len. eq ( & r_len) ) ;
16791716 // element equality (for all positions up to max_len)
16801717 for i in 0 ..max_len {
@@ -1750,7 +1787,16 @@ impl<'a> EncoderCtx<'a> {
17501787 _ => self . next_step ,
17511788 } ;
17521789 let z3_vars = & self . step_vars [ step] [ * idx] ;
1753- Ok ( z3_vars. iter ( ) . map ( |v| v. as_bool ( ) . unwrap ( ) ) . collect ( ) )
1790+ z3_vars
1791+ . iter ( )
1792+ . map ( |v| {
1793+ v. as_bool ( ) . ok_or_else ( || {
1794+ SymbolicError :: Encoding (
1795+ "encode_as_set: expected Bool Z3 variable for set element" . into ( ) ,
1796+ )
1797+ } )
1798+ } )
1799+ . collect :: < SymbolicResult < Vec < _ > > > ( )
17541800 }
17551801 CompiledExpr :: SetLit ( elements) => {
17561802 let mut flags = vec ! [ Bool :: from_bool( false ) ; count] ;
@@ -2074,13 +2120,13 @@ pub fn assert_range_constraints(
20742120fn assert_var_range ( solver : & Solver , kind : & VarKind , z3_vars : & [ Dynamic ] ) {
20752121 match kind {
20762122 VarKind :: Int { lo, hi } => {
2077- if let Some ( lo ) = lo {
2078- let z3_lo = Int :: from_i64 ( * lo ) ;
2079- solver. assert ( z3_vars [ 0 ] . as_int ( ) . unwrap ( ) . ge ( & z3_lo ) ) ;
2080- }
2081- if let Some ( hi) = hi {
2082- let z3_hi = Int :: from_i64 ( * hi) ;
2083- solver . assert ( z3_vars [ 0 ] . as_int ( ) . unwrap ( ) . le ( & z3_hi ) ) ;
2123+ if let Some ( int_var ) = z3_vars . first ( ) . and_then ( |v| v . as_int ( ) ) {
2124+ if let Some ( lo ) = lo {
2125+ solver. assert ( int_var . ge ( Int :: from_i64 ( * lo ) ) ) ;
2126+ }
2127+ if let Some ( hi) = hi {
2128+ solver . assert ( int_var . le ( Int :: from_i64 ( * hi) ) ) ;
2129+ }
20842130 }
20852131 }
20862132 VarKind :: ExplodedDict {
@@ -2097,9 +2143,10 @@ fn assert_var_range(solver: &Solver, kind: &VarKind, z3_vars: &[Dynamic]) {
20972143 }
20982144 VarKind :: ExplodedSeq { max_len, elem_kind } => {
20992145 // len bounded: 0 <= len <= max_len
2100- let len_var = z3_vars[ 0 ] . as_int ( ) . unwrap ( ) ;
2101- solver. assert ( len_var. ge ( Int :: from_i64 ( 0 ) ) ) ;
2102- solver. assert ( len_var. le ( Int :: from_i64 ( * max_len as i64 ) ) ) ;
2146+ if let Some ( len_var) = z3_vars. first ( ) . and_then ( |v| v. as_int ( ) ) {
2147+ solver. assert ( len_var. ge ( Int :: from_i64 ( 0 ) ) ) ;
2148+ solver. assert ( len_var. le ( Int :: from_i64 ( * max_len as i64 ) ) ) ;
2149+ }
21032150 // Element range constraints
21042151 let elem_stride = elem_kind. z3_var_count ( ) ;
21052152 for i in 0 ..* max_len {
0 commit comments