§

De talen

De brontalen en wat ze kunnen uitdrukken

uchar heeft nu drie brontalen: RegelSpraak met GegevensSpraak, Catala en F-logic. Alle drie vertalen naar één IR. Dat aantal is geen grens: een nieuwe brontaal kost één vertaler naar de IR, en elke toevoeging toetst de IR opnieuw op neutraliteit. Deze pagina laat per taal zien wat zij kan uitdrukken, met echte fragmenten uit het corpus en de uitkomst die elke uitvoerder ervan moet geven.

The languages

The source languages and what they can express

uchar currently has three source languages: RegelSpraak with GegevensSpraak, Catala and F-logic. All three translate into one IR. That number is not a limit: a new source language costs one translator into the IR, and every addition tests the IR again for neutrality. This page shows, per language, what it can express, with real fragments from the corpus and the outcome every executor must produce for them.

§ 1overzichtoverview

Drie talen, één IR

Waarom juist deze drie, staat op de startpagina. De lijst is een momentopname, geen ontwerpkeuze: welke talen erbij komen, bepaalt wie ze nodig heeft. Per taal eist een gate dat de frontend elk bronbestand in het corpus opnieuw tot precies de ingecheckte IR vertaalt.

RegelSpraakCatalaF-logic
Wat het isGecontroleerde natuurlijke taal in het Nederlands, versie 2.3.0Programmeertaal voor wetgeving met een default-calculus als kernLogica van frames met klassehiërarchie en overerfbare klasse-defaults
HerkomstBelastingdienstInria; Merigoux, Chataing & Protzenko, ICFP 2021Kifer, Lausen & Wu, JACM 1995
Rol in ucharEerste brontaal; de productieroute is de Drools-backend van uchar, verpakt in de distributie regelspraak-toolchainTweede brontaal; bron voor geprioriteerde defaultsDerde brontaal; toetst de overervingskern
Goldens met bron (7-11-2026)209 · source.rgs12 · source.catala_en2 · source.flogic
Gate10: byte-identieke her-emissie; 16: scenariotoetsen regenereren hun casebestanden byte-identiek9: frontendsuite (ondergrens 201 checks) en her-emissie14: frontendsuite (ondergrens 81 checks) en her-emissie

Three languages, one IR

Why these three were chosen is explained on the home page. The list is a snapshot, not a design decision: which languages are added is decided by who needs them. For each language a gate requires the frontend to translate every source file in the corpus into exactly the checked-in IR again.

RegelSpraakCatalaF-logic
What it isControlled natural language in Dutch, version 2.3.0Programming language for legislation with a default calculus at its coreLogic of frames with a class hierarchy and inheritable class-level defaults
OriginDutch Tax AdministrationInria; Merigoux, Chataing & Protzenko, ICFP 2021Kifer, Lausen & Wu, JACM 1995
Role in ucharFirst source language; its production route is uchar's Drools backend, packaged in the distribution regelspraak-toolchainSecond source language; source for prioritized defaultsThird source language; tests the inheritance kernel
Goldens with source (2026-11-07)209 · source.rgs12 · source.catala_en2 · source.flogic
Gate10: byte-identical re-emission; 16: scenario tests regenerate their case files byte-identically9: frontend suite (floor of 201 checks) and re-emission14: frontend suite (floor of 81 checks) and re-emission
§ 2RegelSpraak

RegelSpraak en GegevensSpraak

Een .rgs-bestand is een reeks definities en regels; meerdere bestanden, zoals objectmodel, regels en scenario's, worden in opgegeven volgorde samengevoegd. De grammatica noemt het declaratiedeel GegevensSpraak en het regeldeel RegelSpraak; de fragmenten staan zoals in het corpus.

Het declaratiedeel

Een objecttype heeft attributen en kenmerken. Een attribuut heeft een datatype (Numeriek, Percentage, Tekst, Boolean, Datum in dagen, Datum en tijd in millisecondes of een domein) en soms een eenheid uit een eenheidsysteem. Een parameter krijgt zijn waarde uit de invoer.

RegelSpraak and GegevensSpraak

An .rgs file is a sequence of definitions and rules; several files, such as an object model, rules and scenarios, are concatenated in the given order. The grammar calls the declaration part GegevensSpraak and the rule part RegelSpraak. RegelSpraak is Dutch by definition: keywords and names are Dutch, and the fragments are quoted as they stand in the corpus, untranslated.

The declaration part

An object type has attributes and characteristics. An attribute has a datatype (Numeriek, Percentage, Tekst, Boolean, Datum in dagen, Datum en tijd in millisecondes or a domain) and sometimes a unit from a unit system. A parameter receives its value from the input.

RegelSpraakcorpus/golden/jutterswet-aanvoergeld/source.rgs
Eenheidsysteem Gewicht
    het kilogram (mv: kilogrammen) kg

Eenheidsysteem Munt
    de euro (mv: euros) EUR €

Objecttype de Jutter (mv: Jutters) (bezield)
    is aanvoerplichtig kenmerk (bijvoeglijk);
    het aangevoerd gewicht Numeriek (niet-negatief getal met 2 decimalen) met eenheid kg;
    de aanvoerwaarde Numeriek (niet-negatief getal met 2 decimalen) met eenheid €;
    het aanvoergeld Numeriek (getal met 2 decimalen) met eenheid €;

Parameter de aanvoerdrempel : Numeriek (niet-negatief getal met 2 decimalen) met eenheid kg
Parameter het aanvoertarief : Numeriek (getal met 2 decimalen) met eenheid €

Een domein is in het corpus een enumeratie, een feittype verbindt objecttypen via rollen met een kardinaliteit, en een dagsoort benoemt een soort dag. Een kenmerk is bijvoeglijk (is …) of bezittelijk (heeft …); beide komen in het corpus voor.

In the corpus a domain is an enumeration, a fact type connects object types through roles with a cardinality, and a day type names a kind of day. A characteristic is adjectival (is …) or possessive (heeft …); both occur in the corpus.

RegelSpraakcorpus/golden/jutterswet-vondstnummer/source.rgs
Objecttype de Vondst (mv: Vondsten)
    het vondstnummer (mv: vondstnummers) Numeriek (positief geheel getal);
    de vondstdag Datum in dagen;
    de aanmelddatum Datum in dagen;
RegelSpraakcorpus/golden/jutterswet-vondstklasse/source.rgs
Domein Vondstklasse is van het type Enumeratie
    'drijfgoed'
    'strandgoed'
    'wrakgoed'

Objecttype de Vondst (mv: Vondsten)
    de klasse Vondstklasse;
    de bestemming Vondstklasse;
RegelSpraakcorpus/golden/jutterswet-ketenband/source.rgs
Feittype ketenband
    de voorligger (mv: voorliggers) Wachter
    de opvolger (mv: opvolgers) Wachter
Eén voorligger heeft meerdere opvolgers
RegelSpraakcorpus/golden/jutterswet-schouwrooster/source.rgs
// Bron: art. 3b-3c Jutterswet
Dagsoort de schouwdag (mv: schouwdagen);
Dagsoort de stormvloeddag (mv: stormvloeddagen);

Het regeldeel

Een regel heeft een naam, een geldigheid en een regelzin (onder meer gelijkstelling, berekening, kenmerktoekenning, initialisatie of consistentie-eis), eventueel met een voorwaarde na indien.

Het uchar-dialect

uchar draagt een dialect met uitbreidingen die officieel RegelSpraak v2.3.0 niet kent. De frontend registreert zijn afwijkingen in frontends/regelspraak/grammar/DIVERGENCES.md; elke uitbreiding is additief en laat officiële v2.3.0-documenten ongemoeid. Daarnaast legt het register enkele versmallingen vast: plaatsen waar de frontend een v2.3.0-spelling bewust smaller leest of weigert. Twee uitbreidingen volgen ALEF (Agile Law Execution Factory), de ontwikkelomgeving van de Belastingdienst waarin RegelSpraak wordt geschreven, gebouwd op JetBrains MPS en open source onder EUPL-1.2; de andere hebben een andere herkomst.

  • Uitzonderingen: Uitzondering op <naam>: <naam>, Afwijking van <basisregel>: <naam> en Uitzonderingen ongeordend: (ook als Uitzonderingen ongeordend op <naam>:). v2.3.0 kent geen uitzondering, voorrang of regelvolgorde, en ALEF evenmin: daar zijn twee verschillende toekenningen aan hetzelfde attribuut een fout. Een uitzondering kan zelf weer uitzonderingen dragen, zonder grens aan de diepte. Een Uitzondering op geldt alleen waar ook haar drager geldt; een Afwijking van geldt onder haar eigen voorwaarde en kan de basisregel dus verruimen. De blokken zijn een eigen uitbreiding van uchar; het model van geprioriteerde defaults eronder volgt de default-calculus van Catala.
  • Subtypen: Objecttype het Wrakrecht is een Strandrecht (mv: Wrakrechten). v2.3.0 en ALEF kennen geen overerving tussen objecttypen; dit is een eigen uitbreiding van uchar voor gegevensmodellen die overerving gebruiken.
  • Het tellen van gevulde waarden: het aantal gevulde waarden van …. v2.3.0 heeft er geen spelling voor; de woordgroep is van uchar. ALEF dient hetzelfde doel door objecten te tellen met een subselectie op "gevuld".
  • Recursieve regelgroepen: Regelgroep <naam> is recursief. v2.3.0 beschrijft recursie alleen in proza. In ALEF is "recursief" een eigenschap van een regelgroep en mag een cyclus alleen lopen via een regel die objecten aanmaakt. uchar eist dat een recursieve groep een regel bevat die objecten of feiten aanmaakt, en dat elke objectcreatie daarin voorwaardelijk is.
  • Scenariotoetsen: Situatie …:, Scenario … en Parameterset …:, achter een eigen startregel. v2.3.0 kent geen testhoofdstuk. Het idee komt uit TestSpraak, de testtaal van ALEF, waarin de regelanalist naast de regels testgevallen vastlegt met een situatie, een verwacht resultaat en een rekendatum. De tekstvorm komt uit regelspraak-java; de RegelSpraak-frontend van uchar vertaalt elk scenario naar een casebestand (gate 16). In het corpus staat zo'n toetsdocument als scenario.rgs naast de source.rgs.
  • Opgave boven berekening: (mag opgegeven worden) achter een attribuut. v2.3.0 kan niet uitdrukken dat een opgegeven waarde voorrang heeft op de berekening. De markering is syntactische suiker van uchar: de frontend maakt er een eigen invoerattribuut van en een defaults-groep die de opgave boven de berekening zet.
  • Afwezigheidsmarkers: (of onbekend), (of niet van toepassing) of (of onbekend of niet van toepassing) achter een attribuut. Een afwezigheidsmarker is een gevulde waarde en niet leeg: een regel kan hem schrijven en een voorwaarde toetsen (indien zijn taxatie onbekend is). v2.3.0 kent n.v.t. alleen in een cel van een beslistabel. Golden jutterswet-afwezigheidsmarkers.
  • Vocabulaires en benamingen: Vocabulaire <naam>, desgewenst met (standaard) en (taal: <code>), declareert een vocabulaire, en (<vocabulaire>: <benaming>) aan het eind van de naamgroep geeft een declaratie een naam in dat vocabulaire, zoals een term uit een handboek of een veldnaam uit een gegevensmodel: Objecttype de Jutter (mv: Jutters) (bezield) (handboek: strandjutter) (cgm: JUTTER). Objecttypen, attributen, kenmerken, feittypen, rollen, enumeratiewaarden, parameters, regels en regelgroepen kunnen een benaming dragen. v2.3.0 kan zulke namen alleen in commentaar kwijt; de uitbreiding is van uchar zelf. In de IR zijn de benamingen een zijtafel zonder semantiek (IR-SPEC hoofdstuk 2.12, WF-116 tot en met WF-120): regels gebruiken altijd de gedeclareerde namen, en gate 13 controleert dat de uitvoerders hetzelfde antwoord geven als de tabel ontbreekt of als de benamingen van plaats wisselen. Het standaardvocabulaire moet elke benoembare declaratie een benaming geven (WF-119), ook de declaraties die de frontend zelf maakt. Voor de elementen van de opgave-markering, de groep van de blokken van een subtype en het lid en de regel van een vouw met stappen na de verzameling stelt de frontend die benaming samen uit de benamingen van hun delen. De regels van de rijen van een beslistabel en het anker van een startpuntbepaling hebben geen benaming; een document met een standaardvocabulaire kan die twee constructies niet gebruiken, en de frontend weigert het met die reden. De distributie regelspraak-toolchain gebruikt de benamingen aan de rand van de beslisservice: een verzoek mag ze schrijven, en antwoord en uitleg kunnen in een gekozen vocabulaire (Voor de DevOps-engineer).

