From af95ec142484fca2fdc9fd6f332882b0ead12d38 Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Thu, 11 Apr 2024 11:56:19 -0400 Subject: [PATCH 01/23] fix: change cargo test profile to get correct times in benchmark --- egg-pre-dcp/Cargo.toml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/egg-pre-dcp/Cargo.toml b/egg-pre-dcp/Cargo.toml index 647fbcfa..c68845d9 100644 --- a/egg-pre-dcp/Cargo.toml +++ b/egg-pre-dcp/Cargo.toml @@ -23,7 +23,12 @@ intervals-good = "0.1.1" [profile.test] debug = true -opt-level = 1 +lto = "fat" +codegen-units = 1 +opt-level = 3 +debug-assertions = false +overflow-checks = false +incremental = false [profile.release] debug = true From 17c6ca88f434b6ae129ad400e2856eef28b99cab Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Fri, 12 Apr 2024 12:13:16 -0400 Subject: [PATCH 02/23] test: all add and mul tests on critical intervals --- egg-pre-dcp/tests/test_domain.rs | 151 ++++++++++++++++++++++++++----- 1 file changed, 129 insertions(+), 22 deletions(-) diff --git a/egg-pre-dcp/tests/test_domain.rs b/egg-pre-dcp/tests/test_domain.rs index 1362471d..b9281335 100644 --- a/egg-pre-dcp/tests/test_domain.rs +++ b/egg-pre-dcp/tests/test_domain.rs @@ -18,7 +18,7 @@ use domain::Domain as Domain; */ -// Addition (10 tests, commutative). +// Addition (16 tests). #[test] fn add_pos_pos() { @@ -52,6 +52,14 @@ fn add_pos_neg() { assert!(result.eq(&expected)); } +#[test] +fn add_nonneg_pos() { + // [0, +inf) + (0, +inf) = (0, +inf) + let result = domain::add(&domain::nonneg_dom(), &domain::pos_dom()); + let expected = domain::pos_dom(); + assert!(result.eq(&expected)); +} + #[test] fn add_nonneg_nonneg() { // [0, +inf) + [0, +inf) = [0, +inf) @@ -76,6 +84,22 @@ fn add_nonneg_neg() { assert!(result.eq(&expected)); } +#[test] +fn add_nonpos_pos() { + // (-inf, 0] + (0, +inf) = (-inf, +inf) + let result = domain::add(&domain::nonpos_dom(), &domain::pos_dom()); + let expected = domain::free_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn add_nonpos_nonneg() { + // (-inf, 0] + [0, +inf) = (-inf, +inf) + let result = domain::add(&domain::nonpos_dom(), &domain::nonneg_dom()); + let expected = domain::free_dom(); + assert!(result.eq(&expected)); +} + #[test] fn add_nonpos_nonpos() { // (-inf, 0] + (-inf, 0] = (-inf, 0] @@ -92,6 +116,30 @@ fn add_nonpos_neg() { assert!(result.eq(&expected)); } +#[test] +fn add_neg_pos() { + // (-inf, 0) + (0, +inf) = (-inf, +inf) + let result = domain::add(&domain::neg_dom(), &domain::pos_dom()); + let expected = domain::free_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn add_neg_nonneg() { + // (-inf, 0) + [0, +inf) = (-inf, +inf) + let result = domain::add(&domain::neg_dom(), &domain::nonneg_dom()); + let expected = domain::free_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn add_neg_nonpos() { + // (-inf, 0) + (-inf, 0] = (-inf, 0) + let result = domain::add(&domain::neg_dom(), &domain::nonpos_dom()); + let expected = domain::neg_dom(); + assert!(result.eq(&expected)); +} + #[test] fn add_neg_neg() { // (-inf, 0) + (-inf, 0) = (-inf, 0) @@ -101,7 +149,7 @@ fn add_neg_neg() { } -// Multiplication (16 tests, commutative). +// Multiplication (16 tests). #[test] fn mul_pos_pos() { @@ -136,6 +184,14 @@ fn mul_pos_neg() { assert!(result.eq(&expected)); } +#[test] +fn mul_nonneg_pos() { + // [0, +inf) * (0, +inf) = [0, +inf) + let result = domain::mul(&domain::nonneg_dom(), &domain::pos_dom()); + let expected = domain::nonneg_dom(); + assert!(result.eq(&expected)); +} + #[test] fn mul_nonneg_nonneg() { // [0, +inf) * [0, +inf) = [0, +inf) @@ -160,6 +216,22 @@ fn mul_nonneg_neg() { assert!(result.eq(&expected)); } +#[test] +fn mul_nonpos_pos() { + // (-inf, 0] * (0, +inf) = (-inf, 0] + let result = domain::mul(&domain::nonpos_dom(), &domain::pos_dom()); + let expected = domain::nonpos_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn mul_nonnpos_nonneg() { + // (-inf, 0] * [0, +inf) = (-inf, 0] + let result = domain::mul(&domain::nonpos_dom(), &domain::nonneg_dom()); + let expected = domain::nonpos_dom(); + assert!(result.eq(&expected)); +} + #[test] fn mul_nonpos_nonpos() { // (-inf, 0] * (-inf, 0] = [0, +inf) @@ -177,24 +249,40 @@ fn mul_nonpos_neg() { } #[test] -fn mul_neg_neg() { - // (-inf, 0) * (-inf, 0) = (0, +inf) - let result = domain::mul(&domain::neg_dom(), &domain::neg_dom()); - let expected = domain::pos_dom(); +fn mul_neg_pos() { + // (-inf, 0) * (0, +inf) = (-inf, 0) + let result = domain::mul(&domain::neg_dom(), &domain::pos_dom()); + let expected = domain::neg_dom(); assert!(result.eq(&expected)); } +#[test] +fn mul_neg_nonneg() { + // (-inf, 0) * [0, +inf) = (-inf, 0] + let result = domain::mul(&domain::neg_dom(), &domain::nonneg_dom()); + let expected = domain::nonpos_dom(); + assert!(result.eq(&expected)); +} -// Subtraction (16 tests, not commutative). +#[test] +fn mul_neg_nonpos() { + // (-inf, 0) * (-inf, 0] = [0, +inf) + let result = domain::mul(&domain::neg_dom(), &domain::nonpos_dom()); + let expected = domain::nonneg_dom(); + assert!(result.eq(&expected)); +} #[test] -fn sub_pos_pos() { - // (0, +inf) - (0, +inf) = (-inf, +inf) - let result = domain::sub(&domain::pos_dom(), &domain::pos_dom()); - let expected = domain::free_dom(); +fn mul_neg_neg() { + // (-inf, 0) * (-inf, 0) = (0, +inf) + let result = domain::mul(&domain::neg_dom(), &domain::neg_dom()); + let expected = domain::pos_dom(); assert!(result.eq(&expected)); } + +// Subtraction (16 tests). + #[test] fn sub_pos_nonneg() { // (0, +inf) - [0, +inf) = (-inf, +inf) @@ -316,7 +404,7 @@ fn sub_neg_neg() { } -// Division (17 tests, not commutative). +// Division (16 tests). #[test] fn div_pos_pos() { @@ -446,15 +534,8 @@ fn div_neg_neg() { assert!(result.eq(&expected)); } -#[test] -fn div_free_pos() { - // (-inf, +inf) / (-inf, 0) = (-inf, +inf) - let result = domain::div(&domain::free_dom(), &domain::neg_dom()); - let expected = domain::free_dom(); - assert!(result.eq(&expected)); -} -// Powers (16 tests, not commutative). +// Powers (16 tests). #[test] fn pow_pos_pos() { @@ -587,8 +668,18 @@ fn pow_neg_neg() { /* Other tests. */ + + +#[test] +fn div_free_pos() { + // (-inf, +inf) / (-inf, 0) = (-inf, +inf) + let result = domain::div(&domain::free_dom(), &domain::neg_dom()); + let expected = domain::free_dom(); + assert!(result.eq(&expected)); +} + #[test] -fn one_div_pos() { +fn div_one_pos() { // [1, 1] / (0, +inf) = (0, +inf) let result = domain::div(&Domain::make_singleton(1.0), &domain::pos_dom()); let expected = domain::pos_dom(); @@ -596,6 +687,9 @@ fn one_div_pos() { } +/* More power tests. */ + + /* Logarithm tests. */ #[test] @@ -689,7 +783,14 @@ fn exp_neg() { assert!(result.eq(&expected)); } -/* Checkers tests. TODO: more. */ + +/* Checkers tests. */ + +// is_zero + +// is_one + +// is_pos #[test] fn is_nonneg_1() { @@ -697,4 +798,10 @@ fn is_nonneg_1() { assert!(domain::is_nonneg(&Domain::make_singleton(1.0))); } +// is_nonpos + +// is_neg + +// does_not_contain_zero + } From bb7ceb6c99e1a96dd3f504eeabe4e4081f7f42b8 Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Fri, 12 Apr 2024 15:48:07 -0400 Subject: [PATCH 03/23] wip: planning more domain tests --- egg-pre-dcp/src/domain.rs | 1 - egg-pre-dcp/tests/test_domain.rs | 113 +++++++++++++++++++------------ 2 files changed, 71 insertions(+), 43 deletions(-) diff --git a/egg-pre-dcp/src/domain.rs b/egg-pre-dcp/src/domain.rs index 7d752a94..9b9c24ea 100644 --- a/egg-pre-dcp/src/domain.rs +++ b/egg-pre-dcp/src/domain.rs @@ -638,7 +638,6 @@ fn perform_mult( } // For multiplication, opennes of endpoints depends on the values. -// NOTE(RFM): For the case splitting part, c.f. with `classify`. pub fn mul(d1: &Domain, d2: &Domain) -> Domain { let d1_pos = is_pos(d1); let d1_neg = is_neg(d1); diff --git a/egg-pre-dcp/tests/test_domain.rs b/egg-pre-dcp/tests/test_domain.rs index b9281335..9aaf2b3a 100644 --- a/egg-pre-dcp/tests/test_domain.rs +++ b/egg-pre-dcp/tests/test_domain.rs @@ -10,12 +10,39 @@ use egg_pre_dcp::domain; use domain::Domain as Domain; -/* Tests for +, *, -, / and ^ on critical intervals: - * Positive (0, +inf), - * Non-negative [0, +inf), - * Non-positive (-inf, 0], - * Negative (-inf, 0). -*/ + +/* Some useful intervals for testing apart from pos, nonneg, nonpos, neg. */ + +// gt_one + +// ge_one + +fn gt_two_lt_three() { + Domain::make_oo(domain::make_float(2.0), domain::make_float(3.0)); +} + +// TODO: more + + + +/* Operations */ + + +// Negation (TODO). + + +// Absolute value (TODO). + + + + +// Square root (TODO). + + +// Min (TODO). + + +// Max (TODO). // Addition (16 tests). @@ -404,7 +431,7 @@ fn sub_neg_neg() { } -// Division (16 tests). +// Division (18 tests). #[test] fn div_pos_pos() { @@ -534,8 +561,24 @@ fn div_neg_neg() { assert!(result.eq(&expected)); } +#[test] +fn div_free_pos() { + // (-inf, +inf) / (-inf, 0) = (-inf, +inf) + let result = domain::div(&domain::free_dom(), &domain::neg_dom()); + let expected = domain::free_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn div_one_pos() { + // [1, 1] / (0, +inf) = (0, +inf) + let result = domain::div(&Domain::make_singleton(1.0), &domain::pos_dom()); + let expected = domain::pos_dom(); + assert!(result.eq(&expected)); +} + -// Powers (16 tests). +// Power (16 tests). #[test] fn pow_pos_pos() { @@ -666,31 +709,7 @@ fn pow_neg_neg() { } -/* Other tests. */ - - - -#[test] -fn div_free_pos() { - // (-inf, +inf) / (-inf, 0) = (-inf, +inf) - let result = domain::div(&domain::free_dom(), &domain::neg_dom()); - let expected = domain::free_dom(); - assert!(result.eq(&expected)); -} - -#[test] -fn div_one_pos() { - // [1, 1] / (0, +inf) = (0, +inf) - let result = domain::div(&Domain::make_singleton(1.0), &domain::pos_dom()); - let expected = domain::pos_dom(); - assert!(result.eq(&expected)); -} - - -/* More power tests. */ - - -/* Logarithm tests. */ +// Logarithm (6 tests). #[test] fn log_pos() { @@ -711,7 +730,7 @@ fn log_nonneg() { #[test] fn log_ge_one() { // log([1, +inf)) = [0, +inf) - let result = domain::log(&Domain::make_co(domain::one(), domain::inf())); + let result = domain::log(&Domain::make_ci(domain::one())); let expected = domain::nonneg_dom(); assert!(result.eq(&expected)); } @@ -741,7 +760,7 @@ fn log_lt_one() { } -/* Exponential tests. */ +// Exponential (6 tests). #[test] fn exp_free() { @@ -784,13 +803,20 @@ fn exp_neg() { } -/* Checkers tests. */ -// is_zero +/* Checkers */ + -// is_one +// is_zero (TODO). -// is_pos + +// is_one (TODO). + + +// is_pos (TODO). + + +// is_nonneg (TODO: more). #[test] fn is_nonneg_1() { @@ -798,10 +824,13 @@ fn is_nonneg_1() { assert!(domain::is_nonneg(&Domain::make_singleton(1.0))); } -// is_nonpos +// is_nonpos (TODO). + + +// is_neg (TODO). + -// is_neg +// does_not_contain_zero (TODO). -// does_not_contain_zero } From fdfece881079ab18843058ede3b9e6d0a9f20a72 Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Tue, 16 Apr 2024 18:55:25 -0400 Subject: [PATCH 04/23] fix: `is_zero` and `is_one` check for empty intervals --- egg-pre-dcp/src/domain.rs | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/egg-pre-dcp/src/domain.rs b/egg-pre-dcp/src/domain.rs index 9b9c24ea..0f226825 100644 --- a/egg-pre-dcp/src/domain.rs +++ b/egg-pre-dcp/src/domain.rs @@ -339,7 +339,7 @@ pub fn zero_dom() -> Domain { } pub fn is_zero(d: &Domain) -> bool { - d.subseteq(&zero_dom()) + d.subseteq(&zero_dom()) && zero_dom().subseteq(&d) } pub fn option_is_zero(d: Option<&Domain>) -> bool { @@ -351,7 +351,7 @@ pub fn one_dom() -> Domain { } pub fn is_one(d: &Domain) -> bool { - d.subseteq(&one_dom()) + d.subseteq(&one_dom()) && one_dom().subseteq(&d) } pub fn option_is_one(d: Option<&Domain>) -> bool { @@ -362,6 +362,22 @@ pub fn free_dom() -> Domain { Domain::make_ii() } +pub fn empty_dom() -> Domain { + Domain::make_oo(zero(), zero()) +} + +pub fn pos_dom() -> Domain { + Domain::make_oi(zero()) +} + +pub fn is_pos(d: &Domain) -> bool { + d.subseteq(&pos_dom()) +} + +pub fn option_is_pos(d: Option<&Domain>) -> bool { + d.map_or(false, is_pos) +} + pub fn nonneg_dom() -> Domain { Domain::make_ci(zero()) } @@ -386,18 +402,6 @@ pub fn option_is_nonpos(d: Option<&Domain>) -> bool { d.map_or(false, is_nonpos) } -pub fn pos_dom() -> Domain { - Domain::make_oi(zero()) -} - -pub fn is_pos(d: &Domain) -> bool { - d.subseteq(&pos_dom()) -} - -pub fn option_is_pos(d: Option<&Domain>) -> bool { - d.map_or(false, is_pos) -} - pub fn neg_dom() -> Domain { Domain::make_io(neg_zero()) } From cfb7f95b2f113550680a672f6c4479e866a7b5ef Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Tue, 16 Apr 2024 18:55:40 -0400 Subject: [PATCH 05/23] test: checker tests for EIF --- egg-pre-dcp/tests/test_domain.rs | 282 +++++++++++++++++++++++++++++-- 1 file changed, 272 insertions(+), 10 deletions(-) diff --git a/egg-pre-dcp/tests/test_domain.rs b/egg-pre-dcp/tests/test_domain.rs index 9aaf2b3a..8663308b 100644 --- a/egg-pre-dcp/tests/test_domain.rs +++ b/egg-pre-dcp/tests/test_domain.rs @@ -13,9 +13,13 @@ use domain::Domain as Domain; /* Some useful intervals for testing apart from pos, nonneg, nonpos, neg. */ -// gt_one +fn gt_one() { + Domain::make_oi(domain::one()); +} -// ge_one +fn ge_one() { + Domain::make_ci(domain::one()); +} fn gt_two_lt_three() { Domain::make_oo(domain::make_float(2.0), domain::make_float(3.0)); @@ -807,30 +811,288 @@ fn exp_neg() { /* Checkers */ -// is_zero (TODO). +// Is zero? + +#[test] +fn is_zero_zero() { + // [0, 0] is zero + assert!(domain::is_zero(&Domain::make_singleton(0.0))); +} + +#[test] +fn not_is_zero_one() { + // [1, 1] is not zero + assert!(!domain::is_zero(&Domain::make_singleton(1.0))); +} + +#[test] +fn not_is_zero_free() { + // (-inf, +inf) is not zero + assert!(!domain::is_zero(&domain::free_dom())); +} + +#[test] +fn not_is_zero_empty() { + // Empty set is not zero + assert!(!domain::is_zero(&domain::empty_dom())); +} + + +// Is one? + +#[test] +fn is_one_one() { + // [1, 1] is one + assert!(domain::is_one(&Domain::make_singleton(1.0))); +} + +#[test] +fn not_is_one_zero() { + // [0, 0] is not one + assert!(!domain::is_one(&Domain::make_singleton(0.0))); +} + +#[test] +fn not_is_one_free() { + // (-inf, +inf) is not one + assert!(!domain::is_one(&domain::free_dom())); +} + +#[test] +fn not_is_one_empty() { + // Empty set is not one + assert!(!domain::is_one(&domain::empty_dom())); +} + + +// Is positive? + +#[test] +fn is_pos_pos() { + // (0, +inf) is positive + assert!(domain::is_pos(&domain::pos_dom())); +} + +#[test] +fn is_pos_one() { + // [1, 1] is positive + assert!(domain::is_pos(&Domain::make_singleton(1.0))); +} + +#[test] +fn is_pos_empty() { + // Empty set is positive + assert!(domain::is_pos(&domain::empty_dom())); +} +#[test] +fn not_is_pos_nonneg() { + // [0, +inf) is not positive + assert!(!domain::is_pos(&domain::nonneg_dom())); +} -// is_one (TODO). +#[test] +fn not_is_pos_free() { + // (-inf, +inf) is not positive + assert!(!domain::is_pos(&domain::free_dom())); +} + +#[test] +fn not_is_pos_zero() { + // [0, 0] is not positive + assert!(!domain::is_pos(&Domain::make_singleton(0.0))); +} -// is_pos (TODO). +// Is non-negative? +#[test] +fn is_nonneg_pos() { + // (0, +inf) is non-negative + assert!(domain::is_nonneg(&domain::pos_dom())); +} -// is_nonneg (TODO: more). +#[test] +fn is_nonneg_nonneg() { + // [0, +inf) is non-negative + assert!(domain::is_nonneg(&domain::nonneg_dom())); +} #[test] -fn is_nonneg_1() { +fn is_nonneg_zero() { + // [0, 0] is non-negative + assert!(domain::is_nonneg(&Domain::make_singleton(0.0))); +} + +#[test] +fn is_nonneg_one() { // [1, 1] is non-negative assert!(domain::is_nonneg(&Domain::make_singleton(1.0))); } -// is_nonpos (TODO). +#[test] +fn is_nonneg_empty() { + // Empty set is non-negative + assert!(domain::is_nonneg(&domain::empty_dom())); +} + +#[test] +fn not_is_nonneg_free() { + // (-inf, +inf) is not non-negative + assert!(!domain::is_nonneg(&domain::free_dom())); +} + +#[test] +fn not_is_nonneg_minus_one() { + // [-1, -1] is not non-negative + assert!(!domain::is_nonneg(&Domain::make_singleton(-1.0))); +} -// is_neg (TODO). +// Is non-positive? +#[test] +fn is_nonpos_nonpos() { + // (-inf, 0] is non-positive + assert!(domain::is_nonpos(&domain::nonpos_dom())); +} -// does_not_contain_zero (TODO). +#[test] +fn is_nonpos_neg() { + // (-inf, 0) is non-positive + assert!(domain::is_nonpos(&domain::neg_dom())); +} +#[test] +fn is_nonpos_zero() { + // [0, 0] is non-positive + assert!(domain::is_nonpos(&Domain::make_singleton(0.0))); +} + +#[test] +fn is_nonpos_minus_one() { + // [-1, -1] is non-positive + assert!(domain::is_nonpos(&Domain::make_singleton(-1.0))); +} + +#[test] +fn is_nonpos_empty() { + // Empty set is non-positive + assert!(domain::is_nonpos(&domain::empty_dom())); +} + +#[test] +fn not_is_nonpos_free() { + // (-inf, +inf) is not non-positive + assert!(!domain::is_nonpos(&domain::free_dom())); +} + +#[test] +fn not_is_nonpos_one() { + // [1, 1] is not non-positive + assert!(!domain::is_nonpos(&Domain::make_singleton(1.0))); +} + + +// Is negative? + +#[test] +fn is_neg_neg() { + // (-inf, 0) is negative + assert!(domain::is_neg(&domain::neg_dom())); +} + +#[test] +fn is_neg_minus_one() { + // [-1, -1] is negative + assert!(domain::is_neg(&Domain::make_singleton(-1.0))); +} + +#[test] +fn is_neg_empty() { + // Empty set is negative + assert!(domain::is_neg(&domain::empty_dom())); +} + +#[test] +fn not_is_neg_nonpos() { + // (-inf, 0] is not negative + assert!(!domain::is_neg(&domain::nonpos_dom())); +} + +#[test] +fn not_is_neg_free() { + // (-inf, +inf) is not negative + assert!(!domain::is_neg(&domain::free_dom())); +} + +#[test] +fn not_is_neg_zero() { + // [0, 0] is not negative + assert!(!domain::is_neg(&Domain::make_singleton(0.0))); +} + +#[test] +fn not_is_neg_one() { + // [1, 1] is not negative + assert!(!domain::is_neg(&Domain::make_singleton(1.0))); +} + + +// Does not contain zero? + +#[test] +fn does_not_contain_zero_pos() { + // (0, +inf) does not contain zero + assert!(domain::does_not_contain_zero(&domain::pos_dom())); +} + +#[test] +fn does_not_contain_zero_neg() { + // (-inf, 0) does not contain zero + assert!(domain::does_not_contain_zero(&domain::neg_dom())); +} + +#[test] +fn does_not_contain_zero_one() { + // [1, 1] does not contain zero + assert!(domain::does_not_contain_zero(&Domain::make_singleton(1.0))); +} + +#[test] +fn does_not_contain_zero_minus_one() { + // [-1, -1] does not contain zero + assert!(domain::does_not_contain_zero(&Domain::make_singleton(-1.0))); +} + +#[test] +fn does_not_contain_zero_empty() { + // Empty set does not contain zero + assert!(domain::does_not_contain_zero(&domain::empty_dom())); +} + +#[test] +fn not_does_not_contain_zero_free() { + // (-inf, +inf) contains zero + assert!(!domain::does_not_contain_zero(&domain::free_dom())); +} + +#[test] +fn not_does_not_contain_zero_nonneg() { + // [0, +inf) contains zero + assert!(!domain::does_not_contain_zero(&domain::nonneg_dom())); +} + +#[test] +fn not_does_not_contain_zero_nonpos() { + // (-inf, 0] contains zero + assert!(!domain::does_not_contain_zero(&domain::nonpos_dom())); +} + +#[test] +fn not_does_not_contain_zero_zero() { + // [0, 0] contains zero + assert!(!domain::does_not_contain_zero(&Domain::make_singleton(0.0))); +} } From f95cdbc31ca6262450e1915bf69e221ce936e9cb Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Thu, 18 Apr 2024 18:17:51 -0400 Subject: [PATCH 06/23] fix: `abs` interval calculation --- egg-pre-dcp/src/domain.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/egg-pre-dcp/src/domain.rs b/egg-pre-dcp/src/domain.rs index 0f226825..044eae2a 100644 --- a/egg-pre-dcp/src/domain.rs +++ b/egg-pre-dcp/src/domain.rs @@ -479,11 +479,11 @@ pub fn abs(d: &Domain) -> Domain { Domain::make_from_endpoints(-b, -a, r, l) } else { if a_abs < b_abs { - Domain::make_from_endpoints(zero(), b, false, r) + Domain::make_from_endpoints(zero(), b_abs, false, r) } else if b_abs < a_abs { - Domain::make_from_endpoints(zero(), a, false, l) + Domain::make_from_endpoints(zero(), a_abs, false, l) } else { - Domain::make_from_endpoints(zero(), a, false, l && r) + Domain::make_from_endpoints(zero(), a_abs, false, l && r) } } } else { From c453992ebf82107b2adc39dc0b0fbbdab4e516c7 Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Thu, 18 Apr 2024 18:18:20 -0400 Subject: [PATCH 07/23] test: interval `neg`, `abs`, and some concrete intervals for `exp` and `log` --- egg-pre-dcp/tests/test_domain.rs | 208 +++++++++++++++++++++++++++---- 1 file changed, 185 insertions(+), 23 deletions(-) diff --git a/egg-pre-dcp/tests/test_domain.rs b/egg-pre-dcp/tests/test_domain.rs index 8663308b..6aa69a82 100644 --- a/egg-pre-dcp/tests/test_domain.rs +++ b/egg-pre-dcp/tests/test_domain.rs @@ -13,31 +13,177 @@ use domain::Domain as Domain; /* Some useful intervals for testing apart from pos, nonneg, nonpos, neg. */ -fn gt_one() { - Domain::make_oi(domain::one()); +// (-2, 2) +fn gt_minus_two_lt_two() -> Domain { + Domain::make_oo(domain::make_float(-2.0), domain::make_float(2.0)) } -fn ge_one() { - Domain::make_ci(domain::one()); +// (-2, 2] +fn gt_minus_two_le_two() -> Domain { + Domain::make_oc(domain::make_float(-2.0), domain::make_float(2.0)) } -fn gt_two_lt_three() { - Domain::make_oo(domain::make_float(2.0), domain::make_float(3.0)); +// (-2, 3) +fn gt_minus_two_lt_three() -> Domain { + Domain::make_oo(domain::make_float(-2.0), domain::make_float(3.0)) } -// TODO: more +// (-3, -2) +fn gt_minus_three_lt_minus_two() -> Domain { + Domain::make_oo(domain::make_float(-3.0), domain::make_float(-2.0)) +} + +// (-3, 2) +fn gt_minus_three_lt_two() -> Domain { + Domain::make_oo(domain::make_float(-3.0), domain::make_float(2.0)) +} + +// [0, 1) +fn ge_zero_lt_one() -> Domain { + Domain::make_co(domain::zero(), domain::one()) +} + +// [0, 1] +fn ge_zero_le_one() -> Domain { + Domain::make_cc(domain::zero(), domain::one()) +} + +// [0, 2) +fn ge_zero_lt_two() -> Domain { + Domain::make_co(domain::zero(), domain::make_float(2.0)) +} + +// [0, 2] +fn ge_zero_le_two() -> Domain { + Domain::make_cc(domain::zero(), domain::make_float(2.0)) +} + +// [0, 3) +fn ge_zero_lt_three() -> Domain { + Domain::make_co(domain::zero(), domain::make_float(3.0)) +} + +// (1, +inf) +fn gt_one() -> Domain { + Domain::make_oi(domain::one()) +} + +// [1, +inf) +fn ge_one() -> Domain { + Domain::make_ci(domain::one()) +} + +// (2, 3) +fn gt_two_lt_three() -> Domain { + Domain::make_oo(domain::make_float(2.0), domain::make_float(3.0)) +} /* Operations */ -// Negation (TODO). +// Negation (6 tests). + +#[test] +fn neg_pos() { + // -(0, +inf) = (-inf, 0) + let result = domain::neg(&domain::pos_dom()); + let expected = domain::neg_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn neg_nonneg() { + // -[0, +inf) = (-inf, 0] + let result = domain::neg(&domain::nonneg_dom()); + let expected = domain::nonpos_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn neg_nonpos() { + // -(-inf, 0] = [0, +inf) + let result = domain::neg(&domain::nonpos_dom()); + let expected = domain::nonneg_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn neg_neg() { + // -(-inf, 0) = (0, +inf) + let result = domain::neg(&domain::neg_dom()); + let expected = domain::pos_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn neg_free() { + // -(-inf, +inf) = (-inf, +inf) + let result = domain::neg(&domain::free_dom()); + let expected = domain::free_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn neg_gt_two_lt_three() { + // -(2, 3) = (-3, -2) + let result = domain::neg(>_two_lt_three()); + let expected = gt_minus_three_lt_minus_two(); + assert!(result.eq(&expected)); +} // Absolute value (TODO). +#[test] +fn abs_gt_two_lt_three() { + // abs((2, 3)) = (2, 3) + let result = domain::abs(>_two_lt_three()); + let expected = gt_two_lt_three(); + assert!(result.eq(&expected)); +} + +#[test] +fn abs_gt_minus_three_lt_minus_two() { + // abs((-3, -2)) = (2, 3) + let result = domain::abs(>_minus_three_lt_minus_two()); + let expected = gt_two_lt_three(); + assert!(result.eq(&expected)); +} + +#[test] +fn abs_gt_minus_two_lt_three() { + // abs((-2, 3)) = [0, 3) + let result = domain::abs(>_minus_two_lt_three()); + let expected = ge_zero_lt_three(); + assert!(result.eq(&expected)); +} + +#[test] +fn abs_gt_minus_three_lt_two() { + // abs((-3, 2)) = [0, 3) + let result = domain::abs(>_minus_three_lt_two()); + let expected = ge_zero_lt_three(); + println!("{:?}", result); + assert!(result.eq(&expected)); +} +#[test] +fn abs_gt_minus_two_le_two() { + // abs((-2, 2]) = [0, 2] + let result = domain::abs(>_minus_two_le_two()); + let expected = ge_zero_le_two(); + assert!(result.eq(&expected)); +} + +#[test] +fn abs_gt_minus_two_lt_two() { + // abs((-2, 2)) = [0, 2) + let result = domain::abs(>_minus_two_lt_two()); + let expected = ge_zero_lt_two(); + assert!(result.eq(&expected)); +} // Square root (TODO). @@ -713,7 +859,7 @@ fn pow_neg_neg() { } -// Logarithm (6 tests). +// Logarithm (7 tests). #[test] fn log_pos() { @@ -734,7 +880,7 @@ fn log_nonneg() { #[test] fn log_ge_one() { // log([1, +inf)) = [0, +inf) - let result = domain::log(&Domain::make_ci(domain::one())); + let result = domain::log(&ge_one()); let expected = domain::nonneg_dom(); assert!(result.eq(&expected)); } @@ -742,29 +888,37 @@ fn log_ge_one() { #[test] fn log_gt_one() { // log((1, +inf)) = (0, +inf) - let result = domain::log(&Domain::make_oi(domain::one())); + let result = domain::log(>_one()); let expected = domain::pos_dom(); assert!(result.eq(&expected)); } #[test] -fn log_le_one() { +fn log_ge_zero_le_one() { // log([0, 1]) = (-inf, 0] - let result = domain::log(&Domain::make_cc(domain::zero(), domain::one())); + let result = domain::log(&ge_zero_le_one()); let expected = domain::nonpos_dom(); assert!(result.eq(&expected)); } #[test] -fn log_lt_one() { +fn log_ge_zero_lt_one() { // log([0, 1)) = (-inf, 0) - let result = domain::log(&Domain::make_co(domain::zero(), domain::one())); + let result = domain::log(&ge_zero_lt_one()); let expected = domain::neg_dom(); assert!(result.eq(&expected)); } +#[test] +fn log_gt_two_lt_three_subseteq() { + // log((2, 3)) \subseteq (0.69, 1.10) + let result = domain::log(>_two_lt_three()); + let enclosure = Domain::make_oo(domain::make_float(0.69), domain::make_float(1.10)); + assert!(result.subseteq(&enclosure)); +} -// Exponential (6 tests). + +// Exponential (7 tests). #[test] fn exp_free() { @@ -806,12 +960,20 @@ fn exp_neg() { assert!(result.eq(&expected)); } +#[test] +fn exp_gt_two_lt_three_subseteq() { + // exp((2, 3)) \subseteq (7.38, 20.09) + let result = domain::exp(>_two_lt_three()); + let enclosure = Domain::make_oo(domain::make_float(7.38), domain::make_float(20.09)); + assert!(result.subseteq(&enclosure)); +} + /* Checkers */ -// Is zero? +// Is zero? (4 tests). #[test] fn is_zero_zero() { @@ -838,7 +1000,7 @@ fn not_is_zero_empty() { } -// Is one? +// Is one? (4 tests). #[test] fn is_one_one() { @@ -865,7 +1027,7 @@ fn not_is_one_empty() { } -// Is positive? +// Is positive? (6 tests). #[test] fn is_pos_pos() { @@ -904,7 +1066,7 @@ fn not_is_pos_zero() { } -// Is non-negative? +// Is non-negative? (7 tests). #[test] fn is_nonneg_pos() { @@ -949,7 +1111,7 @@ fn not_is_nonneg_minus_one() { } -// Is non-positive? +// Is non-positive? (7 tests). #[test] fn is_nonpos_nonpos() { @@ -994,7 +1156,7 @@ fn not_is_nonpos_one() { } -// Is negative? +// Is negative? (7 tests). #[test] fn is_neg_neg() { @@ -1039,7 +1201,7 @@ fn not_is_neg_one() { } -// Does not contain zero? +// Does not contain zero? (9 tests). #[test] fn does_not_contain_zero_pos() { From 2c47908f82133dc2bf2db0e94e449c523564005d Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Thu, 18 Apr 2024 18:29:27 -0400 Subject: [PATCH 08/23] fix: negative cases for interval `sqrt` --- egg-pre-dcp/src/domain.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/egg-pre-dcp/src/domain.rs b/egg-pre-dcp/src/domain.rs index 044eae2a..2740daa5 100644 --- a/egg-pre-dcp/src/domain.rs +++ b/egg-pre-dcp/src/domain.rs @@ -496,7 +496,11 @@ pub fn option_abs(d_o: Option) -> Option { } pub fn sqrt(d: &Domain) -> Domain { - Domain::make(d.interval.sqrt(), d.lo_open, d.hi_open) + if is_nonneg(d) { + Domain::make(d.interval.sqrt(), d.lo_open, d.hi_open) + } else { + free_dom() + } } pub fn option_sqrt(d_o: Option) -> Option { From 1e8180484f4fc3127135600d8c0f342f718bb4c3 Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Thu, 18 Apr 2024 18:29:34 -0400 Subject: [PATCH 09/23] test: interval `sqrt` tests --- egg-pre-dcp/tests/test_domain.rs | 41 ++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/egg-pre-dcp/tests/test_domain.rs b/egg-pre-dcp/tests/test_domain.rs index 6aa69a82..5bbb81bb 100644 --- a/egg-pre-dcp/tests/test_domain.rs +++ b/egg-pre-dcp/tests/test_domain.rs @@ -188,6 +188,47 @@ fn abs_gt_minus_two_lt_two() { // Square root (TODO). +#[test] +fn sqrt_pos() { + // sqrt((0, +inf)) = (0, +inf) + let result = domain::sqrt(&domain::pos_dom()); + let expected = domain::pos_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn sqrt_nonneg() { + // sqrt([0, +inf)) = [0, +inf) + let result = domain::sqrt(&domain::nonneg_dom()); + let expected = domain::nonneg_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn sqrt_nonpos() { + // sqrt((-inf, 0]) = (-inf, +inf) + let result = domain::sqrt(&domain::nonpos_dom()); + let expected = domain::free_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn sqrt_neg() { + // sqrt((-inf, 0)) = (-inf, +inf) + let result = domain::sqrt(&domain::neg_dom()); + let expected = domain::free_dom(); + println!("{:?}", result); + assert!(result.eq(&expected)); +} + +#[test] +fn sqrt_gt_two_lt_three_subseteq() { + // sqrt((2, 3)) \subseteq (1.41, 1.74) + let result = domain::sqrt(>_two_lt_three()); + let enclosure = Domain::make_oo(domain::make_float(1.41), domain::make_float(1.74)); + assert!(result.subseteq(&enclosure)); +} + // Min (TODO). From d08f847192ac02e2b45f0cd95d1a2dc6ba5dea28 Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Thu, 18 Apr 2024 18:40:20 -0400 Subject: [PATCH 10/23] fix: `log` on negative intervals --- egg-pre-dcp/src/domain.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/egg-pre-dcp/src/domain.rs b/egg-pre-dcp/src/domain.rs index 2740daa5..ead9eae2 100644 --- a/egg-pre-dcp/src/domain.rs +++ b/egg-pre-dcp/src/domain.rs @@ -508,7 +508,11 @@ pub fn option_sqrt(d_o: Option) -> Option { } pub fn log(d: &Domain) -> Domain { - Domain::make(d.interval.ln(), d.lo_open, d.hi_open) + if is_pos(d) { + Domain::make(d.interval.ln(), d.lo_open, d.hi_open) + } else { + free_dom() + } } pub fn option_log(d_o: Option) -> Option { From 45637f44c6e60986e2477b640514a02f392a4c70 Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Thu, 18 Apr 2024 18:51:56 -0400 Subject: [PATCH 11/23] fix: let `log` work for non-negative input --- egg-pre-dcp/src/domain.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/egg-pre-dcp/src/domain.rs b/egg-pre-dcp/src/domain.rs index ead9eae2..a8456fef 100644 --- a/egg-pre-dcp/src/domain.rs +++ b/egg-pre-dcp/src/domain.rs @@ -508,7 +508,7 @@ pub fn option_sqrt(d_o: Option) -> Option { } pub fn log(d: &Domain) -> Domain { - if is_pos(d) { + if is_nonneg(d) { Domain::make(d.interval.ln(), d.lo_open, d.hi_open) } else { free_dom() From 2ad6f4f5884b22f89293e25f37037d54695bdeb0 Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Thu, 18 Apr 2024 18:52:15 -0400 Subject: [PATCH 12/23] test: tests up to interval `sub` --- egg-pre-dcp/tests/test_domain.rs | 529 +++++++++++++++++-------------- 1 file changed, 283 insertions(+), 246 deletions(-) diff --git a/egg-pre-dcp/tests/test_domain.rs b/egg-pre-dcp/tests/test_domain.rs index 5bbb81bb..3766ca7d 100644 --- a/egg-pre-dcp/tests/test_domain.rs +++ b/egg-pre-dcp/tests/test_domain.rs @@ -11,7 +11,22 @@ use domain::Domain as Domain; -/* Some useful intervals for testing apart from pos, nonneg, nonpos, neg. */ +/* Some useful intervals for testing apart from pos, nonneg, nonpos, neg, free. */ + +// (-3, -2) +fn gt_minus_three_lt_minus_two() -> Domain { + Domain::make_oo(domain::make_float(-3.0), domain::make_float(-2.0)) +} + +// (-3, 2) +fn gt_minus_three_lt_two() -> Domain { + Domain::make_oo(domain::make_float(-3.0), domain::make_float(2.0)) +} + +// (-3, 3) +fn gt_minus_three_lt_three() -> Domain { + Domain::make_oo(domain::make_float(-3.0), domain::make_float(3.0)) +} // (-2, 2) fn gt_minus_two_lt_two() -> Domain { @@ -28,16 +43,6 @@ fn gt_minus_two_lt_three() -> Domain { Domain::make_oo(domain::make_float(-2.0), domain::make_float(3.0)) } -// (-3, -2) -fn gt_minus_three_lt_minus_two() -> Domain { - Domain::make_oo(domain::make_float(-3.0), domain::make_float(-2.0)) -} - -// (-3, 2) -fn gt_minus_three_lt_two() -> Domain { - Domain::make_oo(domain::make_float(-3.0), domain::make_float(2.0)) -} - // [0, 1) fn ge_zero_lt_one() -> Domain { Domain::make_co(domain::zero(), domain::one()) @@ -186,7 +191,7 @@ fn abs_gt_minus_two_lt_two() { } -// Square root (TODO). +// Square root (5 tests). #[test] fn sqrt_pos() { @@ -230,13 +235,133 @@ fn sqrt_gt_two_lt_three_subseteq() { } -// Min (TODO). +// Logarithm (9 tests). +#[test] +fn log_pos() { + // log((0, +inf)) = (-inf, +inf) + let result = domain::log(&domain::pos_dom()); + let expected = domain::free_dom(); + assert!(result.eq(&expected)); +} -// Max (TODO). +#[test] +fn log_nonneg() { + // log([0, +inf)) = (-inf, +inf) + let result = domain::log(&domain::nonneg_dom()); + let expected = domain::free_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn log_nonpos() { + // log((-inf, 0]) = (-inf, +inf) + let result = domain::log(&domain::nonpos_dom()); + let expected = domain::free_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn log_neg() { + // log((-inf, 0)) = (-inf, +inf) + let result = domain::log(&domain::neg_dom()); + let expected = domain::free_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn log_ge_one() { + // log([1, +inf)) = [0, +inf) + let result = domain::log(&ge_one()); + let expected = domain::nonneg_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn log_gt_one() { + // log((1, +inf)) = (0, +inf) + let result = domain::log(>_one()); + let expected = domain::pos_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn log_ge_zero_le_one() { + // log([0, 1]) = (-inf, 0] + let result = domain::log(&ge_zero_le_one()); + let expected = domain::nonpos_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn log_ge_zero_lt_one() { + // log([0, 1)) = (-inf, 0) + let result = domain::log(&ge_zero_lt_one()); + let expected = domain::neg_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn log_gt_two_lt_three_subseteq() { + // log((2, 3)) \subseteq (0.69, 1.10) + let result = domain::log(>_two_lt_three()); + let enclosure = Domain::make_oo(domain::make_float(0.69), domain::make_float(1.10)); + assert!(result.subseteq(&enclosure)); +} + + +// Exponential (7 tests). + +#[test] +fn exp_free() { + // exp((-inf, +inf)) = (0, +inf) + let result = domain::exp(&domain::free_dom()); + let expected = domain::pos_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn exp_pos() { + // exp((0, +inf)) = (1, +inf) + let result = domain::exp(&domain::pos_dom()); + let expected = Domain::make_oi(domain::one()); + assert!(result.eq(&expected)); +} + +#[test] +fn exp_nonneg() { + // exp([0, +inf)) = [1, +inf) + let result = domain::exp(&domain::nonneg_dom()); + let expected = Domain::make_ci(domain::one()); + assert!(result.eq(&expected)); +} + +#[test] +fn exp_nonpos() { + // exp((-inf, 0]) = (0, 1] + let result = domain::exp(&domain::nonpos_dom()); + let expected = Domain::make_oc(domain::zero(), domain::one()); + assert!(result.eq(&expected)); +} + +#[test] +fn exp_neg() { + // exp((-inf, 0)) = (0, 1) + let result = domain::exp(&domain::neg_dom()); + let expected = Domain::make_oo(domain::zero(), domain::one()); + assert!(result.eq(&expected)); +} + +#[test] +fn exp_gt_two_lt_three_subseteq() { + // exp((2, 3)) \subseteq (7.38, 20.09) + let result = domain::exp(>_two_lt_three()); + let enclosure = Domain::make_oo(domain::make_float(7.38), domain::make_float(20.09)); + assert!(result.subseteq(&enclosure)); +} -// Addition (16 tests). +// Addition (17 tests). #[test] fn add_pos_pos() { @@ -366,258 +491,274 @@ fn add_neg_neg() { assert!(result.eq(&expected)); } +#[test] +fn add_gt_minus_two_le_two_ge_zero_lt_one() { + // (-2, 2] + [0, 1) = (-2, 3) + let result = domain::add(>_minus_two_le_two(), &ge_zero_lt_one()); + let expected = gt_minus_two_lt_three(); + assert!(result.eq(&expected)); +} + -// Multiplication (16 tests). +// Subtraction (16 tests). #[test] -fn mul_pos_pos() { - // (0, +inf) * (0, +inf) = (0, +inf) - let result = domain::mul(&domain::pos_dom(), &domain::pos_dom()); - let expected = domain::pos_dom(); +fn sub_pos_nonneg() { + // (0, +inf) - [0, +inf) = (-inf, +inf) + let result = domain::sub(&domain::pos_dom(), &domain::nonneg_dom()); + let expected = domain::free_dom(); assert!(result.eq(&expected)); } - #[test] -fn mul_pos_nonneg() { - // (0, +inf) * [0, +inf) = [0, +inf) - let result = domain::mul(&domain::pos_dom(), &domain::nonneg_dom()); - let expected = domain::nonneg_dom(); +fn sub_pos_nonpos() { + // (0, +inf) - (-inf, 0] = (0, +inf) + let result = domain::sub(&domain::pos_dom(), &domain::nonpos_dom()); + let expected = domain::pos_dom(); assert!(result.eq(&expected)); } #[test] -fn mul_pos_nonpos() { - // (0, +inf) * (-inf, 0] = (-inf, 0] - let result = domain::mul(&domain::pos_dom(), &domain::nonpos_dom()); - let expected = domain::nonpos_dom(); +fn sub_pos_neg() { + // (0, +inf) - (-inf, 0) = (0, +inf) + let result = domain::sub(&domain::pos_dom(), &domain::neg_dom()); + let expected = domain::pos_dom(); assert!(result.eq(&expected)); } #[test] -fn mul_pos_neg() { - // (0, +inf) * (-inf, 0) = (-inf, 0) - let result = domain::mul(&domain::pos_dom(), &domain::neg_dom()); - let expected = domain::neg_dom(); +fn sub_nonneg_pos() { + // [0, +inf) - (0, +inf) = (-inf, +inf) + let result = domain::sub(&domain::nonneg_dom(), &domain::pos_dom()); + let expected = domain::free_dom(); assert!(result.eq(&expected)); } #[test] -fn mul_nonneg_pos() { - // [0, +inf) * (0, +inf) = [0, +inf) - let result = domain::mul(&domain::nonneg_dom(), &domain::pos_dom()); - let expected = domain::nonneg_dom(); +fn sub_nonneg_nonneg() { + // [0, +inf) - [0, +inf) = (-inf, +inf) + let result = domain::sub(&domain::nonneg_dom(), &domain::nonneg_dom()); + let expected = domain::free_dom(); assert!(result.eq(&expected)); } #[test] -fn mul_nonneg_nonneg() { - // [0, +inf) * [0, +inf) = [0, +inf) - let result = domain::mul(&domain::nonneg_dom(), &domain::nonneg_dom()); +fn sub_nonneg_nonpos() { + // [0, +inf) - (-inf, 0] = [0, +inf) + let result = domain::sub(&domain::nonneg_dom(), &domain::nonpos_dom()); let expected = domain::nonneg_dom(); assert!(result.eq(&expected)); } #[test] -fn mul_nonneg_nonpos() { - // [0, +inf) * (-inf, 0] = (-inf, 0] - let result = domain::mul(&domain::nonneg_dom(), &domain::nonpos_dom()); - let expected = domain::nonpos_dom(); +fn sub_nonneg_neg() { + // [0, +inf) - (-inf, 0) = [0, +inf) + let result = domain::sub(&domain::nonneg_dom(), &domain::neg_dom()); + let expected = domain::pos_dom(); assert!(result.eq(&expected)); } #[test] -fn mul_nonneg_neg() { - // [0, +inf) * (-inf, 0) = (-inf, 0] - let result = domain::mul(&domain::nonneg_dom(), &domain::neg_dom()); - let expected = domain::nonpos_dom(); +fn sub_nonpos_pos() { + // (-inf, 0] - (0, +inf) = (-inf, 0) + let result = domain::sub(&domain::nonpos_dom(), &domain::pos_dom()); + let expected = domain::neg_dom(); assert!(result.eq(&expected)); } #[test] -fn mul_nonpos_pos() { - // (-inf, 0] * (0, +inf) = (-inf, 0] - let result = domain::mul(&domain::nonpos_dom(), &domain::pos_dom()); +fn sub_nonpos_nonneg() { + // (-inf, 0] - [0, +inf) = (-inf, 0] + let result = domain::sub(&domain::nonpos_dom(), &domain::nonneg_dom()); let expected = domain::nonpos_dom(); assert!(result.eq(&expected)); } #[test] -fn mul_nonnpos_nonneg() { - // (-inf, 0] * [0, +inf) = (-inf, 0] - let result = domain::mul(&domain::nonpos_dom(), &domain::nonneg_dom()); - let expected = domain::nonpos_dom(); +fn sub_nonpos_nonpos() { + // (-inf, 0] - (-inf, 0] = (-inf, +inf) + let result = domain::sub(&domain::nonpos_dom(), &domain::nonpos_dom()); + let expected = domain::free_dom(); assert!(result.eq(&expected)); } #[test] -fn mul_nonpos_nonpos() { - // (-inf, 0] * (-inf, 0] = [0, +inf) - let result = domain::mul(&domain::nonpos_dom(), &domain::nonpos_dom()); - let expected = domain::nonneg_dom(); +fn sub_nonpos_neg() { + // (-inf, 0] - (-inf, 0) = (-inf, +inf) + let result = domain::sub(&domain::nonpos_dom(), &domain::neg_dom()); + let expected = domain::free_dom(); assert!(result.eq(&expected)); } #[test] -fn mul_nonpos_neg() { - // (-inf, 0] * (-inf, 0) = [0, +inf) - let result = domain::mul(&domain::nonpos_dom(), &domain::neg_dom()); - let expected = domain::nonneg_dom(); +fn sub_neg_pos() { + // (-inf, 0) - (0, +inf) = (-inf, 0) + let result = domain::sub(&domain::neg_dom(), &domain::pos_dom()); + let expected = domain::neg_dom(); assert!(result.eq(&expected)); } #[test] -fn mul_neg_pos() { - // (-inf, 0) * (0, +inf) = (-inf, 0) - let result = domain::mul(&domain::neg_dom(), &domain::pos_dom()); +fn sub_neg_nonneg() { + // (-inf, 0) - [0, +inf) = (-inf, 0) + let result = domain::sub(&domain::neg_dom(), &domain::nonneg_dom()); let expected = domain::neg_dom(); assert!(result.eq(&expected)); } #[test] -fn mul_neg_nonneg() { - // (-inf, 0) * [0, +inf) = (-inf, 0] - let result = domain::mul(&domain::neg_dom(), &domain::nonneg_dom()); - let expected = domain::nonpos_dom(); +fn sub_neg_nonpos() { + // (-inf, 0) - (-inf, 0] = (-inf, +inf) + let result = domain::sub(&domain::neg_dom(), &domain::nonpos_dom()); + let expected = domain::free_dom(); assert!(result.eq(&expected)); } #[test] -fn mul_neg_nonpos() { - // (-inf, 0) * (-inf, 0] = [0, +inf) - let result = domain::mul(&domain::neg_dom(), &domain::nonpos_dom()); - let expected = domain::nonneg_dom(); +fn sub_neg_neg() { + // (-inf, 0) - (-inf, 0) = (-inf, +inf) + let result = domain::sub(&domain::neg_dom(), &domain::neg_dom()); + let expected = domain::free_dom(); assert!(result.eq(&expected)); } #[test] -fn mul_neg_neg() { - // (-inf, 0) * (-inf, 0) = (0, +inf) - let result = domain::mul(&domain::neg_dom(), &domain::neg_dom()); - let expected = domain::pos_dom(); +fn sub_gt_minus_two_lt_three_ge_zero_le_one() { + // (-2, 3) - [0, 1] = (-3, 3) + let result = domain::sub(>_minus_two_lt_three(), &ge_zero_le_one()); + let expected = gt_minus_three_lt_three(); assert!(result.eq(&expected)); } -// Subtraction (16 tests). +// Multiplication (16 tests). #[test] -fn sub_pos_nonneg() { - // (0, +inf) - [0, +inf) = (-inf, +inf) - let result = domain::sub(&domain::pos_dom(), &domain::nonneg_dom()); - let expected = domain::free_dom(); +fn mul_pos_pos() { + // (0, +inf) * (0, +inf) = (0, +inf) + let result = domain::mul(&domain::pos_dom(), &domain::pos_dom()); + let expected = domain::pos_dom(); assert!(result.eq(&expected)); } + #[test] -fn sub_pos_nonpos() { - // (0, +inf) - (-inf, 0] = (0, +inf) - let result = domain::sub(&domain::pos_dom(), &domain::nonpos_dom()); - let expected = domain::pos_dom(); +fn mul_pos_nonneg() { + // (0, +inf) * [0, +inf) = [0, +inf) + let result = domain::mul(&domain::pos_dom(), &domain::nonneg_dom()); + let expected = domain::nonneg_dom(); assert!(result.eq(&expected)); } #[test] -fn sub_pos_neg() { - // (0, +inf) - (-inf, 0) = (0, +inf) - let result = domain::sub(&domain::pos_dom(), &domain::neg_dom()); - let expected = domain::pos_dom(); +fn mul_pos_nonpos() { + // (0, +inf) * (-inf, 0] = (-inf, 0] + let result = domain::mul(&domain::pos_dom(), &domain::nonpos_dom()); + let expected = domain::nonpos_dom(); assert!(result.eq(&expected)); } #[test] -fn sub_nonneg_pos() { - // [0, +inf) - (0, +inf) = (-inf, +inf) - let result = domain::sub(&domain::nonneg_dom(), &domain::pos_dom()); - let expected = domain::free_dom(); +fn mul_pos_neg() { + // (0, +inf) * (-inf, 0) = (-inf, 0) + let result = domain::mul(&domain::pos_dom(), &domain::neg_dom()); + let expected = domain::neg_dom(); assert!(result.eq(&expected)); } #[test] -fn sub_nonneg_nonneg() { - // [0, +inf) - [0, +inf) = (-inf, +inf) - let result = domain::sub(&domain::nonneg_dom(), &domain::nonneg_dom()); - let expected = domain::free_dom(); +fn mul_nonneg_pos() { + // [0, +inf) * (0, +inf) = [0, +inf) + let result = domain::mul(&domain::nonneg_dom(), &domain::pos_dom()); + let expected = domain::nonneg_dom(); assert!(result.eq(&expected)); } #[test] -fn sub_nonneg_nonpos() { - // [0, +inf) - (-inf, 0] = [0, +inf) - let result = domain::sub(&domain::nonneg_dom(), &domain::nonpos_dom()); +fn mul_nonneg_nonneg() { + // [0, +inf) * [0, +inf) = [0, +inf) + let result = domain::mul(&domain::nonneg_dom(), &domain::nonneg_dom()); let expected = domain::nonneg_dom(); assert!(result.eq(&expected)); } #[test] -fn sub_nonneg_neg() { - // [0, +inf) - (-inf, 0) = [0, +inf) - let result = domain::sub(&domain::nonneg_dom(), &domain::neg_dom()); - let expected = domain::pos_dom(); +fn mul_nonneg_nonpos() { + // [0, +inf) * (-inf, 0] = (-inf, 0] + let result = domain::mul(&domain::nonneg_dom(), &domain::nonpos_dom()); + let expected = domain::nonpos_dom(); assert!(result.eq(&expected)); } #[test] -fn sub_nonpos_pos() { - // (-inf, 0] - (0, +inf) = (-inf, 0) - let result = domain::sub(&domain::nonpos_dom(), &domain::pos_dom()); - let expected = domain::neg_dom(); +fn mul_nonneg_neg() { + // [0, +inf) * (-inf, 0) = (-inf, 0] + let result = domain::mul(&domain::nonneg_dom(), &domain::neg_dom()); + let expected = domain::nonpos_dom(); assert!(result.eq(&expected)); } #[test] -fn sub_nonpos_nonneg() { - // (-inf, 0] - [0, +inf) = (-inf, 0] - let result = domain::sub(&domain::nonpos_dom(), &domain::nonneg_dom()); +fn mul_nonpos_pos() { + // (-inf, 0] * (0, +inf) = (-inf, 0] + let result = domain::mul(&domain::nonpos_dom(), &domain::pos_dom()); let expected = domain::nonpos_dom(); assert!(result.eq(&expected)); } #[test] -fn sub_nonpos_nonpos() { - // (-inf, 0] - (-inf, 0] = (-inf, +inf) - let result = domain::sub(&domain::nonpos_dom(), &domain::nonpos_dom()); - let expected = domain::free_dom(); +fn mul_nonnpos_nonneg() { + // (-inf, 0] * [0, +inf) = (-inf, 0] + let result = domain::mul(&domain::nonpos_dom(), &domain::nonneg_dom()); + let expected = domain::nonpos_dom(); assert!(result.eq(&expected)); } #[test] -fn sub_nonpos_neg() { - // (-inf, 0] - (-inf, 0) = (-inf, +inf) - let result = domain::sub(&domain::nonpos_dom(), &domain::neg_dom()); - let expected = domain::free_dom(); +fn mul_nonpos_nonpos() { + // (-inf, 0] * (-inf, 0] = [0, +inf) + let result = domain::mul(&domain::nonpos_dom(), &domain::nonpos_dom()); + let expected = domain::nonneg_dom(); assert!(result.eq(&expected)); } #[test] -fn sub_neg_pos() { - // (-inf, 0) - (0, +inf) = (-inf, 0) - let result = domain::sub(&domain::neg_dom(), &domain::pos_dom()); - let expected = domain::neg_dom(); +fn mul_nonpos_neg() { + // (-inf, 0] * (-inf, 0) = [0, +inf) + let result = domain::mul(&domain::nonpos_dom(), &domain::neg_dom()); + let expected = domain::nonneg_dom(); assert!(result.eq(&expected)); } #[test] -fn sub_neg_nonneg() { - // (-inf, 0) - [0, +inf) = (-inf, 0) - let result = domain::sub(&domain::neg_dom(), &domain::nonneg_dom()); +fn mul_neg_pos() { + // (-inf, 0) * (0, +inf) = (-inf, 0) + let result = domain::mul(&domain::neg_dom(), &domain::pos_dom()); let expected = domain::neg_dom(); assert!(result.eq(&expected)); } #[test] -fn sub_neg_nonpos() { - // (-inf, 0) - (-inf, 0] = (-inf, +inf) - let result = domain::sub(&domain::neg_dom(), &domain::nonpos_dom()); - let expected = domain::free_dom(); +fn mul_neg_nonneg() { + // (-inf, 0) * [0, +inf) = (-inf, 0] + let result = domain::mul(&domain::neg_dom(), &domain::nonneg_dom()); + let expected = domain::nonpos_dom(); assert!(result.eq(&expected)); } #[test] -fn sub_neg_neg() { - // (-inf, 0) - (-inf, 0) = (-inf, +inf) - let result = domain::sub(&domain::neg_dom(), &domain::neg_dom()); - let expected = domain::free_dom(); +fn mul_neg_nonpos() { + // (-inf, 0) * (-inf, 0] = [0, +inf) + let result = domain::mul(&domain::neg_dom(), &domain::nonpos_dom()); + let expected = domain::nonneg_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn mul_neg_neg() { + // (-inf, 0) * (-inf, 0) = (0, +inf) + let result = domain::mul(&domain::neg_dom(), &domain::neg_dom()); + let expected = domain::pos_dom(); assert!(result.eq(&expected)); } @@ -769,6 +910,12 @@ fn div_one_pos() { } +// Min (TODO). + + +// Max (TODO). + + // Power (16 tests). #[test] @@ -900,116 +1047,6 @@ fn pow_neg_neg() { } -// Logarithm (7 tests). - -#[test] -fn log_pos() { - // log((0, +inf)) = (-inf, +inf) - let result = domain::log(&domain::pos_dom()); - let expected = domain::free_dom(); - assert!(result.eq(&expected)); -} - -#[test] -fn log_nonneg() { - // log([0, +inf)) = (-inf, +inf) - let result = domain::log(&domain::nonneg_dom()); - let expected = domain::free_dom(); - assert!(result.eq(&expected)); -} - -#[test] -fn log_ge_one() { - // log([1, +inf)) = [0, +inf) - let result = domain::log(&ge_one()); - let expected = domain::nonneg_dom(); - assert!(result.eq(&expected)); -} - -#[test] -fn log_gt_one() { - // log((1, +inf)) = (0, +inf) - let result = domain::log(>_one()); - let expected = domain::pos_dom(); - assert!(result.eq(&expected)); -} - -#[test] -fn log_ge_zero_le_one() { - // log([0, 1]) = (-inf, 0] - let result = domain::log(&ge_zero_le_one()); - let expected = domain::nonpos_dom(); - assert!(result.eq(&expected)); -} - -#[test] -fn log_ge_zero_lt_one() { - // log([0, 1)) = (-inf, 0) - let result = domain::log(&ge_zero_lt_one()); - let expected = domain::neg_dom(); - assert!(result.eq(&expected)); -} - -#[test] -fn log_gt_two_lt_three_subseteq() { - // log((2, 3)) \subseteq (0.69, 1.10) - let result = domain::log(>_two_lt_three()); - let enclosure = Domain::make_oo(domain::make_float(0.69), domain::make_float(1.10)); - assert!(result.subseteq(&enclosure)); -} - - -// Exponential (7 tests). - -#[test] -fn exp_free() { - // exp((-inf, +inf)) = (0, +inf) - let result = domain::exp(&domain::free_dom()); - let expected = domain::pos_dom(); - assert!(result.eq(&expected)); -} - -#[test] -fn exp_pos() { - // exp((0, +inf)) = (1, +inf) - let result = domain::exp(&domain::pos_dom()); - let expected = Domain::make_oi(domain::one()); - assert!(result.eq(&expected)); -} - -#[test] -fn exp_nonneg() { - // exp([0, +inf)) = [1, +inf) - let result = domain::exp(&domain::nonneg_dom()); - let expected = Domain::make_ci(domain::one()); - assert!(result.eq(&expected)); -} - -#[test] -fn exp_nonpos() { - // exp((-inf, 0]) = (0, 1] - let result = domain::exp(&domain::nonpos_dom()); - let expected = Domain::make_oc(domain::zero(), domain::one()); - assert!(result.eq(&expected)); -} - -#[test] -fn exp_neg() { - // exp((-inf, 0)) = (0, 1) - let result = domain::exp(&domain::neg_dom()); - let expected = Domain::make_oo(domain::zero(), domain::one()); - assert!(result.eq(&expected)); -} - -#[test] -fn exp_gt_two_lt_three_subseteq() { - // exp((2, 3)) \subseteq (7.38, 20.09) - let result = domain::exp(>_two_lt_three()); - let enclosure = Domain::make_oo(domain::make_float(7.38), domain::make_float(20.09)); - assert!(result.subseteq(&enclosure)); -} - - /* Checkers */ From 060763752b6d4b1e2ce4363fa952e4d32e62880c Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Thu, 18 Apr 2024 20:14:24 -0400 Subject: [PATCH 13/23] test: interval `mul` tests --- egg-pre-dcp/tests/test_domain.rs | 194 ++++++++++++++++++++++++++++++- 1 file changed, 193 insertions(+), 1 deletion(-) diff --git a/egg-pre-dcp/tests/test_domain.rs b/egg-pre-dcp/tests/test_domain.rs index 3766ca7d..942498f4 100644 --- a/egg-pre-dcp/tests/test_domain.rs +++ b/egg-pre-dcp/tests/test_domain.rs @@ -13,6 +13,56 @@ use domain::Domain as Domain; /* Some useful intervals for testing apart from pos, nonneg, nonpos, neg, free. */ +// [-9, 6) +fn ge_minus_nine_lt_six() -> Domain { + Domain::make_co(domain::make_float(-9.0), domain::make_float(6.0)) +} + +// (-9, 6] +fn gt_minus_nine_le_six() -> Domain { + Domain::make_oc(domain::make_float(-9.0), domain::make_float(6.0)) +} + +// [-6, 0] +fn ge_minus_six_le_zero() -> Domain { + Domain::make_cc(domain::make_float(-6.0), domain::neg_zero()) +} + +// (-6, 0] +fn gt_minus_six_le_zero() -> Domain { + Domain::make_oc(domain::make_float(-6.0), domain::zero()) +} + +// (-6, 6) +fn gt_minus_six_lt_six() -> Domain { + Domain::make_oo(domain::make_float(-6.0), domain::make_float(6.0)) +} + +// (-6, 6] +fn gt_minus_six_le_six() -> Domain { + Domain::make_oc(domain::make_float(-6.0), domain::make_float(6.0)) +} + +// (-6, 9) +fn gt_minus_six_lt_nine() -> Domain { + Domain::make_oo(domain::make_float(-6.0), domain::make_float(9.0)) +} + +// [-4, 4) +fn ge_minus_four_lt_four() -> Domain { + Domain::make_co(domain::make_float(-4.0), domain::make_float(4.0)) +} + +// (-4, 4] +fn gt_minus_four_le_four() -> Domain { + Domain::make_oc(domain::make_float(-4.0), domain::make_float(4.0)) +} + +// [-3, -2) +fn ge_minus_three_lt_minus_two() -> Domain { + Domain::make_co(domain::make_float(-3.0), domain::make_float(-2.0)) +} + // (-3, -2) fn gt_minus_three_lt_minus_two() -> Domain { Domain::make_oo(domain::make_float(-3.0), domain::make_float(-2.0)) @@ -28,6 +78,16 @@ fn gt_minus_three_lt_three() -> Domain { Domain::make_oo(domain::make_float(-3.0), domain::make_float(3.0)) } +// [-2, 0] +fn ge_minus_two_le_zero() -> Domain { + Domain::make_cc(domain::make_float(-2.0), domain::zero()) +} + +// [-2, 3) +fn ge_minus_two_lt_three() -> Domain { + Domain::make_co(domain::make_float(-2.0), domain::make_float(3.0)) +} + // (-2, 2) fn gt_minus_two_lt_two() -> Domain { Domain::make_oo(domain::make_float(-2.0), domain::make_float(2.0)) @@ -43,6 +103,11 @@ fn gt_minus_two_lt_three() -> Domain { Domain::make_oo(domain::make_float(-2.0), domain::make_float(3.0)) } +// (-2, 3] +fn gt_minus_two_le_three() -> Domain { + Domain::make_oc(domain::make_float(-2.0), domain::make_float(3.0)) +} + // [0, 1) fn ge_zero_lt_one() -> Domain { Domain::make_co(domain::zero(), domain::one()) @@ -68,6 +133,16 @@ fn ge_zero_lt_three() -> Domain { Domain::make_co(domain::zero(), domain::make_float(3.0)) } +// [0, 6) +fn ge_zero_lt_six() -> Domain { + Domain::make_co(domain::zero(), domain::make_float(6.0)) +} + +// [0, 6] +fn ge_zero_le_six() -> Domain { + Domain::make_cc(domain::zero(), domain::make_float(6.0)) +} + // (1, +inf) fn gt_one() -> Domain { Domain::make_oi(domain::one()) @@ -83,6 +158,11 @@ fn gt_two_lt_three() -> Domain { Domain::make_oo(domain::make_float(2.0), domain::make_float(3.0)) } +// (4, 9) +fn gt_four_lt_nine() -> Domain { + Domain::make_oo(domain::make_float(4.0), domain::make_float(9.0)) +} + /* Operations */ @@ -631,7 +711,7 @@ fn sub_gt_minus_two_lt_three_ge_zero_le_one() { } -// Multiplication (16 tests). +// Multiplication (30 tests). #[test] fn mul_pos_pos() { @@ -762,6 +842,118 @@ fn mul_neg_neg() { assert!(result.eq(&expected)); } +#[test] +fn mul_gt_two_lt_three_gt_two_lt_three() { + // (2, 3) * (2, 3) = (4, 9) + let result = domain::mul(>_two_lt_three(), >_two_lt_three()); + let expected = gt_four_lt_nine(); + assert!(result.eq(&expected)); +} + +#[test] +fn mul_ge_minus_three_lt_minus_two_gt_minus_three_lt_minus_two() { + // [-3, -2) * (-3, -2) = (4, 9) + let result = domain::mul(&ge_minus_three_lt_minus_two(), >_minus_three_lt_minus_two()); + let expected = gt_four_lt_nine(); + assert!(result.eq(&expected)); +} + +#[test] +fn mul_gt_two_lt_three_ge_zero_le_two() { + // (2, 3) * [0, 2] = [0, 6) + let result = domain::mul(>_two_lt_three(), &ge_zero_le_two()); + let expected = ge_zero_lt_six(); + assert!(result.eq(&expected)); +} + +#[test] +fn mul_gt_two_lt_three_ge_minus_two_le_zero() { + // (2, 3) * [-2, 0] = (-6, 0] + let result = domain::mul(>_two_lt_three(), &ge_minus_two_le_zero()); + let expected = gt_minus_six_le_zero(); + assert!(result.eq(&expected)); +} + +#[test] +fn mul_gt_two_lt_three_gt_minus_two_le_three() { + // (2, 3) * (-2, 3] = (-6, 9) + let result = domain::mul(>_two_lt_three(), >_minus_two_le_three()); + let expected = gt_minus_six_lt_nine(); + assert!(result.eq(&expected)); +} + +#[test] +fn mul_gt_two_lt_three_ge_minus_two_lt_three() { + // (2, 3) * [-2, 3) = (-6, 9) + let result = domain::mul(>_two_lt_three(), &ge_minus_two_lt_three()); + let expected = gt_minus_six_lt_nine(); + assert!(result.eq(&expected)); +} + +#[test] +fn mul_ge_minus_three_lt_minus_two_ge_zero_le_two() { + // [-3, -2) * [0, 2] = [-6, 0] + let result = domain::mul(&ge_minus_three_lt_minus_two(), &ge_zero_le_two()); + let expected = ge_minus_six_le_zero(); + assert!(result.eq(&expected)); +} + +#[test] +fn mul_ge_minus_three_lt_minus_two_ge_minus_two_le_zero() { + // [-3, -2) * [-2, 0] = [0, 6] + let result = domain::mul(&ge_minus_three_lt_minus_two(), &ge_minus_two_le_zero()); + let expected = ge_zero_le_six(); + assert!(result.eq(&expected)); +} + +#[test] +fn mul_ge_minus_three_lt_minus_two_gt_minus_two_le_three() { + // [-3, -2) * (-2, 3] = [-9, 6) + let result = domain::mul(&ge_minus_three_lt_minus_two(), >_minus_two_le_three()); + let expected = ge_minus_nine_lt_six(); + assert!(result.eq(&expected)); +} + +#[test] +fn mul_ge_minus_three_lt_minus_two_ge_minus_two_lt_three() { + // [-3, -2) * [-2, 3) = (-9, 6] + let result = domain::mul(&ge_minus_three_lt_minus_two(), &ge_minus_two_lt_three()); + let expected = gt_minus_nine_le_six(); + assert!(result.eq(&expected)); +} + +#[test] +fn mul_gt_minus_two_le_two_ge_zero_le_two() { + // (-2, 2] * [0, 2] = (-4, 4] + let result = domain::mul(>_minus_two_le_two(), &ge_zero_le_two()); + let expected = gt_minus_four_le_four(); + assert!(result.eq(&expected)); +} + +#[test] +fn mul_gt_minus_two_le_two_ge_minus_two_le_zero() { + // (-2, 2] * [-2, 0] = [-4, 4) + let result = domain::mul(>_minus_two_le_two(), &ge_minus_two_le_zero()); + let expected = ge_minus_four_lt_four(); + assert!(result.eq(&expected)); +} + +#[test] +fn mul_gt_minus_two_le_two_gt_minus_two_le_three() { + // (-2, 2] * (-2, 3] = (-6, 6] + let result = domain::mul(>_minus_two_le_two(), >_minus_two_le_three()); + let expected = gt_minus_six_le_six(); + assert!(result.eq(&expected)); +} + +#[test] +fn mul_gt_minus_two_le_two_ge_minus_two_lt_three() { + // (-2, 2] * [-2, 3) = (-6, 6) + let result = domain::mul(>_minus_two_le_two(), &ge_minus_two_lt_three()); + let expected = gt_minus_six_lt_six(); + assert!(result.eq(&expected)); +} + // Division (18 tests). From a6eecc94dc721927d7451fdc61653869b8539dfa Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Thu, 18 Apr 2024 20:20:49 -0400 Subject: [PATCH 14/23] refactor: neater `is_zero` and `is_one` --- egg-pre-dcp/src/domain.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/egg-pre-dcp/src/domain.rs b/egg-pre-dcp/src/domain.rs index a8456fef..72b6623c 100644 --- a/egg-pre-dcp/src/domain.rs +++ b/egg-pre-dcp/src/domain.rs @@ -339,7 +339,7 @@ pub fn zero_dom() -> Domain { } pub fn is_zero(d: &Domain) -> bool { - d.subseteq(&zero_dom()) && zero_dom().subseteq(&d) + d.eq(&zero_dom()) } pub fn option_is_zero(d: Option<&Domain>) -> bool { @@ -351,7 +351,7 @@ pub fn one_dom() -> Domain { } pub fn is_one(d: &Domain) -> bool { - d.subseteq(&one_dom()) && one_dom().subseteq(&d) + d.eq(&one_dom()) } pub fn option_is_one(d: Option<&Domain>) -> bool { From 72f99b5adcb6d38522ceb9ead1786bd0a084ea2c Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Thu, 18 Apr 2024 20:21:20 -0400 Subject: [PATCH 15/23] style: no prints in tests --- egg-pre-dcp/tests/test_domain.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/egg-pre-dcp/tests/test_domain.rs b/egg-pre-dcp/tests/test_domain.rs index 942498f4..c266833a 100644 --- a/egg-pre-dcp/tests/test_domain.rs +++ b/egg-pre-dcp/tests/test_domain.rs @@ -250,7 +250,6 @@ fn abs_gt_minus_three_lt_two() { // abs((-3, 2)) = [0, 3) let result = domain::abs(>_minus_three_lt_two()); let expected = ge_zero_lt_three(); - println!("{:?}", result); assert!(result.eq(&expected)); } @@ -302,7 +301,6 @@ fn sqrt_neg() { // sqrt((-inf, 0)) = (-inf, +inf) let result = domain::sqrt(&domain::neg_dom()); let expected = domain::free_dom(); - println!("{:?}", result); assert!(result.eq(&expected)); } From fbc8dc8e2c2aa291ba8cc70b862158faa9ea70e4 Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Tue, 23 Apr 2024 13:24:28 -0400 Subject: [PATCH 16/23] test: interval `min` and `max` --- egg-pre-dcp/tests/test_domain.rs | 73 +++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/egg-pre-dcp/tests/test_domain.rs b/egg-pre-dcp/tests/test_domain.rs index c266833a..4b34c8d3 100644 --- a/egg-pre-dcp/tests/test_domain.rs +++ b/egg-pre-dcp/tests/test_domain.rs @@ -68,6 +68,11 @@ fn gt_minus_three_lt_minus_two() -> Domain { Domain::make_oo(domain::make_float(-3.0), domain::make_float(-2.0)) } +// (-3, 0] +fn gt_minus_three_le_zero() -> Domain { + Domain::make_oc(domain::make_float(-3.0), domain::zero()) +} + // (-3, 2) fn gt_minus_three_lt_two() -> Domain { Domain::make_oo(domain::make_float(-3.0), domain::make_float(2.0)) @@ -1100,10 +1105,74 @@ fn div_one_pos() { } -// Min (TODO). +// Min (4 tests). + +#[test] +fn min_pos_nonneg() { + // min((0, +inf), [0, +inf)) = [0, +inf) + let result = domain::min(&domain::pos_dom(), &domain::nonneg_dom()); + let expected = domain::nonneg_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn min_nonpos_neg() { + // min((-inf, 0], (-inf, 0)) = (-inf, 0) + let result = domain::min(&domain::nonpos_dom(), &domain::neg_dom()); + let expected = domain::neg_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn min_ge_minus_nine_lt_six_gt_minus_nine_le_six() { + // min([-9, 6), (-9, 6]) = [-9, 6) + let result = domain::min(&ge_minus_nine_lt_six(), >_minus_nine_le_six()); + let expected = ge_minus_nine_lt_six(); + assert!(result.eq(&expected)); +} +#[test] +fn min_gt_minus_three_lt_three_ge_minus_two_le_zero() { + // min((-3, 3), [-2, 0]) = (-3, 0] + let result = domain::min(>_minus_three_lt_three(), &ge_minus_two_le_zero()); + let expected = gt_minus_three_le_zero(); + assert!(result.eq(&expected)); +} -// Max (TODO). + +// Max (4 tests). + +#[test] +fn max_pos_nonneg() { + // max((0, +inf), [0, +inf)) = (0, +inf) + let result = domain::max(&domain::pos_dom(), &domain::nonneg_dom()); + let expected = domain::pos_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn max_nonpos_neg() { + // max((-inf, 0], (-inf, 0)) = (-inf, 0] + let result = domain::max(&domain::nonpos_dom(), &domain::neg_dom()); + let expected = domain::nonpos_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn max_ge_minus_nine_lt_six_gt_minus_nine_le_six() { + // max([-9, 6), (-9, 6]) = (-9, 6] + let result = domain::max(&ge_minus_nine_lt_six(), >_minus_nine_le_six()); + let expected = gt_minus_nine_le_six(); + assert!(result.eq(&expected)); +} + +#[test] +fn max_gt_minus_three_lt_three_ge_minus_two_le_zero() { + // max((-3, 3), [-2, 0]) = [-2, 3) + let result = domain::max(>_minus_three_lt_three(), &ge_minus_two_le_zero()); + let expected = ge_minus_two_lt_three(); + assert!(result.eq(&expected)); +} // Power (16 tests). From f535173bbed3df7dc01729879c475834d82afe9f Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Tue, 23 Apr 2024 14:06:33 -0400 Subject: [PATCH 17/23] feat: interval macros --- egg-pre-dcp/src/domain.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/egg-pre-dcp/src/domain.rs b/egg-pre-dcp/src/domain.rs index 72b6623c..0ad6aaff 100644 --- a/egg-pre-dcp/src/domain.rs +++ b/egg-pre-dcp/src/domain.rs @@ -241,6 +241,33 @@ impl Domain { } } +#[macro_export] +macro_rules! CC { + ($start:expr, $end:expr) => { + Domain::make_cc(domain::make_float($start), domain::make_float($end)) + }; +} + +#[macro_export] +macro_rules! CO { + ($start:expr, $end:expr) => { + Domain::make_co(domain::make_float($start), domain::make_float($end)) + }; +} + +#[macro_export] +macro_rules! OC { + ($start:expr, $end:expr) => { + Domain::make_oc(domain::make_float($start), domain::make_float($end)) + }; +} + +#[macro_export] +macro_rules! OO { + ($start:expr, $end:expr) => { + Domain::make_oo(domain::make_float($start), domain::make_float($end)) + }; +} impl PartialOrd for Domain { fn partial_cmp(&self, other: &Domain) -> Option { From 09c0e98b497f32317aa3cc2e50286e979baf817c Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Tue, 23 Apr 2024 14:15:59 -0400 Subject: [PATCH 18/23] test: more `div` interval tests --- egg-pre-dcp/tests/test_domain.rs | 229 ++++++++++++++++++------------- 1 file changed, 134 insertions(+), 95 deletions(-) diff --git a/egg-pre-dcp/tests/test_domain.rs b/egg-pre-dcp/tests/test_domain.rs index 4b34c8d3..04b84253 100644 --- a/egg-pre-dcp/tests/test_domain.rs +++ b/egg-pre-dcp/tests/test_domain.rs @@ -6,6 +6,10 @@ mod test_domain { use egg_pre_dcp; +use egg_pre_dcp::CC as CC; +use egg_pre_dcp::CO as CO; +use egg_pre_dcp::OC as OC; +use egg_pre_dcp::OO as OO; use egg_pre_dcp::domain; use domain::Domain as Domain; @@ -14,159 +18,130 @@ use domain::Domain as Domain; /* Some useful intervals for testing apart from pos, nonneg, nonpos, neg, free. */ // [-9, 6) -fn ge_minus_nine_lt_six() -> Domain { - Domain::make_co(domain::make_float(-9.0), domain::make_float(6.0)) -} +fn ge_minus_nine_lt_six() -> Domain { CO!(-9.0, 6.0) } // (-9, 6] -fn gt_minus_nine_le_six() -> Domain { - Domain::make_oc(domain::make_float(-9.0), domain::make_float(6.0)) -} +fn gt_minus_nine_le_six() -> Domain { OC!(-9.0, 6.0) } // [-6, 0] -fn ge_minus_six_le_zero() -> Domain { - Domain::make_cc(domain::make_float(-6.0), domain::neg_zero()) -} +fn ge_minus_six_le_zero() -> Domain { CC!(-6.0, 0.0) } // (-6, 0] -fn gt_minus_six_le_zero() -> Domain { - Domain::make_oc(domain::make_float(-6.0), domain::zero()) -} +fn gt_minus_six_le_zero() -> Domain { OC!(-6.0, 0.0) } // (-6, 6) -fn gt_minus_six_lt_six() -> Domain { - Domain::make_oo(domain::make_float(-6.0), domain::make_float(6.0)) -} +fn gt_minus_six_lt_six() -> Domain { OO!(-6.0, 6.0) } // (-6, 6] -fn gt_minus_six_le_six() -> Domain { - Domain::make_oc(domain::make_float(-6.0), domain::make_float(6.0)) -} +fn gt_minus_six_le_six() -> Domain { OC!(-6.0, 6.0) } // (-6, 9) -fn gt_minus_six_lt_nine() -> Domain { - Domain::make_oo(domain::make_float(-6.0), domain::make_float(9.0)) -} +fn gt_minus_six_lt_nine() -> Domain { OO!(-6.0, 9.0) } + +// [-4, -1) +fn ge_minus_four_lt_minus_one() -> Domain { CO!(-4.0, -1.0) } + +// [-4, 2) +fn ge_minus_four_lt_two() -> Domain { CO!(-4.0, 2.0) } // [-4, 4) -fn ge_minus_four_lt_four() -> Domain { - Domain::make_co(domain::make_float(-4.0), domain::make_float(4.0)) -} +fn ge_minus_four_lt_four() -> Domain { CO!(-4.0, 4.0) } + +// (-4, -2) +fn gt_minus_four_lt_minus_two() -> Domain { OO!(-4.0, -2.0) } // (-4, 4] -fn gt_minus_four_le_four() -> Domain { - Domain::make_oc(domain::make_float(-4.0), domain::make_float(4.0)) -} +fn gt_minus_four_le_four() -> Domain { OC!(-4.0, 4.0) } // [-3, -2) -fn ge_minus_three_lt_minus_two() -> Domain { - Domain::make_co(domain::make_float(-3.0), domain::make_float(-2.0)) -} +fn ge_minus_three_lt_minus_two() -> Domain { CO!(-3.0, -2.0) } // (-3, -2) -fn gt_minus_three_lt_minus_two() -> Domain { - Domain::make_oo(domain::make_float(-3.0), domain::make_float(-2.0)) -} +fn gt_minus_three_lt_minus_two() -> Domain { OO!(-3.0, -2.0) } // (-3, 0] -fn gt_minus_three_le_zero() -> Domain { - Domain::make_oc(domain::make_float(-3.0), domain::zero()) -} +fn gt_minus_three_le_zero() -> Domain { OC!(-3.0, 0.0) } // (-3, 2) -fn gt_minus_three_lt_two() -> Domain { - Domain::make_oo(domain::make_float(-3.0), domain::make_float(2.0)) -} +fn gt_minus_three_lt_two() -> Domain { OO!(-3.0, 2.0) } // (-3, 3) -fn gt_minus_three_lt_three() -> Domain { - Domain::make_oo(domain::make_float(-3.0), domain::make_float(3.0)) -} +fn gt_minus_three_lt_three() -> Domain { OO!(-3.0, 3.0) } + +// [-2, -1] +fn ge_minus_two_le_minus_one() -> Domain { CC!(-2.0, -1.0) } // [-2, 0] -fn ge_minus_two_le_zero() -> Domain { - Domain::make_cc(domain::make_float(-2.0), domain::zero()) -} +fn ge_minus_two_le_zero() -> Domain { CC!(-2.0, 0.0) } // [-2, 3) -fn ge_minus_two_lt_three() -> Domain { - Domain::make_co(domain::make_float(-2.0), domain::make_float(3.0)) -} +fn ge_minus_two_lt_three() -> Domain { CO!(-2.0, 3.0) } // (-2, 2) -fn gt_minus_two_lt_two() -> Domain { - Domain::make_oo(domain::make_float(-2.0), domain::make_float(2.0)) -} +fn gt_minus_two_lt_two() -> Domain { OO!(-2.0, 2.0) } // (-2, 2] -fn gt_minus_two_le_two() -> Domain { - Domain::make_oc(domain::make_float(-2.0), domain::make_float(2.0)) -} +fn gt_minus_two_le_two() -> Domain { OC!(-2.0, 2.0) } // (-2, 3) -fn gt_minus_two_lt_three() -> Domain { - Domain::make_oo(domain::make_float(-2.0), domain::make_float(3.0)) -} +fn gt_minus_two_lt_three() -> Domain { OO!(-2.0, 3.0) } // (-2, 3] -fn gt_minus_two_le_three() -> Domain { - Domain::make_oc(domain::make_float(-2.0), domain::make_float(3.0)) -} +fn gt_minus_two_le_three() -> Domain { OC!(-2.0, 3.0) } + +// (-2, 4] +fn gt_minus_two_le_four() -> Domain { OC!(-2.0, 4.0) } + +// (-1, 1) +fn gt_minus_one_le_one() -> Domain { OO!(-1.0, 1.0) } // [0, 1) -fn ge_zero_lt_one() -> Domain { - Domain::make_co(domain::zero(), domain::one()) -} +fn ge_zero_lt_one() -> Domain { CO!(0.0, 1.0) } // [0, 1] -fn ge_zero_le_one() -> Domain { - Domain::make_cc(domain::zero(), domain::one()) -} +fn ge_zero_le_one() -> Domain { CC!(0.0, 1.0) } // [0, 2) -fn ge_zero_lt_two() -> Domain { - Domain::make_co(domain::zero(), domain::make_float(2.0)) -} +fn ge_zero_lt_two() -> Domain { CO!(0.0, 2.0) } // [0, 2] -fn ge_zero_le_two() -> Domain { - Domain::make_cc(domain::zero(), domain::make_float(2.0)) -} +fn ge_zero_le_two() -> Domain { CC!(0.0, 2.0) } // [0, 3) -fn ge_zero_lt_three() -> Domain { - Domain::make_co(domain::zero(), domain::make_float(3.0)) -} +fn ge_zero_lt_three() -> Domain { CO!(0.0, 3.0) } // [0, 6) -fn ge_zero_lt_six() -> Domain { - Domain::make_co(domain::zero(), domain::make_float(6.0)) -} +fn ge_zero_lt_six() -> Domain { CO!(0.0, 6.0) } // [0, 6] -fn ge_zero_le_six() -> Domain { - Domain::make_cc(domain::zero(), domain::make_float(6.0)) -} +fn ge_zero_le_six() -> Domain { CC!(0.0, 6.0) } + +// [1, 2] +fn ge_one_le_two() -> Domain { CC!(1.0, 2.0) } // (1, +inf) -fn gt_one() -> Domain { - Domain::make_oi(domain::one()) -} +fn gt_one() -> Domain { Domain::make_oi(domain::one()) } // [1, +inf) -fn ge_one() -> Domain { - Domain::make_ci(domain::one()) -} +fn ge_one() -> Domain { Domain::make_ci(domain::one()) } + +// (1, 4] +fn gt_one_le_four() -> Domain { OC!(1.0, 4.0) } + +// [2, 4] +fn ge_two_le_four() -> Domain { CC!(2.0, 4.0) } // (2, 3) -fn gt_two_lt_three() -> Domain { - Domain::make_oo(domain::make_float(2.0), domain::make_float(3.0)) -} +fn gt_two_lt_three() -> Domain { OO!(2.0, 3.0) } + +// (2, 4) +fn gt_two_lt_four() -> Domain { OO!(2.0, 4.0) } + +// (2, 4] +fn gt_two_le_four() -> Domain { OC!(2.0, 4.0) } // (4, 9) -fn gt_four_lt_nine() -> Domain { - Domain::make_oo(domain::make_float(4.0), domain::make_float(9.0)) -} +fn gt_four_lt_nine() -> Domain { OO!(4.0, 9.0) } @@ -224,7 +199,7 @@ fn neg_gt_two_lt_three() { } -// Absolute value (TODO). +// Absolute value (6 tests). #[test] fn abs_gt_two_lt_three() { @@ -958,7 +933,7 @@ fn mul_gt_minus_two_le_two_ge_minus_two_lt_three() { } -// Division (18 tests). +// Division (26 tests). #[test] fn div_pos_pos() { @@ -1104,6 +1079,70 @@ fn div_one_pos() { assert!(result.eq(&expected)); } +#[test] +fn div_gt_two_le_four_ge_one_le_two() { + // (2, 4] / [1, 2] = (1, 4] + let result = domain::div(>_two_le_four(), &ge_one_le_two()); + let expected = gt_one_le_four(); + assert!(result.eq(&expected)); +} + +#[test] +fn div_gt_two_le_four_ge_minus_two_le_minus_one() { + // (2, 4] / [-2, -1] = [-4, -1) + let result = domain::div(>_two_le_four(), &ge_minus_two_le_minus_one()); + let expected = ge_minus_four_lt_minus_one(); + assert!(result.eq(&expected)); +} + +#[test] +fn div_ge_minus_four_lt_two_ge_one_le_two() { + // [-4, 2) / [1, 2] = [-4, 2) + let result = domain::div(&ge_minus_four_lt_two(), &ge_one_le_two()); + let expected = ge_minus_four_lt_two(); + assert!(result.eq(&expected)); +} + +#[test] +fn div_ge_minus_four_lt_two_ge_minus_two_le_minus_one() { + // [-4, 2) / [-2, -1] = (-2, 4] + let result = domain::div(&ge_minus_four_lt_two(), &ge_minus_two_le_minus_one()); + let expected = gt_minus_two_le_four(); + assert!(result.eq(&expected)); +} + +#[test] +fn div_gt_minus_two_lt_two_ge_two_le_four() { + // (-2, 2) / [2, 4] = (-1, 1) + let result = domain::div(>_minus_two_lt_two(), &ge_two_le_four()); + let expected = gt_minus_one_le_one(); + assert!(result.eq(&expected)); +} + +#[test] +fn div_ge_zero_le_two_gt_two_lt_four() { + // [0, 2] / (2, 4) = [0, 1) + let result = domain::div(&ge_zero_le_two(), >_two_lt_four()); + let expected = ge_zero_lt_one(); + assert!(result.eq(&expected)); +} + +#[test] +fn div_gt_minus_two_lt_two_ge_minus_two_le_minus_one() { + // (-2, 2) / [-2, -1] = (-2, 2) + let result = domain::div(>_minus_two_lt_two(), &ge_minus_two_le_minus_one()); + let expected = gt_minus_two_lt_two(); + assert!(result.eq(&expected)); +} + +#[test] +fn div_ge_minus_two_le_zero_gt_minus_four_lt_minus_two() { + // [-2, 0] / (-4, -2) = [0, 1) + let result = domain::div(&ge_minus_two_le_zero(), >_minus_four_lt_minus_two()); + let expected = ge_zero_lt_one(); + assert!(result.eq(&expected)); +} + // Min (4 tests). From 3285d4e8e3bb518bf9126f7f676924b6d4537a26 Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Tue, 23 Apr 2024 14:33:13 -0400 Subject: [PATCH 19/23] feat: macros for all intervals --- egg-pre-dcp/src/domain.rs | 36 +++++++++++++++++++++----------- egg-pre-dcp/tests/test_domain.rs | 14 +++++++------ 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/egg-pre-dcp/src/domain.rs b/egg-pre-dcp/src/domain.rs index 0ad6aaff..fe25687c 100644 --- a/egg-pre-dcp/src/domain.rs +++ b/egg-pre-dcp/src/domain.rs @@ -243,30 +243,42 @@ impl Domain { #[macro_export] macro_rules! CC { - ($start:expr, $end:expr) => { - Domain::make_cc(domain::make_float($start), domain::make_float($end)) - }; + ($a:expr, $b:expr) => { Domain::make_cc(domain::make_float($a), domain::make_float($b)) }; } #[macro_export] macro_rules! CO { - ($start:expr, $end:expr) => { - Domain::make_co(domain::make_float($start), domain::make_float($end)) - }; + ($a:expr, $b:expr) => { Domain::make_co(domain::make_float($a), domain::make_float($b)) }; +} + +#[macro_export] +macro_rules! CI { + ($a:expr) => { Domain::make_ci(domain::make_float($a)) }; } #[macro_export] macro_rules! OC { - ($start:expr, $end:expr) => { - Domain::make_oc(domain::make_float($start), domain::make_float($end)) - }; + ($a:expr, $b:expr) => { Domain::make_oc(domain::make_float($a), domain::make_float($b)) }; } #[macro_export] macro_rules! OO { - ($start:expr, $end:expr) => { - Domain::make_oo(domain::make_float($start), domain::make_float($end)) - }; + ($a:expr, $b:expr) => { Domain::make_oo(domain::make_float($a), domain::make_float($b)) }; +} + +#[macro_export] +macro_rules! OI { + ($b:expr) => { Domain::make_oi(domain::make_float($b)) }; +} + +#[macro_export] +macro_rules! IC { + ($b:expr) => { Domain::make_ic(domain::make_float($b)) }; +} + +#[macro_export] +macro_rules! IO { + ($b:expr) => { Domain::make_io(domain::make_float($b)) }; } impl PartialOrd for Domain { diff --git a/egg-pre-dcp/tests/test_domain.rs b/egg-pre-dcp/tests/test_domain.rs index 04b84253..2c13ca3e 100644 --- a/egg-pre-dcp/tests/test_domain.rs +++ b/egg-pre-dcp/tests/test_domain.rs @@ -6,10 +6,12 @@ mod test_domain { use egg_pre_dcp; -use egg_pre_dcp::CC as CC; -use egg_pre_dcp::CO as CO; -use egg_pre_dcp::OC as OC; -use egg_pre_dcp::OO as OO; +use egg_pre_dcp::CC; +use egg_pre_dcp::CO; +use egg_pre_dcp::CI; +use egg_pre_dcp::OC; +use egg_pre_dcp::OO; +use egg_pre_dcp::OI; use egg_pre_dcp::domain; use domain::Domain as Domain; @@ -120,10 +122,10 @@ fn ge_zero_le_six() -> Domain { CC!(0.0, 6.0) } fn ge_one_le_two() -> Domain { CC!(1.0, 2.0) } // (1, +inf) -fn gt_one() -> Domain { Domain::make_oi(domain::one()) } +fn gt_one() -> Domain { OI!(1.0) } // [1, +inf) -fn ge_one() -> Domain { Domain::make_ci(domain::one()) } +fn ge_one() -> Domain { CI!(1.0) } // (1, 4] fn gt_one_le_four() -> Domain { OC!(1.0, 4.0) } From d234a2d23060308d1d26fc59fd4b4b91af093d97 Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Tue, 23 Apr 2024 17:57:05 -0400 Subject: [PATCH 20/23] style: do not name all intervals --- egg-pre-dcp/tests/test_domain.rs | 339 +++++++++++-------------------- 1 file changed, 116 insertions(+), 223 deletions(-) diff --git a/egg-pre-dcp/tests/test_domain.rs b/egg-pre-dcp/tests/test_domain.rs index 2c13ca3e..a3be83ca 100644 --- a/egg-pre-dcp/tests/test_domain.rs +++ b/egg-pre-dcp/tests/test_domain.rs @@ -17,136 +17,6 @@ use domain::Domain as Domain; -/* Some useful intervals for testing apart from pos, nonneg, nonpos, neg, free. */ - -// [-9, 6) -fn ge_minus_nine_lt_six() -> Domain { CO!(-9.0, 6.0) } - -// (-9, 6] -fn gt_minus_nine_le_six() -> Domain { OC!(-9.0, 6.0) } - -// [-6, 0] -fn ge_minus_six_le_zero() -> Domain { CC!(-6.0, 0.0) } - -// (-6, 0] -fn gt_minus_six_le_zero() -> Domain { OC!(-6.0, 0.0) } - -// (-6, 6) -fn gt_minus_six_lt_six() -> Domain { OO!(-6.0, 6.0) } - -// (-6, 6] -fn gt_minus_six_le_six() -> Domain { OC!(-6.0, 6.0) } - -// (-6, 9) -fn gt_minus_six_lt_nine() -> Domain { OO!(-6.0, 9.0) } - -// [-4, -1) -fn ge_minus_four_lt_minus_one() -> Domain { CO!(-4.0, -1.0) } - -// [-4, 2) -fn ge_minus_four_lt_two() -> Domain { CO!(-4.0, 2.0) } - -// [-4, 4) -fn ge_minus_four_lt_four() -> Domain { CO!(-4.0, 4.0) } - -// (-4, -2) -fn gt_minus_four_lt_minus_two() -> Domain { OO!(-4.0, -2.0) } - -// (-4, 4] -fn gt_minus_four_le_four() -> Domain { OC!(-4.0, 4.0) } - -// [-3, -2) -fn ge_minus_three_lt_minus_two() -> Domain { CO!(-3.0, -2.0) } - -// (-3, -2) -fn gt_minus_three_lt_minus_two() -> Domain { OO!(-3.0, -2.0) } - -// (-3, 0] -fn gt_minus_three_le_zero() -> Domain { OC!(-3.0, 0.0) } - -// (-3, 2) -fn gt_minus_three_lt_two() -> Domain { OO!(-3.0, 2.0) } - -// (-3, 3) -fn gt_minus_three_lt_three() -> Domain { OO!(-3.0, 3.0) } - -// [-2, -1] -fn ge_minus_two_le_minus_one() -> Domain { CC!(-2.0, -1.0) } - -// [-2, 0] -fn ge_minus_two_le_zero() -> Domain { CC!(-2.0, 0.0) } - -// [-2, 3) -fn ge_minus_two_lt_three() -> Domain { CO!(-2.0, 3.0) } - -// (-2, 2) -fn gt_minus_two_lt_two() -> Domain { OO!(-2.0, 2.0) } - -// (-2, 2] -fn gt_minus_two_le_two() -> Domain { OC!(-2.0, 2.0) } - -// (-2, 3) -fn gt_minus_two_lt_three() -> Domain { OO!(-2.0, 3.0) } - -// (-2, 3] -fn gt_minus_two_le_three() -> Domain { OC!(-2.0, 3.0) } - -// (-2, 4] -fn gt_minus_two_le_four() -> Domain { OC!(-2.0, 4.0) } - -// (-1, 1) -fn gt_minus_one_le_one() -> Domain { OO!(-1.0, 1.0) } - -// [0, 1) -fn ge_zero_lt_one() -> Domain { CO!(0.0, 1.0) } - -// [0, 1] -fn ge_zero_le_one() -> Domain { CC!(0.0, 1.0) } - -// [0, 2) -fn ge_zero_lt_two() -> Domain { CO!(0.0, 2.0) } - -// [0, 2] -fn ge_zero_le_two() -> Domain { CC!(0.0, 2.0) } - -// [0, 3) -fn ge_zero_lt_three() -> Domain { CO!(0.0, 3.0) } - -// [0, 6) -fn ge_zero_lt_six() -> Domain { CO!(0.0, 6.0) } - -// [0, 6] -fn ge_zero_le_six() -> Domain { CC!(0.0, 6.0) } - -// [1, 2] -fn ge_one_le_two() -> Domain { CC!(1.0, 2.0) } - -// (1, +inf) -fn gt_one() -> Domain { OI!(1.0) } - -// [1, +inf) -fn ge_one() -> Domain { CI!(1.0) } - -// (1, 4] -fn gt_one_le_four() -> Domain { OC!(1.0, 4.0) } - -// [2, 4] -fn ge_two_le_four() -> Domain { CC!(2.0, 4.0) } - -// (2, 3) -fn gt_two_lt_three() -> Domain { OO!(2.0, 3.0) } - -// (2, 4) -fn gt_two_lt_four() -> Domain { OO!(2.0, 4.0) } - -// (2, 4] -fn gt_two_le_four() -> Domain { OC!(2.0, 4.0) } - -// (4, 9) -fn gt_four_lt_nine() -> Domain { OO!(4.0, 9.0) } - - - /* Operations */ @@ -195,8 +65,8 @@ fn neg_free() { #[test] fn neg_gt_two_lt_three() { // -(2, 3) = (-3, -2) - let result = domain::neg(>_two_lt_three()); - let expected = gt_minus_three_lt_minus_two(); + let result = domain::neg(&OO!(2.0, 3.0)); + let expected = OO!(-3.0, -2.0); assert!(result.eq(&expected)); } @@ -206,48 +76,48 @@ fn neg_gt_two_lt_three() { #[test] fn abs_gt_two_lt_three() { // abs((2, 3)) = (2, 3) - let result = domain::abs(>_two_lt_three()); - let expected = gt_two_lt_three(); + let result = domain::abs(&OO!(2.0, 3.0)); + let expected = OO!(2.0, 3.0); assert!(result.eq(&expected)); } #[test] fn abs_gt_minus_three_lt_minus_two() { // abs((-3, -2)) = (2, 3) - let result = domain::abs(>_minus_three_lt_minus_two()); - let expected = gt_two_lt_three(); + let result = domain::abs(&OO!(-3.0, -2.0)); + let expected = OO!(2.0, 3.0); assert!(result.eq(&expected)); } #[test] fn abs_gt_minus_two_lt_three() { // abs((-2, 3)) = [0, 3) - let result = domain::abs(>_minus_two_lt_three()); - let expected = ge_zero_lt_three(); + let result = domain::abs(&OO!(-2.0, 3.0)); + let expected = CO!(0.0, 3.0); assert!(result.eq(&expected)); } #[test] fn abs_gt_minus_three_lt_two() { // abs((-3, 2)) = [0, 3) - let result = domain::abs(>_minus_three_lt_two()); - let expected = ge_zero_lt_three(); + let result = domain::abs(&OO!(-3.0, 2.0)); + let expected = CO!(0.0, 3.0); assert!(result.eq(&expected)); } #[test] fn abs_gt_minus_two_le_two() { // abs((-2, 2]) = [0, 2] - let result = domain::abs(>_minus_two_le_two()); - let expected = ge_zero_le_two(); + let result = domain::abs(&OC!(-2.0, 2.0)); + let expected = CC!(0.0, 2.0); assert!(result.eq(&expected)); } #[test] fn abs_gt_minus_two_lt_two() { // abs((-2, 2)) = [0, 2) - let result = domain::abs(>_minus_two_lt_two()); - let expected = ge_zero_lt_two(); + let result = domain::abs(&OO!(-2.0, 2.0)); + let expected = CO!(0.0, 2.0); assert!(result.eq(&expected)); } @@ -289,7 +159,7 @@ fn sqrt_neg() { #[test] fn sqrt_gt_two_lt_three_subseteq() { // sqrt((2, 3)) \subseteq (1.41, 1.74) - let result = domain::sqrt(>_two_lt_three()); + let result = domain::sqrt(&OO!(2.0, 3.0)); let enclosure = Domain::make_oo(domain::make_float(1.41), domain::make_float(1.74)); assert!(result.subseteq(&enclosure)); } @@ -332,7 +202,7 @@ fn log_neg() { #[test] fn log_ge_one() { // log([1, +inf)) = [0, +inf) - let result = domain::log(&ge_one()); + let result = domain::log(&CI!(1.0)); let expected = domain::nonneg_dom(); assert!(result.eq(&expected)); } @@ -340,7 +210,7 @@ fn log_ge_one() { #[test] fn log_gt_one() { // log((1, +inf)) = (0, +inf) - let result = domain::log(>_one()); + let result = domain::log(&OI!(1.0)); let expected = domain::pos_dom(); assert!(result.eq(&expected)); } @@ -348,7 +218,7 @@ fn log_gt_one() { #[test] fn log_ge_zero_le_one() { // log([0, 1]) = (-inf, 0] - let result = domain::log(&ge_zero_le_one()); + let result = domain::log(&CC!(0.0, 1.0)); let expected = domain::nonpos_dom(); assert!(result.eq(&expected)); } @@ -356,7 +226,7 @@ fn log_ge_zero_le_one() { #[test] fn log_ge_zero_lt_one() { // log([0, 1)) = (-inf, 0) - let result = domain::log(&ge_zero_lt_one()); + let result = domain::log(&CO!(0.0, 1.0)); let expected = domain::neg_dom(); assert!(result.eq(&expected)); } @@ -364,7 +234,7 @@ fn log_ge_zero_lt_one() { #[test] fn log_gt_two_lt_three_subseteq() { // log((2, 3)) \subseteq (0.69, 1.10) - let result = domain::log(>_two_lt_three()); + let result = domain::log(&OO!(2.0, 3.0)); let enclosure = Domain::make_oo(domain::make_float(0.69), domain::make_float(1.10)); assert!(result.subseteq(&enclosure)); } @@ -415,7 +285,7 @@ fn exp_neg() { #[test] fn exp_gt_two_lt_three_subseteq() { // exp((2, 3)) \subseteq (7.38, 20.09) - let result = domain::exp(>_two_lt_three()); + let result = domain::exp(&OO!(2.0, 3.0)); let enclosure = Domain::make_oo(domain::make_float(7.38), domain::make_float(20.09)); assert!(result.subseteq(&enclosure)); } @@ -554,8 +424,8 @@ fn add_neg_neg() { #[test] fn add_gt_minus_two_le_two_ge_zero_lt_one() { // (-2, 2] + [0, 1) = (-2, 3) - let result = domain::add(>_minus_two_le_two(), &ge_zero_lt_one()); - let expected = gt_minus_two_lt_three(); + let result = domain::add(&OC!(-2.0, 2.0), &CO!(0.0, 1.0)); + let expected = OO!(-2.0, 3.0); assert!(result.eq(&expected)); } @@ -685,8 +555,8 @@ fn sub_neg_neg() { #[test] fn sub_gt_minus_two_lt_three_ge_zero_le_one() { // (-2, 3) - [0, 1] = (-3, 3) - let result = domain::sub(>_minus_two_lt_three(), &ge_zero_le_one()); - let expected = gt_minus_three_lt_three(); + let result = domain::sub(&OO!(-2.0, 3.0), &CC!(0.0, 1.0)); + let expected = OO!(-3.0, 3.0); assert!(result.eq(&expected)); } @@ -825,112 +695,112 @@ fn mul_neg_neg() { #[test] fn mul_gt_two_lt_three_gt_two_lt_three() { // (2, 3) * (2, 3) = (4, 9) - let result = domain::mul(>_two_lt_three(), >_two_lt_three()); - let expected = gt_four_lt_nine(); + let result = domain::mul(&OO!(2.0, 3.0), &OO!(2.0, 3.0)); + let expected = OO!(4.0, 9.0); assert!(result.eq(&expected)); } #[test] fn mul_ge_minus_three_lt_minus_two_gt_minus_three_lt_minus_two() { // [-3, -2) * (-3, -2) = (4, 9) - let result = domain::mul(&ge_minus_three_lt_minus_two(), >_minus_three_lt_minus_two()); - let expected = gt_four_lt_nine(); + let result = domain::mul(&CO!(-3.0, -2.0), &OO!(-3.0, -2.0)); + let expected = OO!(4.0, 9.0); assert!(result.eq(&expected)); } #[test] fn mul_gt_two_lt_three_ge_zero_le_two() { // (2, 3) * [0, 2] = [0, 6) - let result = domain::mul(>_two_lt_three(), &ge_zero_le_two()); - let expected = ge_zero_lt_six(); + let result = domain::mul(&OO!(2.0, 3.0), &CC!(0.0, 2.0)); + let expected = CO!(0.0, 6.0); assert!(result.eq(&expected)); } #[test] fn mul_gt_two_lt_three_ge_minus_two_le_zero() { // (2, 3) * [-2, 0] = (-6, 0] - let result = domain::mul(>_two_lt_three(), &ge_minus_two_le_zero()); - let expected = gt_minus_six_le_zero(); + let result = domain::mul(&OO!(2.0, 3.0), &CC!(-2.0, 0.0)); + let expected = OC!(-6.0, 0.0); assert!(result.eq(&expected)); } #[test] fn mul_gt_two_lt_three_gt_minus_two_le_three() { // (2, 3) * (-2, 3] = (-6, 9) - let result = domain::mul(>_two_lt_three(), >_minus_two_le_three()); - let expected = gt_minus_six_lt_nine(); + let result = domain::mul(&OO!(2.0, 3.0), &OC!(-2.0, 3.0)); + let expected = OO!(-6.0, 9.0); assert!(result.eq(&expected)); } #[test] fn mul_gt_two_lt_three_ge_minus_two_lt_three() { // (2, 3) * [-2, 3) = (-6, 9) - let result = domain::mul(>_two_lt_three(), &ge_minus_two_lt_three()); - let expected = gt_minus_six_lt_nine(); + let result = domain::mul(&OO!(2.0, 3.0), &CO!(-2.0, 3.0)); + let expected = OO!(-6.0, 9.0); assert!(result.eq(&expected)); } #[test] fn mul_ge_minus_three_lt_minus_two_ge_zero_le_two() { // [-3, -2) * [0, 2] = [-6, 0] - let result = domain::mul(&ge_minus_three_lt_minus_two(), &ge_zero_le_two()); - let expected = ge_minus_six_le_zero(); + let result = domain::mul(&CO!(-3.0, -2.0), &CC!(0.0, 2.0)); + let expected = CC!(-6.0, 0.0); assert!(result.eq(&expected)); } #[test] fn mul_ge_minus_three_lt_minus_two_ge_minus_two_le_zero() { // [-3, -2) * [-2, 0] = [0, 6] - let result = domain::mul(&ge_minus_three_lt_minus_two(), &ge_minus_two_le_zero()); - let expected = ge_zero_le_six(); + let result = domain::mul(&CO!(-3.0, -2.0), &CC!(-2.0, 0.0)); + let expected = CC!(0.0, 6.0); assert!(result.eq(&expected)); } #[test] fn mul_ge_minus_three_lt_minus_two_gt_minus_two_le_three() { // [-3, -2) * (-2, 3] = [-9, 6) - let result = domain::mul(&ge_minus_three_lt_minus_two(), >_minus_two_le_three()); - let expected = ge_minus_nine_lt_six(); + let result = domain::mul(&CO!(-3.0, -2.0), &OC!(-2.0, 3.0)); + let expected = CO!(-9.0, 6.0); assert!(result.eq(&expected)); } #[test] fn mul_ge_minus_three_lt_minus_two_ge_minus_two_lt_three() { // [-3, -2) * [-2, 3) = (-9, 6] - let result = domain::mul(&ge_minus_three_lt_minus_two(), &ge_minus_two_lt_three()); - let expected = gt_minus_nine_le_six(); + let result = domain::mul(&CO!(-3.0, -2.0), &CO!(-2.0, 3.0)); + let expected = OC!(-9.0, 6.0); assert!(result.eq(&expected)); } #[test] fn mul_gt_minus_two_le_two_ge_zero_le_two() { // (-2, 2] * [0, 2] = (-4, 4] - let result = domain::mul(>_minus_two_le_two(), &ge_zero_le_two()); - let expected = gt_minus_four_le_four(); + let result = domain::mul(&OC!(-2.0, 2.0), &CC!(0.0, 2.0)); + let expected = OC!(-4.0, 4.0); assert!(result.eq(&expected)); } #[test] fn mul_gt_minus_two_le_two_ge_minus_two_le_zero() { // (-2, 2] * [-2, 0] = [-4, 4) - let result = domain::mul(>_minus_two_le_two(), &ge_minus_two_le_zero()); - let expected = ge_minus_four_lt_four(); + let result = domain::mul(&OC!(-2.0, 2.0), &CC!(-2.0, 0.0)); + let expected = CO!(-4.0, 4.0); assert!(result.eq(&expected)); } #[test] fn mul_gt_minus_two_le_two_gt_minus_two_le_three() { // (-2, 2] * (-2, 3] = (-6, 6] - let result = domain::mul(>_minus_two_le_two(), >_minus_two_le_three()); - let expected = gt_minus_six_le_six(); + let result = domain::mul(&OC!(-2.0, 2.0), &OC!(-2.0, 3.0)); + let expected = OC!(-6.0, 6.0); assert!(result.eq(&expected)); } #[test] fn mul_gt_minus_two_le_two_ge_minus_two_lt_three() { // (-2, 2] * [-2, 3) = (-6, 6) - let result = domain::mul(>_minus_two_le_two(), &ge_minus_two_lt_three()); - let expected = gt_minus_six_lt_six(); + let result = domain::mul(&OC!(-2.0, 2.0), &CO!(-2.0, 3.0)); + let expected = OO!(-6.0, 6.0); assert!(result.eq(&expected)); } @@ -1076,7 +946,7 @@ fn div_free_pos() { #[test] fn div_one_pos() { // [1, 1] / (0, +inf) = (0, +inf) - let result = domain::div(&Domain::make_singleton(1.0), &domain::pos_dom()); + let result = domain::div(&domain::one_dom(), &domain::pos_dom()); let expected = domain::pos_dom(); assert!(result.eq(&expected)); } @@ -1084,64 +954,64 @@ fn div_one_pos() { #[test] fn div_gt_two_le_four_ge_one_le_two() { // (2, 4] / [1, 2] = (1, 4] - let result = domain::div(>_two_le_four(), &ge_one_le_two()); - let expected = gt_one_le_four(); + let result = domain::div(&OC!(2.0, 4.0), &CC!(1.0, 2.0)); + let expected = OC!(1.0, 4.0); assert!(result.eq(&expected)); } #[test] fn div_gt_two_le_four_ge_minus_two_le_minus_one() { // (2, 4] / [-2, -1] = [-4, -1) - let result = domain::div(>_two_le_four(), &ge_minus_two_le_minus_one()); - let expected = ge_minus_four_lt_minus_one(); + let result = domain::div(&OC!(2.0, 4.0), &CC!(-2.0, -1.0)); + let expected = CO!(-4.0, -1.0); assert!(result.eq(&expected)); } #[test] fn div_ge_minus_four_lt_two_ge_one_le_two() { // [-4, 2) / [1, 2] = [-4, 2) - let result = domain::div(&ge_minus_four_lt_two(), &ge_one_le_two()); - let expected = ge_minus_four_lt_two(); + let result = domain::div(&CO!(-4.0, 2.0), &CC!(1.0, 2.0)); + let expected = CO!(-4.0, 2.0); assert!(result.eq(&expected)); } #[test] fn div_ge_minus_four_lt_two_ge_minus_two_le_minus_one() { // [-4, 2) / [-2, -1] = (-2, 4] - let result = domain::div(&ge_minus_four_lt_two(), &ge_minus_two_le_minus_one()); - let expected = gt_minus_two_le_four(); + let result = domain::div(&CO!(-4.0, 2.0), &CC!(-2.0, -1.0)); + let expected = OC!(-2.0, 4.0); assert!(result.eq(&expected)); } #[test] fn div_gt_minus_two_lt_two_ge_two_le_four() { // (-2, 2) / [2, 4] = (-1, 1) - let result = domain::div(>_minus_two_lt_two(), &ge_two_le_four()); - let expected = gt_minus_one_le_one(); + let result = domain::div(&OO!(-2.0, 2.0), &CC!(2.0, 4.0)); + let expected = OO!(-1.0, 1.0); assert!(result.eq(&expected)); } #[test] fn div_ge_zero_le_two_gt_two_lt_four() { // [0, 2] / (2, 4) = [0, 1) - let result = domain::div(&ge_zero_le_two(), >_two_lt_four()); - let expected = ge_zero_lt_one(); + let result = domain::div(&CC!(0.0, 2.0), &OO!(2.0, 4.0)); + let expected = CO!(0.0, 1.0); assert!(result.eq(&expected)); } #[test] fn div_gt_minus_two_lt_two_ge_minus_two_le_minus_one() { // (-2, 2) / [-2, -1] = (-2, 2) - let result = domain::div(>_minus_two_lt_two(), &ge_minus_two_le_minus_one()); - let expected = gt_minus_two_lt_two(); + let result = domain::div(&OO!(-2.0, 2.0), &CC!(-2.0, -1.0)); + let expected = OO!(-2.0, 2.0); assert!(result.eq(&expected)); } #[test] fn div_ge_minus_two_le_zero_gt_minus_four_lt_minus_two() { // [-2, 0] / (-4, -2) = [0, 1) - let result = domain::div(&ge_minus_two_le_zero(), >_minus_four_lt_minus_two()); - let expected = ge_zero_lt_one(); + let result = domain::div(&CC!(-2.0, 0.0), &OO!(-4.0, -2.0)); + let expected = CO!(0.0, 1.0); assert!(result.eq(&expected)); } @@ -1167,16 +1037,16 @@ fn min_nonpos_neg() { #[test] fn min_ge_minus_nine_lt_six_gt_minus_nine_le_six() { // min([-9, 6), (-9, 6]) = [-9, 6) - let result = domain::min(&ge_minus_nine_lt_six(), >_minus_nine_le_six()); - let expected = ge_minus_nine_lt_six(); + let result = domain::min(&CO!(-9.0, 6.0), &OC!(-9.0, 6.0)); + let expected = CO!(-9.0, 6.0); assert!(result.eq(&expected)); } #[test] fn min_gt_minus_three_lt_three_ge_minus_two_le_zero() { // min((-3, 3), [-2, 0]) = (-3, 0] - let result = domain::min(>_minus_three_lt_three(), &ge_minus_two_le_zero()); - let expected = gt_minus_three_le_zero(); + let result = domain::min(&OO!(-3.0, 3.0), &CC!(-2.0, 0.0)); + let expected = OC!(-3.0, 0.0); assert!(result.eq(&expected)); } @@ -1202,21 +1072,21 @@ fn max_nonpos_neg() { #[test] fn max_ge_minus_nine_lt_six_gt_minus_nine_le_six() { // max([-9, 6), (-9, 6]) = (-9, 6] - let result = domain::max(&ge_minus_nine_lt_six(), >_minus_nine_le_six()); - let expected = gt_minus_nine_le_six(); + let result = domain::max(&CO!(-9.0, 6.0), &OC!(-9.0, 6.0)); + let expected = OC!(-9.0, 6.0); assert!(result.eq(&expected)); } #[test] fn max_gt_minus_three_lt_three_ge_minus_two_le_zero() { // max((-3, 3), [-2, 0]) = [-2, 3) - let result = domain::max(>_minus_three_lt_three(), &ge_minus_two_le_zero()); - let expected = ge_minus_two_lt_three(); + let result = domain::max(&OO!(-3.0, 3.0), &CC!(-2.0, 0.0)); + let expected = CO!(-2.0, 3.0); assert!(result.eq(&expected)); } -// Power (16 tests). +// Power (TODO tests). #[test] fn pow_pos_pos() { @@ -1346,6 +1216,29 @@ fn pow_neg_neg() { assert!(result.eq(&expected)); } +// (-inf, inf) ^ [0, 0] = (-inf, +inf) +// [0, 0] ^ [0, 0] = (-inf, +inf) +// (2, 4] ^ [0, 0] = [1, 1] +// [-3, -2) ^ [0, 0] = [1, 1] + +// (-inf, inf) ^ [1, 1] = (-inf, +inf) +// [0, 0] ^ [1, 1] = [0, 0] +// (2, 4] ^ [1, 1] = (2, 4] +// [-3, -2) ^ [1, 1] = [-3, -2) + +// (-inf, inf) ^ [2, 2] = [0, +inf) +// [0, 0] ^ [2, 2] = [0, 0] +// (2, 4] ^ [2, 2] = (4, 16] +// [-3, -2) ^ [2, 2] = (4, 9] +// (2, 4] ^ [4, 4] = (16, 256] +// [-3, -2) ^ [4, 4] = (16, 81] + +// (2, 4] ^ [2, 3) +// (2, 4] ^ [-3, + +// (0, 0.5] + +// [0.5, 3) /* Checkers */ @@ -1356,13 +1249,13 @@ fn pow_neg_neg() { #[test] fn is_zero_zero() { // [0, 0] is zero - assert!(domain::is_zero(&Domain::make_singleton(0.0))); + assert!(domain::is_zero(&domain::zero_dom())); } #[test] fn not_is_zero_one() { // [1, 1] is not zero - assert!(!domain::is_zero(&Domain::make_singleton(1.0))); + assert!(!domain::is_zero(&domain::one_dom())); } #[test] @@ -1383,13 +1276,13 @@ fn not_is_zero_empty() { #[test] fn is_one_one() { // [1, 1] is one - assert!(domain::is_one(&Domain::make_singleton(1.0))); + assert!(domain::is_one(&domain::one_dom())); } #[test] fn not_is_one_zero() { // [0, 0] is not one - assert!(!domain::is_one(&Domain::make_singleton(0.0))); + assert!(!domain::is_one(&domain::zero_dom())); } #[test] @@ -1416,7 +1309,7 @@ fn is_pos_pos() { #[test] fn is_pos_one() { // [1, 1] is positive - assert!(domain::is_pos(&Domain::make_singleton(1.0))); + assert!(domain::is_pos(&domain::one_dom())); } #[test] @@ -1440,7 +1333,7 @@ fn not_is_pos_free() { #[test] fn not_is_pos_zero() { // [0, 0] is not positive - assert!(!domain::is_pos(&Domain::make_singleton(0.0))); + assert!(!domain::is_pos(&domain::zero_dom())); } @@ -1461,13 +1354,13 @@ fn is_nonneg_nonneg() { #[test] fn is_nonneg_zero() { // [0, 0] is non-negative - assert!(domain::is_nonneg(&Domain::make_singleton(0.0))); + assert!(domain::is_nonneg(&domain::zero_dom())); } #[test] fn is_nonneg_one() { // [1, 1] is non-negative - assert!(domain::is_nonneg(&Domain::make_singleton(1.0))); + assert!(domain::is_nonneg(&domain::one_dom())); } #[test] @@ -1506,7 +1399,7 @@ fn is_nonpos_neg() { #[test] fn is_nonpos_zero() { // [0, 0] is non-positive - assert!(domain::is_nonpos(&Domain::make_singleton(0.0))); + assert!(domain::is_nonpos(&domain::zero_dom())); } #[test] @@ -1530,7 +1423,7 @@ fn not_is_nonpos_free() { #[test] fn not_is_nonpos_one() { // [1, 1] is not non-positive - assert!(!domain::is_nonpos(&Domain::make_singleton(1.0))); + assert!(!domain::is_nonpos(&domain::one_dom())); } @@ -1569,13 +1462,13 @@ fn not_is_neg_free() { #[test] fn not_is_neg_zero() { // [0, 0] is not negative - assert!(!domain::is_neg(&Domain::make_singleton(0.0))); + assert!(!domain::is_neg(&domain::zero_dom())); } #[test] fn not_is_neg_one() { // [1, 1] is not negative - assert!(!domain::is_neg(&Domain::make_singleton(1.0))); + assert!(!domain::is_neg(&domain::one_dom())); } @@ -1596,7 +1489,7 @@ fn does_not_contain_zero_neg() { #[test] fn does_not_contain_zero_one() { // [1, 1] does not contain zero - assert!(domain::does_not_contain_zero(&Domain::make_singleton(1.0))); + assert!(domain::does_not_contain_zero(&domain::one_dom())); } #[test] @@ -1632,7 +1525,7 @@ fn not_does_not_contain_zero_nonpos() { #[test] fn not_does_not_contain_zero_zero() { // [0, 0] contains zero - assert!(!domain::does_not_contain_zero(&Domain::make_singleton(0.0))); + assert!(!domain::does_not_contain_zero(&domain::zero_dom())); } } From ab664fc44aff86f63aea04203fc195ca24f91f6c Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Tue, 23 Apr 2024 18:50:29 -0400 Subject: [PATCH 21/23] fix: be careful with `0 ^ 0` --- egg-pre-dcp/src/domain.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/egg-pre-dcp/src/domain.rs b/egg-pre-dcp/src/domain.rs index fe25687c..af506fd1 100644 --- a/egg-pre-dcp/src/domain.rs +++ b/egg-pre-dcp/src/domain.rs @@ -899,7 +899,7 @@ pub fn pow(d1: &Domain, d2: &Domain) -> Domain { return Domain::make_singleton(1.0); } else if n == 1 { return d1.clone(); - } else if n % 2 == 0 { + } else if n > 0 && n % 2 == 0 { let d = abs(d1); let lo = d.lo_float(); let hi = d.hi_float(); From 90e294ae05a5bdda01798153e24e4bf53054f307 Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Tue, 23 Apr 2024 18:56:40 -0400 Subject: [PATCH 22/23] fix: `I ^ [0, 0] = [1, 1]` --- egg-pre-dcp/src/domain.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/egg-pre-dcp/src/domain.rs b/egg-pre-dcp/src/domain.rs index af506fd1..ec3726ae 100644 --- a/egg-pre-dcp/src/domain.rs +++ b/egg-pre-dcp/src/domain.rs @@ -895,7 +895,7 @@ pub fn pow(d1: &Domain, d2: &Domain) -> Domain { Some(f) => { if ((f as u32) as f64) == f { let n = f as u32; - if n == 0 && does_not_contain_zero(d1) { + if n == 0 { return Domain::make_singleton(1.0); } else if n == 1 { return d1.clone(); From 03153b523ec6b76027d682c760247bc906aa0d82 Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Mir Date: Tue, 23 Apr 2024 19:40:13 -0400 Subject: [PATCH 23/23] test: many tests for interval `pow` --- egg-pre-dcp/tests/test_domain.rs | 337 +++++++++++++++++++++++++++++-- 1 file changed, 317 insertions(+), 20 deletions(-) diff --git a/egg-pre-dcp/tests/test_domain.rs b/egg-pre-dcp/tests/test_domain.rs index a3be83ca..789f4672 100644 --- a/egg-pre-dcp/tests/test_domain.rs +++ b/egg-pre-dcp/tests/test_domain.rs @@ -5,13 +5,13 @@ Tests for extended interval arithmetic. mod test_domain { use egg_pre_dcp; - use egg_pre_dcp::CC; use egg_pre_dcp::CO; use egg_pre_dcp::CI; use egg_pre_dcp::OC; use egg_pre_dcp::OO; use egg_pre_dcp::OI; + use egg_pre_dcp::domain; use domain::Domain as Domain; @@ -1086,7 +1086,7 @@ fn max_gt_minus_three_lt_three_ge_minus_two_le_zero() { } -// Power (TODO tests). +// Power (56 tests). #[test] fn pow_pos_pos() { @@ -1216,29 +1216,326 @@ fn pow_neg_neg() { assert!(result.eq(&expected)); } -// (-inf, inf) ^ [0, 0] = (-inf, +inf) -// [0, 0] ^ [0, 0] = (-inf, +inf) -// (2, 4] ^ [0, 0] = [1, 1] -// [-3, -2) ^ [0, 0] = [1, 1] +#[test] +fn pow_free_zero() { + // (-inf, inf) ^ [0, 0] = [1, 1] + let result = domain::pow(&domain::free_dom(), &domain::zero_dom()); + let expected = domain::one_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_zero_zero() { + // [0, 0] ^ [0, 0] = [1, 1] + let result = domain::pow(&domain::zero_dom(), &domain::zero_dom()); + let expected = domain::one_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_gt_two_le_four_zero() { + // (2, 4] ^ [0, 0] = [1, 1] + let result = domain::pow(&OC!(2.0, 4.0), &domain::zero_dom()); + let expected = domain::one_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_minus_three_lt_minus_two_zero() { + // [-3, -2) ^ [0, 0] = [1, 1] + let result = domain::pow(&CO!(-3.0, -2.0), &domain::zero_dom()); + let expected = domain::one_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_free_one() { + // (-inf, inf) ^ [1, 1] = (-inf, +inf) + let result = domain::pow(&domain::free_dom(), &domain::one_dom()); + let expected = domain::free_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_zero_one() { + // [0, 0] ^ [1, 1] = [0, 0] + let result = domain::pow(&domain::zero_dom(), &domain::one_dom()); + let expected = domain::zero_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_gt_two_le_four_one() { + // (2, 4] ^ [1, 1] = (2, 4] + let result = domain::pow(&OC!(2.0, 4.0), &domain::one_dom()); + let expected = OC!(2.0, 4.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_minus_three_lt_minus_two_one() { + // [-3, -2) ^ [1, 1] = [-3, -2) + let result = domain::pow(&CO!(-3.0, -2.0), &domain::one_dom()); + let expected = CO!(-3.0, -2.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_free_two() { + // (-inf, inf) ^ [2, 2] = [0, +inf) + let result = domain::pow(&domain::free_dom(), &CC!(2.0, 2.0)); + let expected = domain::nonneg_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_zero_two() { + // [0, 0] ^ [2, 2] = [0, 0] + let result = domain::pow(&domain::zero_dom(), &CC!(2.0, 2.0)); + let expected = domain::zero_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_gt_two_le_four_two() { + // (2, 4] ^ [2, 2] = (4, 16] + let result = domain::pow(&OC!(2.0, 4.0), &CC!(2.0, 2.0)); + let expected = OC!(4.0, 16.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_minus_three_lt_minus_two_two() { + // [-3, -2) ^ [2, 2] = (4, 9] + let result = domain::pow(&CO!(-3.0, -2.0), &CC!(2.0, 2.0)); + let expected = OC!(4.0, 9.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_gt_two_le_four_four() { + // (2, 4] ^ [4, 4] = (16, 256] + let result = domain::pow(&OC!(2.0, 4.0), &CC!(4.0, 4.0)); + let expected = OC!(16.0, 256.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_minus_three_lt_minus_two_four() { + // [-3, -2) ^ [4, 4] = (16, 81] + let result = domain::pow(&CO!(-3.0, -2.0), &CC!(4.0, 4.0)); + let expected = OC!(16.0, 81.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_gt_minus_two_le_four_ge_two_lt_three() { + // (-2, 4] ^ [2, 3) = (-inf, +inf) + let result = domain::pow(&OC!(-2.0, 4.0), &CO!(2.0, 3.0)); + let expected = domain::free_dom(); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_gt_two_le_four_ge_two_lt_three() { + // (2, 4] ^ [2, 3) = (4, 64) + let result = domain::pow(&OC!(2.0, 4.0), &CO!(2.0, 3.0)); + let expected = OO!(4.0, 64.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_gt_two_le_four_ge_minus_three_lt_minus_two() { + // (2, 4] ^ [-3, -2) = [0.015625, 0.25) + let result = domain::pow(&OC!(2.0, 4.0), &CO!(-3.0, -2.0)); + let expected = CO!(0.015625, 0.25); + assert!(result.eq(&expected)); +} -// (-inf, inf) ^ [1, 1] = (-inf, +inf) -// [0, 0] ^ [1, 1] = [0, 0] -// (2, 4] ^ [1, 1] = (2, 4] -// [-3, -2) ^ [1, 1] = [-3, -2) +#[test] +fn pow_gt_two_le_four_ge_minus_three_lt_two() { + // (2, 4] ^ [-3, 2) = [0.015625, 16) + let result = domain::pow(&OC!(2.0, 4.0), &CO!(-3.0, 2.0)); + let expected = CO!(0.015625, 16.0); + assert!(result.eq(&expected)); +} -// (-inf, inf) ^ [2, 2] = [0, +inf) -// [0, 0] ^ [2, 2] = [0, 0] -// (2, 4] ^ [2, 2] = (4, 16] -// [-3, -2) ^ [2, 2] = (4, 9] -// (2, 4] ^ [4, 4] = (16, 256] -// [-3, -2) ^ [4, 4] = (16, 81] +#[test] +fn pow_gt_two_lt_four_ge_minus_three_le_zero() { + // (2, 4) ^ [-3, 0] = (0.015625, 1] + let result = domain::pow(&OO!(2.0, 4.0), &CC!(-3.0, 0.0)); + let expected = OC!(0.015625, 1.0); + assert!(result.eq(&expected)); +} -// (2, 4] ^ [2, 3) -// (2, 4] ^ [-3, +#[test] +fn pow_gt_two_lt_four_ge_zero_lt_two() { + // (2, 4) ^ [0, 2) = [1, 16) + let result = domain::pow(&OO!(2.0, 4.0), &CO!(0.0, 2.0)); + let expected = CO!(1.0, 16.0); + assert!(result.eq(&expected)); +} -// (0, 0.5] +#[test] +fn pow_gt_point_one_two_five_le_point_five_ge_two_lt_three() { + // (0.125, 0.5] ^ [2, 3) = (0.001953125, 0.25] + let result = domain::pow(&OC!(0.125, 0.5), &CO!(2.0, 3.0)); + let expected = OC!(0.001953125, 0.25); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_gt_point_one_two_five_le_point_five_ge_minus_three_lt_minus_two() { + // (0.125, 0.5] ^ [-3, -2) = (4, 512) + let result = domain::pow(&OC!(0.125, 0.5), &CO!(-3.0, -2.0)); + let expected = OO!(4.0, 512.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_gt_point_one_two_five_le_point_five_ge_minus_three_lt_two() { + // (0.125, 0.5] ^ [-3, 2) = (0.015625, 512) + let result = domain::pow(&OC!(0.125, 0.5), &CO!(-3.0, 2.0)); + let expected = OO!(0.015625, 512.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_gt_point_one_two_five_le_point_five_ge_minus_three_le_zero() { + // (0.125, 0.5] ^ [-3, 0] = [1, 512) + let result = domain::pow(&OC!(0.125, 0.5), &CC!(-3.0, 0.0)); + let expected = CO!(1.0, 512.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_gt_point_one_two_five_le_point_five_ge_zero_lt_two() { + // (0.125, 0.5] ^ [0, 2) = (0.015625, 1] + let result = domain::pow(&OC!(0.125, 0.5), &CO!(0.0, 2.0)); + let expected = OC!(0.015625, 1.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_point_five_lt_four_ge_two_lt_three() { + // [0.5, 4) ^ [2, 3) = (0.125, 64) + let result = domain::pow(&CO!(0.5, 4.0), &CO!(2.0, 3.0)); + let expected = OO!(0.125, 64.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_point_five_lt_four_ge_minus_three_lt_minus_two() { + // [0.5, 4) ^ [-3, -2) = (0.015625, 8] + let result = domain::pow(&CO!(0.5, 4.0), &CO!(-3.0, -2.0)); + let expected = OC!(0.015625, 8.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_point_five_lt_four_ge_minus_three_lt_two() { + // [0.5, 4) ^ [-3, 2) = (0.015625, 16) + let result = domain::pow(&CO!(0.5, 4.0), &CO!(-3.0, 2.0)); + let expected = OO!(0.015625, 16.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_point_five_lt_four_ge_minus_three_lt_zero() { + // [0.5, 4) ^ [-3, 0) = (0.015625, 8] + let result = domain::pow(&CO!(0.5, 4.0), &CO!(-3.0, 0.0)); + let expected = OC!(0.015625, 8.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_point_five_lt_four_ge_zero_lt_two() { + // [0.5, 4) ^ [0, 2) = (0.25, 16) + let result = domain::pow(&CO!(0.5, 4.0), &CO!(0.0, 2.0)); + let expected = OO!(0.25, 16.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_zero_lt_four_ge_two_lt_three() { + // [0, 4) ^ [2, 3) = [0, 64) + let result = domain::pow(&CO!(0.0, 4.0), &CO!(2.0, 3.0)); + let expected = CO!(0.0, 64.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_zero_lt_four_ge_minus_three_lt_minus_two() { + // [0, 4) ^ [-3, -2) = (0.015625, +inf) + let result = domain::pow(&CO!(0.0, 4.0), &CO!(-3.0, -2.0)); + let expected = OI!(0.015625); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_zero_lt_four_ge_minus_three_lt_two() { + // [0, 4) ^ [-3, 2) = [0, +inf) + let result = domain::pow(&CO!(0.0, 4.0), &CO!(-3.0, 2.0)); + let expected = CI!(0.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_zero_lt_four_ge_minus_three_lt_zero() { + // [0, 4) ^ [-3, 0) = (0.015625, +inf) + let result = domain::pow(&CO!(0.0, 4.0), &CO!(-3.0, 0.0)); + let expected = OI!(0.015625); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_zero_lt_four_ge_zero_lt_two() { + // [0, 4) ^ [0, 2) = [0, 16) + let result = domain::pow(&CO!(0.0, 4.0), &CO!(0.0, 2.0)); + let expected = CO!(0.0, 16.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_one_lt_four_ge_two_lt_three() { + // [1, 4) ^ [2, 3) = [1, 64) + let result = domain::pow(&CO!(1.0, 4.0), &CO!(2.0, 3.0)); + let expected = CO!(1.0, 64.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_one_lt_four_ge_minus_three_lt_minus_two() { + // [1, 4) ^ [-3, -2) = (0.015625, 1] + let result = domain::pow(&CO!(1.0, 4.0), &CO!(-3.0, -2.0)); + let expected = OC!(0.015625, 1.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_one_lt_four_ge_minus_three_lt_two() { + // [1, 4) ^ [-3, 2) = (0.015625, 16) + let result = domain::pow(&CO!(1.0, 4.0), &CO!(-3.0, 2.0)); + let expected = OO!(0.015625, 16.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_one_lt_four_ge_minus_three_lt_zero() { + // [1, 4) ^ [-3, 0) = (0.015625, 1) + let result = domain::pow(&CO!(1.0, 4.0), &CO!(-3.0, 0.0)); + let expected = OC!(0.015625, 1.0); + assert!(result.eq(&expected)); +} + +#[test] +fn pow_ge_one_lt_four_ge_zero_lt_two() { + // [1, 4) ^ [0, 2) = [1, 16) + let result = domain::pow(&CO!(1.0, 4.0), &CO!(0.0, 2.0)); + let expected = CO!(1.0, 16.0); + assert!(result.eq(&expected)); +} -// [0.5, 3) /* Checkers */