我正在查看一阶逻辑定理证明器,例如 Vampire 和 E-Prover,TPTP 语法似乎是要走的路。我更熟悉诸如答案集编程和 Prolog 之类的逻辑编程语法,虽然我尝试参考TPTP 语法的详细描述,但我似乎仍然没有掌握如何正确区分解释和非解释函子(我可能使用错误的术语)。
本质上,我试图通过证明没有模型作为反例来证明一个定理。我的第一个困难是我没想到下面的逻辑程序是可以满足的。
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"
。所以它可能与 function 重合g
。尽管一个从不重合的手动规范可以解决问题f
,g
但以下程序不能令人满意,我觉得我做错了。而且它可能无法扩展到我的真实环境,当它们在语法上不同时,所有术语都被解释为不同的。
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))).