Skip to content

Commit 4d9a52a

Browse files
OvascosThomas HaderThomas Hader
authored
Feasibility set int (#80)
* WIP WIP: intersection/union done * intersection and printing done * removed capacity * added lp_polynomial_constraint_get_feasible_set_Zp * added doctest tests for c files * Update doc * adds further test and fixes * further tests * Removed unnecessary header file * Fixed assertion location --------- Co-authored-by: Thomas Hader <[email protected]> Co-authored-by: Thomas Hader <[email protected]>
1 parent 7a4dedc commit 4d9a52a

File tree

11 files changed

+1564
-6
lines changed

11 files changed

+1564
-6
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ endif()
8282
if (BUILD_TESTING)
8383
# Configure the C++ tests
8484
enable_testing()
85+
add_subdirectory(test/poly)
8586
add_subdirectory(test/polyxx)
8687
endif()
8788

include/feasibility_set_int.h

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/**
2+
* Copyright 2024, SRI International.
3+
*
4+
* This file is part of LibPoly.
5+
*
6+
* LibPoly is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Lesser General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* LibPoly is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with LibPoly. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
#pragma once
21+
22+
#include "poly.h"
23+
#include "integer.h"
24+
#include <stdbool.h>
25+
26+
#ifdef __cplusplus
27+
extern "C" {
28+
#endif
29+
30+
/**
31+
* Set of disjoint intervals representing an algebraic set, ordered from
32+
* left to right (-inf to +inf).
33+
*/
34+
struct lp_feasibility_set_int_struct {
35+
/** The ring in which the feasibility set lives. */
36+
lp_int_ring_t *K;
37+
38+
/** If true, set represents K \setminus elements */
39+
bool inverted;
40+
41+
/** Number of elements */
42+
size_t size;
43+
44+
/**
45+
* Vector feasibility elements
46+
* Values are normalized wrt to K, kept sorted and unique
47+
*/
48+
lp_integer_t* elements;
49+
};
50+
51+
/**
52+
* Create a new feasibility set K.
53+
*/
54+
lp_feasibility_set_int_t* lp_feasibility_set_int_new_full(lp_int_ring_t *K);
55+
56+
/**
57+
* Create a new feasibility set {}.
58+
*/
59+
lp_feasibility_set_int_t* lp_feasibility_set_int_new_empty(lp_int_ring_t *K);
60+
61+
/**
62+
* Construct a copy.
63+
*/
64+
lp_feasibility_set_int_t* lp_feasibility_set_int_new_copy(const lp_feasibility_set_int_t* set);
65+
66+
/**
67+
* Construct from integers.
68+
*/
69+
lp_feasibility_set_int_t* lp_feasibility_set_int_new_from_integer(lp_int_ring_t *K, const lp_integer_t* integers, size_t integers_size, bool inverted);
70+
71+
/**
72+
* Delete the given feasibility set.
73+
*/
74+
void lp_feasibility_set_int_delete(lp_feasibility_set_int_t* set);
75+
76+
/**
77+
* Assignment.
78+
*/
79+
void lp_feasibility_set_int_assign(lp_feasibility_set_int_t* set, const lp_feasibility_set_int_t* from);
80+
81+
/**
82+
* Swap.
83+
*/
84+
void lp_feasibility_set_int_swap(lp_feasibility_set_int_t* s1, lp_feasibility_set_int_t* s2);
85+
86+
/**
87+
* Check if the given set is empty.
88+
*/
89+
int lp_feasibility_set_int_is_empty(const lp_feasibility_set_int_t* set);
90+
91+
/**
92+
* Check if the given set is full.
93+
*/
94+
int lp_feasibility_set_int_is_full(const lp_feasibility_set_int_t* set);
95+
96+
/**
97+
* Check if the set is a point {a}.
98+
*/
99+
int lp_feasibility_set_int_is_point(const lp_feasibility_set_int_t* set);
100+
101+
/**
102+
* assigns the size of the set to out
103+
*/
104+
void lp_feasibility_set_int_size(const lp_feasibility_set_int_t *set, lp_integer_t *out);
105+
106+
/**
107+
* returns the size; guaranteed to be correct if it fits in long
108+
*/
109+
size_t lp_feasibility_set_int_size_approx(const lp_feasibility_set_int_t *set);
110+
111+
/**
112+
* Check if the given value belongs to the set.
113+
*/
114+
int lp_feasibility_set_int_contains(const lp_feasibility_set_int_t* set, const lp_integer_t* value);
115+
116+
/**
117+
* Pick a value from the feasible set (must be non-empty).
118+
*/
119+
void lp_feasibility_set_int_pick_value(const lp_feasibility_set_int_t* set, lp_integer_t* value);
120+
121+
/**
122+
* Get intersection of the two sets.
123+
* s1 and s2 must be over the same ring K.
124+
*/
125+
lp_feasibility_set_int_t* lp_feasibility_set_int_intersect(const lp_feasibility_set_int_t* s1, const lp_feasibility_set_int_t* s2);
126+
127+
/**
128+
* Get union of the two sets.
129+
* s1 and s2 must be over the same ring K.
130+
*/
131+
lp_feasibility_set_int_t* lp_feasibility_set_int_union(const lp_feasibility_set_int_t* s1, const lp_feasibility_set_int_t* s2);
132+
133+
typedef enum {
134+
LP_FEASIBILITY_SET_INT_S1,
135+
LP_FEASIBILITY_SET_INT_S2,
136+
LP_FEASIBILITY_SET_INT_NEW,
137+
LP_FEASIBILITY_SET_INT_EMPTY
138+
} lp_feasibility_set_int_status_t;
139+
140+
/**
141+
* Get intersection of the two sets, returns the status in the given variable.
142+
* The set s1 is given precedence so LP_FEASIBILITY_SET_S2 is the
143+
* status only if the intersect is not s1.
144+
* s1 and s2 must be over the same ring K.
145+
*/
146+
lp_feasibility_set_int_t* lp_feasibility_set_int_intersect_with_status(const lp_feasibility_set_int_t* s1, const lp_feasibility_set_int_t* s2, lp_feasibility_set_int_status_t * status);
147+
148+
/**
149+
* Get union of the two sets, returns the status in the given variable.
150+
* The set s1 is given precedence so LP_FEASIBILITY_SET_S2 is the
151+
* status only if the union is not s1.
152+
* s1 and s2 must be over the same ring K.
153+
*/
154+
lp_feasibility_set_int_t* lp_feasibility_set_int_union_with_status(const lp_feasibility_set_int_t* s1, const lp_feasibility_set_int_t* s2, lp_feasibility_set_int_status_t* status);
155+
156+
/**
157+
* Add one set to another, i.e. s = s \cup from.
158+
*/
159+
void lp_feasibility_set_int_add(lp_feasibility_set_int_t* s, const lp_feasibility_set_int_t* from);
160+
161+
/**
162+
* Returns true if both sets are equal
163+
*/
164+
bool lp_feasibility_set_int_eq(const lp_feasibility_set_int_t* s1, const lp_feasibility_set_int_t* s2);
165+
166+
/**
167+
* Print the set.
168+
*/
169+
int lp_feasibility_set_int_print(const lp_feasibility_set_int_t* set, FILE* out);
170+
171+
/**
172+
* Return the string representation of the set.
173+
*/
174+
char* lp_feasibility_set_int_to_string(const lp_feasibility_set_int_t* set);
175+
176+
#ifdef __cplusplus
177+
} /* close extern "C" { */
178+
#endif

