6. Build and update a Boolean table

Treat rows as a set of permission assignments. The columns indicate read, write and share permission. Duplicate input rows represent the same assignment.

6.1. Load rows

Pass a row-major array of bytes, each 0 or 1. Column IDs specify which variable each position describes.

enum { READ = 1, WRITE, SHARE };
const uint32_t columns[] = {READ, WRITE, SHARE};
const uint8_t rows[][3] = {{1,0,0}, {1,1,0}, {1,0,1}, {1,1,0}};
TididiCircuit *table = NULL;
check(tididi_from_models(vtree, columns, 3, &rows[0][0], 4, &table, NULL));
printf("Distinct rows: %" PRIu64 "\n", count(table));

Output:

Distinct rows: 3

6.2. Change the set

Insert the all-permissions row, then remove read-and-write without sharing. An update consumes the old circuit and returns a minimized replacement.

const int64_t add[] = {READ, WRITE, SHARE}, remove[] = {READ, WRITE, -SHARE};
const TididiCube insertions[] = {{add, 3}}, deletions[] = {{remove, 3}};
TididiCircuit *updated = NULL;
check(tididi_update(table, insertions, 1, deletions, 1, &updated, NULL));
printf("After updating: %" PRIu64 "\n", count(updated));

Output:

After updating: 3

The updated table contains read-only, read-and-share, and all three permissions. The count is unchanged, but its rows differ.

6.3. Filter rows

Conjunction with the share literal selects rows that permit sharing. Filter a copy so the full table stays available for the next update.

TididiCircuit *share = NULL, *selected = NULL, *table_copy = copy(updated);
check(tididi_literal(vtree, SHARE, &share, NULL));
check(tididi_and(table_copy, share, &selected, NULL));
printf("Rows allowing sharing: %" PRIu64 "\n", count(selected));

Output:

Rows allowing sharing: 2

6.4. Remove a group of rows

Suppose sharing is withdrawn entirely. A partial assignment names just the permissions to match: {SHARE} selects every row where sharing is true, whatever its read and write values. Pass no insertions and one deletion cube:

const int64_t sharing[] = {SHARE};
const TididiCube matching[] = {{sharing, 1}};
TididiCircuit *without_sharing = NULL;
check(tididi_update(updated, NULL, 0, matching, 1, &without_sharing, NULL));
printf("After withdrawing sharing: %" PRIu64 "\n", count(without_sharing));

Output:

After withdrawing sharing: 1

Only read access without write or share remains. Removing matching rows does not change their share column to false. An empty cube matches all assignments.

6.5. Complete program

Download tables.c and the shared helper. The source includes cleanup for all handles. Both files are included in the source checkout.