检查 equivalence/subset 个允许值的数值约束表达式
Check numeric constraint expressions for equivalence/subset of allowed values
我有一个 AST 表示这样的表达式:
(<=10 && >=3) || ==0
==1 || ==2 || ==3
==1 && !=1
有数值型也有布尔型(||
,&&
)和数值型(<
,<=
,==
,!=
, >=
, >
) 运算符。如果需要,可以将布尔 not
运算符添加到 AST。这些表达式用于限制可能的数字输入值(注意最后一个不允许任何值)。
我正在寻找一种比较两个表达式的方法。我需要知道它们是否允许完全相同的一组数字(等效),或者一个表达式是否允许另一个表达式的子集。
你可以写一个函数
evaluate :: Expression -> ValueSet
将一个表达式计算为一组为真的值。这个值集可能类似于
data Value = MinusInfinity | Finite Integer | PositiveInfinity
type Range = (Value, Value)
type ValueSet = [Range]
其中 ValueSet
是封闭的、不相交的范围的排序列表。然后,您可以使用类似于排序合并的逻辑一个一个地实现 evaluate
的情况。
这个问题是NP难的。无论如何,感觉确实如此。
但也许还有希望。如前所述,您的表达语言非常受限。例如,您没有提到 not
运算符,这意味着 &&
永远无法转换为 ||
.
这是答案的概要:
- 标准化比较运算符:遍历树,通过交换操作数将所有 <= 转换为 >。同时,将>=转换为<.
- 折叠重复 和 秒和 或 秒到 'a multi-operand tree node'。例如,重写
A || ( B || C )
使其成为单个三操作数树节点 or(A,B,C)
。当且仅当节点与其父节点是相同的运算符时,它才能折叠。
- 使用稳定排序对操作数
||
、&&
、or
和 and
进行排序,以便 C || (B || A)
也折叠为 or(A,B,C)
.和 B || A
和`A
- 既然树已经规范化了,递归树比较就可以了。
此答案未考虑重叠集。例如,
它不会树表达式
我有一个 AST 表示这样的表达式:
(<=10 && >=3) || ==0
==1 || ==2 || ==3
==1 && !=1
有数值型也有布尔型(||
,&&
)和数值型(<
,<=
,==
,!=
, >=
, >
) 运算符。如果需要,可以将布尔 not
运算符添加到 AST。这些表达式用于限制可能的数字输入值(注意最后一个不允许任何值)。
我正在寻找一种比较两个表达式的方法。我需要知道它们是否允许完全相同的一组数字(等效),或者一个表达式是否允许另一个表达式的子集。
你可以写一个函数
evaluate :: Expression -> ValueSet
将一个表达式计算为一组为真的值。这个值集可能类似于
data Value = MinusInfinity | Finite Integer | PositiveInfinity
type Range = (Value, Value)
type ValueSet = [Range]
其中 ValueSet
是封闭的、不相交的范围的排序列表。然后,您可以使用类似于排序合并的逻辑一个一个地实现 evaluate
的情况。
这个问题是NP难的。无论如何,感觉确实如此。
但也许还有希望。如前所述,您的表达语言非常受限。例如,您没有提到 not
运算符,这意味着 &&
永远无法转换为 ||
.
这是答案的概要:
- 标准化比较运算符:遍历树,通过交换操作数将所有 <= 转换为 >。同时,将>=转换为<.
- 折叠重复 和 秒和 或 秒到 'a multi-operand tree node'。例如,重写
A || ( B || C )
使其成为单个三操作数树节点or(A,B,C)
。当且仅当节点与其父节点是相同的运算符时,它才能折叠。 - 使用稳定排序对操作数
||
、&&
、or
和and
进行排序,以便C || (B || A)
也折叠为or(A,B,C)
.和B || A
和`A - 既然树已经规范化了,递归树比较就可以了。
此答案未考虑重叠集。例如, 它不会树表达式