Skip to content

feat(language): a file may declare sets of labels and the properties of a dimension or a set - #1

Draft
FBumann wants to merge 3 commits into
claude/gallant-franklin-6ndbd1from
claude/sets-properties-prototype-9m3zu6
Draft

FBumann wants to merge 3 commits into
claude/gallant-franklin-6ndbd1from
claude/sets-properties-prototype-9m3zu6

Conversation

@FBumann

@FBumann FBumann commented Oct 23, 2026

Copy link
Copy Markdown

Prompt: 1. The loader: sets: and properties:, lowered to the program's existing relation nodes, with the refusals above, the two levels of missing:, the schema regenerated, and the reference page.

Note

The following content was generated by AI.

What this changes

A file can now declare sets: and properties:. A set lowers to a bare relation with its own name. A property lowers to a relation named subject.property. An entry over a set is refused, and the message names the rewrite: the member dimensions with where:.

Why

This is PR 1 of the stack in which sets and properties replace relations. It stacks on energy-models#945 (the parameter mask).

The YAML, the lowering, and the refusals
sets:
  connection: { dims: [entity, port], missing: absent }
  cover: { dims: { generator: generator, start: snapshot, covered: snapshot }, missing: absent }
properties:
  generator: { bus: bus }                                 # short form of {into: bus}
  line: { bus0: bus, bus1: { into: bus, missing: absent } }
  connection: { bus: bus }
  • A set becomes Relation(columns from dims, key = every member, missing) under its own name. So where: connection and a parameter mask that reads a set work on the paths that exist today.
  • A property becomes Relation((*subject key, (name, into)), subject key, missing, subject=subject) under subject.property. No file can write a dotted name, so it collides with nothing.
  • Namespace.relations holds only the names a file can write, so the error messages do not offer generator.bus. The program gets every table, through Namespace.tables.
  • missing: works at two levels. On a set, it asks whether every combination of dims is a row. On a property, it asks whether every row of the subject has the property. Both take refused or absent only.
  • The loader refuses:
    • an entry over a set, with the rewrite;
    • a set with fewer than two members;
    • a set that repeats a dimension without naming the members;
    • a set that names another set;
    • a member over an undeclared dimension;
    • a member named after another dimension;
    • a subject that is neither a dimension nor a set;
    • a property into a set or into an undeclared dimension;
    • a property that has the name of a key member;
    • a property named after a dimension it does not map into;
    • a property of a set that has two members over one dimension;
    • a set name that collides with another name;
    • a property name that is not a NAME.
Departures, and what this PR does not do
  • Relation has a new field, subject. It is the one change to an existing node. A property of a sparse set with missing: refused means "every row of the set". The existing missing cannot say that, and an engine needs subject for the check "every property key is a row of its subject".
  • override lays properties: over one subject at a time. Without that, a patch that adds a new subject crashed with an AttributeError. merge still refuses a subject or a set that appears in two fragments. Joining them is PR 3.
  • No calls yet. subject[property] is PR 2. Until then, nothing in an expression reads a property.
  • The typesetter prints the dotted names, as generator.bus: G → B, in all three formats. The real legend is PR 4.
  • relations: stays until PR 5.
Gates, and the mutation table
  • Passed: pixi run lint and pixi run test (3165 passed, 1 skipped).
  • Passed: pixi run docs-build (strict). Every YAML fence on the new page loads, and the quoted refusal and the math were taken from the code's real output.
  • Not run: pixi run compile-tex. Tectonic cannot download its bundle in this container, so all 54 documents failed, the existing ones included.
  • Mutation table: this repo has no tools/mutate.py, so a script took the table instead. The script refuses a tree with uncommitted changes, restores each file with git checkout --, and drops __pycache__ before and after each mutation. The tree came back clean.
guard deleted suite
entry over a set: the set rewrite caught (3 failed)
a set has at least two members caught
a set repeats a dimension without names caught
a set names a set caught
a set over an undeclared dimension caught
a member named after another dimension caught
a subject neither a dimension nor a set caught (2)
a subject with two members over one dimension caught
a property named as a key member caught (2)
a property into a set caught
a property into an undeclared dimension caught
a property named after another dimension caught
a set in the flat namespace caught
a property name is a name caught
missing: on a set or a property takes two words caught (6)
missing: null on a set or a property caught (3)
the short form of a property is written back caught (5)
a property relation carries its subject caught (5)
the namespace lists no property caught
the normal form sorts each subject caught
a patch lays over one subject at a time caught (2)
a patch reads a short-form property as into caught
merge names the properties of a subject caught

Generated by Claude Code

…of a dimension or a set

`sets:` names which combinations of labels exist, and `properties:` maps each
row of a dimension or a set into a dimension. Both lower to the program's
relations: a set under its own name, a property under `subject.property` with
`Relation.subject` naming the rows its key ranges over. An entry over a set is
refused with the rewrite to the member dimensions and `where:`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W6yvGzZN2iR4WyA9RumvvJ
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W6yvGzZN2iR4WyA9RumvvJ
@coderabbitai

coderabbitai Bot commented Oct 23, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

…t declare without a misspelling

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W6yvGzZN2iR4WyA9RumvvJ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants