Skip to content

Commit 4e2b911

Browse files
committed
Added C++ interface and test for lp_polynomial_constraint_evaluate_subs
and added missing `Value(int)` constructor.
1 parent 32ff199 commit 4e2b911

File tree

5 files changed

+61
-2
lines changed

5 files changed

+61
-2
lines changed

include/polyxx/polynomial.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ namespace poly {
117117
* assignment. */
118118
bool is_assigned_over_assignment(const Polynomial& p, const Assignment& a);
119119
/** Evaluates p over a given assignment and returns an univariate polynomial.
120-
* Assumes that a assigns all variable in p but the top variable.
121-
* Assumes that a assigns to integer only. */
120+
* Assumes that 'a' assigns all variable in p but the top variable.
121+
* Assumes that 'a' assigns to integer only. */
122122
UPolynomial to_univariate(const Polynomial& p, const Assignment& a);
123123
/** Compute the sign of a polynomial over an assignment. */
124124
int sgn(const Polynomial& p, const Assignment& a);
@@ -127,6 +127,11 @@ namespace poly {
127127
/** Evaluate a polynomial constraint over an assignment. */
128128
bool evaluate_constraint(const Polynomial& p, const Assignment& a,
129129
SignCondition sc);
130+
/** Checks if a polynomial constraint is fully evaluated over assignment.
131+
* Returns -1 if 'a' does not fully evaluate the constraint.
132+
* Otherwise, returns true if the constraint holds under 'a'. */
133+
int evaluate_constraint_subs(const Polynomial& p, const Assignment& a,
134+
SignCondition sc);
130135
/** Evaluate a polynomial over an interval assignment. The result is only an
131136
* approximation. */
132137
Interval evaluate(const Polynomial& p, const IntervalAssignment& a);

include/polyxx/value.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ namespace poly {
2929
/** Construct a none value. */
3030
Value();
3131
/** Construct from a native integer. */
32+
Value(int i);
33+
/** Construct from a native integer. */
3234
Value(long i);
3335
/** Copy from the given Value. */
3436
Value(const Value& val);

src/polyxx/polynomial.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,11 @@ namespace poly {
165165
return lp_polynomial_constraint_evaluate(
166166
p.get_internal(), to_sign_condition(sc), a.get_internal());
167167
}
168+
int evaluate_constraint_subs(const Polynomial& p, const Assignment& a,
169+
SignCondition sc) {
170+
return lp_polynomial_constraint_evaluate_subs(
171+
p.get_internal(), to_sign_condition(sc), a.get_internal());
172+
}
168173
Interval evaluate(const Polynomial& p, const IntervalAssignment& a) {
169174
Interval res;
170175
lp_polynomial_interval_value(p.get_internal(), a.get_internal(),

src/polyxx/value.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace poly {
1313
}
1414

1515
Value::Value() { lp_value_construct_none(&mValue); }
16+
Value::Value(int i) { lp_value_construct_int(get_internal(), i); }
1617
Value::Value(long i) { lp_value_construct_int(get_internal(), i); }
1718
Value::Value(const Value& val) {
1819
lp_value_construct_copy(get_internal(), val.get_internal());

test/polyxx/test_polynomial.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,49 @@ TEST_CASE("polynomial::constructor") {
100100
CHECK(p_cp == p_cp_a);
101101
CHECK(ptr == p_mv_a.get_internal());
102102
}
103+
104+
TEST_CASE("polynomial::evaluate") {
105+
Variable x("x");
106+
Variable y("y");
107+
Polynomial p1 = 1 * pow(x, 6) + 2 * pow(x, 5) + 3 * y - 1;
108+
Polynomial p2 = 1 * y * pow(x + 1, 4);
109+
110+
// full assignment
111+
Assignment a;
112+
a.set(x, -1);
113+
a.set(y, 2);
114+
CHECK(a.has(x));
115+
CHECK(a.has(y));
116+
117+
CHECK(evaluate(p1, a) == Value(4));
118+
CHECK(evaluate_constraint(p1, a, SignCondition::GE) == true);
119+
CHECK(evaluate_constraint(p1, a, SignCondition::LT) == false);
120+
CHECK(evaluate_constraint(p1, a, SignCondition::EQ) == false);
121+
CHECK(evaluate_constraint_subs(p1, a, SignCondition::GE) == 1);
122+
CHECK(evaluate_constraint_subs(p1, a, SignCondition::LT) == 0);
123+
CHECK(evaluate_constraint_subs(p1, a, SignCondition::EQ) == 0);
124+
125+
CHECK(evaluate(p2, a) == Value(0));
126+
CHECK(evaluate_constraint(p2, a, SignCondition::GE) == true);
127+
CHECK(evaluate_constraint(p2, a, SignCondition::LT) == false);
128+
CHECK(evaluate_constraint(p2, a, SignCondition::EQ) == true);
129+
CHECK(evaluate_constraint_subs(p2, a, SignCondition::GE) == 1);
130+
CHECK(evaluate_constraint_subs(p2, a, SignCondition::LT) == 0);
131+
CHECK(evaluate_constraint_subs(p2, a, SignCondition::EQ) == 1);
132+
133+
// partial assignment
134+
a.unset(y);
135+
CHECK(a.has(x));
136+
CHECK(!a.has(y));
137+
138+
CHECK(evaluate_constraint_subs(p1, a, SignCondition::GE) == -1);
139+
CHECK(evaluate_constraint_subs(p1, a, SignCondition::LT) == -1);
140+
CHECK(evaluate_constraint_subs(p1, a, SignCondition::EQ) == -1);
141+
142+
CHECK(evaluate_constraint(p2, a, SignCondition::GE) == true);
143+
CHECK(evaluate_constraint(p2, a, SignCondition::LT) == false);
144+
CHECK(evaluate_constraint(p2, a, SignCondition::EQ) == true);
145+
CHECK(evaluate_constraint_subs(p2, a, SignCondition::GE) == 1);
146+
CHECK(evaluate_constraint_subs(p2, a, SignCondition::LT) == 0);
147+
CHECK(evaluate_constraint_subs(p2, a, SignCondition::EQ) == 1);
148+
}

0 commit comments

Comments
 (0)