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...
} 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> The DTRules Workflow
From business requirements to production execution
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> 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 |
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 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.
engine := dtrules.NewEngine()
engine.LoadProject("TaxReturn")
rsess := engine.NewSession()
rsess.MapInput(taxpayerData)
rsess.Execute("Compute_Tax_Return")
result := rsess.GetOutput() 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.
FIRST Tables
Executes only the first matching column. Columns are evaluated left-to-right.
ALL Tables
Executes all matching columns. Multiple rules can fire for the same input.
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.