decisionTable

package module
v1.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 19, 2024 License: Apache-2.0 Imports: 11 Imported by: 0

README

Decision Table

This library enables the creation and conversion of decision tables in Golang programming language. Inspired by the JBOSS Drools or Camunda DMN Suite. Decision tables are commonly used or rather visualized as a table in a UI to represent complex decisions in a more human-readable way. The library can be used as a data representation in Golang for such frontend/UI components.

Each table represents a complex system of rules. Such systems describe a decision for which input, which output is to be generated. The library allows:

  • The creation of such rules
  • Data-type dependent validation of rule expression
  • Converting into a rule-engine format (to finally execute rules)

Table Example

Image of Decision Table

Decision Table Builder (Code Example)

table, _ := decisionTable.NewDecisionTableBuilder().
    SetID("determineEmployee").
    SetName("Determine Employee").
    SetHitPolicy(hitPolicy.Unique).
    SetExpressionLanguage(expressionLanguage.SFEEL).
    SetStandard(standard.GRULE).
    AddInputField(field.Field{Name: "Claim.TypeOfClaim", Type: dataType.String}).
    AddInputField(field.Field{Name: "Claim.ExpenditureOfClaim", Type: dataType.Integer}).
    AddOutputField(field.Field{Name: "Employee.ResponsibleEmployee", Type: dataType.String}).
    AddOutputField(field.Field{Name: "Employee.FourEyesPrinciple", Type: dataType.Boolean}).
    AddRule(decisionTable.NewRuleBuilder().
        SetAnnotation("R1").
        AddInputEntry(`"Car Accident"`).
        AddInputEntry("<1000").
        AddOutputEntry(`"Müller"`).
        AddOutputEntry("false").
        Build(),
    ).
    AddRule(decisionTable.NewRuleBuilder().
        SetAnnotation("R2").
        AddInputEntry(`"Car Accident"`).
        AddInputEntry("[1000..10000]").
        AddOutputEntry(`"Schulz"`).
        AddOutputEntry("false").
        Build(),
    ).
    AddRule(decisionTable.NewRuleBuilder().
        SetAnnotation("R3").
        AddInputEntry("-").
        AddInputEntry(">=10000").
        AddOutputEntry("-").
        AddOutputEntry("true").
        Build(),
    ).
    Build()
    
rules, _ := table.Convert(standard.GRULE)
fmt.Print(rules)

We assume that the frontend will represent a decision table as a kind of table. In case, that a user changes something in the frontend table, we assume that the old decision table representation will be dropped and then rebuild from the new (frontend) table (which was manipulated by the user). By doing so, we don't need any "insert function" for rules/inputs/outputs etc and so it keeps the DecisionTable-Builder simple.

Hit Policies and Collect Operators

A decision table consists of several rules, typically represented as rows. When reading such a row we look at certain input values and deduct a certain result represented by output values.

When using the simplest hit policy "unique" (U), such rules do not overlap: only a single rule must match.

Now consider that we build a decision table with overlapping rules. In other words that means more than one rule may match a given set of input values. We then need one of the alternative hit policy indicators to unambiguously understand the decision logic according to which such rules are interpreted.

Single Decision Tables

Such tables either return the output of only one rule or aggregate the output of many rules into one result. The hit policies to be considered are

  • Unique: Rules do not overlap. Only a single rule can match.
  • First: Rules are evaluated from top to bottom. Rules may overlap, but only the first match counts.
  • Priority: Rule outputs are prioritized. Rules may overlap, but only the match with the highest output priority counts.
  • Any: Multiple matching rules must not make a difference: all matching rules must lead to the same output.
  • Collect: The output of all matching rules is aggregated by means of an operator:
    • Sum: Sums/Add all outputs of the matching rule’s distinct outputs.
    • Minimum: Take the smallest value of all the matching rule’s outputs.
    • Maximum: Take the largest value of all the matching rule’s outputs.
    • Number: Return the number of all the matching rule’s distinct outputs.
Multiple Result DecisionTable

Multiple result tables may return the output of multiple rules. The hit policies for such tables are:

  • Collect: All outputs of the matching rules are combined in an arbitrarily ordered list of all the output entries.
    • List: Collect all outputs of all matching rules in a list of output entries
  • Rule Order: All outputs of the matching rules are combined in a list of outputs ordered by the sequence of those rules in the decision table.
  • Output Order: All outputs of the matching rules are combined in a list of outputs ordered by their (decreasing) output priority.
Examples

Examples can be found here: Camunda Page

Supported Variable Types

The allowed types of input or output variables differs on the selected notation standard of a decision table:

Variable Types DMN Notation GRL Notation
Boolean X X
String X X
Integer X X
Float X
Long X
Double X
DateTime X X

More Details can be found here:

Supported Entry Languages

The expresion language defined the functions and comparisons of a single rule entry. It depends on the chosen table notations standard. So far we support the SFEEL Standard partially.

SFEEL INPUT EXPRESSIONS

Converter for Standards/Engines

The following converter are supported, so far:

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrDecisionTableSerializationError   = "decision table serialization error"
	ErrDecisionTableUnserializationError = "decision table unserialization error"
)
View Source
var (
	ErrDecisionTableNotValid = "decision table is not valid"
)

Functions

