Skip to main content
Generated from the rslc compiler. RSL has a fixed set of functions. A call to any other name gets E-UNRESOLVED. lookup! and interpolate! end in !: the check proves that every call finds a value.

Tables and geographies

lookup

Reads one row of a table by its keys. The check proves that every call finds a row.
Result: The column’s type. Use lookup! to read a filed value from a table: a base rate, a factor, a territory code. The check proves that every key the call can pass has a row, so each rating finds its value. Rules
  • The first argument names a table from Tables. Each later argument is one key, in the order of the table’s dims.
  • Write .column after the call to pick the output column. For a map column, add the member in brackets: .rate[p].
  • A key for an enumeration, Code or Bool dimension has that type. A key for a band or value-set dimension is a number.
  • A band dimension gives the row of the band that holds the key. A value-set or Code dimension gives the row with the same value.
  • A table with an otherwise row gives that row for every key that the filed rows leave out.
  • The ! is part of the name. A call spelled lookup(…) gets E-LOOKUP-SYNTAX.
  • A number key that can fall outside its dimension gets E-KEY-RANGE. Bound the input, clamp the key with max or min, or add an otherwise row.
  • A key combination that lacks a row gets E-LOOKUP-GAP. Add the filed row, narrow the key, or add an otherwise row.
  • A key of type Option gets E-TYPE. Open it with match first, and pass the value inside.
  • A call that passes fewer or more keys than the table has dims gets E-TYPE. An unknown table or column gets E-UNRESOLVED.
Example
The read takes two enumeration keys. A frame home in the suburban territory gives a base rate of 690.
A home aged 25 falls in the band that starts at 25 and gives 1.12. A deductible of 2,500 is a listed value and gives 0.85. A ZIP code that the table leaves out gives the otherwise factor of 1.
The column rate holds one rate for each peril, and [p] reads the rate of peril p. Protection class 5 falls in the band that starts at 4, so the fire rate is 2.60.

interpolate

Reads a value between two rows of a table by linear interpolation, with each rounding stated.
Result: The column’s type. Use interpolate! when a filing prints factors at set points and reads values between them on a straight line. The call states each rounding that the filing states. The check proves that the key stays between the first and last filed points. Rules
  • The last dimension of the table holds the filed points as a value set, such as IntValues(100000, 200000, 300000). Only the last key interpolates. Earlier keys select rows as they do in lookup!.
  • At a filed point, the result is that row’s cell, exactly as filed. The three roundings apply only between points.
  • Between two points, the ratio is the key’s distance from the lower point divided by the gap between the points. The step is the ratio times the difference of the two cells. The result is the lower cell plus the step.
  • ratio:, step: and result: each take (scale, mode) and round that quantity as round does. Write all three, in any order.
  • ratio: and step: also take exact, for a filing that rounds only the result. result: always takes a scale and a mode.
  • A key that can fall outside the filed points gets E-INTERP-RANGE. Bound the input, or write the filed clamp around the key, such as max(min(x, 750000), 100000).
  • A last dimension that is a band or a Code, and a table with an otherwise row, get E-INTERP-KEY.
  • A point that the key can reach and that lacks a row gets E-LOOKUP-GAP.
  • A missing or repeated rounding gets E-LOOKUP-SYNTAX, and so does a call spelled interpolate(…).
  • result: exact gets E-ROUND, and so does a ratio: scale below 0.
Example
The table files 1.000 at 200,000 and 1.270 at 300,000. A Coverage A amount of 260,000 gives a ratio of 0.6000, a step of 0.1620 and a factor of 1.162.
This table has a territory key before the amount, and its filing rounds only the result. The rural rows file 1.10 at 200,000 and 1.14 at 300,000, so an amount of 233,333 gives 1.113.

locate

Finds the cell of a geography that holds a point.
Result: Option of the cell’s key. Use locate when a filing assigns a territory or a factor from the latitude and longitude of the risk. It finds the filed cell of a geography that holds the point. A cell that it finds is always a row of the cell table. Rules
  • The first argument names a geography from Geographies. The second is the latitude and the third is the longitude, as numbers in decimal degrees.
  • The result is an Option of the cell table’s key. Some(key) names a filed row, so lookup! with that key always finds it.
  • The result is None for a point outside every filed cell. Handle both cases with match, and state what the filing does for such a point.
  • A point on a line between cells belongs to each cell that touches it. With on_line: least_key, the cell with the least key wins.
  • A first argument that is other than a declared geography gets E-GEOGRAPHY. So does a call with fewer than three arguments, and a coordinate that is other than a number.
  • The check places the point of each table row in its cell. It fails when two rows share a cell, or when a row’s point lies on a cell line.
Example
The geography lays a grid of 0.01-degree cells over the rows of the table WildfireCell.
A home at latitude 33.4567 and longitude -112.0712 lies in cell W101 and takes its factor of 1.10. A home at latitude 33.5 lies outside the four filed cells and takes the unmapped factor of 1.5.