Verdere constructies

Elk van de volgende vormen heeft een golden met cases die de referentie-interpreter, Clingo en Drools naspelen. Voorbeelden met uitleg staan op Voor de regelanalist.

  • Een kwantor over een pad van relaties: indien ten minste één van de vondsten van de melder van de Melding zwaar is. In de IR is het bereik van de QuantifierFold het geschreven pad (sourcePath, IR-SPEC 4.5). Golden jutterswet-dringende-melding.
  • Een vouw in het filter van een andere vouw: de laatste einddag van de zware klachten van een Schuit, gelezen in het filter over haar ladingen. De binnenste vouw draagt het vormanker (§ 7). Golden jutterswet-schone-maand-na-zware-klacht.
  • Geneste voorwaarden op drie en meer niveaus. Het niveau van een opsommingsteken volgt uit het aantal tekens: - en • zijn niveau 1, .. en •• niveau 2, ... en ••• niveau 3; een dieper teken opent een niveau onder het vorige. Golden jutterswet-vrijstelling-drie-niveaus.
  • zelf, een uitbreiding van het dialect: de Vergunning zelf noemt in een filter of in de toets van een kwantor het onderwerp van de regel, ook als de elementen hetzelfde type hebben (- hij is niet de Vergunning zelf). In de IR is dat het vormanker met de knoop IdentityCheck (§ 7). Golden jutterswet-registervoorrang.
  • Een kenmerk dat een subtype declareert, getoetst op een object van het supertype: Een Strandrecht is landvast indien hij geen vaartijd heeft, waar alleen het subtype Wrakrecht vaartijd declareert. De toets is waar voor een instantie van het subtype met het kenmerk en onwaar voor elk ander object. In de IR noemt het veld host van de CharacteristicCheck het subtype (IR-SPEC 4.6, RUNTIME-SEMANTICS 5.8b, WF-109). Golden jutterswet-ploegblokkade.
  • Een kring over instanties: een waarde van een object hangt af van dezelfde waarde van zijn voorganger, een object van hetzelfde type. De einddag van een vergunning telt het restant van de vorige vergunning mee, en dat restant hangt af van de einddag van die vorige vergunning. De uitvoerders rekenen per object in de volgorde van de keten; vormen de schakels in de case zelf een kring, dan wordt de case geweigerd met EF-033 (IR-SPEC 5.3, RUNTIME-SEMANTICS 6.2). Goldens jutterswet-vergunningketen en jutterswet-vergunningtermijnen.
  • De datumconstructie de datum met jaar: …, maand: … en dag: …. Delen die geen kalenderdag noemen, zoals 31 april, geven een fout met code EF-032 (RUNTIME-SEMANTICS 3.8). Golden date-with-parts.
  • Een voorwaarde die veel waarden leest: in jutterswet-strandvoogdkeuring achttien, veertien van de Jutter zelf en vier van zijn strandpost. De DRL-tekst geeft ze alle aan één Java-functie, die ten hoogste 255 parameters neemt.

The rule part

A rule has a name, a validity and a rule sentence (among others assignment, calculation, characteristic assignment, initialisation or consistency requirement), optionally with a condition after indien (if).

The uchar dialect

uchar carries a dialect with extensions that official RegelSpraak v2.3.0 does not have. The frontend records its deviations in frontends/regelspraak/grammar/DIVERGENCES.md; every extension is additive and leaves official v2.3.0 documents unaffected. The register also records a few narrowings: places where the frontend deliberately reads a v2.3.0 spelling more narrowly or refuses it. Two extensions follow ALEF (Agile Law Execution Factory), the Dutch Tax Administration's development environment for writing RegelSpraak, built on JetBrains MPS and open source under EUPL-1.2; the others have a different origin.

  • Exceptions: Uitzondering op <naam>: <naam> (exception to), Afwijking van <basisregel>: <naam> (deviation from) and Uitzonderingen ongeordend: (unordered exceptions, also as Uitzonderingen ongeordend op <naam>:). v2.3.0 has no exception, priority or rule ordering, and neither has ALEF: there, two different assignments to the same attribute are an error. An exception can carry exceptions of its own, to any depth. An Uitzondering op applies only where its carrier applies as well; an Afwijking van applies under its own condition and can therefore widen the base rule. The blocks are uchar's own extension; the prioritized-defaults model beneath them follows Catala's default calculus.
  • Subtypes: Objecttype het Wrakrecht is een Strandrecht (mv: Wrakrechten). v2.3.0 and ALEF have no inheritance between object types; this is uchar's own extension for data models that use inheritance.
  • Counting filled values: het aantal gevulde waarden van …. v2.3.0 has no spelling for that operation; the phrase is uchar's own. ALEF serves the same purpose by counting objects with a sub-selection on "filled".
  • Recursive rule groups: Regelgroep <naam> is recursief. v2.3.0 describes recursion in prose only. In ALEF "recursive" is a property of a rule group and a cycle may only run through a rule that creates objects. uchar requires a recursive group to contain a rule that creates objects or facts, and every object creation in it to be conditional.
  • Scenario tests: Situatie …: (situation), Scenario … and Parameterset …: (parameter set), behind a start rule of their own. v2.3.0 has no test chapter. The idea comes from TestSpraak, ALEF's test language, in which the rule analyst records test cases next to the rules with a situation, an expected result and a calculation date. The textual form comes from regelspraak-java; uchar's RegelSpraak frontend translates every scenario into a case file (gate 16). In the corpus such a test document sits as scenario.rgs next to the source.rgs.
  • Given before computed: (mag opgegeven worden) (may be given) after an attribute. v2.3.0 cannot express that a supplied value takes precedence over the computation. The marker is uchar's syntactic sugar: the frontend turns it into a separate input attribute and a defaults group that ranks the given value above the computation.
  • Absence markers: (of onbekend) (or unknown), (of niet van toepassing) (or not applicable) or (of onbekend of niet van toepassing) after an attribute. An absence marker is a filled value, not an empty one: a rule can write it and a condition test it (indien zijn taxatie onbekend is, if its valuation is unknown). v2.3.0 has n.v.t. only in a cell of a decision table. Golden jutterswet-afwezigheidsmarkers.
  • Vocabularies and designations: Vocabulaire <naam>, optionally with (standaard) (default) and (taal: <code>) (language), declares a vocabulary, and (<vocabulaire>: <benaming>) at the end of the name group gives a declaration a name in that vocabulary, such as a term from a handbook or a field name from a data model: Objecttype de Jutter (mv: Jutters) (bezield) (handboek: strandjutter) (cgm: JUTTER). Object types, attributes, characteristics, fact types, roles, enumeration values, parameters, rules and rule groups can carry a designation. v2.3.0 can hold such names only in comments; the extension is uchar's own. In the IR the designations are a side table without semantics (IR-SPEC chapter 2.12, WF-116 to WF-120): rules always use the declared names, and gate 13 checks that the executors give the same answer when the table is absent or when the designations change places. The default vocabulary must give every designatable declaration a designation (WF-119), the declarations the frontend makes itself included. For the elements of the given-before-computed marker, the group of a subtype's blocks and the member and the rule of a fold with steps after the set, the frontend composes that designation from the designations of their parts. The rules of a decision table's rows and the anchor of a start-point determination carry none; a document with a default vocabulary cannot use those two constructs, and the frontend refuses it with that reason. The distribution regelspraak-toolchain uses the designations at the edge of the decision service: a request may write them, and the response and the explanation can be in a chosen vocabulary (For the DevOps engineer).

Further constructs

Each of the following forms has a golden with cases that the reference interpreter, Clingo and Drools replay. Examples with an explanation are on For the rule analyst.

  • A quantifier over a path of relations: indien ten minste één van de vondsten van de melder van de Melding zwaar is (if at least one of the finds of the reporter of the report is heavy). In the IR the range of the QuantifierFold is the written path (sourcePath, IR-SPEC 4.5). Golden jutterswet-dringende-melding.
  • A fold in the filter of another fold: the last end day of a Schuit's heavy complaints, read in the filter over its loads. The inner fold carries the form anchor (§ 7). Golden jutterswet-schone-maand-na-zware-klacht.
  • Nested conditions on three or more levels. The level of a bullet follows from the number of signs: - and • are level 1, .. and •• level 2, ... and ••• level 3; a deeper sign opens a level below the previous one. Golden jutterswet-vrijstelling-drie-niveaus.
  • zelf (itself), a dialect extension: de Vergunning zelf names, in a filter or in the test of a quantifier, the subject of the rule, also where the elements have the same type (- hij is niet de Vergunning zelf, he is not the licence itself). In the IR this is the form anchor with the node IdentityCheck (§ 7). Golden jutterswet-registervoorrang.
  • A characteristic that a subtype declares, tested on an object of the supertype: Een Strandrecht is landvast indien hij geen vaartijd heeft (a Strandrecht is landbound if it has no sailing time), where only the subtype Wrakrecht declares vaartijd. The test is true for an instance of the subtype that has the characteristic and false for every other object. In the IR the field host of the CharacteristicCheck names the subtype (IR-SPEC 4.6, RUNTIME-SEMANTICS 5.8b, WF-109). Golden jutterswet-ploegblokkade.
  • A cycle across instances: a value of an object depends on the same value of its predecessor, an object of the same type. The end day of a licence adds the remainder of the previous licence, and that remainder depends on the end day of the previous licence. The executors compute per object in the order of the chain; where the links in the case itself form a cycle, the case is refused with EF-033 (IR-SPEC 5.3, RUNTIME-SEMANTICS 6.2). Goldens jutterswet-vergunningketen and jutterswet-vergunningtermijnen.
  • The date construction de datum met jaar: …, maand: … en dag: … (the date with year, month and day). Parts that name no calendar day, such as 31 April, give a fault with code EF-032 (RUNTIME-SEMANTICS 3.8). Golden date-with-parts.
  • A condition that reads many values: in jutterswet-strandvoogdkeuring eighteen, fourteen of the Jutter itself and four of his beach post. The DRL text passes them all to one Java function, which takes at most 255 parameters.
