Skip to content

Commit 15388a2

Browse files
DiegoCiviJulianGCalderongabrielbosio
authored
Fix comparison of bounded_int_constrain (#1480)
* Handle cmpi for bounded ints properly * Fix clippy * Refactor of tests * Refactor name tests * Update src/libfuncs/bounded_int.rs Co-authored-by: Julian Gonzalez Calderon <gonzalezcalderonjulian@gmail.com> --------- Co-authored-by: Julian Gonzalez Calderon <gonzalezcalderonjulian@gmail.com> Co-authored-by: Gabriel Bosio <38794644+gabrielbosio@users.noreply.github.com>
1 parent f003a2a commit 15388a2

File tree

1 file changed

+85
-208
lines changed

1 file changed

+85
-208
lines changed

src/libfuncs/bounded_int.rs

Lines changed: 85 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -659,17 +659,13 @@ fn build_constrain<'ctx, 'this>(
659659
entry.const_int_from_type(context, location, info.boundary.clone(), src_value.r#type())?
660660
};
661661

662-
let is_lower = entry.cmpi(
663-
context,
664-
if src_range.lower.sign() == Sign::Minus {
665-
CmpiPredicate::Slt
666-
} else {
662+
let cmpi_predicate =
663+
if src_ty.is_bounded_int(registry)? || src_range.lower.sign() != Sign::Minus {
667664
CmpiPredicate::Ult
668-
},
669-
src_value,
670-
boundary,
671-
location,
672-
)?;
665+
} else {
666+
CmpiPredicate::Slt
667+
};
668+
let is_lower = entry.cmpi(context, cmpi_predicate, src_value, boundary, location)?;
673669

674670
let lower_block = helper.append_block(Block::new(&[]));
675671
let upper_block = helper.append_block(Block::new(&[]));
@@ -883,10 +879,9 @@ fn build_wrap_non_zero<'ctx, 'this>(
883879

884880
#[cfg(test)]
885881
mod test {
886-
use cairo_lang_sierra::{extensions::utils::Range, program::Program};
882+
use cairo_lang_sierra::program::Program;
887883
use cairo_vm::Felt252;
888884
use lazy_static::lazy_static;
889-
use num_bigint::BigInt;
890885
use test_case::test_case;
891886

892887
use crate::{
@@ -1198,29 +1193,21 @@ mod test {
11981193
assert_bool_output(result, 0);
11991194
}
12001195

1201-
fn assert_constrain_output(result: Value, expected_bi: Value) {
1202-
if let Value::Enum { tag, value, .. } = result {
1203-
assert_eq!(tag, 0);
1204-
if let Value::Struct { fields, .. } = *value {
1205-
assert_eq!(expected_bi, fields[0]);
1206-
}
1207-
}
1208-
}
1209-
1210-
#[test]
1211-
fn test_constrain() {
1212-
let program = load_cairo! {
1196+
lazy_static! {
1197+
static ref TEST_CONSTRAIN_PROGRAM: (String, Program) = load_cairo! {
12131198
#[feature("bounded-int-utils")]
12141199
use core::internal::bounded_int::{self, BoundedInt, ConstrainHelper, constrain};
12151200

1216-
fn run_test_1(a: i8) -> BoundedInt<-128, -1> {
1201+
fn constrain_bi_m128_127_lt_0(a: felt252) -> BoundedInt<-128, -1> {
1202+
let a: i8 = a.try_into().unwrap();
12171203
match constrain::<i8, 0>(a) {
12181204
Ok(lt0) => lt0,
12191205
Err(_gt0) => panic!(),
12201206
}
12211207
}
12221208

1223-
fn run_test_2(a: i8) -> BoundedInt<0, 127> {
1209+
fn constrain_bi_m128_127_gt_0(a: felt252) -> BoundedInt<0, 127> {
1210+
let a: i8 = a.try_into().unwrap();
12241211
match constrain::<i8, 0>(a) {
12251212
Ok(_lt0) => panic!(),
12261213
Err(gt0) => gt0,
@@ -1232,19 +1219,19 @@ mod test {
12321219
type HighT = BoundedInt<5, 15>;
12331220
}
12341221

1235-
fn run_test_3(a: felt252) -> BoundedInt<0, 4> {
1222+
fn constrain_bi_0_15_lt_5(a: felt252) -> BoundedInt<0, 4> {
12361223
let a_bi: BoundedInt<0, 15> = a.try_into().unwrap();
12371224
match constrain::<_, 5>(a_bi) {
1238-
Ok(lt0) => lt0,
1239-
Err(_gt0) => panic!(),
1225+
Ok(lt) => lt,
1226+
Err(_gt) => panic!(),
12401227
}
12411228
}
12421229

1243-
fn run_test_4(a: felt252) -> BoundedInt<5, 15> {
1230+
fn constrain_bi_0_15_gt_5(a: felt252) -> BoundedInt<5, 15> {
12441231
let a_bi: BoundedInt<0, 15> = a.try_into().unwrap();
12451232
match constrain::<_, 5>(a_bi) {
1246-
Ok(_lt0) => panic!(),
1247-
Err(gt0) => gt0,
1233+
Ok(_lt) => panic!(),
1234+
Err(gt) => gt,
12481235
}
12491236
}
12501237

@@ -1253,15 +1240,15 @@ mod test {
12531240
type HighT = BoundedInt<0, 10>;
12541241
}
12551242

1256-
fn run_test_5(a: felt252) -> BoundedInt<-10, -1> {
1243+
fn constrain_bi_m10_10_lt_0(a: felt252) -> BoundedInt<-10, -1> {
12571244
let a_bi: BoundedInt<-10, 10> = a.try_into().unwrap();
12581245
match constrain::<_, 0>(a_bi) {
12591246
Ok(lt0) => lt0,
12601247
Err(_gt0) => panic!(),
12611248
}
12621249
}
12631250

1264-
fn run_test_6(a: felt252) -> BoundedInt<0, 10> {
1251+
fn constrain_bi_m10_10_gt_0(a: felt252) -> BoundedInt<0, 10> {
12651252
let a_bi: BoundedInt<-10, 10> = a.try_into().unwrap();
12661253
match constrain::<_, 0>(a_bi) {
12671254
Ok(_lt0) => panic!(),
@@ -1274,19 +1261,19 @@ mod test {
12741261
type HighT = BoundedInt<31, 61>;
12751262
}
12761263

1277-
fn run_test_7(a: felt252) -> BoundedInt<1, 30> {
1264+
fn constrain_bi_1_61_lt_31(a: felt252) -> BoundedInt<1, 30> {
12781265
let a_bi: BoundedInt<1, 61> = a.try_into().unwrap();
12791266
match constrain::<_, 31>(a_bi) {
1280-
Ok(lt0) => lt0,
1281-
Err(_gt0) => panic!(),
1267+
Ok(lt) => lt,
1268+
Err(_gt) => panic!(),
12821269
}
12831270
}
12841271

1285-
fn run_test_8(a: felt252) -> BoundedInt<31, 61> {
1272+
fn constrain_bi_1_61_gt_31(a: felt252) -> BoundedInt<31, 61> {
12861273
let a_bi: BoundedInt<1, 61> = a.try_into().unwrap();
12871274
match constrain::<_, 31>(a_bi) {
1288-
Ok(_lt0) => panic!(),
1289-
Err(gt0) => gt0,
1275+
Ok(_lt) => panic!(),
1276+
Err(gt) => gt,
12901277
}
12911278
}
12921279

@@ -1295,19 +1282,19 @@ mod test {
12951282
type HighT = BoundedInt<-150, -100>;
12961283
}
12971284

1298-
fn run_test_9(a: felt252) -> BoundedInt<-200, -151> {
1285+
fn constrain_bi_m200_m100_lt_m150(a: felt252) -> BoundedInt<-200, -151> {
12991286
let a_bi: BoundedInt<-200, -100> = a.try_into().unwrap();
13001287
match constrain::<_, -150>(a_bi) {
1301-
Ok(lt0) => lt0,
1302-
Err(_gt0) => panic!(),
1288+
Ok(lt) => lt,
1289+
Err(_gt) => panic!(),
13031290
}
13041291
}
13051292

1306-
fn run_test_10(a: felt252) -> BoundedInt<-150, -100> {
1293+
fn constrain_bi_m200_m100_gt_m150(a: felt252) -> BoundedInt<-150, -100> {
13071294
let a_bi: BoundedInt<-200, -100> = a.try_into().unwrap();
13081295
match constrain::<_, -150>(a_bi) {
1309-
Ok(_lt0) => panic!(),
1310-
Err(gt0) => gt0,
1296+
Ok(_lt) => panic!(),
1297+
Err(gt) => gt,
13111298
}
13121299
}
13131300

@@ -1316,179 +1303,69 @@ mod test {
13161303
type HighT = BoundedInt<100, 100>;
13171304
}
13181305

1319-
fn run_test_11(a: felt252) -> BoundedInt<100, 100> {
1306+
fn constrain_bi_30_100_gt_100(a: felt252) -> BoundedInt<100, 100> {
13201307
let a_bi: BoundedInt<30, 100> = a.try_into().unwrap();
13211308
match constrain::<_, 100>(a_bi) {
1322-
Ok(_lt0) => panic!(),
1323-
Err(gt0) => gt0,
1309+
Ok(_lt) => panic!(),
1310+
Err(gt) => gt,
13241311
}
13251312
}
1326-
};
1327-
1328-
let result = run_program(&program, "run_test_1", &[Value::Sint8(-1)]).return_value;
1329-
assert_constrain_output(
1330-
result,
1331-
Value::BoundedInt {
1332-
value: Felt252::from(-1),
1333-
range: Range {
1334-
lower: BigInt::from(-128),
1335-
upper: BigInt::from(0),
1336-
},
1337-
},
1338-
);
1339-
1340-
let result = run_program(&program, "run_test_2", &[Value::Sint8(1)]).return_value;
1341-
assert_constrain_output(
1342-
result,
1343-
Value::BoundedInt {
1344-
value: Felt252::from(1),
1345-
range: Range {
1346-
lower: BigInt::from(0),
1347-
upper: BigInt::from(128),
1348-
},
1349-
},
1350-
);
1351-
1352-
let result = run_program(&program, "run_test_2", &[Value::Sint8(0)]).return_value;
1353-
assert_constrain_output(
1354-
result,
1355-
Value::BoundedInt {
1356-
value: Felt252::from(0),
1357-
range: Range {
1358-
lower: BigInt::from(0),
1359-
upper: BigInt::from(128),
1360-
},
1361-
},
1362-
);
1363-
1364-
let result =
1365-
run_program(&program, "run_test_3", &[Value::Felt252(Felt252::from(0))]).return_value;
1366-
assert_constrain_output(
1367-
result,
1368-
Value::BoundedInt {
1369-
value: Felt252::from(0),
1370-
range: Range {
1371-
lower: BigInt::from(0),
1372-
upper: BigInt::from(5),
1373-
},
1374-
},
1375-
);
1376-
1377-
let result =
1378-
run_program(&program, "run_test_4", &[Value::Felt252(Felt252::from(15))]).return_value;
1379-
assert_constrain_output(
1380-
result,
1381-
Value::BoundedInt {
1382-
value: Felt252::from(15),
1383-
range: Range {
1384-
lower: BigInt::from(5),
1385-
upper: BigInt::from(16),
1386-
},
1387-
},
1388-
);
13891313

1390-
let result =
1391-
run_program(&program, "run_test_5", &[Value::Felt252(Felt252::from(-5))]).return_value;
1392-
assert_constrain_output(
1393-
result,
1394-
Value::BoundedInt {
1395-
value: Felt252::from(-5),
1396-
range: Range {
1397-
lower: BigInt::from(-10),
1398-
upper: BigInt::from(0),
1399-
},
1400-
},
1401-
);
1402-
1403-
let result =
1404-
run_program(&program, "run_test_6", &[Value::Felt252(Felt252::from(5))]).return_value;
1405-
assert_constrain_output(
1406-
result,
1407-
Value::BoundedInt {
1408-
value: Felt252::from(5),
1409-
range: Range {
1410-
lower: BigInt::from(0),
1411-
upper: BigInt::from(11),
1412-
},
1413-
},
1414-
);
1415-
1416-
let result =
1417-
run_program(&program, "run_test_7", &[Value::Felt252(Felt252::from(30))]).return_value;
1418-
assert_constrain_output(
1419-
result,
1420-
Value::BoundedInt {
1421-
value: Felt252::from(30),
1422-
range: Range {
1423-
lower: BigInt::from(1),
1424-
upper: BigInt::from(31),
1425-
},
1426-
},
1427-
);
1428-
1429-
let result =
1430-
run_program(&program, "run_test_8", &[Value::Felt252(Felt252::from(31))]).return_value;
1431-
assert_constrain_output(
1432-
result,
1433-
Value::BoundedInt {
1434-
value: Felt252::from(31),
1435-
range: Range {
1436-
lower: BigInt::from(31),
1437-
upper: BigInt::from(62),
1438-
},
1439-
},
1440-
);
1314+
impl ConstrainTest6 of ConstrainHelper<BoundedInt<-30, 31>, 0> {
1315+
type LowT = BoundedInt<-30, -1>;
1316+
type HighT = BoundedInt<0, 31>;
1317+
}
14411318

1442-
let result = run_program(
1443-
&program,
1444-
"run_test_9",
1445-
&[Value::Felt252(Felt252::from(-200))],
1446-
)
1447-
.return_value;
1448-
assert_constrain_output(
1449-
result,
1450-
Value::BoundedInt {
1451-
value: Felt252::from(-200),
1452-
range: Range {
1453-
lower: BigInt::from(-200),
1454-
upper: BigInt::from(-150),
1455-
},
1456-
},
1457-
);
1319+
fn constrain_bi_m30_31_lt_0(a: felt252) -> BoundedInt<-30, -1> {
1320+
let a_bi: BoundedInt<-30, 31> = a.try_into().unwrap();
1321+
match constrain::<_, 0>(a_bi) {
1322+
Ok(lt0) => lt0,
1323+
Err(_gt0) => panic!(),
1324+
}
1325+
}
14581326

1459-
let result = run_program(
1460-
&program,
1461-
"run_test_10",
1462-
&[Value::Felt252(Felt252::from(-150))],
1463-
)
1464-
.return_value;
1465-
assert_constrain_output(
1466-
result,
1467-
Value::BoundedInt {
1468-
value: Felt252::from(-150),
1469-
range: Range {
1470-
lower: BigInt::from(-150),
1471-
upper: BigInt::from(-99),
1472-
},
1473-
},
1474-
);
1327+
fn constrain_bi_m30_31_gt_0(a: felt252) -> BoundedInt<0, 31> {
1328+
let a_bi: BoundedInt<-30, 31> = a.try_into().unwrap();
1329+
match constrain::<_, 0>(a_bi) {
1330+
Ok(_lt0) => panic!(),
1331+
Err(gt0) => gt0,
1332+
}
1333+
}
1334+
};
1335+
}
14751336

1337+
#[test_case("constrain_bi_m128_127_lt_0", -1, -1)]
1338+
#[test_case("constrain_bi_m128_127_gt_0", 1, 1)]
1339+
#[test_case("constrain_bi_m128_127_gt_0", 0, 0)]
1340+
#[test_case("constrain_bi_0_15_lt_5", 0, 0)]
1341+
#[test_case("constrain_bi_0_15_gt_5", 15, 15)]
1342+
#[test_case("constrain_bi_m10_10_lt_0", -5, -5)]
1343+
#[test_case("constrain_bi_m10_10_gt_0", 5, 5)]
1344+
#[test_case("constrain_bi_1_61_lt_31", 30, 30)]
1345+
#[test_case("constrain_bi_1_61_gt_31", 31, 31)]
1346+
#[test_case("constrain_bi_m200_m100_lt_m150", -200, -200)]
1347+
#[test_case("constrain_bi_m200_m100_gt_m150", -150, -150)]
1348+
#[test_case("constrain_bi_30_100_gt_100", 100, 100)]
1349+
#[test_case("constrain_bi_m30_31_lt_0", -5, -5)]
1350+
#[test_case("constrain_bi_m30_31_gt_0", 5, 5)]
1351+
fn test_constrain(entry_point: &str, input: i32, expected_result: i32) {
14761352
let result = run_program(
1477-
&program,
1478-
"run_test_11",
1479-
&[Value::Felt252(Felt252::from(100))],
1353+
&TEST_CONSTRAIN_PROGRAM,
1354+
entry_point,
1355+
&[Value::Felt252(Felt252::from(input))],
14801356
)
14811357
.return_value;
1482-
assert_constrain_output(
1483-
result,
1484-
Value::BoundedInt {
1485-
value: Felt252::from(100),
1486-
range: Range {
1487-
lower: BigInt::from(100),
1488-
upper: BigInt::from(101),
1489-
},
1490-
},
1491-
);
1358+
if let Value::Enum { value, .. } = result {
1359+
if let Value::Struct { fields, .. } = *value {
1360+
assert!(
1361+
matches!(fields[0], Value::BoundedInt { value, .. } if value == Felt252::from(expected_result))
1362+
)
1363+
} else {
1364+
panic!("Test returned an unexpected value");
1365+
}
1366+
} else {
1367+
panic!("Test didn't return an enum as expected");
1368+
}
14921369
}
14931370

14941371
lazy_static! {

0 commit comments

Comments
 (0)