skip to content
==> 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}