Numbers and rounding

round

Rounds a number to scale decimal places with the stated rounding mode.
Result: The type of x. Use round wherever the filing states a rounding: a premium to the cent, a factor to three places. Every other operation keeps exact values, so a value changes only where you write round. Rules
  • scale is a whole-number literal from -1000 to 1000: the number of decimal places. A scale of 2 rounds to cents, 0 to whole units and -2 to hundreds.
  • mode is one of seven names. Every call states its mode.
  • half_up rounds to the nearest value, and a tie goes away from zero: 2.5 gives 3 and -2.5 gives -3.
  • half_down rounds to the nearest value, and a tie goes toward zero: 2.5 gives 2 and -2.5 gives -2.
  • half_even rounds to the nearest value, and a tie goes to the even digit: 2.5 gives 2 and 3.5 gives 4.
  • up rounds away from zero: 2.4 gives 3 and -2.4 gives -3.
  • down rounds toward zero: 2.4 gives 2 and -2.4 gives -2.
  • ceiling rounds toward positive infinity: 2.4 gives 3 and -2.4 gives -2.
  • floor rounds toward negative infinity: 2.4 gives 2 and -2.4 gives -3.
  • Each rating outcome passes through a round in a calculation that cites the rounding rule. An outcome that lacks one gets E-OUTCOME-ROUND.
  • A calculation that rounds carries a citation, on itself or on its step. One that lacks both gets E-PROVENANCE.
  • A call with two arguments, an unknown mode, or a scale that is other than a whole-number literal gets E-ROUND.
Example
The premium is the payroll in thousands times the rate of 2, rounded to the cent. A payroll of 1,234,567 gives 2,469.134 before rounding and 2,469.13 after it.

root

Takes the nth root of a number, rounded to scale decimal places.
Result: The type of x. Use root for a filed square root or higher root, such as a credibility factor. Most roots have endless decimals, so the call states a scale and a mode. The result is the true root, rounded once. Rules
  • n is the degree, a whole number of 1 or more: 2 for a square root, 3 for a cube root.
  • scale and mode follow the rules of round. The square root of 2 at scale 3 gives 1.414 with half_up and 1.415 with up.
  • An even degree needs a value of zero or more. The check proves it from the input ranges, and a value that can be negative gets E-ROOT. Clamp the value with max(x, 0).
  • An odd degree takes any value: the cube root of -8 is -2.
  • A degree that is a calculation must be a proven whole number of 1 or more, or the call gets E-ROOT.
  • A literal degree below 1, a fractional degree, an unknown mode, or a call with other than four arguments gets E-ROOT.
  • A calculation that calls root rounds, so it carries a citation on itself or on its step.
Example
Credibility is the square root of the claim count over the full-credibility standard of 400, to two places, capped at 1. A count of 100 gives 0.50, and a count of 900 gives 1.

pow

Raises a number to a whole power exactly, or to a fractional power with a stated rounding.
Result: The type of x. Use pow to raise a number to a power: a trend compounded over years, or a filed curve with a fractional exponent. A whole power is exact. A fractional power states its rounding, and the result is the true power, rounded once. Rules
  • pow(x, n) takes a whole-number exponent and gives the exact power. The exponent is a literal or a calculation that the check proves whole, such as an input with precision: int.
  • An exponent of 0 gives 1.
  • A negative exponent needs a base other than zero. The check proves it from the input ranges, and a base that can be zero gets E-POW-EXPONENT.
  • An exponent that can hold a fraction gets E-POW-EXPONENT in the two-argument form. So does a literal exponent above 131072.
  • pow(x, exponent, scale, mode) takes a fractional literal exponent, such as -0.15 or 1.5. It rounds the power to scale with mode, as round does.
  • As a fraction in lowest terms, the exponent has a numerator and a denominator of at most 1000. 0.125 is 1/8 and passes. 0.123456789 gets E-POW-EXPONENT.
  • An exponent with an even denominator, such as 0.5, needs a base of zero or more. A base that can be negative gets E-ROOT.
  • A whole exponent in the four-argument form gets E-POW-EXPONENT. Write round(pow(x, n), scale, mode).
  • An exponent that is a calculation gets E-POW-EXPONENT in the four-argument form.
  • A calculation that calls the four-argument form rounds, so it carries a citation on itself or on its step.
Example
The annual trend of 1.03 compounds over a whole number of years. Two years give exactly 1.0609.
The size factor follows a filed curve with the exponent -0.15, to four places. Revenue of 2,500,000 is 2.5 times the base and gives 0.8716.

abs

Gives the size of a number, with its sign dropped.
Result: Num. Use abs when a rule reads the size of a difference and ignores its direction, such as the distance of a modification from 1. The result is exact. Rules
  • abs takes one number and gives its distance from zero. abs(-2.5) and abs(2.5) both give 2.5.
  • The result is zero or more, and the check uses that fact in later proofs.
  • A call with zero arguments gets E-TYPE.
