Skip to main content
Install Relativities and download the synthetic examples before running this page. rslc check verifies structural and calculation properties of the implemented rater. This page explains those properties, their assumptions, and the diagnostics. A passing check establishes properties of the declared inputs, formulas, tables, and citations. Source review and independent rating examples establish whether those declarations reflect the applicable filing. Validate a program covers that separate evidence. Each failing example on this page makes a small change to the dwelling fire rater from Write your first rater.

The promises at a glance

A bad request gets explicit refusal reasons

The promise. The rater checks the whole request before it calculates anything. A request that breaks a rule gets a refusal that lists detected violations with codes, messages, and available citations. The refusal contract defines evaluation order and truncation limits. The check. The rater checks each input against its declaration:
  • the value has the declared type, such as a number, a date or a member of an enum;
  • a number sits on its precision, such as whole cents;
  • a number sits inside its range;
  • each required input is present;
  • each rule from the filing holds.
Send a Coverage A as text and a protection class of 11:
The refusal names both problems. PROTECTION-CLASS is a rule from the filing, so the refusal is a BusinessRejection. A request that breaks only type and range rules gets InvalidInputs:
When the check fails. Each number input needs a range. With the range taken off coverage_a, the check stops:
Refusals lists each refusal code.

An accepted request always gets a premium

The promise. A request that passes the rules gets a premium. The calculation finishes for every such request, with a value at each step. The check. rslc works out the range of each value from the input rules. It then proves each risky step safe for every value in that range: if narrows the range inside each branch. So if b != 0 then a / b else 0 passes. When the check fails. The message names the step, the range it found, and the fixes. This calculation averages the item charges:
A policy can have zero items, so the division can fail. Each fix makes a choice the filing has to make:
  • The filing refuses the case. Change the rule on the input, for example where len(self) in [1, 10]. The rater then refuses a policy with zero items.
  • The filing rates the case. Handle it in the calculation, with the filed value in the other branch:
The same choice fixes the other messages. With max in place of sum over the items:
With the protection class range widened to [0, 10], class 0 falls below the first band:
A match over the perils that lists only fire and wind:

The numbers are exact, and they round as declared

The promise. The rater calculates with exact decimals, so 1.1 + 2.2 is exactly 3.3. A value changes only where a round says so. Each machine gets the same premium, to the cent. The check. A type with a precision, such as Money in whole cents, is a promise about the value. The check proves the formula lands on that precision. Where it can land between cents, the formula needs a round with the filed mode. When the check fails. Here charge is typed Money, but 1.5% of a value in cents can land on a fraction of a cent:
The fix is the filed rule: round(self.value * 0.015, 2, half_up). Exact numbers explains the arithmetic.

Required declarations carry source citations

The promise. Each required table, constant, and rounding calculation carries a citation or an explicit reason. A reviewer checks the source region against the implemented value or rule. The check. The check requires a citation on each table, each constant, and each calculation that rounds. It also checks that each citation names a declared source, in the right form for that kind of document. When the check fails. With the citation taken off BaseRate:
Citations covers sources, citation forms and reasons.

The rater returns a rounded premium

The promise. Each rater identifies its premium outcome and states the rounding operation that produces it. The author establishes that the operation follows the filing. The check. The rater needs a RatingOutcomes block with at least one Premium outcome. True-or-false and named-value outcomes, such as eligibility, sit next to the premium. Each outcome that is a number passes through a round, and that calculation cites the rounding rule. When the check fails. A rater that leaves out the RatingOutcomes block:
A premium that multiplies by 1.05 after the last round:
A sum of rounded values counts as rounded. So a premium that adds rounded peril premiums, rounded item charges and a whole-dollar fee passes.

The work of one rating is known in advance

The promise. The check states how much work one rating takes. The work grows with the length of each list in the request, at a rate the check prints. The check. rslc check counts the steps for each outcome: each calculation, table lookup and pass over a list. It prints the count as the cost line:
|Policy.items| is the number of scheduled items. The premium takes 12 steps, plus 2 for each item. The figures in brackets show the total for 1, 3 and 10 items. The count is an upper bound. When the check fails. A calculation on each item that walks the whole item list makes the work grow with the square of the list length. The check stops it with E-QUADRATIC, and names the fix: compute the walk once, on the policy.

The limits that make these promises possible

RSL restricts calculations and input constraints so its checker can establish these properties. The author remains responsible for faithful source interpretation.

Calculations follow the manual, step by step

RSL repeats work in one way only: a calculation walks a list or an enum with sum, product, min, max, avg or count. A calculation that needs its own value fails the check:
Here the premium adds tax, and tax reads the premium. Compute the amount before tax in its own calculation, and read it in both.

Rules go on the inputs

A calculation always produces a value, so it stops short of refusing a request. Each rule that refuses a request goes on an input, or on a record after its closing brace. The rater then checks every rule before it calculates, and refuses with every reason at once.

Tables cover every key a lookup reaches

Each lookup finds a row for every request the rules accept. When the filing leaves out some keys, choose one of these:
  • narrow the input so it excludes those keys, with a rule from the filing;
  • type the input Key(T), so the rater accepts only keys that table T prints;
  • add a cited otherwise row when the filing prints an all-other value;
  • write unfiled in a row the filing leaves blank, and narrow the input to exclude it.
Read a filed table shows each choice.