§ 3cataloguscatalogue

Constructencatalogus

Per construct een fragment uit een source.rgs en de case met handgerekende verwachtingen, die de referentie-interpreter en Clingo exact moeten naspelen en Drools naspeelt of met reden weigert. Notatie: invoer → verwachting; ¬ is een afwezig kenmerk, leeg een attribuut zonder waarde.

Catalogue of constructs

For each construct, a fragment from a source.rgs and the case with hand-computed expectations, which the reference interpreter and Clingo must replay exactly and Drools replays or refuses with a reason. Notation: input → expectation; ¬ is an absent characteristic, leeg (empty) an attribute without a value.

Gelijkstelling en berekening

Een attribuut krijgt een waarde door gelijkstelling (moet gesteld worden op) of berekening (moet berekend worden als); er wordt exact met breuken gerekend. Afronden is een operator in de expressie, geen eigenschap van het attribuut: 100/8 = 12,5 wordt 12. Kan de uitkomst meer decimalen hebben dan het doel toelaat, zoals bij een deling door een attribuut, dan weigeren frontend en verifier de regel vóór de uitvoering (WF-023); de auteur rondt zelf af, zoals bij het helpersdeel hieronder, of kiest een doel Numeriek (getal). Een waarde die bij de uitvoering toch niet past, geeft de fout EF-006. Een gevulde teller gedeeld door een lege deler geeft leeg en een feit EF-031 op het foutkanaal (case3 hieronder); gedeeld door een numerieke nul geeft hij leeg en een feit EF-005 (golden division-by-numeric-zero). De berekening breekt in beide gevallen niet af (§ 8).

Assignment and calculation

An attribute receives a value by assignment (moet gesteld worden op) or by calculation (moet berekend worden als); arithmetic is exact, on fractions. Rounding is an operator in the expression, not a property of the attribute: 100/8 = 12.5 becomes 12. If the result can have more decimals than the target allows, as with a division by an attribute, the frontend and the verifier refuse the rule before execution (WF-023); the author rounds explicitly, as for helpersdeel below, or chooses a target Numeriek (getal). A value that still does not fit at execution gives the fault EF-006. A filled dividend divided by an empty divisor gives an empty value and a fact EF-031 on the error channel (case3 below); divided by a numeric zero it gives an empty value and a fact EF-005 (golden division-by-numeric-zero). In neither case does the computation abort (§ 8).

RegelSpraakcorpus/golden/jutterswet-bergloon/source.rgs
Regel premie van een berging
    geldig altijd
        De premie van een Berging moet berekend worden als 20% van de opbrengst van de Berging.

Regel helpersdeel van een berging
    geldig altijd
        Het helpersdeel van een Berging moet berekend worden als de opbrengst van de Berging gedeeld door het helpersaantal van de Berging rekenkundig afgerond op 0 decimalen.

Regel dagdeel van een berging
    geldig altijd
        Het dagdeel van een Berging moet berekend worden als de opbrengst van de Berging gedeeld door de vermenigvuldiger van de Berging naar beneden afgerond op 0 decimalen.
casecorpus/golden/jutterswet-bergloon/
case1  opbrengst 100 · helpersaantal 4 · vermenigvuldiger 8
       → premie 20 · helpersdeel 25 · dagdeel 12
case3  opbrengst 90 · helpersaantal leeg · vermenigvuldiger 8
       → premie 18 · helpersdeel leeg · dagdeel 11 · inconsistent EF-031 (helpersdeel van een berging)

Daarbij geldt benoemt een tussenwaarde; in de IR van deze golden is dat één Let met twee leesverwijzingen.

Daarbij geldt (where) names an intermediate value; in this golden's IR it is one Let with two reads.

RegelSpraakcorpus/golden/jutterswet-lichterloon/source.rgs
Regel lichterloon van een lichterbeurt
    geldig altijd
        Het lichterloon van een Lichterbeurt moet berekend worden als het grondloon plus het grondloon maal het spoedtal van de Lichterbeurt.
        Daarbij geldt:
            het grondloon is het vrachttal van de Lichterbeurt maal het eenheidsloon van de Lichterbeurt.
casecorpus/golden/jutterswet-lichterloon/
vrachttal 3 · spoedtal 2 · eenheidsloon 40 → lichterloon 360
vrachttal 5 · spoedtal 0 · eenheidsloon 20 → lichterloon 100

Eenheden en omrekening

Een eenheidsysteem legt eenheden en verhoudingen vast; omrekenfactoren zijn exacte breuken. Een eenheid kan samengesteld zijn uit eenheden met een gehele macht, zoals €/dg/m en 1/dg (golden jutterswet-sleeptarief). M2 vangt een uitvoerder die 1 t als heel getal 1000 neemt en de decimalen van de operand laat vallen: die antwoordt 1000,00.

Units and conversion

A unit system fixes units and ratios; conversion factors are exact fractions. A unit can be compound, built from units with whole exponents, such as €/dg/m and 1/dg (golden jutterswet-sleeptarief). M2 catches an executor that takes 1 t as the whole number 1000 and drops the operand's decimals: it would answer 1000.00.

RegelSpraakcorpus/golden/jutterswet-muntweging/source.rgs
Eenheidsysteem Gewicht
    het kilogram (mv: kilogrammen) kg
    de ton (mv: tonnen) t = 1000 kg
…
        Het aangegeven gewicht van een Vondst moet berekend worden als het brutogewicht van de Vondst plus 1 t.
casecorpus/golden/jutterswet-muntweging/case.json
V1 brutogewicht 3.00 → aangegeven gewicht 1003.00
M1 brutogewicht 2.00 → aangegeven gewicht 1002.00
M2 brutogewicht 0.50 → aangegeven gewicht 1000.50

Kenmerktoekenning met voorwaarde

Een object krijgt een kenmerk als de voorwaarde geldt; afwezigheid is een eigen, toetsbare uitkomst. eerder is dan is strikt.

Characteristic assignment with a condition

An object receives a characteristic when the condition holds; absence is an outcome in its own right and can be tested. eerder is dan (earlier than) is strict.

RegelSpraakcorpus/golden/jutterswet-vondstverjaring/source.rgs
        Een Vondst is verjaard
        indien zijn vondstdag eerder is dan 31-01-2024.
casecorpus/golden/jutterswet-vondstverjaring/
vondstdag 2023-12-31 → verjaard
vondstdag 2024-01-31 → ¬verjaard
vondstdag 2024-02-01 → ¬verjaard

Samengestelde voorwaarden

Leden combineren met alle, geen van, ten minste, ten hoogste of precies … van de volgende voorwaarden; een tweelingregel zet minsteteken met ten minste één. Bij W1 beslist het eerste lid al, dus 100/0 wordt nooit berekend. Zou het wel berekend worden, dan bleef het aandeel leeg en ontstond een feit EF-005; de case pint consistent en legt zo vast dat de evaluatie na het eerste lid stopt.

Compound conditions

Members combine with alle (all), geen van (none of), ten minste (at least), ten hoogste (at most) or precies (exactly) … van de volgende voorwaarden (of the following conditions); a twin rule sets minsteteken with ten minste één (at least one). For W1 the first member already decides, so 100/0 is never computed. If it were computed, the share would stay empty and a fact EF-005 would arise; the case pins consistent and so pins down that evaluation stops after the first member.

RegelSpraakcorpus/golden/jutterswet-wachtdeling/source.rgs
Regel geenteken van een wacht
    geldig altijd
        Het geenteken van een Wacht moet gesteld worden op 1
        indien hij aan geen van de volgende voorwaarden voldoet:
        - zijn ploegomvang is gelijk aan 0
        - het aandeel is groter dan 0.
        Daarbij geldt:
            het aandeel is de vangstwaarde van de Wacht gedeeld door de ploegomvang van de Wacht naar beneden afgerond op 0 decimalen.
casecorpus/golden/jutterswet-wachtdeling/case.json
W1 ploegomvang 0 · vangstwaarde 100 → geenteken leeg · minsteteken 1
W2 ploegomvang 4 · vangstwaarde 100 → geenteken leeg · minsteteken 1
W3 ploegomvang 7 · vangstwaarde 3   → geenteken 1 · minsteteken leeg
→ consistent

Kwantoren over gekoppelde instanties

Een telling over de leden van een via een feittype gekoppelde verzameling, eventueel met subselectie (die gekeurd zijn). Een lid zonder waarde telt niet mee, want vergelijken met leeg is onwaar; over een lege verzameling zijn alle en geen van allebei waar (jutterswet-schouwploeg).

Quantifiers over linked instances

A count over the members of a set linked through a fact type, optionally with a sub-selection (die gekeurd zijn, that are inspected). A member without a value does not count, because comparing with an empty value is false; over an empty set, alle (all) and geen van (none of) are both true (jutterswet-schouwploeg).

RegelSpraakcorpus/golden/jutterswet-vuurtoren/source.rgs
Regel helder bij sterkte
    geldig altijd
        Een Vuurtoren is helder indien de sterkte van ten minste 2 van de lampen van de Vuurtoren groter is dan 5.

Regel zuinig bij sterkte
    geldig altijd
        Een Vuurtoren is zuinig indien de sterkte van ten hoogste 1 van de lampen van de Vuurtoren groter is dan 5.

Regel enkelvoudig bij sterkte
    geldig altijd
        Een Vuurtoren is enkelvoudig indien de sterkte van precies 1 van de lampen van de Vuurtoren groter is dan 5.

Regel keurig bij sterkte
    geldig altijd
        Een Vuurtoren is keurig indien de sterkte van ten minste 2 van de lampen van de Vuurtoren die gekeurd zijn groter is dan 5.
casecorpus/golden/jutterswet-vuurtoren/
L1 sterkte 8, gekeurd · L2 sterkte 6, gekeurd
→ helder · keurig · ¬zuinig · ¬enkelvoudig · lampental 2
L1 sterkte leeg · L2 sterkte 3
→ zuinig · ¬helder · ¬enkelvoudig · ¬keurig · lampental 2

Met alle over een hele periode: K1 is aangemeld met 50 per maand, K2 niet; diens 30 telt dus niet en de keurploeg is premiewaardig.

With alle over a whole period: K1 is registered at 50 a month, K2 is not; its 30 therefore does not count and the crew is premiewaardig (eligible for a bonus).

RegelSpraakcorpus/golden/jutterswet-keurploeg/source.rgs
        Een Keurploeg is premiewaardig indien de keurvergoeding van alle keurmeesters van de Keurploeg die aangemeld zijn gedurende het gehele jaar groter is dan 40.

Aggregaties

het aantal, de som van, het totaal van en de minimale waarde van vouwen over een verzameling, ook langs twee rollen (jutterswet-vondstketen). Zonder of 0 als die er niet zijn is een som over niets leeg, maar geeft het totaal van 0; het aantal gevulde waarden van (dialect) telt alleen gevulde waarden.