This section is empty.

Types

type DecisionTable

type DecisionTable struct {
	// contains filtered or unexported fields
}

func Unserialize added in v1.1.0

func Unserialize(s string) (DecisionTable, error)

func (DecisionTable) CollectOperator

func (d DecisionTable) CollectOperator() collectOperator.CollectOperator

func (DecisionTable) Convert

func (d DecisionTable) Convert(standard standard.Standard) (interface{}, error)

func (DecisionTable) ExpressionLanguage added in v1.0.4

func (d DecisionTable) ExpressionLanguage() expressionLanguage.ExpressionLanguage

func (DecisionTable) HitPolicy

func (d DecisionTable) HitPolicy() hitPolicy.HitPolicy

func (DecisionTable) ID added in v1.0.4

func (d DecisionTable) ID() string

func (DecisionTable) InputFields

func (d DecisionTable) InputFields() []field.Field

func (DecisionTable) MarshalJSON added in v1.1.2

func (d DecisionTable) MarshalJSON() ([]byte, error)

func (DecisionTable) Name

func (d DecisionTable) Name() string

func (DecisionTable) OutputFields

func (d DecisionTable) OutputFields() []field.Field

func (DecisionTable) Rules

func (d DecisionTable) Rules() []rule.Rule

func (DecisionTable) Serialize added in v1.1.0

func (d DecisionTable) Serialize() (string, error)

func (DecisionTable) Standard added in v1.0.4

func (d DecisionTable) Standard() standard.Standard

func (*DecisionTable) UnmarshalJSON added in v1.1.2

func (d *DecisionTable) UnmarshalJSON(data []byte) error

func (DecisionTable) Validate added in v1.0.0

func (d DecisionTable) Validate(standard standard.Standard) error

type DecisionTableBuilder

type DecisionTableBuilder struct {
	// contains filtered or unexported fields
}

func (DecisionTableBuilder) AddInputField

func (d DecisionTableBuilder) AddInputField(inputField field.Field) DecisionTableBuilderInterface

func (DecisionTableBuilder) AddOutputField

func (d DecisionTableBuilder) AddOutputField(outputField field.Field) DecisionTableBuilderInterface

func (DecisionTableBuilder) AddRule

func (DecisionTableBuilder) Build

func (DecisionTableBuilder) BuildWithoutValidation added in v1.0.0

func (d DecisionTableBuilder) BuildWithoutValidation() DecisionTable

func (DecisionTableBuilder) SetCollectOperator

func (DecisionTableBuilder) SetExpressionLanguage added in v1.0.4

func (DecisionTableBuilder) SetHitPolicy

func (DecisionTableBuilder) SetID added in v1.0.4

func (DecisionTableBuilder) SetName

func (DecisionTableBuilder) SetStandard added in v1.0.4

type DecisionTableBuilderInterface

type DecisionTableBuilderInterface interface {
	SetID(id string) DecisionTableBuilderInterface
	SetName(name string) DecisionTableBuilderInterface
	SetHitPolicy(hitPolicy hitPolicy.HitPolicy) DecisionTableBuilderInterface
	SetCollectOperator(collectOperator collectOperator.CollectOperator) DecisionTableBuilderInterface
	SetExpressionLanguage(expressionLanguage expressionLanguage.ExpressionLanguage) DecisionTableBuilderInterface
	SetStandard(standard standard.Standard) DecisionTableBuilderInterface
	AddInputField(inputField field.Field) DecisionTableBuilderInterface
	AddOutputField(outputField field.Field) DecisionTableBuilderInterface
	AddRule(rule Rule) DecisionTableBuilderInterface
	Build() (DecisionTable, error)
	BuildWithoutValidation() DecisionTable
}

func NewDecisionTableBuilder added in v1.0.4

func NewDecisionTableBuilder() DecisionTableBuilderInterface

type Rule added in v1.0.4

type Rule struct {
	// contains filtered or unexported fields
}

func (Rule) Annotation added in v1.0.4

func (r Rule) Annotation() string

func (Rule) InputEntries added in v1.0.4

func (r Rule) InputEntries() []string

func (Rule) OutputEntries added in v1.0.4

func (r Rule) OutputEntries() []string

type RuleBuilder added in v1.0.4

type RuleBuilder struct {
	// contains filtered or unexported fields
}

func (RuleBuilder) AddInputEntry added in v1.0.4

func (r RuleBuilder) AddInputEntry(expression string) RuleBuilderInterface

func (RuleBuilder) AddOutputEntry added in v1.0.4

func (r RuleBuilder) AddOutputEntry(expression string) RuleBuilderInterface

func (RuleBuilder) Build added in v1.0.4

func (r RuleBuilder) Build() Rule

func (RuleBuilder) SetAnnotation added in v1.0.4

func (r RuleBuilder) SetAnnotation(annotation string) RuleBuilderInterface

type RuleBuilderInterface added in v1.0.4

type RuleBuilderInterface interface {
	SetAnnotation(annotation string) RuleBuilderInterface
	AddInputEntry(expression string) RuleBuilderInterface
	AddOutputEntry(expression string) RuleBuilderInterface
	Build() Rule
}

func NewRuleBuilder added in v1.0.4

func NewRuleBuilder() RuleBuilderInterface

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL