5. Tables and updates

A permission table records which combinations of read, write, and share are allowed. Construct a circuit directly from Boolean rows, update the allowed set, and query it with another Boolean condition.

from tididi import Vtree, from_models, literal

vtree = Vtree.balanced(3)
read, write, share = 1, 2, 3
rows = [
    (True, False, False),
    (True, True, False),
    (True, False, True),
    (True, True, False),
]
permissions = from_models(vtree, [read, write, share], rows)
print("Distinct permission sets:", permissions.model_count())
Distinct permission sets: 3

Rows describe a set: the repeated row contributes only once. The positions in each row correspond to the supplied variable list. Other vtree variables, if any, would be free.

Insert the combination with all three permissions and remove read/write without sharing. Updates use signed literals; -share means sharing is false. The operation consumes the old circuit and returns its replacement.

permissions = permissions.update(insert=[[read, write, share]], remove=[[read, write, -share]])
print("After updates:", permissions.model_count())
After updates: 3

The updated table contains read-only, read-and-share, and all three permissions. Filter a copy so the full table stays available for the next update.

sharing = permissions.copy() & literal(vtree, share)
print("Permission sets allowing sharing:", sharing.model_count())
Permission sets allowing sharing: 2

5.1. 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.

permissions = permissions.update(remove=[[share]])
print("After withdrawing sharing:", permissions.model_count())
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.