1+ /* ++
2+ Copyright (c) 2025 Daily Test Coverage Improver
3+
4+ Module Name:
5+
6+ api_pb.cpp
7+
8+ Abstract:
9+
10+ Test API pseudo-boolean constraint functions
11+
12+ Author:
13+
14+ Daily Test Coverage Improver 2025-09-17
15+
16+ Notes:
17+ Tests the Z3 API functions for creating pseudo-boolean constraints:
18+ - Z3_mk_atmost: at most k of the variables can be true
19+ - Z3_mk_atleast: at least k of the variables can be true
20+ - Z3_mk_pble: weighted pseudo-boolean less-than-or-equal constraint
21+ - Z3_mk_pbge: weighted pseudo-boolean greater-than-or-equal constraint
22+ - Z3_mk_pbeq: weighted pseudo-boolean equality constraint
23+
24+ --*/
25+ #include " api/z3.h"
26+ #include " util/trace.h"
27+ #include " util/debug.h"
28+
29+ void tst_api_pb () {
30+ Z3_config cfg = Z3_mk_config ();
31+ Z3_context ctx = Z3_mk_context (cfg);
32+ Z3_del_config (cfg);
33+
34+ // Create some boolean variables for testing
35+ Z3_sort bool_sort = Z3_mk_bool_sort (ctx);
36+ Z3_ast x = Z3_mk_const (ctx, Z3_mk_string_symbol (ctx, " x" ), bool_sort);
37+ Z3_ast y = Z3_mk_const (ctx, Z3_mk_string_symbol (ctx, " y" ), bool_sort);
38+ Z3_ast z = Z3_mk_const (ctx, Z3_mk_string_symbol (ctx, " z" ), bool_sort);
39+
40+ // Test Z3_mk_atmost: at most k variables can be true
41+ {
42+ Z3_ast vars[] = {x, y, z};
43+ Z3_ast constraint = Z3_mk_atmost (ctx, 3 , vars, 2 );
44+ ENSURE (constraint != nullptr );
45+
46+ // Test with zero variables (edge case)
47+ Z3_ast constraint_empty = Z3_mk_atmost (ctx, 0 , nullptr , 0 );
48+ ENSURE (constraint_empty != nullptr );
49+
50+ // Test with single variable
51+ Z3_ast constraint_single = Z3_mk_atmost (ctx, 1 , vars, 1 );
52+ ENSURE (constraint_single != nullptr );
53+ }
54+
55+ // Test Z3_mk_atleast: at least k variables can be true
56+ {
57+ Z3_ast vars[] = {x, y, z};
58+ Z3_ast constraint = Z3_mk_atleast (ctx, 3 , vars, 1 );
59+ ENSURE (constraint != nullptr );
60+
61+ // Test with zero threshold
62+ Z3_ast constraint_zero = Z3_mk_atleast (ctx, 3 , vars, 0 );
63+ ENSURE (constraint_zero != nullptr );
64+
65+ // Test with all variables required
66+ Z3_ast constraint_all = Z3_mk_atleast (ctx, 3 , vars, 3 );
67+ ENSURE (constraint_all != nullptr );
68+ }
69+
70+ // Test Z3_mk_pble: weighted pseudo-boolean less-than-or-equal
71+ {
72+ Z3_ast vars[] = {x, y, z};
73+ int coeffs[] = {1 , 2 , 3 }; // weights for x, y, z
74+ Z3_ast constraint = Z3_mk_pble (ctx, 3 , vars, coeffs, 4 );
75+ ENSURE (constraint != nullptr );
76+
77+ // Test with negative coefficients
78+ int neg_coeffs[] = {-1 , 2 , -3 };
79+ Z3_ast constraint_neg = Z3_mk_pble (ctx, 3 , vars, neg_coeffs, 0 );
80+ ENSURE (constraint_neg != nullptr );
81+
82+ // Test with zero coefficients
83+ int zero_coeffs[] = {0 , 0 , 0 };
84+ Z3_ast constraint_zero = Z3_mk_pble (ctx, 3 , vars, zero_coeffs, 5 );
85+ ENSURE (constraint_zero != nullptr );
86+
87+ // Test with single variable
88+ int single_coeff[] = {5 };
89+ Z3_ast constraint_single = Z3_mk_pble (ctx, 1 , vars, single_coeff, 3 );
90+ ENSURE (constraint_single != nullptr );
91+ }
92+
93+ // Test Z3_mk_pbge: weighted pseudo-boolean greater-than-or-equal
94+ {
95+ Z3_ast vars[] = {x, y, z};
96+ int coeffs[] = {2 , 3 , 1 }; // weights for x, y, z
97+ Z3_ast constraint = Z3_mk_pbge (ctx, 3 , vars, coeffs, 3 );
98+ ENSURE (constraint != nullptr );
99+
100+ // Test with large coefficients
101+ int large_coeffs[] = {100 , 200 , 50 };
102+ Z3_ast constraint_large = Z3_mk_pbge (ctx, 3 , vars, large_coeffs, 150 );
103+ ENSURE (constraint_large != nullptr );
104+
105+ // Test with negative threshold
106+ int pos_coeffs[] = {1 , 1 , 1 };
107+ Z3_ast constraint_neg_threshold = Z3_mk_pbge (ctx, 3 , vars, pos_coeffs, -1 );
108+ ENSURE (constraint_neg_threshold != nullptr );
109+ }
110+
111+ // Test Z3_mk_pbeq: weighted pseudo-boolean equality
112+ {
113+ Z3_ast vars[] = {x, y, z};
114+ int coeffs[] = {1 , 1 , 1 }; // equal weights
115+ Z3_ast constraint = Z3_mk_pbeq (ctx, 3 , vars, coeffs, 2 );
116+ ENSURE (constraint != nullptr );
117+
118+ // Test with different coefficients
119+ int diff_coeffs[] = {3 , 5 , 7 };
120+ Z3_ast constraint_diff = Z3_mk_pbeq (ctx, 3 , vars, diff_coeffs, 5 );
121+ ENSURE (constraint_diff != nullptr );
122+
123+ // Test with zero threshold
124+ int unit_coeffs[] = {2 , 4 , 6 };
125+ Z3_ast constraint_zero_eq = Z3_mk_pbeq (ctx, 3 , vars, unit_coeffs, 0 );
126+ ENSURE (constraint_zero_eq != nullptr );
127+ }
128+
129+ // Test complex scenario: combining different constraints
130+ {
131+ Z3_ast vars[] = {x, y, z};
132+ int coeffs[] = {1 , 2 , 3 };
133+
134+ Z3_ast atmost_constraint = Z3_mk_atmost (ctx, 3 , vars, 2 );
135+ Z3_ast atleast_constraint = Z3_mk_atleast (ctx, 3 , vars, 1 );
136+ Z3_ast pble_constraint = Z3_mk_pble (ctx, 3 , vars, coeffs, 5 );
137+ Z3_ast pbge_constraint = Z3_mk_pbge (ctx, 3 , vars, coeffs, 2 );
138+ Z3_ast pbeq_constraint = Z3_mk_pbeq (ctx, 3 , vars, coeffs, 3 );
139+
140+ ENSURE (atmost_constraint != nullptr );
141+ ENSURE (atleast_constraint != nullptr );
142+ ENSURE (pble_constraint != nullptr );
143+ ENSURE (pbge_constraint != nullptr );
144+ ENSURE (pbeq_constraint != nullptr );
145+
146+ // Create a conjunction of constraints to ensure they can be combined
147+ Z3_ast constraints[] = {atmost_constraint, atleast_constraint};
148+ Z3_ast combined = Z3_mk_and (ctx, 2 , constraints);
149+ ENSURE (combined != nullptr );
150+ }
151+
152+ // Test edge cases with empty arrays
153+ {
154+ // Empty array should work for atmost/atleast
155+ Z3_ast empty_atmost = Z3_mk_atmost (ctx, 0 , nullptr , 0 );
156+ Z3_ast empty_atleast = Z3_mk_atleast (ctx, 0 , nullptr , 0 );
157+ ENSURE (empty_atmost != nullptr );
158+ ENSURE (empty_atleast != nullptr );
159+
160+ // Empty arrays should work for weighted constraints too
161+ Z3_ast empty_pble = Z3_mk_pble (ctx, 0 , nullptr , nullptr , 5 );
162+ Z3_ast empty_pbge = Z3_mk_pbge (ctx, 0 , nullptr , nullptr , -2 );
163+ Z3_ast empty_pbeq = Z3_mk_pbeq (ctx, 0 , nullptr , nullptr , 0 );
164+ ENSURE (empty_pble != nullptr );
165+ ENSURE (empty_pbge != nullptr );
166+ ENSURE (empty_pbeq != nullptr );
167+ }
168+
169+ Z3_del_context (ctx);
170+ }
0 commit comments