include/poly.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ typedef struct lp_dyadic_interval_struct lp_dyadic_interval_t;
6666
typedef struct lp_interval_struct lp_interval_t;
6767

6868
typedef struct lp_feasibility_set_struct lp_feasibility_set_t;
69+
typedef struct lp_feasibility_set_int_struct lp_feasibility_set_int_t;
6970
typedef struct lp_polynomial_hash_set_struct lp_polynomial_hash_set_t;
7071
typedef struct lp_polynomial_vector_struct lp_polynomial_vector_t;
7172
typedef struct lp_polynomial_heap_struct lp_polynomial_heap_t;

include/polynomial.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,17 @@ void lp_polynomial_roots_isolate(const lp_polynomial_t* A, const lp_assignment_t
343343
*/
344344
lp_feasibility_set_t* lp_polynomial_constraint_get_feasible_set(const lp_polynomial_t* A, lp_sign_condition_t sgn_condition, int negated, const lp_assignment_t* M);
345345

346+
/**
347+
* Given a polynomial A(x1, ..., xn, y) with y being the top variable, a sign
348+
* condition, and an assignment M that assigns x1, ..., xn, the function returns
349+
* a subset of Zp where
350+
*
351+
* sgn(A(M(x1), ..., M(xn), y)) = sgn_condition .
352+
*
353+
* If negated is true, the constraint is considered negated.
354+
*/
355+
lp_feasibility_set_int_t* lp_polynomial_constraint_get_feasible_set_Zp(const lp_polynomial_t* A, lp_sign_condition_t sgn_condition, int negated, const lp_assignment_t* M);
356+
346357
/**
347358
* Given a polynomial A(x1, ..., xn) and a sign condition, the function returns
348359
* tries to infer bounds on the variables and stores them into the given interval

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ set(poly_SOURCES
3434
polynomial/polynomial.c
3535
polynomial/polynomial_context.c
3636
polynomial/feasibility_set.c
37+
polynomial/feasibility_set_int.c
3738
polynomial/polynomial_hash_set.c
3839
polynomial/polynomial_heap.c
3940
polynomial/polynomial_vector.c

src/polynomial/feasibility_set.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,18 @@
3232
#include "polynomial/feasibility_set.h"
3333

3434
static
35-
void lp_feasibility_set_ensure_capacity(lp_feasibility_set_t* s, size_t size) {
36-
if (size && size > s->capacity) {
37-
s->capacity = size;
35+
void lp_feasibility_set_ensure_capacity(lp_feasibility_set_t* s, size_t capacity) {
36+
if (capacity && capacity > s->capacity) {
37+
s->capacity = capacity;
3838
s->intervals = realloc(s->intervals, s->capacity * sizeof(lp_interval_t));
3939
}
4040
}
4141

42+
static
4243
void lp_feasibility_set_construct(lp_feasibility_set_t* s, size_t size) {
4344
s->size = 0;
4445
s->capacity = 0;
45-
s->intervals = 0;
46+
s->intervals = NULL;
4647
lp_feasibility_set_ensure_capacity(s, size);
4748
}
4849

@@ -86,6 +87,7 @@ void lp_feasibility_set_delete(lp_feasibility_set_t* set) {
8687
free(set);
8788
}
8889

90+
static
8991
void lp_feasibility_set_construct_copy(lp_feasibility_set_t* set, const lp_feasibility_set_t* from) {
9092
lp_feasibility_set_construct(set, from->size);
9193
size_t i;

src/polynomial/feasibility_set.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,4 @@
1919

2020
#pragma once
2121

22-
void lp_feasibility_set_construct(lp_feasibility_set_t* s, size_t size);
23-
2422
lp_feasibility_set_t* lp_feasibility_set_new_internal(size_t size);

0 commit comments

Comments
 (0)