Example
A modification within 0.05 of 1 rates at 1. A modification of 0.96 has a swing of 0.04 and rates at 1. A modification of 1.2 has a swing of 0.2 and applies as it is.

floor

Gives the greatest whole number at or below a number.
Result: Num. Use floor to count whole units and drop the rest: full years in a number of months, full thousands in a limit. The result is exact. Rules
  • floor takes one number and gives the greatest whole number at or below it. 3.9 gives 3, and 3 gives 3.
  • A negative number moves away from zero: -2.5 gives -3.
  • floor(x) equals round(x, 0, floor).
  • The check knows that the result is whole. A calculation typed Num {precision: int} accepts it as it is.
  • A call with zero arguments gets E-TYPE.
Example
The discount counts full claim-free years, up to 5. Forty months hold 3 full years and give a discount factor of 0.94.

ceil

Gives the least whole number at or above a number.
Result: Num. Use ceil when a filing charges for each unit “or part of a unit”: each $1,000 of revenue, each started day. The result is exact. Rules
  • ceil takes one number and gives the least whole number at or above it. 3.1 gives 4, and 3 gives 3.
  • A negative number moves toward zero: -2.5 gives -2.
  • ceil(x) equals round(x, 0, ceiling).
  • The check knows that the result is whole. A calculation typed Num {precision: int} accepts it as it is.
  • A call with zero arguments gets E-TYPE.
Example
The rate applies to each $1,000 of revenue or part of it. Revenue of 1,250,000.00 gives 1,250 units, and revenue of 1,250,000.01 gives 1,251.

min

Gives the least of several values, or of one value for each item.
Result: The type of the values. Use min to cap a value at a filed maximum, or to find the least value across a list or an enumeration. The result is exact: it is one of the values, unchanged. Rules
  • min(a, b, …) takes one or more numbers and gives the least.
  • min(list as v, value) computes value once for each item of the list, with v naming the item, and gives the least.
  • min(Enum as m, value) computes value once for each member of an enumeration, or of a refined subset of one, and gives the least.
  • Every value is a number.
  • The list form needs a list that holds one item or more. A list that can be empty gets E-EMPTY-FOLD.
  • To satisfy that rule, bound the list input with where len(self) in [1, 5], or guard the call with if len(list) > 0 then … else ….
  • by and round_each belong to sum and product. On min they get E-FOLD-KEY.
Example
The inner call caps the schedule modifier at the highest filed value, 1.25.
The policy reads the earliest year built across its locations. Buildings from 1965 and 1998 give 1965.
Each location takes the better of its two protection credits, and the credits stay separate. A sprinkler credit of 0.85 and an alarm credit of 0.95 give 0.85.

max

Gives the greatest of several values, or of one value for each item.
Result: The type of the values. Use max to hold a value at or above a filed minimum, or to find the greatest value across a list or an enumeration. The result is exact: it is one of the values, unchanged. Rules
  • max(a, b, …) takes one or more numbers and gives the greatest.
  • max(list as v, value) computes value once for each item of the list, with v naming the item, and gives the greatest.
  • max(Enum as m, value) computes value once for each member of an enumeration, or of a refined subset of one, and gives the greatest.
  • Every value is a number.
  • The list form needs a list that holds one item or more. A list that can be empty gets E-EMPTY-FOLD.
  • To satisfy that rule, bound the list input with where len(self) in [1, 5], or guard the call with if len(list) > 0 then … else ….
  • by and round_each belong to sum and product. On max they get E-FOLD-KEY.
  • To read another field of the item with the greatest value, use argmax.
Example
The policy pays the modified premium or the minimum premium of 500, whichever is greater. A modified premium of 226.50 gives 500.
The policy reads the largest limit across its locations. The input rule on locations asks for one location or more, so the call passes the check.
Each location reads the largest of its three coverage limits. Limits of 400,000, 150,000 and 100,000 give 400,000.

sum

Adds one value for each item of a list or each member of an enumeration.
Result: The type of the values. Use sum to add one value for each item of a list or each member of an enumeration: vehicle premiums into a policy premium, coverage premiums into a location premium. The plain forms are exact. The stepwise form rounds after each addition, as some filings state. Rules
  • sum(list as v, value) computes value once for each item, with v naming the item, and adds the results. An empty list gives 0.
  • sum(Enum as m, value) computes value once for each member of an enumeration, or of a refined subset of one.
  • The stepwise form sum(list as v by v.key, value, round_each: (scale, mode)) adds the items in ascending order of the key. It rounds the running total after each item, as round does.
  • The stepwise form reads a list. An enumeration takes the plain form.
  • The key is a number or Date input of the item, read as v.field. Any other key gets E-FOLD-KEY.
  • The key is distinct across the list. Rating refuses a request that repeats a key value as invalid input.
  • by and round_each go together. One of them alone gets E-FOLD-KEY.
  • A calculation with round_each rounds, so it carries a citation on itself or on its step. One that lacks both gets E-PROVENANCE.
  • To add separate values, write a + b.
Example
The policy adds the premium of each vehicle. Vehicle premiums of 1,260.00, 696.00 and 1,663.20 give 3,619.20.
Each location adds its premium for each member of Coverage. Premiums of 480, 375 and 80 give 935.
The policy adds the locations in order of their number and rounds to the dollar after each one. Location premiums of 100.50 and 200.50 give 101, then 302. The exact sum is 301.

product

Multiplies one value for each item of a list or each member of an enumeration.
Result: The type of the values. Use product to multiply one factor for each item of a list or each member of an enumeration. The plain forms are exact. The stepwise form rounds after each multiplication, as many filings state for a chain of factors. Rules
  • product(list as v, value) computes value once for each item, with v naming the item, and multiplies the results. An empty list gives 1.
  • product(Enum as m, value) computes value once for each member of an enumeration, or of a refined subset of one.
  • The stepwise form product(list as v by v.key, value, round_each: (scale, mode)) multiplies the items in ascending order of the key. It rounds the running product after each item, as round does.
  • The key alone sets the order of a stepwise product, so the order of the request leaves the result unchanged.
  • The stepwise form reads a list. An enumeration takes the plain form.
  • The key is a number or Date input of the item, read as v.field. Any other key gets E-FOLD-KEY.
  • The key is distinct across the list. Rating refuses a request that repeats a key value as invalid input.
  • by and round_each go together. One of them alone gets E-FOLD-KEY.
  • A calculation with round_each rounds, so it carries a citation on itself or on its step. One that lacks both gets E-PROVENANCE.
Example
The policy multiplies the factor of each endorsement. Factors of 1.05 and 1.1 give exactly 1.155, and a policy with zero endorsements gives 1.
The account factor multiplies one adjustment for each member of Adjustment. A large-limit factor of 0.9 and an old-building factor of 1.1 give 0.99.
The filing rounds the schedule modifier to three places after each factor. Modifiers numbered 1, 2 and 3 with factors 0.875, 0.925 and 0.955 give 0.875, then 0.809, then 0.773.

avg

Gives the mean of several values, or of one value for each item.
Result: The type of the values. Use avg for the mean of one value across the items of a list, such as the average age of the rated drivers. The mean is exact: the sum divided by the number of items. Rules
  • avg(list as v, value) computes value once for each item, with v naming the item, and gives the mean.
  • The result keeps every decimal. Ages of 45, 40 and 22 give exactly 107/3, so round the mean where the filing states a rounding.
  • The list holds one item or more. A list that can be empty gets E-EMPTY-FOLD.
  • To satisfy that rule, bound the list input with where len(self) in [1, 6], or guard the call with if len(list) > 0 then … else ….
  • by and round_each belong to sum and product. On avg they get E-FOLD-KEY.
Example
The filtered list can be empty, so the guard on len comes first. Rated drivers aged 62 and 58 give an average age of 60 and the mature discount of 0.97.

Lists

len

Gives the number of items in a list.
Result: Num. Use len for the number of items in a list: vehicles on a policy, drivers that a filter keeps. It also bounds the size of a list input, and the check uses that bound in its proofs. Rules
  • len(list) takes a list input or a calculated list, such as the result of filter or topn. An empty list gives 0.
  • In a rule on a list input, self is the list: where len(self) in [1, 4]. Rating refuses a request whose list falls outside the bound.
  • A bound that starts at 1 or more proves the list holds an item. avg, min and max over that list then pass the check.
  • A guard such as if len(list) > 0 then … else … gives the same proof for a calculated list.
Example
The rule admits one to four vehicles. Rating refuses a request with five vehicles and gives the code VEHICLE-COUNT.
A policy with two or more vehicles takes the multi-car factor of 0.95.

count

Counts the items that meet a condition.
Result: Num. Use count for the number of items that meet a condition: drivers under 25, accidents inside a look-back window. The result is a whole number. Rules
  • count(list as v, condition) tests the condition once for each item, with v naming the item. It gives the number of items for which the condition is true.
  • count(Enum as m, condition) tests the condition once for each member of an enumeration.
  • An empty list gives 0.
  • For the size of a whole list, use len.
  • by belongs to a stepwise sum or product. On count it gets E-FOLD-KEY.
Example
Each driver under 25 adds a charge of 75. A household with drivers aged 45 and 19 has a count of 1 and a charge of 75.
The condition reads a field of the item and a field of the policy. For an effective date of 2026-06-01, accidents on 2023-06-01 and 2023-05-31 give a count of 1.

exists

Is true when one item or more meets a condition.
Result: Bool. Use exists to ask whether one item or more meets a condition: any driver with a filing, any vehicle used for business. The result is a Bool. Rules
  • exists(list as v, condition) tests the condition for the items of the list, with v naming the item. It is true when the condition holds for one item or more.
  • exists(Enum as m, condition) tests the condition for the members of an enumeration.
  • An empty list gives false.
  • exists is the opposite of all with the opposite condition. not exists(list as v, c) is true when every item fails c.
  • by belongs to a stepwise sum or product. On exists it gets E-FOLD-KEY.
Example
One filing fee of 25 applies when any driver needs a filing. Two drivers with filings still give one fee of 25.

all

Is true when every item meets a condition.
Result: Bool. Use all to ask whether every item meets a condition: every driver free of points, every location sprinklered. It also states an input rule that each item of a list must meet. The result is a Bool. Rules
  • all(list as v, condition) tests the condition for the items of the list, with v naming the item. It is true when the condition holds for every item.
  • all(Enum as m, condition) tests the condition for the members of an enumeration.
  • An empty list gives true.
  • In a rule on a list input, self is the list: where all(self as d, d.points <= 6). With a code and a message, rating refuses a request that breaks the rule and gives that code.
  • A call that lacks the as name or the condition gets E-TYPE.
Example
The household is claim free when every driver has zero points. Two drivers with zero points give the discount factor of 0.9, and one point on either driver gives 1.

find

Gives the first item that meets a condition.
Result: Option of the record. Use find to pick the one item that meets a condition, such as the driver whose rank matches a vehicle’s. The answer depends on the list’s key and the data, and the order of the request leaves it unchanged. Rules
  • find(list as v, condition) gives an Option of the item: Some(item) for the first item that meets the condition, and None when zero items meet it.
  • “First” follows the list’s keyed by key, in ascending order. Over a list of values, it follows the values themselves.
  • A list of records needs a key: declare the input as List(Driver) keyed by number. A list that lacks a key gets E-SELECT-TIE.
  • Open the result with match, and state what the filing does in the None case.
  • .field after the call reads one field of the item. The result is an Option of that field.
  • find takes the list and the condition only. by gets E-FOLD-KEY, and then gets E-SELECT-TIE.
Example
Each vehicle takes the class factor of the driver that holds the same rank. With two drivers and three vehicles, the vehicle ranked third gets None and takes the extra-vehicle factor.

filter

Keeps the items that meet a condition.
Result: A list of the record. Use filter to keep the items of a list that meet a condition, and then count them, add them or select from them. The result is a list of the same items. Rules
  • filter(list as v, condition) tests the condition once for each item, with v naming the item. It keeps the items for which the condition is true.
  • Type a calculation that holds the result as a list of the record, such as List(Driver).
  • Pass the result to any function that reads a list: len, sum, avg, topn, or filter again.
  • The result can be empty. avg, min and max over it need a guard, such as if len(kept) > 0 then … else …, or they get E-EMPTY-FOLD.
  • An item keeps its place in the input list. index(v) on an item of the result gives its position in the list as sent.
  • by belongs to a stepwise sum or product. On filter it gets E-FOLD-KEY.
Example
The average age reads only the drivers that the policy rates. With drivers aged 45, 40 and 22 rated and a driver aged 60 excluded, the average is 107/3.

argmax

Gives the item with the greatest score, with each tie-breaker stated.
Result: Option of the record. Use argmax to pick the item with the greatest score and then read its other fields: the class factor of the driver with the most points. Every tie has a stated winner, so the order of the request leaves the answer unchanged. Rules
  • argmax(list as v, score) computes the score once for each item, with v naming the item. It gives an Option of the item: Some(item), or None for an empty list.
  • The score is a number.
  • then [cite: source:region]: priority states a filed tie rule. Among items with the greatest score, the item with the greatest priority wins.
  • The priority carries the citation of the rule that states it. A then that lacks one gets E-CITATION.
  • Among items that are still tied, the item with the least keyed by key wins.
  • A list of records needs a key: declare the input as List(Driver) keyed by number. A list that lacks a key gets E-SELECT-TIE.
  • A priority written as a plain third argument gets E-SELECT-TIE. Write it with then.
  • Open the result with match. To read only the greatest score, use max.
Example
A vehicle beyond the number of drivers rates with the driver that has the most points. Drivers 2 and 3 both have 5 points, with class factors of 1.75 and 2.1. The filed tie rule picks the higher class factor, so the result is 2.1.

argmin

Gives the item with the least score, with each tie-breaker stated.
Result: Option of the record. Use argmin to pick the item with the least score and then read its other fields: the age of the driver with the fewest years licensed. Every tie has a stated winner, so the order of the request leaves the answer unchanged. Rules
  • argmin(list as v, score) computes the score once for each item, with v naming the item. It gives an Option of the item: Some(item), or None for an empty list.
  • The score is a number.
  • then [cite: source:region]: priority states a filed tie rule. Among items with the least score, the item with the greatest priority wins.
  • The priority carries the citation of the rule that states it. A then that lacks one gets E-CITATION.
  • Among items that are still tied, the item with the least keyed by key wins.
  • A list of records needs a key: declare the input as List(Driver) keyed by number. A list that lacks a key gets E-SELECT-TIE.
  • A priority written as a plain third argument gets E-SELECT-TIE. Write it with then.
  • Open the result with match. To read only the least score, use min.
Example
The surcharge reads the age of the driver with the fewest years licensed. Drivers licensed for 27 years and 2 years, aged 45 and 19, give an age of 19 and a surcharge of 1.1.

topn

Keeps the n items with the greatest scores.
Result: A list of the record. Use topn to keep the items with the greatest scores, such as the two drivers with the most points. Every tie at the cut has a stated winner, so the order of the request leaves the result unchanged. Rules
  • topn(list as v, score, n) computes the score once for each item, with v naming the item. It gives a list of the n items with the greatest scores.
  • A list with fewer than n items gives every item. An n of 0 gives an empty list.
  • n is a whole number of zero or more. A literal such as -1 or 2.5 gets E-TOPN-LIMIT, and so does a calculation that can be negative or fractional.
  • then [cite: source:region]: priority states a filed tie rule. Among items tied at the cut, the item with the greatest priority stays. A then that lacks a citation gets E-CITATION.
  • Among items that are still tied, the item with the least keyed by key stays.
  • A list of records needs a key: declare the input as List(Driver) keyed by number. A list that lacks a key gets E-SELECT-TIE.
  • Pass the result to any function that reads a list, such as sum, avg or len.
Example
Only the two drivers with the most points count toward the household. Drivers with 0, 3 and 5 points give 8 household points and a surcharge of 1.08.

rank

Gives the position of one item when the list is ordered by a score.
Result: Num when a record ranks itself in its own list, else Option(Num). Use rank for the place of one item when a list is put in order of a score: the highest-rated driver first, then the next. Each item gets its own position, counted from 0. Rules
  • rank(list as v, score, target, direction) orders the list by the score, with v naming the item. It gives the position of the item whose keyed by key equals target.
  • direction is desc or asc. With desc, the greatest score takes position 0. With asc, the least score takes position 0.
  • The list is a list of records with a key, and target has the type of that key. A list that lacks a key gets E-SELECT-TIE.
  • then [cite: source:region]: priority states a filed tie rule. Among items with equal scores, the greater priority takes the earlier position, in both directions. A then that lacks a citation gets E-CITATION.
  • Among items that are still tied, the lesser key takes the earlier position. Items with equal scores still get separate positions.
  • The result is Num when a record ranks itself in the list that holds it: rank(Policy.drivers as d, …, self.number, desc) inside Driver.
  • For any other target the result is Option(Num), and it is None when the list holds zero items with that key.
  • A call with other than four arguments, another direction, or a score that is other than a number gets E-TYPE.
Example
Each driver takes its place by class factor, highest first. Drivers 1, 2 and 3 with class factors of 1, 1.75 and 2.1 take positions 2, 1 and 0.
Vehicles take their places by symbol, and find pairs each vehicle with the driver in the same position. Two vehicles with symbol 10, numbered 7 and 3, take positions 1 and 0.

index

Gives the position of a record in a plain list, counted from 0.
Result: Num. Use index when a rule depends on where a record sits in a plain list as the request sends it: the first trailer listed, each additional location. Positions count from 0. Rules
  • index(self) gives the position of the current record in the list that holds it.
  • index(v) gives the position of the item that v names in a call such as count, filter or min.
  • The list is a plain List(R). A list declared keyed by is a map from key to record, and index on it gets E-KEYED-ORDER.
  • The position follows the order of the request.
  • An item of a filtered list keeps its position in the list as sent.
  • The record sits in a list input of its parent. A record held any other way gets E-TYPE.
  • The argument is self or the name after as. A field, or a call with two arguments, gets E-TYPE.
  • A rating that reads index changes when the request reorders the list. When a filing orders items by a rating value, use rank.
Example
The first trailer listed rates at 1, and each later trailer takes the additional-trailer factor of 0.9. Two trailers worth 4,000 each have charges of 40.00 and 36.00.

unique

States that a key, or each value, is distinct across a list.
Result: A list refinement. Use unique to state that one field has a distinct value on every item of a list input: one license for each driver, one address for each location. Rating refuses a request that repeats a value, before any calculation runs. Rules
  • Write it as a rule on a list input, where self is the list: where unique(self as v, v.field).
  • The key is one required input of the item, read as v.field. A calculation, an optional input or an expression gets E-REFINEMENT.
  • On a list of values, the key is the value itself: where unique(self as v, v).
  • With a code and a message, rating refuses a request that repeats a value and gives that code. A rule that carries only the call reports invalid input with the code INPUT-UNIQUE.
  • unique stands alone as one where rule. Inside not, inside a calculation, or anywhere else, it gets E-REFINEMENT.
  • A list keyed by a field already has distinct values of that field. Use unique for a second field.
Example
Drivers carry distinct numbers through keyed by and distinct licenses through unique. Rating refuses a request with two drivers on license A00000001 and gives the code DUPLICATE-LICENSE.

Dates

diff_days

Counts the days from one date to a later date.
Result: Num. Use diff_days for the length of a period in days: a policy term for a pro rata premium, the days since a lapse. The count is exact and follows the calendar, leap days included. Rules
  • diff_days(later, earlier) takes two dates and gives the number of days from the second to the first.
  • The same date twice gives 0. From 2026-02-01 to 2026-03-01 gives 28.
  • When the first date is the earlier one, the result is negative: one day back gives -1.
  • The result is a whole number, and the check knows its range from the ranges of the two dates.
Example
The premium is pro rata by day. A term from 2026-06-01 to 2026-12-01 has 183 days and earns 183/365 of the annual premium.

diff_months

Counts the calendar months from one date to a later date. The day of the month is ignored.
Result: Num. Use diff_months for a count of calendar months between two dates, such as months of prior insurance. It compares the year and the month and ignores the day. Rules
  • diff_months(later, earlier) takes two dates. It gives 12 times the difference of the years plus the difference of the months.
  • The day of the month has zero effect. From 2026-02-28 to 2026-03-01 gives 1, and from 2025-12-01 to 2026-01-31 also gives 1.
  • Two dates in the same calendar month give 0.
  • When the first date is in an earlier month, the result is negative.
  • For a count that respects the day, compare against a shifted date: d >= add_months(start, 36).
Example
The discount asks for 36 calendar months of insurance. A policy effective 2026-06-01 and insured since 2023-06-30 counts 36 months and takes the factor 0.95.

diff_years

Counts the full years from one date to a later date, as an age in years is counted.
Result: Num. Use diff_years for an age or a tenure in full years. It counts as people count an age: a year completes on the anniversary of the earlier date. Rules
  • diff_years(later, earlier) takes two dates and gives the number of full years from the second to the first.
  • A year counts on the anniversary. From 2000-03-15, the date 2026-03-14 gives 25 and 2026-03-15 gives 26.
  • A start date of February 29 has its anniversary on March 1 in a common year. From 2024-02-29, the date 2027-02-28 gives 2 and 2027-03-01 gives 3.
  • Less than one full year gives 0.
  • When the first date is the earlier one, the result is negative: the same count with a minus sign.
Example
The rider’s age is the age on the effective date. A rider born 2001-06-02 is 24 on 2026-06-01 and 25 one day later.

add_days

Shifts a date by a whole number of days.
Result: Date. Use add_days to move a date by a fixed number of days: a quote deadline, a grace period, a waiting period. The result is a date that you compare with other dates. Rules
  • add_days(date, n) gives the date n days after date. A negative n moves back.
  • n is a whole-number literal, such as 30 or -7. An input, a calculation or a fraction gets E-TYPE.
  • The result stays inside the years 0001 to 9999. The check proves it from the range of the date, and a date input that lacks a bound gets E-DATE-RANGE.
  • Give each date input a range, such as where self in [2026-01-01, 2030-12-31].
  • A calculation of type Date holds the result. A rating outcome is a number, a Bool or an enumeration member, so compare the date before it reaches an outcome.
Example
The discount applies to a quote made seven days or more before the effective date. For an effective date of 2026-06-01, a quote on 2026-05-25 qualifies and a quote on 2026-05-26 pays the full rate.

add_months

Shifts a date by a whole number of months. A day past the month’s end becomes its last day.
Result: Date. Use add_months to move a date by whole calendar months: a 36-month look-back for accidents, a six-month term. The day of the month stays the same where the target month has that day. Rules
  • add_months(date, n) gives the same day of the month, n months later. A negative n moves back.
  • A day past the end of the target month becomes its last day. 2026-01-31 plus one month gives 2026-02-28, and in 2024 it gives 2024-02-29.
  • The same rule holds going back: 2026-03-31 minus one month gives 2026-02-28.
  • n is a whole-number literal, such as 6 or -36. An input, a calculation or a fraction gets E-TYPE.
  • The result stays inside the years 0001 to 9999. The check proves it from the range of the date, and a date input that lacks a bound gets E-DATE-RANGE.
Example
An accident is chargeable for 36 months. For an effective date of 2026-06-01 the window opens on 2023-06-01: an accident on that day counts, and one on 2023-05-31 falls outside.

add_years

Shifts a date by a whole number of years.
Result: Date. Use add_years to move a date by whole years: the day a rider turns 65, the latest end of a one-year term. The month and the day stay the same. Rules
  • add_years(date, n) gives the same month and day, n years later. A negative n moves back.
  • February 29 becomes February 28 when the target year is a common year. 2024-02-29 plus one year gives 2025-02-28, and minus four years gives 2020-02-29.
  • n is a whole-number literal, such as 1 or -10. An input, a calculation or a fraction gets E-TYPE.
  • The result stays inside the years 0001 to 9999. The check proves it from the range of the date, and a date input that lacks a bound gets E-DATE-RANGE.
  • The call works in a calculation and in a where rule.
Example
A rider is a senior from the 65th birthday. A rider born 1961-06-01 is a senior for a policy effective 2026-06-01.
The rule on the policy limits a term to one year. For an effective date of 2026-06-01, rating accepts an expiration date of 2027-06-01 and refuses 2027-06-02 with the code TERM-LENGTH.

year

Gives the year of a date.
Result: Num. Use year to read the calendar year of a date, such as the policy year for the age of a vehicle. The result is a whole number. Rules
  • year(date) takes one date and gives its year: year(2026-06-01) is 2026.
  • A call with zero or two arguments gets E-TYPE, and so does an argument that is a number.
  • In an RSL 0.4.1 rater, read year inside a comparison, a max or min, or a lookup key.
  • A calculation whose body is year(d) alone, or plain arithmetic on it such as year(d) - self.model_year, gets E-CHAIN in an RSL 0.4.1 rater.
  • For an age in full years between two dates, use diff_years.
Example
The vehicle age is the policy year minus the model year, held between 0 and 10. A 2021 model on a policy effective in 2026 has an age of 5 and a discount factor of 0.9. A 2027 model has an age of 0.

month

Gives the month of a date, from 1 to 12.
Result: Num. Use month to read the calendar month of a date, for a rule that depends on the season. The result is a whole number from 1 to 12. Rules
  • month(date) takes one date and gives its month: January is 1 and December is 12.
  • A call with zero or two arguments gets E-TYPE, and so does an argument that is a number.
  • In an RSL 0.4.1 rater, read month inside a comparison, a max or min, or a lookup key.
  • A calculation whose body is month(d) alone, or plain arithmetic on it, gets E-CHAIN in an RSL 0.4.1 rater.
  • For a count of months between two dates, use diff_months.
Example
A policy that starts from April to September takes the riding-season factor. An effective date of 2026-06-01 has month 6 and gives 1.1.

Options, choices and placeholders

Some

Makes a present Option from a value.
Result: Option of the value’s type. Use Some to give a present value where the rater expects an Option: a calculation that holds a cell code for some risks and None for others. None is the matching word for an absent value. Rules
  • Some(value) takes one value. A call with zero or two arguments gets E-TYPE.
  • It stands only where an Option is expected, such as a calculation typed Option(Factor) or an arm of a match with that type. Anywhere else it gets E-TYPE.
  • The value has the type inside the Option. Wrapping a value that is already an Option gets E-TYPE.
  • Every arm of a match or if has the same type. When one arm gives an Option, wrap the plain values of the other arms in Some.
  • In a match pattern, Some(c) => … opens a present value and names it c.
Example
A surveyed cell wins over the located cell. locate gives an Option, so the first arm wraps the surveyed cell c in Some to match it. A request with the surveyed cell W202 rates in W202 wherever its point lies.

select

Gives a value between a filed low and a filed high, at a chosen position.
Result: The type of the bounds. Use select when a filing gives a low and a high value and the underwriter chooses a point between them, as in schedule rating. The result is exact. Rules
  • select(low..high, position) gives low + position * (high - low).
  • A position of 0 gives low, 1 gives high and 0.5 gives the midpoint.
  • low, high and position are numbers. Each is a constant, an input, a calculation or a literal.
  • The call computes any position as written. Bound the position input with where self in [0, 1] to keep the result between low and high.
  • The result keeps every decimal. Round it where the filing states a rounding.
  • select belongs to RSL 0.4.1. A rater that declares rsl: "0.4" gets E-RSL-PATCH.
Example
The filed schedule factor runs from 0.75 to 1.25. A risk position of 0.3 gives 0.75 plus 0.3 times 0.5, which is 0.9.

nl

Holds the place of a calculation that is still in plain words. A strict check fails while one remains.
Result: The expected type. Use nl while you build a rater, to hold the place of a calculation that still waits for its formula. The text says in plain words what the calculation must do. The rest of the rater keeps its types, and the check lists each placeholder. Rules
  • Write nl "text", with the text in double quotes. It takes the type that its place expects.
  • It stands wherever a value goes: as a whole calculation, inside arithmetic, or as a condition.
  • A strict rslc check fails while a placeholder remains. It prints one obligation line for each, with the position and the text.
  • rslc check --allow-incomplete passes when placeholders are the only open items. Every other message still fails the check.
  • A rater builds and rates only after each placeholder that an outcome reads has its formula.
  • Put a citation on the calculation, before the =: factor: Factor [cite: manual:p4] = nl "…".
Example The experience factor waits for its formula, and the premium already reads it.
nl/rater.rsl
The strict check fails and names the placeholder at line 26. Replace nl "…" with the formula, and the check passes.

Removed functions