‹ back to the board

Saturday, October 24

Mastermulti-constraint & composite logic

The Gate-Charters of the Veshari Embassy

The Veshari Embassy stands at the crossroads of the courts of the wild. Fae envoys, fiend-princes and giant-kin all pass through its gates, and every gate obeys the Embassy's charter. The charter is a list of clauses, each granting or refusing passage. They are sometimes written for a single being, sometimes for a whole kind, and sometimes for anyone at all. The Warden-Clerks will pay a bounty for a reckoner that settles, for each being at each gate, which clause prevails.

Write gateVerdicts(lineage, clauses, queries), which returns a list of verdicts.

Arguments

  • lineage: a mapping from a name (string) to the name of its parent kind (string). A name that is not a key has no parent. There are no cycles. The *ancestors* of a being are its parent, its parent's parent, and so on.
  • clauses: a list of clauses. Each clause is a 5-element array [who, gate, verdict, seal, edict]:
  • who: a string, either a name or "*".
  • gate: a string, either a gate name or "*".
  • verdict: "allow" or "deny".
  • seal: an integer.
  • edict: a boolean.
  • queries: a list of [being, gate] pairs of strings.

When a clause applies

A clause applies to a query only if both of these hold:

  • its who is "*", or equals the query's being, or equals one of that being's ancestors;
  • its gate is "*", or equals the query's gate.

A clause naming a *descendant* of the being does not apply.

The *kinship distance* of an applicable clause is:

  • 0 if who equals the being;
  • 1 if who is its parent;
  • 2 if who is its grandparent, and so on.

A who of "*" counts as farther than any ancestor.

Which clause prevails

Compare the applicable clauses by these criteria in order. The first criterion on which two clauses differ decides between them.

1. A clause with edict true beats one with edict false. 2. A smaller kinship distance beats a larger one. 3. A clause with a named gate beats one whose gate is "*". 4. A higher seal beats a lower one. 5. "deny" beats "allow".

The verdict for a query is the verdict of the prevailing clause. If no clause applies, the verdict is "deny".

Return a list of strings, each "allow" or "deny", with one entry per query, in the same order as queries.

  • rule engines with overrides
  • Master

examples

  1. case 1lineage: frost-sprite's parent is sprite, sprite's parent is fae. Clauses: [fae, moon-gate, deny, seal 9, no edict] and [frost-sprite, *, allow, seal 0, no edict]. Query: frost-sprite at moon-gate.["allow"]: kinship distance 0 outranks distance 2, even though the other clause names the gate and has a higher seal.
  2. case 2Same lineage. Clauses: [frost-sprite, moon-gate, allow, seal 5, no edict] and [*, *, deny, seal 0, edict]. Query: frost-sprite at moon-gate.["deny"]: an edict beats every non-edict clause, however specific the non-edict clause is.
  3. case 3lineage: ember-imp's parent is imp. Clauses: [imp, garden-arch, allow, seal 3, no edict] and [imp, garden-arch, deny, seal 3, no edict]. Query: ember-imp at garden-arch.["deny"]: the two clauses tie on every other criterion, so deny wins.
  4. case 4lineage empty. Clauses: [giant, moon-gate, allow, seal 0, no edict]. Query: dwarf at moon-gate.["deny"]: no clause applies, so the verdict defaults to deny.
reward
540 XP
signature
gateVerdicts
not yet run

TypeScript, run as ES2022 — types are stripped, not checked. If a JS engine would run it, so will we.

loading the editor…
  • kind specificity and wildcard fallback
  • closeness beats named gate and seal; descendants never apply
  • edicts override everything
  • seal decides, then deny wins exact ties
  • named gate beats higher seal with empty lineage
  • no clauses defaults to deny
  • no queries
  • distant ancestor beats wildcard
  • edicts ranked among themselves by closeness
  • tied wildcards resolve to deny
  • clause for wrong gate does not apply
The Gate-Charters of the Veshari Embassy · bitwick