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.
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’sdims. - Write
.columnafter the call to pick the output column. For a map column, add the member in brackets:.rate[p]. - A key for an enumeration,
CodeorBooldimension 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
Codedimension gives the row with the same value. - A table with an
otherwiserow gives that row for every key that the filed rows leave out. - The
!is part of the name. A call spelledlookup(…)getsE-LOOKUP-SYNTAX. - A number key that can fall outside its dimension gets
E-KEY-RANGE. Bound the input, clamp the key withmaxormin, or add anotherwiserow. - A key combination that lacks a row gets
E-LOOKUP-GAP. Add the filed row, narrow the key, or add anotherwiserow. - A key of type
OptiongetsE-TYPE. Open it withmatchfirst, and pass the value inside. - A call that passes fewer or more keys than the table has
dimsgetsE-TYPE. An unknown table or column getsE-UNRESOLVED.
otherwise factor of 1.
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.
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 inlookup!. - 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:andresult:each take(scale, mode)and round that quantity asrounddoes. Write all three, in any order.ratio:andstep:also takeexact, 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 asmax(min(x, 750000), 100000). - A last dimension that is a band or a
Code, and a table with anotherwiserow, getE-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 spelledinterpolate(…). result: exactgetsE-ROUND, and so does aratio:scale below 0.
locate
Finds the cell of a geography that holds a point.
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
Optionof the cell table’s key.Some(key)names a filed row, solookup!with that key always finds it. - The result is
Nonefor a point outside every filed cell. Handle both cases withmatch, 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.
WildfireCell.
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.
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
scaleis 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.modeis one of seven names. Every call states its mode.half_uprounds to the nearest value, and a tie goes away from zero: 2.5 gives 3 and -2.5 gives -3.half_downrounds to the nearest value, and a tie goes toward zero: 2.5 gives 2 and -2.5 gives -2.half_evenrounds to the nearest value, and a tie goes to the even digit: 2.5 gives 2 and 3.5 gives 4.uprounds away from zero: 2.4 gives 3 and -2.4 gives -3.downrounds toward zero: 2.4 gives 2 and -2.4 gives -2.ceilingrounds toward positive infinity: 2.4 gives 3 and -2.4 gives -2.floorrounds toward negative infinity: 2.4 gives 2 and -2.4 gives -3.- Each rating outcome passes through a
roundin a calculation that cites the rounding rule. An outcome that lacks one getsE-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.
root
Takes the nth root of a number, rounded to scale decimal places.
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
nis the degree, a whole number of 1 or more: 2 for a square root, 3 for a cube root.scaleandmodefollow the rules ofround. The square root of 2 at scale 3 gives 1.414 withhalf_upand 1.415 withup.- 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 withmax(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
rootrounds, so it carries a citation on itself or on its step.
pow
Raises a number to a whole power exactly, or to a fractional power with a stated rounding.
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 withprecision: 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-EXPONENTin the two-argument form. So does a literal exponent above 131072. pow(x, exponent, scale, mode)takes a fractional literal exponent, such as-0.15or1.5. It rounds the power toscalewithmode, asrounddoes.- As a fraction in lowest terms, the exponent has a numerator and a denominator of at most 1000.
0.125is 1/8 and passes.0.123456789getsE-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 getsE-ROOT. - A whole exponent in the four-argument form gets
E-POW-EXPONENT. Writeround(pow(x, n), scale, mode). - An exponent that is a calculation gets
E-POW-EXPONENTin the four-argument form. - A calculation that calls the four-argument form rounds, so it carries a citation on itself or on its step.
abs
Gives the size of a number, with its sign dropped.
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
abstakes one number and gives its distance from zero.abs(-2.5)andabs(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.
floor
Gives the greatest whole number at or below a number.
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
floortakes 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)equalsround(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.
ceil
Gives the least whole number at or above a number.
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
ceiltakes 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)equalsround(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.
min
Gives the least of several values, or of one value for each item.
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)computesvalueonce for each item of the list, withvnaming the item, and gives the least.min(Enum as m, value)computesvalueonce 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 withif len(list) > 0 then … else …. byandround_eachbelong tosumandproduct. Onminthey getE-FOLD-KEY.
max
Gives the greatest of several values, or of one value for each item.
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)computesvalueonce for each item of the list, withvnaming the item, and gives the greatest.max(Enum as m, value)computesvalueonce 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 withif len(list) > 0 then … else …. byandround_eachbelong tosumandproduct. Onmaxthey getE-FOLD-KEY.- To read another field of the item with the greatest value, use
argmax.
locations asks for one location or more, so the call passes the check.
sum
Adds one value for each item of a list or each member of an enumeration.
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)computesvalueonce for each item, withvnaming the item, and adds the results. An empty list gives 0.sum(Enum as m, value)computesvalueonce 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, asrounddoes. - The stepwise form reads a list. An enumeration takes the plain form.
- The key is a number or
Dateinput of the item, read asv.field. Any other key getsE-FOLD-KEY. - The key is distinct across the list. Rating refuses a request that repeats a key value as invalid input.
byandround_eachgo together. One of them alone getsE-FOLD-KEY.- A calculation with
round_eachrounds, so it carries a citation on itself or on its step. One that lacks both getsE-PROVENANCE. - To add separate values, write
a + b.
Coverage. Premiums of 480, 375 and 80 give 935.
product
Multiplies one value for each item of a list or each member of an enumeration.
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)computesvalueonce for each item, withvnaming the item, and multiplies the results. An empty list gives 1.product(Enum as m, value)computesvalueonce 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, asrounddoes. - 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
Dateinput of the item, read asv.field. Any other key getsE-FOLD-KEY. - The key is distinct across the list. Rating refuses a request that repeats a key value as invalid input.
byandround_eachgo together. One of them alone getsE-FOLD-KEY.- A calculation with
round_eachrounds, so it carries a citation on itself or on its step. One that lacks both getsE-PROVENANCE.
Adjustment. A large-limit factor of 0.9 and an old-building factor of 1.1 give 0.99.
avg
Gives the mean of several values, or of one value for each item.
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)computesvalueonce for each item, withvnaming 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 withif len(list) > 0 then … else …. byandround_eachbelong tosumandproduct. Onavgthey getE-FOLD-KEY.
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.
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 offilterortopn. An empty list gives 0.- In a rule on a list input,
selfis 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,minandmaxover that list then pass the check. - A guard such as
if len(list) > 0 then … else …gives the same proof for a calculated list.
VEHICLE-COUNT.
count
Counts the items that meet a condition.
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, withvnaming 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. bybelongs to a stepwisesumorproduct. Oncountit getsE-FOLD-KEY.
exists
Is true when one item or more meets a condition.
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, withvnaming 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.
existsis the opposite ofallwith the opposite condition.not exists(list as v, c)is true when every item failsc.bybelongs to a stepwisesumorproduct. Onexistsit getsE-FOLD-KEY.
all
Is true when every item meets a condition.
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, withvnaming 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,
selfis the list:where all(self as d, d.points <= 6). With acodeand amessage, rating refuses a request that breaks the rule and gives that code. - A call that lacks the
asname or the condition getsE-TYPE.
find
Gives the first item that meets a condition.
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 anOptionof the item:Some(item)for the first item that meets the condition, andNonewhen zero items meet it.- “First” follows the list’s
keyed bykey, 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 getsE-SELECT-TIE. - Open the result with
match, and state what the filing does in theNonecase. .fieldafter the call reads one field of the item. The result is anOptionof that field.findtakes the list and the condition only.bygetsE-FOLD-KEY, andthengetsE-SELECT-TIE.
None and takes the extra-vehicle factor.
filter
Keeps the items that meet a condition.
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, withvnaming 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, orfilteragain. - The result can be empty.
avg,minandmaxover it need a guard, such asif len(kept) > 0 then … else …, or they getE-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. bybelongs to a stepwisesumorproduct. Onfilterit getsE-FOLD-KEY.
argmax
Gives the item with the greatest score, with each tie-breaker stated.
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, withvnaming the item. It gives anOptionof the item:Some(item), orNonefor an empty list.- The score is a number.
then [cite: source:region]: prioritystates 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
thenthat lacks one getsE-CITATION. - Among items that are still tied, the item with the least
keyed bykey wins. - A list of records needs a key: declare the input as
List(Driver) keyed by number. A list that lacks a key getsE-SELECT-TIE. - A priority written as a plain third argument gets
E-SELECT-TIE. Write it withthen. - Open the result with
match. To read only the greatest score, usemax.
argmin
Gives the item with the least score, with each tie-breaker stated.
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, withvnaming the item. It gives anOptionof the item:Some(item), orNonefor an empty list.- The score is a number.
then [cite: source:region]: prioritystates 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
thenthat lacks one getsE-CITATION. - Among items that are still tied, the item with the least
keyed bykey wins. - A list of records needs a key: declare the input as
List(Driver) keyed by number. A list that lacks a key getsE-SELECT-TIE. - A priority written as a plain third argument gets
E-SELECT-TIE. Write it withthen. - Open the result with
match. To read only the least score, usemin.
topn
Keeps the n items with the greatest scores.
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, withvnaming the item. It gives a list of thenitems with the greatest scores.- A list with fewer than
nitems gives every item. Annof 0 gives an empty list. nis a whole number of zero or more. A literal such as-1or2.5getsE-TOPN-LIMIT, and so does a calculation that can be negative or fractional.then [cite: source:region]: prioritystates a filed tie rule. Among items tied at the cut, the item with the greatest priority stays. Athenthat lacks a citation getsE-CITATION.- Among items that are still tied, the item with the least
keyed bykey stays. - A list of records needs a key: declare the input as
List(Driver) keyed by number. A list that lacks a key getsE-SELECT-TIE. - Pass the result to any function that reads a list, such as
sum,avgorlen.
rank
Gives the position of one item when the list is ordered by a score.
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, withvnaming the item. It gives the position of the item whosekeyed bykey equalstarget.directionisdescorasc. Withdesc, the greatest score takes position 0. Withasc, the least score takes position 0.- The list is a list of records with a key, and
targethas the type of that key. A list that lacks a key getsE-SELECT-TIE. then [cite: source:region]: prioritystates a filed tie rule. Among items with equal scores, the greater priority takes the earlier position, in both directions. Athenthat lacks a citation getsE-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
Numwhen a record ranks itself in the list that holds it:rank(Policy.drivers as d, …, self.number, desc)insideDriver. - For any other target the result is
Option(Num), and it isNonewhen 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.
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.
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 thatvnames in a call such ascount,filterormin.- The list is a plain
List(R). A list declaredkeyed byis a map from key to record, andindexon it getsE-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
selfor the name afteras. A field, or a call with two arguments, getsE-TYPE. - A rating that reads
indexchanges when the request reorders the list. When a filing orders items by a rating value, userank.
unique
States that a key, or each value, is distinct across a list.
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
selfis 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 getsE-REFINEMENT. - On a list of values, the key is the value itself:
where unique(self as v, v). - With a
codeand amessage, rating refuses a request that repeats a value and gives that code. A rule that carries only the call reports invalid input with the codeINPUT-UNIQUE. uniquestands alone as onewhererule. Insidenot, inside a calculation, or anywhere else, it getsE-REFINEMENT.- A list
keyed bya field already has distinct values of that field. Useuniquefor a second field.
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.
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.
diff_months
Counts the calendar months from one date to a later date. The day of the month is ignored.
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).
diff_years
Counts the full years from one date to a later date, as an age in years is counted.
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.
add_days
Shifts a date by a whole number of days.
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 datendays afterdate. A negativenmoves back.nis a whole-number literal, such as30or-7. An input, a calculation or a fraction getsE-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
Dateholds the result. A rating outcome is a number, aBoolor an enumeration member, so compare the date before it reaches an outcome.
add_months
Shifts a date by a whole number of months. A day past the month’s end becomes its last day.
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,nmonths later. A negativenmoves 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.
nis a whole-number literal, such as6or-36. An input, a calculation or a fraction getsE-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.
add_years
Shifts a date by a whole number of years.
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,nyears later. A negativenmoves 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.
nis a whole-number literal, such as1or-10. An input, a calculation or a fraction getsE-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
whererule.
TERM-LENGTH.
year
Gives the year of a date.
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
yearinside a comparison, amaxormin, or a lookup key. - A calculation whose body is
year(d)alone, or plain arithmetic on it such asyear(d) - self.model_year, getsE-CHAINin an RSL 0.4.1 rater. - For an age in full years between two dates, use
diff_years.
month
Gives the month of a date, from 1 to 12.
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
monthinside a comparison, amaxormin, or a lookup key. - A calculation whose body is
month(d)alone, or plain arithmetic on it, getsE-CHAINin an RSL 0.4.1 rater. - For a count of months between two dates, use
diff_months.
Options, choices and placeholders
Some
Makes a present Option from a value.
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 getsE-TYPE.- It stands only where an
Optionis expected, such as a calculation typedOption(Factor)or an arm of amatchwith that type. Anywhere else it getsE-TYPE. - The value has the type inside the
Option. Wrapping a value that is already anOptiongetsE-TYPE. - Every arm of a
matchorifhas the same type. When one arm gives anOption, wrap the plain values of the other arms inSome. - In a
matchpattern,Some(c) => …opens a present value and names itc.
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.
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)giveslow + position * (high - low).- A position of 0 gives
low, 1 giveshighand 0.5 gives the midpoint. low,highandpositionare 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 betweenlowandhigh. - The result keeps every decimal. Round it where the filing states a rounding.
selectbelongs to RSL 0.4.1. A rater that declaresrsl: "0.4"getsE-RSL-PATCH.
nl
Holds the place of a calculation that is still in plain words. A strict check fails while one remains.
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 checkfails while a placeholder remains. It prints oneobligationline for each, with the position and the text. rslc check --allow-incompletepasses 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 "…".
nl/rater.rsl
nl "…" with the formula, and the check passes.