在TPTP中表示语法上不同的术语

时间:2017-06-05 23:36:29

标签: syntax theorem-proving logic-programming first-order-logic

我正在研究一阶逻辑定理证明,如Vampire和E-Prover,TPTP语法似乎是要走的路。我更熟悉逻辑编程语法,如答案集编程和Prolog,虽然我尝试参考TPTP syntax的详细描述,我似乎仍然没有掌握如何正确区分解释函数和非解释函子(我可能会使用错误的术语)。

基本上,我试图通过证明没有模型作为反例来证明一个定理。我的第一个困难是我没想到以下逻辑程序是可以满足的。

fof(all_foo, axiom, ![X] : (pred(X) => (X = foo))).
fof(exists_bar, axiom, pred(bar)).

确实令人满意,因为没有什么可以阻止bar等于foo。因此,第一个解决方案是坚持这两个术语是不同的,我们获得以下不可满足的计划。

fof(all_foo, axiom, ![X] : pred(X) => (X = foo)).
fof(exists_bar, axiom, pred(bar)).
fof(foo_not_bar, axiom, foo != bar).

技术报告澄清了不同的双引号字符串确实是不同的对象,因此另一种解决方案是在这里和那里放置引号,以便获得以下不可满足的程序。

fof(all_foo, axiom, ![X] : (pred(X) => (X = "foo"))).
fof(exists_bar, axiom, pred("bar")).

我很高兴不要手动指定不等式,因为这显然不会扩展到更现实的情况。接近我的实际情况,我实际上必须处理组合的术语,不幸的是,以下程序是可以满足的。

fof(all_foo, axiom, ![X] : (pred(X) => (X = f("foo")))).
fof(exists_bar, axiom, pred(g("bar"))).

我猜f("foo")不是一个术语,而是f函数应用于对象"foo"。因此它可能与函数g重合。虽然fg的手动规范从不重合,但下面的程序是不可接受的,我觉得我做错了。它可能不会扩展到我的真实环境中,当它们在语法上不同时,大量的术语都被解释为不同的。

fof(all_foo, axiom, ![X] : (pred(X) => (X = f("foo")))).
fof(exists_bar, axiom, pred(g("bar"))).
fof(f_not_g, axiom, ![X, Y] : f(X) != g(Y)).

我试过抛出单引号,但我找不到合适的方法。

如何制作语法上不同(组合)的术语并测试语法上的相等?

附属问题:以下程序是可以接受的,因为自动定理证明器将f理解为函数而不是未解释的函子。

fof(exists_f_g, axiom, (?[I] : ((f(foo) = f(I)) & pred(g(I))))).
fof(not_g_foo, axiom, ~pred(g(foo))).

为了使其不可满足,我需要手动指定f是单射的。如果不指定程序中出现的所有仿函数的注入性,那么获得此行为的自然方法是什么?

fof(exists_f_g, axiom, (?[I] : ((f(foo) = f(I)) & pred(g(I))))).
fof(not_g_foo, axiom, ~pred(g(foo))).
fof(f_injective, axiom, ![X,Y] : (f(X) = f(Y) => (X = Y))).

1 个答案:

答案 0 :(得分:3)

首先让我指出TPTP的Syntax BNF。原则上,您有Prolog术语与一些适当优先级的预定义中缀/前缀运算符。这意味着,变量以大写形式写入,常量以小写形式写入。也像Prolog一样,用单引号转义允许我们写一个以大写字母开头的常量,即'X'。到目前为止,我从未见过双引号原子,因此您可能需要查看证明者如何解释它们的说明。

但即使语法是Prolog-ish,自动化定理证明也是一种不同的野兽。没有封闭的世界假设,也没有假设不同的常数 - 这就是为什么你找不到证据的原因:

fof(c1, conjecture, a=b ).

并且都不是:

fof(c1, conjecture, ~(a=b) ).

因此,如果你想要语法不平等,你需要对其进行公理化。现在,假设与b不同,显示它们是不同的,所以我至少声称:“假设有两个不同的常数a和b,那么存在一些不是b的变量。”

fof(a1, axiom, ~(a=b)).
fof(c1, conjecture, ?[X]: ~(X=b)).

由于一阶逻辑中的函数不一定是单射的,所以你也不会在那里添加你的假设。

请注意输入公式的不同作用:到目前为止,您只说了公理而没有猜想,即您要求证明者将公理集显示为不一致。一些证明者甚至可能会放弃,因为他们使用一些分辨率改进(例如支持集)来限制公理之间的分辨率[1]。在任何情况下,你需要知道你试图证明的公式是A1 ∧ ... ∧ An → C1 ∨ ... Cm形式,其中A是公理,C是猜想。[2]

我希望现在至少语法更清晰一些 - 不幸的是,问题的答案更多的是,定理的定理证明并没有做出你期望的假设,所以你必须对它们进行公理化。这些公理化通常也是无效的,你可能会从专业工具中获得更好的表现。

[1]正如您已经注意到的那样,像Vampire或E Prover这样的高级证明者会告诉您(反)可满足性。

[2]基于分辨率的定理证明器将首先否定该公式并执行CNF转换,但即使大多数TPTP接受证明器都是基于分辨率的,但这不是必需的。