Aggregations

het aantal (the number of), de som van (the sum of), het totaal van (the total of) and de minimale waarde van (the minimum of) fold over a set, also along two roles (jutterswet-vondstketen). Without of 0 als die er niet zijn (or 0 if there are none), a sum over nothing is empty, but het totaal van gives 0; het aantal gevulde waarden van (dialect) counts only filled values.

RegelSpraakcorpus/golden/jutterswet-vondsttelling/source.rgs
Regel aantal aangemelde vondsten
    geldig altijd
        Het aantal aangemelde vondsten van een Jutter moet berekend worden als het aantal vondsten van de Jutter.

Regel aangemeld gewicht
    geldig altijd
        Het aangemeld gewicht van een Jutter moet berekend worden als de som van het gewicht van alle vondsten van de Jutter of 0 als die er niet zijn.
casecorpus/golden/jutterswet-vondsttelling/case.json
J1 vondsten.gewicht [2.50, 1.25, leeg] → aantal aangemelde vondsten 3 · aangemeld gewicht 3.75
J2 vondsten.gewicht []                 → aantal aangemelde vondsten 0 · aangemeld gewicht 0
J3 vondsten.gewicht [leeg]             → aantal aangemelde vondsten 1 · aangemeld gewicht 0

Verdeling

Een bedrag wordt naar rato verdeeld, met een maximum per lid en afronding; wat boven het maximum uitkomt, wordt niet herverdeeld maar valt in de rest. In gelijke delen (jutterswet-bergingsdeling) geeft 1001 over twee leden 500 en 500, rest 1.

Distribution

An amount is distributed in proportion, with a maximum per member and rounding; what exceeds the maximum is not redistributed but goes to the remainder. In equal shares (jutterswet-bergingsdeling), 1001 over two members gives 500 and 500, remainder 1.

RegelSpraakcorpus/golden/jutterswet-berging/source.rgs
Regel verdeel de opbrengst van een berging
    geldig altijd
        De opbrengst van een berging wordt verdeeld over de bergingsaandelen van alle bergers van de berging, waarbij wordt verdeeld:
        - naar rato van het geborgen gewicht,
        - met een maximum van het bergingsmaximum,
        - afgerond op 0 decimalen naar beneden.
        Als onverdeelde rest blijft de onverdeelde rest van de berging over.
casecorpus/golden/jutterswet-berging/case.json
opbrengst 1200
W geborgen gewicht 3.00 · bergingsmaximum 300
H geborgen gewicht 1.00 · bergingsmaximum 300
D geborgen gewicht 2.00 · bergingsmaximum 300
→ bergingsaandeel W 300 · H 200 · D 300 · onverdeelde rest 400

Tijdlijnen

Een attribuut, kenmerk of parameter voor elke maand (of dag, of jaar) heeft een tijdlijn: een waarde per periode, over alle tijd. het totaal van … gedurende de tijd dat hij wachtplichtig is telt alleen de perioden waarin het kenmerk geldt, en een deel van een maand naar zijn dagen. Het aantal decimalen van zo'n deel is niet begrensd; daarom rondt de regel af.

Timelines

An attribute, characteristic or parameter voor elke maand (for every month; also per day or per year) has a timeline: a value per period, over all time. het totaal van … gedurende de tijd dat hij wachtplichtig is (the total of … during the time he is on watch duty) counts only the periods in which the characteristic holds, and a part of a month by its days. The decimals of such a part are unbounded; that is why the rule rounds.

RegelSpraakcorpus/golden/jutterswet-getijdenwacht/source.rgs
    de wachtvergoeding per maand Numeriek (geheel getal) voor elke maand;
    is wachtplichtig kenmerk (bijvoeglijk) voor elke maand;
…
Regel wachtsom van een jutter
    geldig altijd
        De wachtsom van een Jutter moet gesteld worden op (het totaal van zijn wachtvergoeding per maand gedurende de tijd dat hij wachtplichtig is) rekenkundig afgerond op 0 decimalen.
casecorpus/golden/jutterswet-getijdenwacht/case.json
wachtvergoeding per maand: 10 in 2023 · 11 in 2024-01 – 2024-06
wachtplichtig: 2023-07-01 – 2024-02-01
→ wachtsom 71 = 6 × 10 + 1 × 11

Een bewerking zonder eigen tijdsbetekenis, zoals plus of een vergelijking, geldt op een tijdlijn per dag. Een regel met een tijdlijndoel leest zijn voorwaarde per periode en schrijft alleen waar die geldt; twee regels botsen alleen op een dag waarop ze verschillend beslissen, en waar geen regel beslist, blijft de invoer staan. Uitzonderingen, (mag opgegeven worden) en initialisaties werken daar ook per dag. Wat open blijft, zoals de macht of het minimum over een tijdlijn, weigert elke uitvoerder met naam (RUNTIME-SEMANTICS 3.12).

An operation without a time semantics of its own, such as plus or a comparison, holds per day on a timeline. A rule with a timeline target reads its condition per period and writes only where it holds; two rules clash only on a day on which they decide differently, and where no rule decides, the input stays. Exceptions, (mag opgegeven worden) and initialisations work per day there as well. Every executor refuses by name what remains open, such as the power or the minimum over a timeline (RUNTIME-SEMANTICS 3.12).

RegelSpraakcorpus/golden/jutterswet-loon-per-periode/source.rgs
Objecttype de Jutter (mv: Jutters) (bezield)
    is aangesteld kenmerk (bijvoeglijk) voor elke maand;
…
    het strandloon Numeriek (geheel getal) voor elke maand;
    de stormtoeslag Numeriek (geheel getal) voor elke maand;
    het aangestelde loon Numeriek (geheel getal) voor elke maand;
…
Regel aangesteld loon van een jutter
    geldig altijd
        Het aangestelde loon van een Jutter moet berekend worden als zijn strandloon plus zijn stormtoeslag gedurende de tijd dat hij aangesteld is.
casecorpus/golden/jutterswet-loon-per-periode/case1-voorbeeld.json
strandloon: 100 in 2024-01 – 2024-03 · 150 in 2024-04 – 2024-09
stormtoeslag: 30 in 2024-03 – 2024-05
aangesteld: 2024-02-01 – 2024-08-01
→ aangestelde loon: 100 in 2024-02 · 130 in 2024-03 · 180 in 2024-04 – 2024-05 · 150 in 2024-06 – 2024-07

Tijdrekening

Een datum schuift op met dagen van een dagsoort, hier springtijdagen: de 1e en de 15e van de maand. Een tijdsduur telt hele eenheden; de begindag telt niet mee.

Date arithmetic

A date moves by days of a day type, here springtijdagen (spring-tide days): the 1st and the 15th of the month. A duration counts whole units; the start day does not count.

RegelSpraakcorpus/golden/jutterswet-bergingsklok/source.rgs
Regel uiterste bergingsdatum van een bergingsploeg
    geldig altijd
        De uiterste bergingsdatum van een Bergingsploeg moet berekend worden als zijn meldingsdatum plus zijn bergingsbestek.

Regel vroegste meldingsdatum van een bergingsploeg
    geldig altijd
        De vroegste meldingsdatum van een Bergingsploeg moet berekend worden als zijn meldingsdatum min zijn bergingsbestek.

Regel bergingsspanne van een bergingsploeg
    geldig altijd
        De bergingsspanne van een Bergingsploeg moet berekend worden als de tijdsduur van zijn meldingsdatum tot zijn opleverdatum in hele springtijdagen.

Regel bergingsafstand van een bergingsploeg
    geldig altijd
        De bergingsafstand van een Bergingsploeg moet berekend worden als de absolute tijdsduur van zijn opleverdatum tot zijn meldingsdatum in hele springtijdagen.
casecorpus/golden/jutterswet-bergingsklok/case1.json
P1 meldingsdatum 2026-03-10 · bergingsbestek 3 · opleverdatum 2026-04-20
→ uiterste bergingsdatum 2026-04-15 · vroegste meldingsdatum 2026-02-01 · bergingsspanne 3 · bergingsafstand 3
P2 meldingsdatum 2026-03-15 · bergingsbestek 1
→ uiterste bergingsdatum 2026-04-01
P3 bergingsbestek 0 · opleverdatum < meldingsdatum
→ uiterste bergingsdatum = meldingsdatum · bergingsspanne −1 · bergingsafstand 1

Dagsoorten

Een definitieregel legt vast welke dagen tot een dagsoort behoren; in deze golden gebruikt geen expressie de stormvloeddag.

Day types

A definition rule determines which days belong to a day type; in this golden no expression uses stormvloeddag (storm-surge day).

RegelSpraakcorpus/golden/jutterswet-schouwrooster/source.rgs
Regel Dagsoortdefinitie stormvloeddag
    geldig altijd
        Een dag is een stormvloeddag
        indien er aan alle volgende voorwaarden wordt voldaan:
        - de dag later is dan 30-09-2026
        - de dag eerder is dan 01-03-2027.

Dimensies

Een attribuut kan gedimensioneerd zijn, hier naar seizoen: het heeft een waarde per cel. Een regel leest één cel met in voorjaar; een cel zonder invoer leest leeg. Alle uitvoerders lezen en schrijven cellen en vouwen erover, ook over meer dimensies.

Dimensions

An attribute can be dimensioned, here by season: it has a value per cell. A rule reads one cell with in voorjaar (in spring); a cell without input reads as empty. All executors read and write cells and fold over them, also over more than one dimension.

RegelSpraakcorpus/golden/jutterswet-seizoenvondst/source.rgs
Dimensie het seizoen, bestaande uit de seizoenen (na het attribuut met voorzetsel in):
    1. voorjaar
    2. najaar

Objecttype de Jutter (mv: Jutters) (bezield)
    het vondstgewicht Numeriek (niet-negatief getal met 2 decimalen) met eenheid kg gedimensioneerd met seizoen;
    het voorjaarsgewicht Numeriek (niet-negatief getal met 2 decimalen) met eenheid kg;
…
… moet berekend worden als zijn vondstgewicht in voorjaar.
casecorpus/golden/jutterswet-seizoenvondst/case1-voorjaarscel.json
J1 vondstgewicht voorjaar 12.50 · najaar 4.00 → voorjaarsgewicht 12.50
J2 vondstgewicht najaar 4.00                  → voorjaarsgewicht leeg
→ consistent

Uitzonderingen en geprioriteerde defaults

Een uitzondering gaat vóór haar basisregel. Het subtype Wrakrecht vervangt de geërfde basis door grondslag maal 2 en voegt een eigen uitzondering toe (55,00 bij bergingsdiepte boven 20), die vóór de geërfde gaat.

Exceptions and prioritized defaults

An exception takes precedence over its base rule. The subtype Wrakrecht replaces the inherited base with the base amount times 2 and adds its own exception (55.00 for a salvage depth above 20), which precedes the inherited one.

RegelSpraakcorpus/golden/jutterswet-wrakrecht/source.rgs
Regel uitkering van een strandrecht
    geldig altijd
        De uitkering van een Strandrecht moet gesteld worden op zijn grondslag.

Uitzondering op uitkering van een strandrecht: uitkering van een betwist strandrecht
    geldig altijd
        De uitkering van een Strandrecht moet gesteld worden op 99,00
        indien het Strandrecht betwist is.
casecorpus/golden/jutterswet-wrakrecht/
grondslag 10.00
Strandrecht                            → uitkering 10.00
Wrakrecht, bergingsdiepte 5            → uitkering 20.00
Strandrecht, betwist                   → uitkering 99.00
Wrakrecht, bergingsdiepte 5, betwist   → uitkering 99.00
Wrakrecht, bergingsdiepte 25           → uitkering 55.00
Wrakrecht, bergingsdiepte 25, betwist  → uitkering 55.00

Een ongeordende groep kent geen voorrang: beslissen twee leden verschillend, dan blijft het attribuut leeg en volgt een inconsistentie met code EF-027, geen afbreking.

An unordered group has no priority: if two members decide differently, the attribute stays empty and an inconsistency with code EF-027 follows, not an abort.

RegelSpraakcorpus/golden/jutterswet-wachtgeld/source.rgs
Uitzonderingen ongeordend:
Regel wachtgeld voor kustwachters
    geldig altijd
        Het wachtgeld van een Jutter moet gesteld worden op 30
        indien hij kustwacht is.
casecorpus/golden/jutterswet-wachtgeld/case2-conflict.json
M kustwacht · havenmeester → wachtgeld leeg · inconsistent EF-027 (Jutter.wachtgeld)

Consistentie en uniciteit

Een schending is geen fout maar een waarneembaar inconsistentie-feit per betrokken object, met de code van haar soort: EF-025 voor een consistentie-eis, EF-026 voor een uniciteit.

Consistency and uniqueness

A violation is not an error but an observable inconsistency fact per object involved, with the code of its kind: EF-025 for a consistency requirement, EF-026 for a uniqueness.

RegelSpraakcorpus/golden/jutterswet-vondstnummer/source.rgs
Regel eenmalig vondstnummer
    geldig altijd
        De vondstnummers van alle Vondsten moeten uniek zijn.

Regel aanmelding niet voor de vondstdag
    geldig altijd
        De aanmelddatum van een Vondst moet later of gelijk zijn aan de vondstdag van de Vondst.
casecorpus/golden/jutterswet-vondstnummer/
V1 vondstnummer 7 · V2 vondstnummer 7           → inconsistent EF-026: V1, V2 (eenmalig vondstnummer)
vondstdag 2025-03-01 · aanmelddatum 2025-02-01  → inconsistent EF-025 (aanmelding niet voor de vondstdag)
V1 vondstnummer 7 · V2 vondstnummer 8           → consistent

Regelversies met geldigheid

Deze regel heeft een geldigheidsvenster en doet alleen mee als de evaluatiedatum erin valt. Op 2026-06-01 is het wintertal van H1 2 en van H2 1, op 2026-02-01 overal 0.

Rule versions with validity

This rule has a validity window and applies only if the evaluation date falls within it. On 2026-06-01 the winter count of H1 is 2 and of H2 1, on 2026-02-01 it is 0 everywhere.

RegelSpraakcorpus/golden/jutterswet-dubbelverbinding/source.rgs
Regel winterberging door de haven
    geldig vanaf 01-03-2026
        Een winterschuit van een Haven is een ligger van de Haven
        indien de Haven veilig is.
§ 4Jutterswet

De Jutterswet als casus

Het corpus is gebouwd op de Jutterswet, de Wet op de jutterspenning van het verzonnen eiland Scholde. De wet regelt wie erkend jutter is en wie recht heeft op de jutterspenning. Er zijn vijf versies met fictieve data, van v0 (2020, vijf artikelen) tot v4 (2025, dertien artikelen); negen dossiers leggen per versie de bedoelde uitkomst vast. "Bergloon" en "keurmeester" komen uit de goldens, niet uit de wet. De README van het corpus koppelt vijf goldens aan hun artikel; deze pagina toont er drie.

The Jutterswet as a case study

The corpus is built on the Jutterswet, the Beachcombers' Token Act of the fictional island of Scholde. The act governs who is a recognised beachcomber and who is entitled to the beachcombers' token. There are five versions with fictional dates, from v0 (2020, five articles) to v4 (2025, thirteen articles); nine dossiers fix the intended outcome per version. "Bergloon" (salvage fee) and "keurmeester" (inspector) come from the goldens, not from the act. The corpus README links five goldens to their articles; this page shows three of them.

Artikel 3 en jutterswet-penningdrempel

Art. 3 (penningrecht) corpus/jutterswet/wet-v4.md

Recht op de jutterspenning heeft de erkende jutter van onbesproken juttersgedrag die in het penningjaar ten minste zoveel vondsten als de vondstdrempel bij de strandvoogd heeft aangemeld.

Article 3 and jutterswet-penningdrempel

Art. 3 (token entitlement) corpus/jutterswet/wet-v4.md (translation)

Entitled to the beachcombers' token is the recognised beachcomber of irreproachable beachcombing conduct who, in the token year, has reported at least as many finds to the beach warden as the find threshold.

RegelSpraakcorpus/golden/jutterswet-penningdrempel/source.rgs
Parameter de vondstdrempel : Numeriek (geheel getal)

Regel Kenmerktoekenning jutter penninggerechtigd
    geldig altijd
        Een Jutter is penninggerechtigd
        indien zijn aantal aangemelde vondsten groter of gelijk is aan de vondstdrempel.

De vondstdrempel uit artikel 7 is een parameter. "Erkende jutter" en "van onbesproken juttersgedrag" ontbreken, en het aantal aangemelde vondsten is invoer (zie § 8).

The find threshold from article 7 is a parameter. "Recognised beachcomber" and "of irreproachable beachcombing conduct" are absent, and the number of reported finds is input (see § 8).

Artikel 3b en jutterswet-penningjaar

Art. 3b (telling) corpus/jutterswet/wet-v4.md

Voor de toepassing van artikel 3 telt iedere in het penningjaar aangemelde vondst eenmaal; een vondst waarvan de dag een stormvloeddag is, telt tweemaal. Het penningjaar is het kalenderjaar.

Article 3b and jutterswet-penningjaar

Art. 3b (count) corpus/jutterswet/wet-v4.md (translation)

For the purposes of article 3, every find reported in the token year counts once; a find whose day is a storm-surge day counts twice. The token year is the calendar year.

RegelSpraakcorpus/golden/jutterswet-penningjaar/source.rgs
Tijdlijn het penningjaar heeft tijdvakken van een jaar startend op dag 1 van maand 1;

Eenheidsysteem Munt
    de euro (mv: euros) EUR €

Objecttype de Jutter (mv: Jutters) (bezield)
    is penninggerechtigd kenmerk (bijvoeglijk);
    is aanmeldplichtig kenmerk (bijvoeglijk);
    het aantal aangemelde vondsten Numeriek (niet-negatief geheel getal) voor elke penningjaar;
    het totaal aangemelde vondsten Numeriek (geheel getal);

Parameter de vondstdrempel : Numeriek (geheel getal)
Parameter het penningbedrag : Numeriek (geheel getal) met eenheid € voor elk jaar

Regel totaal aangemelde vondsten
    geldig altijd
        Het totaal aangemelde vondsten van een Jutter moet berekend worden als het totaal van zijn aantal aangemelde vondsten.

Regel Kenmerktoekenning penninggerechtigd
    geldig altijd
        Een Jutter is penninggerechtigd
        indien zijn totaal aangemelde vondsten groter of gelijk is aan de vondstdrempel.

Regel Kenmerktoekenning aanmeldplichtig
    geldig altijd
        Een Jutter is aanmeldplichtig
        indien hij niet penninggerechtigd is.
casecorpus/golden/jutterswet-penningjaar/case.json
asOfDate 2026-03-15 · vondstdrempel 12
J1 aantal aangemelde vondsten 14   → totaal aangemelde vondsten 14 · penninggerechtigd · ¬aanmeldplichtig
J2 aantal aangemelde vondsten 3    → ¬penninggerechtigd · aanmeldplichtig
J3 aantal aangemelde vondsten leeg → totaal aangemelde vondsten 0 · ¬penninggerechtigd · aanmeldplichtig

Het penningjaar was de eerste benoemde tijdlijn in het corpus, en indien hij niet penninggerechtigd is de eerste negatieve afhankelijkheid. Niet gemodelleerd: de dubbele telling op stormvloeddagen en de beperking van de telling tot het penningjaar.

The token year was the corpus's first named timeline, and indien hij niet penninggerechtigd is (if he is not entitled) the first negative dependency. Not modelled: the double count on storm-surge days and the restriction of the count to the token year.

Artikel 9 en jutterswet-berging

Art. 9 (gezamenlijke berging) corpus/jutterswet/wet-v4.md

Bergen twee of meer jutters gezamenlijk één zaak, dan wordt de opbrengst van de berging in euro's over de bergers verdeeld naar rato van ieders aandeel in het geborgen gewicht, met voor iedere berger ten hoogste het bergingsmaximum dat de strandvoogd bij de aanvang van de berging voor hem heeft vastgesteld, en ieder aandeel afgerond op hele euro's naar beneden. Wat door het maximum of de afronding onverdeeld blijft, valt toe aan het eilandfonds. Is geen gewicht per berger vastgesteld, dan wordt in gelijke delen verdeeld.

Article 9 and jutterswet-berging

Art. 9 (joint salvage) corpus/jutterswet/wet-v4.md (translation)

If two or more beachcombers jointly salvage one item, the proceeds of the salvage in euros are distributed over the salvors in proportion to each one's share of the salvaged weight, with for each salvor at most the salvage maximum the beach warden set for him at the start of the salvage, and each share rounded down to whole euros. Whatever remains undistributed because of the maximum or the rounding accrues to the island fund. If no weight has been established per salvor, the proceeds are distributed in equal shares.

RegelSpraakcorpus/golden/jutterswet-berging/source.rgs
Eenheidsysteem Munt
    de euro (mv: euros) EUR €

Eenheidsysteem Gewicht
    het kilogram (mv: kilogrammen) kg
    de ton (mv: tonnen) t = 1000 kg

Objecttype de Berging (mv: Bergingen)
    de opbrengst Numeriek (geheel getal) met eenheid €;
    de onverdeelde rest Numeriek (geheel getal) met eenheid €;

Objecttype de Berger (mv: Bergers) (bezield)
    het bergingsaandeel (mv: bergingsaandelen) Numeriek (geheel getal) met eenheid €;
    het geborgen gewicht Numeriek (getal met 2 decimalen) met eenheid kg;
    het bergingsmaximum Numeriek (geheel getal) met eenheid €;

Feittype bergingsdeelname
    de berging Berging
    de berger (mv: bergers) Berger
Eén berging heeft meerdere bergers

Regel verdeel de opbrengst van een berging
    geldig altijd
        De opbrengst van een berging wordt verdeeld over de bergingsaandelen van alle bergers van de berging, waarbij wordt verdeeld:
        - naar rato van het geborgen gewicht,
        - met een maximum van het bergingsmaximum,
        - afgerond op 0 decimalen naar beneden.
        Als onverdeelde rest blijft de onverdeelde rest van de berging over.

