Skip to content

RuleAtlas/rac

Repository files navigation

RAC (Rules as Code)

Parse, compile, and execute encoded law.

RAC provides a pipeline for encoding tax and benefit rules as executable code:

.rac source → parse → compile (temporal resolution) → execute / Rust codegen

Part of the Rules Foundation open-source infrastructure.

Quick start

pip install rac
from datetime import date
from rac import parse, compile, execute

module = parse("""
    entity person:
        income: float

    gov/rate:
        from 2024-01-01: 0.20

    person/tax:
        entity: person
        from 2024-01-01: income * gov/rate
""")

ir = compile([module], as_of=date(2024, 6, 1))
result = execute(ir, {"person": [{"id": 1, "income": 50000}]})

print(result.scalars)  # {'gov/rate': 0.2}
print(result.entities)  # {'person': {'person/tax': [10000.0]}}

Pipeline

Parse

The parser reads .rac source into a Pydantic AST:

from rac import parse, parse_file

module = parse(source_string)
module = parse_file("path/to/rules.rac")

AST nodes: Module, VariableDecl, EntityDecl, AmendDecl, TemporalValue, Expr, etc.

Compile

The compiler resolves temporal layers for a specific date and topologically sorts the variable graph:

from rac import compile

ir = compile([base_module, reform_module], as_of=date(2024, 6, 1))
# ir.variables: dict of resolved expressions
# ir.order: topologically sorted variable paths
# ir.schema_: entity schema

Execute

The Python executor evaluates the IR against input data:

from rac import execute

result = execute(ir, {"person": [{"id": 1, "income": 50000}]})
result.scalars   # scalar variables
result.entities  # per-entity computed values

Rust codegen

Generate Rust source for native compilation (~97M rows/sec):

from rac import generate_rust, compile_to_binary

rust_code = generate_rust(ir)  # Rust source string
binary = compile_to_binary(ir)  # compiled native binary

Model API

High-level API combining parse + compile + native binary:

from rac import Model

model = Model.from_file("rules.rac", as_of=date(2024, 6, 1))
result = model.run({"person": large_dataset})

# Reform comparison
reform = Model.from_file("rules.rac", "reform.rac", as_of=date(2025, 1, 1))
comparison = model.compare(reform, data)

Syntax

# Entity declarations
entity person:
    income: float
    age: int
    household: -> household   # foreign key

# Scalar parameters with temporal values
gov/tax/rate:
    from 2024-01-01: 0.20
    from 2025-01-01: 0.22

# Entity variables with formulas
person/tax:
    entity: person
    from 2024-01-01: income * gov/tax/rate

# Conditionals
person/benefit:
    entity: person
    from 2024-01-01:
        if income < 20000: 5000
        else: 0

# Amendments (for reform modeling)
amend gov/tax/rate:
    from 2025-06-01: 0.18

Development

git clone https://github.com/RulesFoundation/rac
cd rac
pip install -e ".[dev]"
pytest tests/ -v

Rust toolchain needed for native compilation tests (auto-installs via rustup).

License

Apache 2.0

About

Next-generation policy rules engine - the API layer for AI systems to access the law, encoded

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages