子句包含算法

Clause subsumption algorithm

提问人:rwallace 提问时间:1/5/2019 最后编辑:rwallace 更新时间:1/5/2019 访问量:336

问:

自动定理证明的一个重要部分是通过弄清楚一个子句何时包含另一个子句来减少冗余。

直观地说,一个子句(CNF 中的一阶逻辑公式)C 包含另一个子句 D,当它至少是一般的。具体的定义是,必须用变量替换项,将 C 变成 D 的子多集(不是子集;这将让子句包含它自己的因子,这将破坏一些最佳饱和演算的完整性,例如叠加。

有一些索引技术可以大大减少必须进行的包含尝试次数,但即便如此,包含也会消耗大量的 CPU 时间,因此对其进行优化非常重要。显然,在一般情况下,它是已知的NP困难,但使大多数特定情况快速运行仍然是可能的,也是必要的。

以下伪代码正确但效率低下。(在实践中,否定和正文字必须分开处理,然后会出现一些问题,例如尝试双向方程,但在这里我只考虑匹配两袋文字的核心算法。

def match_clauses(c, d, map):
    if c == {}:
        return true
    for ci in c:
        for di in d:
            if match_terms(ci, di, map):
                if match_clauses(c - ci, d - di, map):
                    return true
    return false

为什么效率低下?考虑两个子句和 .上面的算法会先匹配成功,然后匹配成功,然后注意不匹配。好的,但是接下来它会以相反的方式尝试:首先成功匹配,然后成功匹配,然后再次通知不匹配。如果有 N 个文字匹配,则浪费的工作将是 N 阶乘的,在某些实际情况下,效率低下。p(x) | q(y) | r(42)p(x) | q(y) | r(54)p(x)q(y)r(42)r(54)q(y)p(x)r(42)r(54)

如果有足够的时间,我无疑可以想出一个更好的算法,但其他人一定在我之前做过,所以似乎值得一问:最著名的算法是什么?

算法 不可 知定理证明 一阶逻辑

评论

0赞 btilly 1/5/2019
我认为 CS 可能是要求“最知名算法”的更好地方。不过,作为一个实用的建议,我建议搜索可以暂停然后返回的包含,然后让你的定理证明算法有断点,你考虑它是否已经运行了足够长的时间,值得尝试进一步分析包含,如果你发现你认为应该更快的搜索,就重新开始。所以你很少分析简单的问题,而对困难的问题做很多分析。
0赞 Dima Chubarov 1/6/2019
相加确实是解析类型循环中最耗时的部分,因为相包含尝试的次数可能与工作集中子句对数的增长速度一样快。似乎术语索引技术可能有助于提高个人包含尝试的效率,我记得在《自动推理手册》中读到过它,但恐怕如果不再次查找,我无法凭记忆回答。
0赞 rwallace 1/8/2019
@DmitriChubarov 我在手册中没有看到任何关于索引的提及,只提到了单个子句的包含(而且只是在集合级别,而不是多集级别)。你确定你没有在其他地方读过吗?我目前的理解是,术语索引只会减少单个包含尝试的次数,而不是每次尝试所花费的时间,尽管我可以自由地承认我的理解可能不完整。

答: 暂无答案