Vastgelegde afwijkingen: de rest blijft op de Berging in plaats van naar het eilandfonds te gaan, en de terugval op gelijke delen staat in een aparte golden.

Recorded deviations: the remainder stays on the Berging instead of going to the island fund, and the fallback to equal shares lives in a separate golden.

§ 5Catala

Catala

Catala is de programmeertaal voor wetgeving van Inria (Merigoux, Chataing & Protzenko, ICFP 2021). Haar kern is een default-calculus: een algemene regel met geprioriteerde uitzonderingen, in de taal zelf en niet in de engine. Een bron is literate: artikeltekst en code in één bestand.

De frontend is een zelfstandig OCaml-programma dat de Catala-compiler als bibliotheek linkt en aanhaakt op scopelang, vóórdat scopes tot functies worden gecompileerd; zo zijn scopestructuur en richting van overrides nog zichtbaar. Een scope wordt een objecttype, een basis met uitzonderingen één groep geprioriteerde defaults. Wat buiten het vastgestelde fragment valt, weigert de frontend met naam en exitcode 3.

Catala

Catala is Inria's programming language for legislation (Merigoux, Chataing & Protzenko, ICFP 2021). Its core is a default calculus: a general rule with prioritized exceptions, in the language itself rather than in the engine. A source is literate: article text and code in one file.

The frontend is a standalone OCaml program that links the Catala compiler as a library and attaches at scopelang, before scopes compile to functions, so scope structure and the direction of overrides are still visible. A scope becomes an object type, a base with exceptions one group of prioritized defaults. The frontend refuses anything outside the decided fragment by name, with exit code 3.

logfrontends/catala/test/refuse_sort.catala_en
catala_frontend: refused: row 10: list sorting (Sort) is out of the 5b kernel — argmin/argmax and ordering stay refused (§4)

Kamerheffing: het kortste voorbeeld

Kamerheffing roept per grondslag Kamerbedrag aan en telt op; in de IR wordt dat een functiedefinitie met een aanroep per element. Het artikelnummer hoort bij de golden; de nummering van v4 van de wet loopt tot artikel 9.

Kamerheffing: the shortest example

Kamerheffing calls Kamerbedrag for every base amount and sums the results; in the IR that becomes a function definition with one call per element. The article number belongs to the golden; the numbering of v4 of the act runs up to article 9.

Catalacorpus/golden/jutterswet-kamerheffing-catala/source.catala_en
# Jutterswet, artikel 14 — de kamerheffing

Art. 14 (kamerheffing). Een jutter die over meer vondsten verschuldigd is,
betaalt per vondst een kamerbedrag. Het kamerbedrag is de grondslag van de
vondst, vermeerderd met het vaste kamerrecht van honderd gulden. De
kamerheffing is de som van de kamerbedragen over alle grondslagen.
…
```catala
declaration scope Kamerbedrag:
  input grondslag content integer
  output bedrag content integer

scope Kamerbedrag:
  definition bedrag equals grondslag + 100

declaration scope Kamerheffing:
  input grondslagen content list of integer
  output heffing content integer

scope Kamerheffing:
  definition heffing equals
    combine all b
      among (map each g among grondslagen to (output of Kamerbedrag with { -- grondslag: g }).bedrag)
      in acc initially 0 with (acc + b)
```
casecorpus/golden/jutterswet-kamerheffing-catala/
grondslagen [200, 400] → heffing 800 · consistent
grondslagen []         → heffing 0 · consistent

Penningrecht: de default-calculus

Deze golden modelleert artikel 3 in de v0-lezing (drempel twaalf) met een hardheidsgrond: boven de basis false staat artikel 3, en daarboven artikel 5 als uitzondering óp artikel 3. In de IR is dat één PrioritizedDefaults-knoop met drie leden; de RegelSpraak-tweeling jutterswet-penningrecht schrijft hetzelfde als twee kenmerktoekenningen, met dezelfde cases.

Penningrecht: the default calculus

This golden models article 3 in its v0 reading (threshold twelve) with a hardship ground: above the base false stands article 3, and above it article 5 as an exception to article 3. In the IR this is one PrioritizedDefaults node with three members; the RegelSpraak twin jutterswet-penningrecht writes the same as two characteristic assignments, with the same cases.

Catalacorpus/golden/jutterswet-penningrecht-catala/source.catala_en
declaration scope Penningrecht:
  input aantal_aangemelde_vondsten content integer
  input hardheid_toegepast content boolean
  output penninggerechtigd content boolean

scope Penningrecht:
  # De stilte-basis: zonder gegronde aanspraak geen recht.
  definition penninggerechtigd equals false

  # Artikel 3: de gewone drempel.
  label artikel_3 exception
  definition penninggerechtigd
  under condition aantal_aangemelde_vondsten >= 12
  consequence equals
    true

  # Artikel 5 leest artikel 3 met "zes": de hardheidsgrond gaat vóór
  # en is daarom een uitzondering óp artikel 3 — de keten, niet een
  # tweede ongeordende grond.
  exception artikel_3
  definition penninggerechtigd
  under condition
    hardheid_toegepast
    and aantal_aangemelde_vondsten >= 6
  consequence equals
    true
casecorpus/golden/jutterswet-penningrecht-catala/
aantal_aangemelde_vondsten 12                      → penninggerechtigd · consistent
aantal_aangemelde_vondsten 6 · hardheid_toegepast  → penninggerechtigd · consistent
aantal_aangemelde_vondsten 6                       → ¬penninggerechtigd · consistent
aantal_aangemelde_vondsten 4 · hardheid_toegepast  → ¬penninggerechtigd · consistent
aantal_aangemelde_vondsten 12 · hardheid_toegepast → penninggerechtigd · consistent

Conflict: bewust anders dan Catala

In jutterswet-tariefrecht-catala staan boven een basistarief en een eerste uitzondering twee ongeordende uitzonderingen: 10 % bij ten minste vier kinderen, 0 % bij een inkomen tot en met $10,000. Gelden beide, dan breekt catala interpret af met een ConflictError; referentie-interpreter en Clingo laten tarief bewust leeg en melden een inconsistentie met code EF-027.

Conflict: deliberately unlike Catala

In jutterswet-tariefrecht-catala, two unordered exceptions sit above a base rate and a first exception: 10 % with at least four children, 0 % with an income of at most $10,000. If both apply, catala interpret aborts with a ConflictError; the reference interpreter and Clingo deliberately leave tarief empty and report an inconsistency with code EF-027.

casecorpus/golden/jutterswet-tariefrecht-catala/
inkomen 20000.00 · kindertal 4 → tarief 0.1000 · aanslag 1000.00
inkomen 8000.00 · kindertal 4  → tarief leeg · aanslag 0.00 · inconsistent EF-027 (Penningplichtige.tarief/0)

Gate 9 vertaalt alle twaalf Catala-goldens opnieuw, na canonicalisatie byte-identiek aan hun ir.json; de suite blijft boven haar ondergrens van 201 checks. Drools speelt er zes na en weigert er zes, elk met een code en een reden: structs (DROOLS-009), functiedefinities (twee keer, DROOLS-002), lijsten (DROOLS-008) en Match (twee keer, DROOLS-021). Beide weergaven van de Drools-backend geven daarbij per golden dezelfde statusregel (§ 7).

Gate 9 translates all twelve Catala goldens again; after canonicalization each is byte-identical to its ir.json, and the suite stays above its floor of 201 checks. Drools replays six and refuses six, each with a code and a reason: structs (DROOLS-009), function definitions (twice, DROOLS-002), lists (DROOLS-008) and Match (twice, DROOLS-021). Both renderings of the Drools backend give the same status line per golden (§ 7).

§ 6F-logic

F-logic

F-logic (Kifer, Lausen & Wu, JACM 1995) beschrijft objecten als frames, met een klassehiërarchie en waarden die een klasse aan haar subklassen doorgeeft. Komen het supertype, de ketengesloten ledenresolutie en de voorrang van de subklasse ook vanuit F-logic op de wire, dan is de overervingskern aantoonbaar geen weergave van RegelSpraak. F-logic bewaakt ook de kwantorvouw: een telling vergeleken met een getal geeft atLeast, atMost, exactly, none of all, zonder negatievorm; de golden jutterswet-vuurtoren-flogic toont de eerste drie, de suite van de frontend alle vijf.

De frontend accepteert een syntactische deelverzameling van Flora-2 2.2. Elke vorm tot 12 september 2026 is in die onafhankelijke redeneerder zelf gecontroleerd; drie latere vormen, de count{…}-body met een conjunctie, de kenmerkkop ?X : k :- … en <=, zijn alleen aan de hand van de gedocumenteerde grammatica van Flora-2 beredeneerd, nog niet in de redeneerder zelf gedraaid. De vorm van de regel bepaalt de IR:

VormBetekenis
C::D.D is het enige directe supertype van C
C[|a => numeriek(sign, scale)|].attribuutdeclaratie op C
@!{'name'} C[|a -> 5|].overerfbare klasse-default: de basis van een defaultsgroep op C.a
@!{'name'} ?X[a -> Expr] :- ?X : C, Cond, ….voorwaardelijke definitie: een uitzondering
@!{'name'} ?X : k :- ?X : C, Cond, ….kenmerktoekenning: C.k geldt waar het lichaam geldt

F-logic

F-logic (Kifer, Lausen & Wu, JACM 1995) describes objects as frames, with a class hierarchy and values that a class passes on to its subclasses. If the supertype, chain-closed member resolution and the precedence of the subclass also reach the wire from F-logic, the inheritance kernel is demonstrably not a rendering of RegelSpraak. F-logic also guards the quantifier fold: a count compared with a number gives atLeast, atMost, exactly, none or all, without a negation form; the golden jutterswet-vuurtoren-flogic shows the first three, the frontend's suite all five.

The frontend accepts a syntactic subset of Flora-2 2.2. Every form up to 12 September 2026 was checked in that independently maintained reasoner itself; three later forms, the count{…} body with a conjunction, the characteristic head ?X : k :- … and <=, have only been argued from Flora-2's documented grammar, not yet run in the reasoner itself. The shape of the rule determines the IR:

FormReading
C::D.C's single direct supertype is D
C[|a => numeriek(sign, scale)|].an attribute declaration on C
@!{'name'} C[|a -> 5|].the inheritable class-level default: a defaults base on C.a
@!{'name'} ?X[a -> Expr] :- ?X : C, Cond, ….a conditional definition: an exception
@!{'name'} ?X : k :- ?X : C, Cond, ….a characteristic assignment: C.k holds where the body does
F-logiccorpus/golden/jutterswet-wrakrecht-flogic/source.flogic
// The bare rule on the supertype: no exception anywhere, so it is a
// standing norm rather than a default, and it fires for Wrakrechten too.
@!{'registratiekosten van een strandrecht'}
?S[registratiekosten -> 5.00] :- ?S : Strandrecht.

// Strandrecht.uitkering: an unconditional rule is the base, a conditional
// one an exception above it.
@!{'uitkering van een strandrecht'}
?S[uitkering -> ?S.grondslag] :- ?S : Strandrecht.

@!{'uitkering van een betwist strandrecht'}
?S[uitkering -> 99.00] :- ?S : Strandrecht, ?S : betwist.

// Wrakrecht.uitkering: its own base replaces the inherited one, its own
// exception joins the inherited one above that.
@!{'uitkering van een wrakrecht'}
?W[uitkering -> ?W.grondslag * 2] :- ?W : Wrakrecht.

@!{'uitkering van een diep wrakrecht'}
?W[uitkering -> 55.00] :- ?W : Wrakrecht, ?W.bergingsdiepte > 20.
casecorpus/golden/jutterswet-wrakrecht-flogic/
grondslag 10.00
Strandrecht                            → uitkering 10.00 · registratiekosten 5.00
Wrakrecht, bergingsdiepte 5            → uitkering 20.00 · registratiekosten 5.00
Strandrecht, betwist                   → uitkering 99.00
Wrakrecht, bergingsdiepte 5, betwist   → uitkering 99.00
Wrakrecht, bergingsdiepte 25           → uitkering 55.00
Wrakrecht, bergingsdiepte 25, betwist  → uitkering 55.00

De vier case-bestanden van jutterswet-wrakrecht-flogic zijn byte-gelijk aan die van de RegelSpraak-versie in § 3 en van het anker jutterswet-strandrechtketen. Twee goldens hebben een F-logic-bron; de suite blijft boven haar ondergrens van 81 checks. Een weigering eindigt met exitcode 2, zonder uitvoerbestand.

The four case files of jutterswet-wrakrecht-flogic are byte-identical to those of the RegelSpraak version in § 3 and of the anchor jutterswet-strandrechtketen. Two goldens have an F-logic source; the suite stays above its floor of 81 checks. A refusal exits with code 2 and leaves no output file.

logfrontends/flogic/test/refuse_naf.flogic
flogic: REFUSED refuse_naf.flogic: the negation form \naf (line 4) — outside the F-logic slice fixed by spec/proposals/SUBTYPING.md
§ 7vier gedaantenfour forms

Eén regel, vier gedaanten

Artikel 3 geeft recht op de jutterspenning bij ten minste zoveel aangemelde vondsten als de vondstdrempel. jutterswet-penningdrempel modelleert alleen dat drempeldeel: één regel, één parameter, één vergelijking. De case: J1 met 14 en J2 met 3 aangemelde vondsten, drempel 12. In bron, ASP en DRL zijn de gemarkeerde regels de wetsregel zelf.

One rule, four forms

Article 3 grants the beachcombers' token for at least as many reported finds as the find threshold. jutterswet-penningdrempel models only that threshold part: one rule, one parameter, one comparison. The case: J1 with 14 and J2 with 3 reported finds, threshold 12. In the source, the ASP and the DRL the highlighted lines are the legal rule itself.

RegelSpraakcorpus/golden/jutterswet-penningdrempel/source.rgs
Objecttype de Jutter (mv: Jutters) (bezield)
    is penninggerechtigd kenmerk (bijvoeglijk);
    het aantal aangemelde vondsten Numeriek (niet-negatief geheel getal);

Parameter de vondstdrempel : Numeriek (geheel getal)

Regel Kenmerktoekenning jutter penninggerechtigd
    geldig altijd
»        Een Jutter is penninggerechtigd
»        indien zijn aantal aangemelde vondsten groter of gelijk is aan de vondstdrempel.

De bron zoals ingecheckt; de RegelSpraak-frontend vertaalt haar zonder canonicalisatie byte-identiek naar ir.json (gate 10).

The source as checked in; the RegelSpraak frontend translates it, without canonicalization, byte-identically into ir.json (gate 10).

Zo komen de onderdelen overeen:

How the parts correspond:

RegelSpraakIRASPDRL
"Een Jutter"target.subjectType "Jutter"isa(S,"jutter")$onderwerp : dev.uchar.regelspraak.facts.Jutter( … )
"is penninggerechtigd"target: AttributeReference "penninggerechtigd"; value: Literal {"boolean": true}has(S,"penninggerechtigd")insertLogical(new HasCharacteristic($onderwerp, ElementKey.of("jutter", "penninggerechtigd", true)))
"zijn aantal aangemelde vondsten"AttributeReference "aantal aangemelde vondsten"val(S,"aantal aangemelde vondsten",A1)$aantalAangemeldeVondsten : aantalAangemeldeVondsten
"groter of gelijk is aan"Comparison, op greaterOrEqualA1 >= P2rsAggVergelijk(…, ">=") in de toetsfunctie, aangeroepen inin the test function, called in eval( … )
"de vondstdrempel"ParameterReference "vondstdrempel"param("vondstdrempel",P2)ParameterState( parameter == "vondstdrempel", $vondstdrempel : value )
afwezig bij J2: geen tekst nodigabsent for J2: no text neededgeen knoopno nodegeen atoom (negation-as-failure)no atom (negation as failure)regel vuurt niet: geen HasCharacteristicrule does not fire: no HasCharacteristic

De IR en het differentiaalvierkant

De IR gaat als JSON over de draad in het formaat uchar-ir-v1, cases in uchar-case-v0, elk met een strikt JSON Schema (additionalProperties: false). Knopen, velden en enumeratiewaarden hebben Engelse namen (AttributeReference, greaterOrEqual), en de brontekst staat in een record source. Gedeclareerde namen, zoals objecttypen, attributen en labels, staan zoals ze geschreven zijn, in het Nederlands. v1 is afgeleid van v0, de getrouwe dump van het opgeloste model van regelspraak-java; elke afwijking van v0 staat in het constructenregister (§ 8). Elke MUST in de specificatie draagt een id WF-### en heeft een check in de verifier, een slagende golden en een falende negatieve case, of staat als OPEN in de index. Gate 2 eist dat elk document na inlezen en canoniek terugschrijven byte-identiek is.

Naast wat de evaluatie leest, draagt de IR velden zonder semantiek, voor wie een document toont of een beslissing uitlegt. Gate 13 haalt ze weg en eist dat de referentie-interpreter, Clingo en beide Drools-weergaven daarna dezelfde uitkomst geven als met de velden.

  • origin (IR-SPEC 2.13, WF-121), op een declaratie die de frontend zelf maakte: de vorm die haar maakte (inputAboveComputation, exceptionForSubtype, decisionTableRow, stepsAfterSet of startPoint) en de declaratie waar zij van komt. Aan de naam is zo'n declaratie niet te herkennen, want een auteur kan dezelfde woorden schrijven.
  • Default.name (IR-SPEC 6.1): de naam die de bron aan het blok van een default geeft. In jutterswet-meldingsketen draagt de default van Uitzondering op erkende meldingsdatum: herstelde melding de naam herstelde melding; een uitleg kan zo de default noemen die besliste.
  • Default.statuteAnnotations (IR-SPEC 6.1, WF-082): de // Bron:-regels boven het blok van een default, één string per regel, in bronvolgorde.

Het vormanker heeft wel semantiek. Het filter van een vouw en de toets van een kwantor worden per element gelezen, met het element als onderwerp. Met anchor: "form" op een AttributeReference, CharacteristicCheck, Aggregation of QuantifierFold wordt die knoop gelezen op het onderwerp van de vorm, het object waarop de regel loopt; de voorwaardeknoop IdentityCheck toetst of het element dat onderwerp is (IR-SPEC 4.1a en 4.5, WF-122). Zo vertaalt de frontend het woord zelf en een vouw over een relatie van het onderwerp in een filter (§ 2). De specificatie legt het vormanker vast als voorlopig besluit.

De specificatie legt ook vast hoe de voorwaarde van een vorm wordt gelezen in het fixpunt, de toestand waarin geen regel nog iets verandert (RUNTIME-SEMANTICS 5.12): per vorm en object een status (HOLDS, FAILS, FAULTS, DISPLACED of OUTSIDE_VALIDITY) en per knoop het oordeel of de waarde die de evaluatie vond, of de fout met haar EF-code. Een lezing verandert niets aan wat de sessie berekent; een uitleg leest haar, in plaats van de voorwaarde in een eigen semantiek opnieuw uit te rekenen. De referentie-interpreter schrijft haar met --trace (tab Uitkomst hierboven), de Drools-backend met DroolsBackendMain --readings, en gate 17 houdt beide per casebestand gelijk; Clingo levert geen lezing. Meer op Onder de motorkap.

Referentie-interpreter, Clingo en Drools spelen elke case na tegen dezelfde vastgelegde verwachtingen; wat Clingo of Drools niet draagt, weigert die uitvoerder met naam, code en reden (gates 6 en 12, § 8). Overeenstemming alleen geldt niet als waarheid: de ankersubset legt absolute, met de hand berekende waarden vast. Specificatie en gates staan op Onder de motorkap.

The IR and the differential square

The IR travels over the wire as JSON in the format uchar-ir-v1, cases in uchar-case-v0, each with a strict JSON Schema (additionalProperties: false). Nodes, fields and enumeration values have English names (AttributeReference, greaterOrEqual), and the source text sits in a source record. Declared names, such as object types, attributes and labels, stand as they were written, in Dutch. v1 derives from v0, the faithful dump of regelspraak-java's resolved model; every deviation from v0 is in the construct register (§ 8). Every MUST in the specification carries an id WF-### and has a check in the verifier, a passing golden and a failing negative case, or is marked OPEN in the index. Gate 2 requires every document to round-trip canonically, byte for byte.

Beside what evaluation reads, the IR carries fields without semantics, for a consumer that shows a document or explains a decision. Gate 13 removes them and requires the reference interpreter, Clingo and both Drools renderings to give the same outcome without them as with them.

  • origin (IR-SPEC 2.13, WF-121), on a declaration the frontend made itself: the form that made it (inputAboveComputation, exceptionForSubtype, decisionTableRow, stepsAfterSet or startPoint) and the declaration it comes from. Such a declaration cannot be recognised by its name, because an author can write the same words.
  • Default.name (IR-SPEC 6.1): the name the source gives the block a default comes from. In jutterswet-meldingsketen the default of Uitzondering op erkende meldingsdatum: herstelde melding carries the name herstelde melding; an explanation can thus name the default that decided.
  • Default.statuteAnnotations (IR-SPEC 6.1, WF-082): the // Bron: lines above the block of a default, one string per line, in source order.

The form anchor does carry semantics. The filter of a fold and the test of a quantifier are read per element, with the element as subject. With anchor: "form" on an AttributeReference, CharacteristicCheck, Aggregation or QuantifierFold, that node is read on the subject of the form, the object the rule runs on; the condition node IdentityCheck tests whether the element is that subject (IR-SPEC 4.1a and 4.5, WF-122). This is how the frontend translates the word zelf and a fold over a relation of the subject in a filter (§ 2). The specification records the form anchor as a provisional decision.

The specification also fixes how the condition of a form is read at the fixpoint, the state in which no rule changes anything any more (RUNTIME-SEMANTICS 5.12): per form and object a status (HOLDS, FAILS, FAULTS, DISPLACED or OUTSIDE_VALIDITY) and per node the verdict or value the evaluation found, or the fault with its EF code. A reading changes nothing the session computes; an explanation reads it instead of evaluating the condition again in a semantics of its own. The reference interpreter writes it with --trace (tab Result above), the Drools backend with DroolsBackendMain --readings, and gate 17 holds the two equal per case file; Clingo gives no reading. More in Under the hood.

