介绍
决策表是一种用来表述DRD中Decision决策逻辑的方式。决策表是用表格形式表示一组相关联的输入和输出表达式,组织成规则,说明一组特定的输入项所适用的输出项。决策表包含所有(仅)用于确定输出的输入项。此外,一个完整的表包含输入值(所有的规则)的所有可能组合。
使用决策表和表层次结构在表现决策逻辑时有较好效果。规范化不同形式和类型决策表是DMN的目的之一。
一个决策表包含:
- 名称
- 一组输入,每个输入(可选)关联一个类型与一组输入值
- 一组输出,每个输出(可选)关联一个类型与一组输出值
- 一组在表中的行或列的规则(取决于方向),其中每个规则组成的表行(或列)的特定输入项和输出项
决策表显示规则使用一种速记符号,通过排列条目在表格单元格中:
在以上决策表片段的三个突出显示的单元格表示以下规则:
IF input expression 1 matches x AND input expression 2 matches y THEN a result (a "hit") is z.
如果"输入表达式1"匹配了"x",并且"输入表达式2"匹配了"y",则结果(一次命中)是"z"
这样简写在每个规则中都以相同的顺序显示所有的输入,因此有一些可读性和验证的优势。
一组规则描述了决策的逻辑。如果规则允许包含重复输入组合,该表的命中策略需要提示重复规则如何被解释,以避免不一致。
规则列表中可能包含了输入值的所有可能性组合,在这种情况下,该表被称为"完整(complete)"。
标记符号
本节是建立在决策逻辑通用符号和boxed表达式基础之上。
决策表表示规范:
- 方向(行式,列式或交叉表),如图所示的表
- 放置输入、输出和一组值(可选)在表格单元格中的标准位置
- 线条样式和可选色彩的运用
- 特定规则的输入和输出项单元格的内容
- 命中策略,提示如何解释重复的输入组合
- 聚合,说明如何将多个命中聚集
- 表名、命中策略(H)、完整性提示器(C)、聚合(A)和规则号的位置
线的样式和颜色
线条样式是标准的。输入部分和输出部分之间是加粗线(double line),并且输入/输出和规则项单元格之间是加粗线(double line)。其它单元格是通过普通线(单线)隔开。
建议有颜色,但不影响意义。使用不同的颜色用于输入、输出和规则值,这被认为是很好的做法。
表格方向
根据大小,决策表可呈水平方向(行规则)、垂直(列规则)或交叉表(从两个输入维度组成的规则)。交叉表只能有默认的命中策略(见下文)。
表格的排列方式必须以下的一种:(单元格标签中的斜体部分是可选的,如果设置了允许值范围则显示)
交叉表是允许超过两个以上的输入项。(只是这里没有显示)
输入表达式
输入表达式通常是简单的,例如:一个名称(客户状态)或一个测试(年龄<25)。表达式可以是任意文本(如,自然语言文本)但是不应与FEEL语法冲突。
输入值
输入表达式可以预期结果是一个有限的数据或是一个有限的取值范围。
重要的是对期望值进行建模,如果它的规则涵盖预期输入值的所有组合,一个决策表可以被认为是完整的。
不管如何对预期的输入值进行建模,输入值都应该是排他的,完整的。排他(Exclusive)表示输入值不重叠。完整(Complete)是指从域中所有相关的输入值都包括在内。
例如,下面的两个输入值范围重叠:<5,<10。下面的两个范围是不完整的:<5,>5。
一组输入值是可选的。如果提供,它是一组一元测试,必须要求相应的输入的测试值为真(true)。该列表可以是任何文字(例如,自然语言文本),但不应该与FEEL语法冲突。
表格名称和输出名称
表格名称或输出名称必须指定。
如果指定了表格名称,输出名称必须和表格名称相同,或者不指定(空box的单输出表,或者省略"box"的多输出表)。如果表名未指定,则输出名称必须指定。
输出值
一个决策表的输出项通常是由一组输出值绘制。当多个规则被匹配时,这组输出值排序可以用来指定优先级,最终仅有一个会被命中并被返回。当命中的策略是输出顺序时,排序也可以被使用。
这组输出值是可选的。如果提供,它是一个列表,限制输出项的值为在给定列表的值。这个列表可以是任何文字(例如,自然语言文本),但不应该与FEEL语法冲突。
多输出
决策表可以展现出一个复合输出
输入项
规则输入项是表达式。该表达式可以是任何文本(如自然语言文本),但不应该与FEEL语法冲突。破折号符号(' - ')可以用来指任何输入值,即输入与规则无关。
一元测试的值应该是' - '或指定的输入值的子集。例如,如果对输入'年龄'的输入值指定为[0 ..120],接着输入条目<0时应当报告为无效。
表包含' - '被称为约定表。其他被称为扩展。
表中每一个输入项为真,假,或' - '历来称为有限表,但这里没有必要维持这一限制。
评估表达式在决策表中不产生负面影响。输入项顺序在实现时不关联到任何执行顺序。
合并输入实体单元格
不同规则的相邻输入项单元格,并且有相同内容和相同次序的单元格可以合并。规则输出单元不能合并(除交叉表)
输出项
规则输出项是表达式。该表达式可以是任何文本(如自然语言文本),但不应该与FEEL语法冲突。
垂直表(列规则)与一个单输出名称是和表名相同,一个速记符号可以被用来表示:输出适用(X)或不适用( - ),这是决策表的常见做法。
命中策略
决策表可以具有多个规则,并且通常多于一个规则可以被匹配至一组给定的输入。命中策略指定了决策表的结果,在这样的情况下还包含了可用于在设计时要检查是否正确的附加信息。为清楚起见,命中策略是在一个特定的决策表单元使用的单个字符摘要。工具可以支持命中策略的一个子集,但表类型必须是清晰的,因此命中策略指示为强制性的。
命中策略必须默认为不重复。用不重复命中决策表不包含重叠的输入项的规则。
如果规则允许包含重叠的输入项,那么命中策略得要说明这些重叠的规则如何解释。单命中表只返回一个规则的输出;多命中表可能会返回多个规则的输出(或函数的输出,如数值sum)。
单命中表只返回一个规则的输出。它可以也可以不包含重叠的规则。在重叠规则的情况下,命中策略必须指定选择哪个匹配的规则。
单命中策略 之 单输出决策表:
- 不重复( U:Unique):没有重叠并且所有规则都是互斥的。只有一个规则可以被匹配。这是默认的。
- 任意(A:Any):有可能有重叠,但所有的匹配规则都显示相同的输出,所以任何匹配都可以使用。
- 优先级(P:Priority):多个规则可以匹配有不同的输出。该策略将返回具有最高优先级的输出匹配规则。输出优先级是指定了一组值的顺序。例如,期望的输出值的列表。
- 第一个(F:First):多个(重叠)规则可以匹配有不同的输出。按规则顺序第一次命中立即返回(和执行可中断)。这是一个常见的用法,因为它通过强制第一次命中解决不一致的问题。重要的是要从其他几个表中区分这种类型的表,关键在于该表的意义依赖规则的顺序。最后一条规则往往特别有用。因为有顺序,这种表很难手工验证,因此必须谨慎使用。
一个多命中表可以从多个规则中返回输出项。这个结果将是一组规则输出或一个函数输出。
多命中策略 之 单输出决策表:
- 不排序(N:No order):返回所有的命中,在无序不重复的列表中。
- 输出顺序(O:Output order):返回所有的命中,按照优先级递减的顺序。输出优先级是指定在一个有序的值列表中。
- 规则顺序(R:Rule order):返回所有的命中,根据规则顺序。注意:意义取决于规则的顺序。
其他策略,如在输出上做更复杂的操作,可以通过后处理输出列表来执行(外部决策表)。
以上命中策略的单个字母也标识出这个决策表是单命中还是多命中的。
为了降低复杂性,决策表与复合输出仅支持以下命中政策:Unique,Any,First,No order和Rule order。
注意事项1
交叉表是通过定义保证唯一性和完整性的,所以不需要命中策略来标识。
注意事项2
除了在First tables (单命中) 和Rule order tables (多命中)中,其他的决策表中的规则顺序是不影响其意义的。所以这两种表应当谨慎使用。
完整性提示
表的完整性是一个可选属性。默认情况下,表是完整的,为每一种可能的情况产生一个结果。如果没有提示器应认为是不完整的。不完整的表格可以指定一个默认的输出。
聚合
多次命中必须被合并为一个单一的结果。DMN1.0指定了六个聚集方式,即:collect, sum, min, max, count, average。可选地,所述聚合提示符可以被包括在表中。默认为collect。
决策表只有单个命中时,聚合方式不起作用。
在决策表具有多次命中策略时,聚集提示符的语义:
- collect:决策表中的结果是所有输出的列表,每个命中策略有序或无序。
- sum:决策表中的结果是所有的输出的总和。
- min:决策表的结果是所有输出的最小值。
- max:决策表的结果是所有输出的最大值。
- count:决策表的结果是输出的个数。
- average:决策表的结果是所有的输出的平均值,定义为sum除以count, 其中sum和count语义是上面定义的。
其他策略,例如在输出更复杂的操作,可以通过后处理的输出列表(外决策表)来进行。
元模型
决策表元模型
DMN 1.0中,类DecisionTable是用来对决策表建模的。
DecisionTable是Expression的一个实现。
DecisionTable实例包含一组rules,它是DecisionRule实例;还有一组clauses,它是Clause实例。
它有一个preferedOrientation属性,它必须是集合中的一个:DecisionTableOrientation: Rule-as-Row, Rule-as-Column或CrossTable。DecisionTable实例应当如preferedOrientation指定的形式呈现。
DecisionTable实例有一个关联的hitPolicy,它必须是集合中的一个:HitPolicy: UNIQUE, FIRST, PRIORITY, ANY, UNORDERED, RULE ORDER, OUTPUT ORDER。hitPolicy属性的默认值是:UNIQUE。在DecisionTable实例的示意图中,hitPolicy是按照命中策略章节定义来表现的。
DecisionTable实例的语义是依赖于他关联的hitPolicy,它已在命中策略章节中描述。
如果DecisionTable实例关联的hitPolicy是:FIRST或RULE ORDER,DecisionTable所关联的rules必须是ordered。顺序是在DecisionTable的图形展现中表示规则的明确的编号。
如果DecisionTable实例关联的hitPolicy是:PRIORITY 或OUTPUT ORDER,DecisionTable的条款中的outputEntry也必须是有序的,以及这些outputEntries必须被关联作为DecisionTable规则的结论。DecisionTable的图形表示,执行的顺序是按照命中策略章节定义来表现的。
DecisionTable实例有一个关联的aggregation,它是BuiltinAggregator集合中的一个值。默认值是COLLECT。
作为Expression的一种类型,DecisionTable实例有一个值,依赖于关联的rules、hitPolicy、aggregration(或其他)的结论。DecisionTable实例的值是根据下面的规范来确定:
- hitPolicy是UNIQUE,DecisionTable实例的值是:仅适用规则的结论(conclusion)值。(参见决策规则,规则适用的定义)
- hitPolicy是FIRST,DecisionTable实例的值是:第一个适用规则的结论(conclusion)值,根据规则顺序。
- hitPolicy是PRIORITY,DecisionTable实例的值是:第一个适用规则的结论值,根据其结论(conclusion)条款(clause)的输出项(outputEntry)顺序。
- hitPolicy是ANY,DecisionTable实例的值是:所有适用规则的结论(conclusion)值。
- hitPolicy是UNORDERED,DecisionTable实例的值是:结果应用聚合函数处理所有适用的规则,通过DecisionTable的aggregation属性对一组结论值不做排序。
- hitPolicy是RULE ORDER,DecisionTable实例的值是:结果应用聚合函数处理所有适用的规则,通过DecisionTable的aggregation属性对一组结论的值根据规则顺序排序。
- hitPolicy是OUTPUT ORDER,DecisionTable实例的值是:结果应用聚合函数处理所有适用的规则,通过DecisionTable的aggregation属性对一组结论的值根据结论中clause的outputEntry顺序排序。
DecisionTable有个可选Boolean属性:isComplete。如果DecisionTable实例有isComplete属性,当DecisionTable不完整时,这个属性的值必须是false。仅当所有DecisionTable的inputVariables绑定是有效的,才可以说一个DecisionTable实例是完整的。至少一个DecisionTable规则是适用的。
DecisionTable有个可选Boolean属性:isConsistent。如果DecisionTable实例有isConsistent属性,该属性的值必须是false,除非DecisionTable是一致的。仅当所有DecisionTable的inputVariables绑定是有效的,所有适用的规则具有相同的值,才可以说一个DecisionTable实例是一致的。
DecisionTable从Expression中集成了所有属性和模型关联。
属性 | 描述 |
clause: Clause [*] | 该属性列出Clause实例,它构成DecisionTable |
rule: DecisionRule [*] | 该属性列出DecisionRule实例,它构成DecisionTable |
hitPolicy: HitPolicy | 命中策略决定了DecisionTable的语义。默认是:UNIQUE |
aggregation: BuiltinAggregator | 聚合功能应用到适用的rules值上,当它是超过一个,决定DecisionTable的值。默认是COLLECT |
isComplete: Boolean [0..1] | 如果存在,这个属性必须是false,除非这DecisionTable是完整的。默认:false |
isConsistent: Boolean [0..1] | 如果存在,这个属性必须是false,除非这DecisionTable是一致的。默认:false |
preferedOrientation:DecisionTableOrientation [0..1] | DecisionTable图形展现的优先方向,DecisionTable应与该属性指定的表现一致。 |
决策表条款元模型(Clause)
在一个决策表中,一个条款指定一个主题,这是由一个输入表达式或输出域中定义,以及有限数量主题域的子域集,他们是一块决策逻辑相关的,是描述决策表的。
在DMN 1.0中,类Clause是用来对决策表条款建模的。
Clause实例是由一个可选的inputExpression和一组inputEntry,或一个可选的名字和一组outputEntry组成,它是Expression实例。一个Clause元素如果已经有了一个inputExpression则必须有一组inputEntry,如果它没有inputExpression则必须有一组outputEntry,一个Clause元素不允许同时拥有inputEntry 和outputEntry。
Clause实例可以有一个String类型的name,并且可以引用一个outputDefinition,它是ItemDefinition元素。一个Clause实例An instance of Clause that does not have an inputExpression MUST reference an outputDefinition。一个Clause实例包含一个inputExpression,不能引用自outputDefinition。如果Clause元素引用一个outputDefinition没有name,他默认的name就是引用的ItemDefinition元素的名称。
inputEntry元素的valueDefinition必须是Boolean并且它可以被省略。inputEntry元素必须检测它的值包含clause的inputExpression,尽可能隐式的。outputEntry的valueDefinition必须是outputDefinition或包含clause的outputDefinition继承实现类,它可以被省略:如果outputEntry 的valueDefinition 被省略了,它默认为包含clause的outputDefinition。
在一个表格显示的DecisionTable中,Clause实例显示依赖于决策表的方向。举例来说,如果决策表水平展现(行规则),Clause实例表现为列,带有inputExpression或Clause元素的name,展现在最上面的单元格,它的值域可选的列在单元格下面,并且每个单元格下面展现Clause的一个inputEntry 或者outputEntry。所有由一组inputEntry组成的Clause 实例都在左侧,任何由一组outputEntry组成的Clause必须展现在右侧。
属性 | 描述 |
inputExpression: Expression [0.1] | 这个输入clause的主题 |
outputDefinition: ItemDefinition [0.1] | 这个输出clause的范围 |
name: String [,0.1] | 这个输出clause的名称 |
inputEntry: Expression [*] | 这个属性列出Expression实例,他组成这个clause |
outputEntry: Expression [*] | 这个属性列出Expression实例,他组成这个clause |
决策表规则元模型(Rule)
在DMN 1.0中,类DecisionRule是用来对决策表中的规则建模的。
DecisionRule实例有一组conditions和一组不为空的conclusions,他们都是Expression实例。
DecisionRule实例的条件(condition)是引用Expression实例,必须关联到一个本决策表包含的clause中的inputEntry。相同的,DecisionRule实例的结论(conclusion)也是引用Expression实例,必须关联到一个本决策表包含的clause中的outputEntry。
DecisonRule元素在相同的clause中不允许有超过一个结论(conclusion)。
在一个表格显示的DecisionTable中,DecisionRule展现依赖于决策表的方向。举例来说,如果决策表是横向展现的(行规则),DecisionRule实例作为行展现,所有的条件(conditions)展现在所有结论(conclusions)的左边。
根据定义,一个DecisionRule元素没有condition表示总是应用。否则,应给clauses的condition的inputExpressions设置一组值,DecisionRule实例,一个DecisionRule实例被认为是适用的(applicable)仅当每一个Clause元素包含至少一个规则的condition,至少一个规则的condition是包含在Clause元素时,返回true。相同的,在逻辑方面,DecisionRule元素被认为是适用的(applicable),如果结合是true,其中有一个结合每一个Clause元素,他最少有一个inputEntry被DecisionRule元素引用作为一个条件,并且每个结合是分离所有规则条件,它是包含在相同的Clause元素中的。
属性 | 描述 |
condition: Expression [*] | 这个属性列出Expression实例,他组成这个DecisionRule的condition |
conclusion: Expression [1..*] | 这个属性列出Expression实例,他组成这个DecisionRule的conclusion |
例子
以下提供了各种类型的决策表的示例,以供在本节讨论。