我有一堆约束,每个约束包含两个符号和一个比较运算符:<
,<=
,!=
,==
,>=
,或>
。所以,例如:
A <= B
C >= B
A != C
C == D
D > E
我希望能够做三件事:
A > B
,B > C
和A == C
,则会出现不一致,因为A
必须等于C
且大于query(A, C)
且大于{<}
它。query(B, E)
应返回{<, =, >}
(由单个元素组成的集合:小于),F == G
应返回!=
。<
。查询比添加约束更常见。
如果您没有<=
个约束,我已经提出了一个有效的方法:
X == Y
或X <= Y
(所以:Y <= X
转为X > Y
和Y < X
的约束, <
变成query(X, Y)
等。)。X
边缘,则存在矛盾。至Y
:
{<, =, >}
和<
之间的任意路径。
{<}
。{<, =}
,则此部分的结果为Y
。X
。{<, =, >}
和<
之间的任意路径
{>}
。{=, >}
,则此部分的结果为!=
。!=
。(显然,我可以缓存查询,至少在我添加另一个约束之前)
我可以将其扩展为包含!=
,但随后它会以指数方式变慢w.r.t.使用<
的约束数。 (保留一组图形而不是一个。每次使用>
添加约束时,对于集合中的每个图形,将其替换为两个副本,一个要添加的约束为A
,一个它是B
。任何时候产生矛盾,丢弃它。如果图形集是空的,则存在矛盾。在查询中,检查所有图形,将答案合并在一起。)
那么,有没有更有效的方法来解决这个问题?或者它是否会成为指数时间的最坏情况?
我知道我可以使用SAT求解器,但是它显得有点过分,说得温和,特别是因为我看不到它超过100个限制,10更典型。
(对于那些对此产生兴趣的人,我正在研究一种玩具编程语言,并对制作自定义中缀运算符的想法感兴趣,其中优先级取决于现有运算符而不是直接数值(如果您想要添加优先级高于!=
但低于{{1}}的新运算符,则会出现问题,但两者之间没有差距。{{1}}并非严格要求此问题,但我对如何包含它感兴趣。)
答案 0 :(得分:3)
有一些可爱的数学效果,除非你能证明A&lt; = B和B&lt; = A使用反身性和及物性,否则存在A!= B的模型。强制平等变量上的类与&lt; = - 相关变量的图的强连通分量一一对应(其中A = B诱导A <= B且B <= A)。
总的来说,用于确定可行性的算法是提取所有&lt; =约束(其中A