> ## Documentation Index
> Fetch the complete documentation index at: https://docs.canary.effectiveai.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Split a rater into files

> Move types and tables into a second file, import it, and check, format and export the rater as one program.

[Install Relativities](https://docs.canary.effectiveai.app/relativities/setup.md) before running the synthetic examples.

As a rater grows, its types and tables crowd its calculations.
Move them into a second file, and name that file in the rater:

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
import "territory.rsl"
```

The example splits a personal auto rater from the synthetic carrier Example Mutual.
It also imports a set of marital status values from the standard library.

## Move declarations into a second file

Save the rater as `personal-auto/rater.rsl`. This file is the entry point: the file you check, export and build.

> [accordion] Complete example: personal-auto/rater.rsl
>
> ```rsl personal-auto/rater.rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
> spec {
>     rsl: "0.4.1",
>     carrier: "Example Mutual",
>     state: AZ,
>     product: "Personal Auto",
>     effective_date: 2026-01-01
> }
>
> import "std/ppa.rsl"
> import "territory.rsl"
>
> Sources = {
>     manual: Source = {
>         artifact: artifact("00000000-0000-4000-8000-000000000000"),
>         kind: pdf
>     }
> }
>
> Constants = {
>     base_premium [cite: manual:p2] = 600,
>     married_factor [cite: manual:p4] = 0.92
> }
>
> Records = {
>     Policy = {
>         inputs {
>             territory: Territory,
>             marital_status: MaritalStatus
>         },
>         step rating {
>             territory_factor: Factor = lookup!(TerritoryFactor, self.territory).factor,
>             marital_factor: Factor = if self.marital_status = @MaritalStatus.married then married_factor else 1,
>             premium: Premium [cite: manual:p2] =
>                 round(base_premium * self.territory_factor * self.marital_factor, 2, half_up)
>         }
>     }
> }
>
> RatingOutcomes = {
>     premium: Policy.premium
> }
> ```

Save the territory type and its table as `personal-auto/territory.rsl`:

```rsl personal-auto/territory.rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
Types = {
    Territory = {
        urban,
        suburban,
        rural
    }
}

Tables = {
    TerritoryFactor [cite: manual:p3] :
        table dims (territory: Territory) -> {
            factor: Factor
        }
}
```

Save the table's rows as `personal-auto/tables/TerritoryFactor.csv`:

```csv personal-auto/tables/TerritoryFactor.csv theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
territory,factor
urban,1.25
suburban,1.00
rural,0.90
```

Check the entry point:

```sh theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
rslc check personal-auto/rater.rsl
```

```text theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
PASS personal-auto/rater.rsl (strict)
cost premium: 4 (each list of size 1: 4, 3: 4, 10: 4)
```

The check reads `rater.rsl`, each file it imports and each table, and checks them as one rater.
Build and rate it the same way as a rater in one file:

```python theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
from relativities import Rater

rater = Rater.build("personal-auto/rater.rsl")
print(rater.explain({"territory": "urban", "marital_status": "married"}))
#           kind              name    value
# 0        input         territory    urban
# 1        input    marital_status  married
# 2  calculation  territory_factor     1.25
# 3  calculation    marital_factor     0.92
# 4  calculation           premium      690
```

The annual premium is `600 × 1.25 × 0.92 = 690`.

## Follow the import rules

* Write each `import` on its own line, outside the sections. The example writes its imports after `spec`.
* A path is relative to the file that writes the `import`. A path that starts with `std/` names the standard library.
* An imported file holds sections such as `Types`, `Constants` and `Tables`. The rater reads them as its own.
* Each name has one declaration across the files.
* The `spec` block of the entry point applies to every file.
* An imported file may import other files. Two files that import each other fail the check.
* Keep each imported file inside the folder of the entry point. A bundle holds that one folder.

A missing file, a repeated name or a circular import gets
[`E-UNRESOLVED`](https://docs.canary.effectiveai.app/rsl/reference/check-messages/names#e-unresolved), with the file and the line.

## Keep the CSV files beside the entry point

```text theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
personal-auto/
  rater.rsl              the entry point
  territory.rsl          an imported file
  tables/
    TerritoryFactor.csv  the rows of a table that territory.rsl declares
```

* The rater reads each table from `tables/` beside the entry point, whichever file declares the table.
* An enumeration declared as `Name = Enum` reads its members from `enums/Name.csv` beside the entry point.

## Check, format and export the rater

| Command | Reads | Run it on |
| - | - | - |
| `rslc check` | The entry point, each imported file and each table | The entry point |
| `rslc fmt` | One file | Each file, one at a time |
| `rslc export` | The entry point, each imported file and each table | The entry point |

An imported file checked alone lacks the other files.
`territory.rsl` cites the source `manual`, which `rater.rsl` declares:

```sh theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
rslc check personal-auto/territory.rsl
```

```text theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
FAIL personal-auto/territory.rsl (strict)
error: E-CITATION personal-auto/territory.rsl:10:28: citation 'manual:p3' names unknown source 'manual'. Declare it in Sources or cite a declared source (none are declared).
```

Format each file with its own command:

```sh theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
rslc fmt personal-auto/rater.rsl
rslc fmt personal-auto/territory.rsl
```

```text theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
PASS personal-auto/rater.rsl is formatted
PASS personal-auto/territory.rsl is formatted
```

Export the entry point:

```sh theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
rslc export personal-auto/rater.rsl --format bundle --out personal-auto.zip
```

```text theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
WROTE bundle: personal-auto.zip
```

The bundle holds the entry point, each imported file at its path, and each table:

```python theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
from zipfile import ZipFile

print(*ZipFile("personal-auto.zip").namelist(), sep="\n")
# program-manifest.json
# program/input-schema.json
# program/program.py
# rater-manifest.json
# rater.rsl
# runtime/rslc_wasm.wasm
# tables/TerritoryFactor.csv
# territory.rsl
```

The standard library ships with the compiler, so `std/ppa.rsl` stays out of the bundle.
[Package a rater](https://docs.canary.effectiveai.app/rsl/commands.md#package-a-rater) describes the other files.

## Import from the standard library

The standard library holds value sets that many raters share. Import a file by its `std/` path:

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
import "std/ppa.rsl"
```

The rater then uses a type from that file by name:

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
marital_status: MaritalStatus
```

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
marital_factor: Factor = if self.marital_status = @MaritalStatus.married then married_factor else 1,
```

`inputs` lists the values each type accepts:

```python theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
print(rater.inputs[["path", "type", "values"]].to_string())
#              path  type                                                           values
# 0  marital_status  enum  single, married, divorced, widowed, separated, domestic_partner
# 1       territory  enum                                           urban, suburban, rural
```

Each of these files declares enumerations for one line of business:

| Import | Line of business | Examples of its types |
| - | - | - |
| `std/ppa.rsl` | Personal auto | `Gender`, `MaritalStatus`, `VehicleUse` |
| `std/ho.rsl` | Homeowners | `PolicyForm`, `ConstructionType`, `RoofType` |
| `std/ca.rsl` | Commercial auto | `VehicleType`, `SizeClass`, `RadiusOfOperation` |
| `std/gl.rsl` | General liability | `LegalEntity`, `BasisOfPremium`, `CoverageForm` |
| `std/wc.rsl` | Workers' compensation | `BasisType`, `EmploymentType`, `OfficerTitle` |

* The files install with the compiler, in the `std` folder of the `rslc` package. Read a file there for its full list.
* Import one of these files in a rater. Several of them declare the same name, such as `MaritalStatus`.
* A name from an imported file is taken: choose a different name for your own type.

## Related

* [Use a filed rate table](https://docs.canary.effectiveai.app/rsl/how-to/read-a-filed-table.md) declares tables and their CSV files.
* [Use the rslc commands](https://docs.canary.effectiveai.app/rsl/commands.md) covers `rslc check`, `rslc fmt` and `rslc export`.
* [Versions](https://docs.canary.effectiveai.app/rsl/explanation/versions.md) explains how a bundle pins its source and tables.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.