How DTRules Works

Define business logic in spreadsheets. Execute it at production scale. Understand exactly how decisions are made.

The Problem with Traditional Code

Complex business logic becomes unmaintainable when written as nested if-else statements.

Traditional Approach

func calculateTax(income float64, status string, age int) float64 {
    if status == "MFJ" {
        if income <= 23850 {
            return income * 0.10
        } else if income <= 96950 {
            return 2385 + (income - 23850) * 0.12
        } else if income <= 206700 {
            return 11157 + (income - 96950) * 0.22
        } else if income <= 394600 {
            // ... more brackets ...
        }
        // But what about:
        // - AMT calculation?
        // - Capital gains rates?
        // - Phase-outs?
        // - State taxes?
        // Code becomes unmaintainable!
    } else if status == "Single" {
        // Duplicate logic for single filers
    } else if status == "HOH" {
        // And again for head of household
    }
    // Hundreds of lines of nested conditions...
}
Hard to read. Hard to validate. Hard to change.

Decision Table Approach

<decision_table>
  <table_name>Apply_Tax_Brackets_MFJ</table_name>
  <Type>FIRST</Type>

  <conditions>
    <condition>taxable_income <= 23850</condition>
    <condition>taxable_income <= 96950</condition>
    <condition>taxable_income <= 206700</condition>
  </conditions>

  <actions>
    <action>tax = taxable_income * 0.10</action>
    <action>tax = 2385 + (taxable_income - 23850) * 0.12</action>
    <action>tax = 11157 + (taxable_income - 96950) * 0.22</action>
  </actions>
</decision_table>
Clear. Verifiable. Maintainable by policy experts.

The DTRules Workflow

From business requirements to production execution

1

Define Your Data Model (EDD)

Create an Entity Data Dictionary in Excel or XML that defines your business objects, their attributes, and relationships.

<entity name="taxpayer">
  <field name="name" type="string" />
  <field name="age" type="integer" />
  <field name="income" type="double" />
  <field name="filing_status" type="string" />
  <field name="dependents" type="array" subtype="dependent" />
</entity>
2

Create Decision Tables

Author decision tables in Excel or the visual editor. Each table handles one specific decision, with conditions as rows and rules as columns.

Rule 1 Rule 2 Rule 3
Conditions
income <= 50000 Y N N
income <= 100000 * Y N
Actions
set rate = ? 0.10 0.15 0.25
3

Compile to XML

The Excel files are compiled to XML format. This validates all expressions, checks for missing conditions, and generates optimized bytecode.

java -jar compilerutil.jar -compile MyProject.xls
4

Execute with Java or Go Runtime

Load the XML files into the runtime, provide input data, and execute the decision tables. Get deterministic results with full execution traces.

Go
engine := dtrules.NewEngine()
engine.LoadProject("TaxReturn")

rsess := engine.NewSession()
rsess.MapInput(taxpayerData)
rsess.Execute("Compute_Tax_Return")

result := rsess.GetOutput()
Java
RuleSession session = engine.newSession();
session.mapInput(taxpayerData);
session.execute("Compute_Tax_Return");

EntityState result = session.getState();

Execution Model

How decision tables evaluate and execute

BALANCED Tables

Every possible combination of conditions must be explicitly defined. The compiler ensures completeness.

Use for: Compliance requirements where every case must be documented.

FIRST Tables

Executes only the first matching column. Columns are evaluated left-to-right.

Use for: Priority-based rules, tax brackets, cascading discounts.

ALL Tables

Executes all matching columns. Multiple rules can fire for the same input.

Use for: Accumulating values, applying multiple adjustments.

Why Decision Tables?

Business-Readable

Policy experts can review and validate rules without understanding code.

Deterministic

Same inputs always produce same outputs. Essential for compliance and auditing.

Traceable

Full execution traces show exactly which rules fired and why.

Testable

Each table is a unit that can be tested independently.

Versioned

XML files work with version control. See exactly what changed.

Performant

Go runtime executes 15,000+ tax returns per second with sub-millisecond latency.

Ready to Try It?

Start with the interactive demo or dive into the documentation.