The reference interpreter, Clingo and Drools replay every case against the same pinned expectations; what Clingo or Drools does not carry, that executor refuses by name, with a code and a reason (gates 6 and 12, § 8). Agreement alone does not count as truth: the anchor subset pins absolute, hand-computed values. The specification and the gates are described in Under the hood.

§ 8reikwijdtescope

Beperkingen en reikwijdte

Een parser of backend mag zeggen dat hij iets niet kan; hij mag niet doen alsof. Wat een frontend-parser niet in de IR kan uitdrukken, staat er als Unresolved; wat een backend niet kan uitvoeren, weigert hij met naam en reden, en de gate telt die weigeringen, zodat een uitkomst óf volgens de specificatie is berekend óf uitdrukkelijk is geweigerd, en nooit stil ontbreekt.

Unresolved

Voor wat een bron niet kan uitdrukken heeft de IR de knoop Unresolved (in v0: Onopgelost); een document mag hem bevatten maar nooit verbergen (WF-044). Alleen een knoop die de evaluatie bereikt, geeft een fout; de met de hand gebouwde golden unresolved-behind-a-failing-condition heeft er drie achter een voorwaarde die niet geldt. De rode case corpus/red/wf044-unresolved-reached bereikt de knoop en moet in elke uitvoerder falen met foutsoort EF-019. De case pint die code, niet de tekst van een melding; de runners van referentie-interpreter en Clingo schrijven CODE EF-019 {}. De open begrippen van de Jutterswet, "onbesproken juttersgedrag" en "bijzondere gevallen", zijn bewust zo'n grens.

Zonder bronspelling

Eén IR-vorm heeft nog geen spelling in een brontaal: het lezen van een tijdlijn op een ander tijdstip dan de evaluatiedatum (TemporalRead). Geen frontend produceert hem; hij komt alleen voor in handgeschreven goldens. Beslistabellen (de frontend ontsuikert ze tot één regel per rij), objectcreatie, machtsverheffen, alle afrondingsrichtingen, verdeling op volgorde van, het maximum, recursieve regelgroepen en twee versies van één regelnaam hebben elk een golden met RegelSpraak-bron, zodat gate 10 ook hun byte-identieke her-emissie bewijst.

Weigeringen

Een tijdsafhankelijk attribuut of kenmerk in de voorwaarde van een regel met een scalair doel weigeren alle uitvoerders, behalve onder gedurende het gehele …; op een tijdlijndoel lezen ze zo'n voorwaarde per periode (§ 3). Clingo weigert vijf goldens met naam en code (gate 6). Drools speelt het merendeel van de goldens na en weigert de rest met naam en code (de actuele dekking staat in de gates-tabel op Onder de motorkap), zoals EXCLUDE DROOLS-023: loader: form not carried by the v0 Drools backend: Expr:TemporalRead (unknown expression node). De twee weergaven van de backend, executable model en DRL-tekst, geven per golden dezelfde statusregel (gate 12); een deel van de Catala-goldens gebruikt vormen die Drools niet ondersteunt (§ 5). De Catala-frontend weigert onder meer duration en het sorteren van lijsten, de F-logic-frontend onder meer \naf, F-logic's eigen verweerbare redeneren en een tweede supertype.

Foutsoorten

RUNTIME-SEMANTICS 5.7b geeft elke foutsoort een code, EF-001 tot en met EF-040, met een kanaal, parameters en een getuige in het corpus; een code wordt nooit hergebruikt of hernummerd. Het kanaal zegt wat er gebeurt: de case wordt bij het inlezen geweigerd (case input), de sessie breekt af (fault), elke uitvoerder weigert een vorm waaraan de specificatie geen betekenis geeft (declined), of er ontstaat een feit op het foutkanaal (§9.5, RUNTIME-SEMANTICS 5.6). Op dat laatste kanaal staan een schending van een consistentie-eis (EF-025), een dubbele uniciteitssleutel (EF-026), ongeordende defaults die verschillend beslissen (EF-027), een leeg gewicht of een leeg of negatief maximum bij een verdeling (EF-028 tot en met EF-030), een negatief gewicht bij een verdeling naar rato (EF-038), een deling door een lege deler (EF-031), en een gevulde teller gedeeld door een numerieke nul of een numerieke nul tot een negatieve macht (EF-005). Zo'n feit breekt de sessie niet af en draagt de code naast regel en object. Een uitvoerder zet de code vóór de tekst van zijn melding; die tekst is van de uitvoerder zelf. Een rode case pint een code met parameters, geen tekst, en een golden mag op een inconsistentie een code pinnen (§ 3).

Buiten de reikwijdte van v1

v0 is de getrouwe kopie van de IR van regelspraak-java; v1 is de eigen versie van uchar, met Engelse namen op de draad (§ 7). Elke afwijking staat als rij in het constructenregister (spec/CONSTRUCTS.md): een tabel met per construct de herkomst (RegelSpraak, Catala, LegalRuleML, OpenFisca of de review), het oordeel voor v1 (kern, dialect, suiker, later, of geen doel), of het een eigen kernelknoop nodig heeft, en wat er van v0 naar v1 veranderde. Datzelfde register legt dus ook vast wat v1 bewust niet doet, met reden en termijn.

  • Een tweede tijdas, kennistijd, en daarmee terugwerkende kracht: v1 kent één tijdas en benoemt alleen het uitbreidingspunt; gepland voor v2. Een later raadsbesluit met terugwerking is daarom nog niet te modelleren.
  • Jurisdictie: geen doel van v1; het blijft een vaste toets aan LegalRuleML.
  • De deontische laag, verplichting, toestemming, verbod, schending en herstel: geen doel, omdat v1 een constitutieve reken-IR is. Regels bepalen wat als wat geldt, niet wie wat moet doen. Gemeten aan de meldplicht in de Jutterswet: een plichtpositie kan als gewone waarde in de huidige kern meerijden, en een aparte laag werd daardoor minder waarschijnlijk, niet meer.
  • Parameterschijven, schijventarieven zoals in de inkomstenbelasting: centraal in belastingrecht, maar afwezig in RegelSpraak; vandaag uit te drukken als regels of beslistabel. Een eigen knoop komt pas als een brontaal erom vraagt.
  • Normautoriteit, wie de norm stelt: metadata op bronverwijzingen, later.
  • Een scenario- of conformancetestformaat is voor de IR geen doel; het leverde wel het case-schema van het corpus. Daarom staan scenariotoetsen niet in de IR: de RegelSpraak-frontend vertaalt ze naar casebestanden (§ 2).

Limitations and scope

A parser or backend may say that it cannot do something; it may not pretend. What a frontend parser cannot express in the IR is recorded there as Unresolved; what a backend cannot execute, it refuses by name and with a reason, and the gate counts those refusals, so that an outcome is either computed according to the specification or explicitly refused, and never silently missing.

Unresolved

For what a source cannot express, the IR has the node Unresolved (in v0: Onopgelost); a document may contain it but never hide it (WF-044). Only a node the evaluation reaches gives a fault; the hand-built golden unresolved-behind-a-failing-condition has three behind a condition that does not hold. The red case corpus/red/wf044-unresolved-reached reaches the node and must fail in every executor with fault kind EF-019. The case pins that code, not the text of a message; the runners of the reference interpreter and Clingo write CODE EF-019 {}. The Jutterswet's open concepts, "onbesproken juttersgedrag" (irreproachable conduct) and "bijzondere gevallen" (special cases), are deliberately such a boundary.

Without a source spelling

One IR form has no spelling in a source language yet: reading a timeline at a time other than the evaluation date (TemporalRead). No frontend produces it; it occurs only in hand-written goldens. Decision tables (the frontend desugars them into one rule per row), object creation, exponentiation, all rounding directions, distribution op volgorde van (in order of), the maximum, recursive rule groups and two versions of one rule name each have a golden with a RegelSpraak source, so gate 10 proves their byte-identical re-emission as well.

Refusals

All executors refuse a time-dependent attribute or characteristic in the condition of a rule with a scalar target, except under gedurende het gehele … (during the whole …); on a timeline target they read such a condition per period (§ 3). Clingo refuses five goldens by name and code (gate 6). Drools replays most of the goldens and refuses the rest by name and code (the current coverage is in the gates table on Under the hood), such as EXCLUDE DROOLS-023: loader: form not carried by the v0 Drools backend: Expr:TemporalRead (unknown expression node). The two renderings of the backend, the executable model and DRL text, give the same status line per golden (gate 12); some of the Catala goldens use forms Drools does not carry (§ 5). The Catala frontend refuses, for instance, the duration type and list sorting; the F-logic frontend refuses, for instance, \naf, F-logic's own defeasible reasoning and a second supertype.

Fault kinds

RUNTIME-SEMANTICS 5.7b gives every fault kind a code, EF-001 to EF-040, with a channel, parameters and a witness in the corpus; a code is never reused or renumbered. The channel says what happens: the case is refused while it is read (case input), the session aborts (fault), every executor refuses a form to which the specification gives no meaning (declined), or a fact arises on the error channel (§9.5, RUNTIME-SEMANTICS 5.6). On that last channel stand a violated consistency requirement (EF-025), a duplicate uniqueness key (EF-026), unordered defaults that decide differently (EF-027), an empty weight or an empty or negative cap in an allocation (EF-028 to EF-030), a negative weight in a proportional allocation (EF-038), a division by an empty divisor (EF-031), and a division of a filled dividend by a numeric zero or a numeric zero raised to a negative power (EF-005). Such a fact does not abort the session and carries the code beside rule and object. An executor puts the code before the text of its message; that text is the executor's own. A red case pins a code with parameters, not a text, and a golden may pin a code on an inconsistency (§ 3).

Outside the scope of v1

v0 is the faithful copy of the IR of regelspraak-java; v1 is uchar's own version, with English names on the wire (§ 7). Every deviation is a row in the construct register (spec/CONSTRUCTS.md): a table with, per construct, its origin (RegelSpraak, Catala, LegalRuleML, OpenFisca or the review), the verdict for v1 (core, dialect, sugar, later, or non-goal), whether it needs a kernel node of its own, and what changed from v0 to v1. That same register therefore also fixes what v1 deliberately does not do, with a reason and a horizon.

  • A second time axis, knowledge time, and with it retroactivity: v1 has one time axis and only names the extension point; planned for v2. A later council decision with retroactive effect therefore cannot be modelled yet.
  • Jurisdiction: not a goal of v1; it remains a standing test against LegalRuleML.
  • The deontic layer, obligation, permission, prohibition, violation and reparation: not a goal, because v1 is a constitutive calculation IR. Rules define what counts as what, not who must do what. Measured against the reporting duty in the Jutterswet: a duty position can ride along as an ordinary value in the current kernel, which made a separate layer less likely, not more.
  • Parameter brackets, bracket tariffs as in income tax: central to tax law but absent from RegelSpraak; expressible today as rules or a decision table. A node of its own comes only when a source language asks for it.
  • Norm authority, who sets the norm: metadata on source references, later.
  • A scenario or conformance-test format is not a goal for the IR; it did supply the case schema of the corpus. That is why scenario tests are not part of the IR: the RegelSpraak frontend translates them into case files (§ 2).