==> tests/solver.c <==1/* Cassowary on the small problems kasuari's tests use: required equalities, a weak preference
2 * overridden by a strong one, an inequality that clips, an unsatisfiable required pair, and a
3 * chain of segments shared by required ordering constraints (as a layout makes). */
4#include "mesh/check.h"
5#include "tui/solver.h"
6
7#include <math.h>
8
9#define V(i) tui_expr_var(i)
10#define C(x) tui_expr_const(x)
11
12static bool near(double a, double b) { return fabs(a - b) < 1e-6; }
13
14int main(void) {
15 tui_solver *s = tui_solver_new();
16 /* x + y == 10 (required), x == 3 (strong), y == 9 (weak): x = 3, y = 7. */
17 CHECK(tui_solver_add(s, tui_expr_add(V(0), V(1)), TUI_EQ, TUI_STRENGTH_REQUIRED, C(10)));
18 CHECK(tui_solver_add(s, V(0), TUI_EQ, TUI_STRENGTH_STRONG, C(3)));
19 CHECK(tui_solver_add(s, V(1), TUI_EQ, TUI_STRENGTH_WEAK, C(9)));
20 CHECK(near(tui_solver_value(s, 0), 3) && near(tui_solver_value(s, 1), 7));
21 /* x <= 2 (required) overrides the strong preference. */
22 CHECK(tui_solver_add(s, V(0), TUI_LE, TUI_STRENGTH_REQUIRED, C(2)));
23 CHECK(near(tui_solver_value(s, 0), 2) && near(tui_solver_value(s, 1), 8));
24 /* A required contradiction is refused (kasuari leaves the tableau as the failed pivot left it;
25 * ratatui never adds one). */
26 CHECK(!tui_solver_add(s, V(0), TUI_EQ, TUI_STRENGTH_REQUIRED, C(5)));
27 CHECK(near(tui_solver_value(s, 42), 0));
28 tui_solver_free(s);
29
30 /* Two segments in [0, 100]: a == 30 strong, both grow medium, equal sizes weak. */
31 s = tui_solver_new();
32 CHECK(tui_solver_add(s, V(0), TUI_EQ, TUI_STRENGTH_REQUIRED, C(0)));
33 CHECK(tui_solver_add(s, V(3), TUI_EQ, TUI_STRENGTH_REQUIRED, C(100)));
34 for (uint32_t v = 0; v < 4; v++) {
35 CHECK(tui_solver_add(s, V(v), TUI_GE, TUI_STRENGTH_REQUIRED, V(0)));
36 CHECK(tui_solver_add(s, V(v), TUI_LE, TUI_STRENGTH_REQUIRED, V(3)));
37 }
38 CHECK(tui_solver_add(s, V(1), TUI_LE, TUI_STRENGTH_REQUIRED, V(2)));
39 CHECK(tui_solver_add(s, tui_expr_sub(V(1), V(0)), TUI_EQ, TUI_STRENGTH_STRONG, C(30)));
40 CHECK(tui_solver_add(s, tui_expr_sub(V(2), V(1)), TUI_EQ, TUI_STRENGTH_REQUIRED, C(0)));
41 CHECK(tui_solver_add(s, tui_expr_sub(V(3), V(2)), TUI_EQ, TUI_STRENGTH_MEDIUM, tui_expr_sub(V(3), V(0))));
42 CHECK(near(tui_solver_value(s, 1), 30) && near(tui_solver_value(s, 2), 30));
43 tui_solver_free(s);
44 return mesh_check_done();
45}