3.8 模型的建立
我们一直假设我们已经有了一个模型,并要检查模型中的一个句子的真值。相比之下,模型的建立是给定一些句子的集合,尝试创造一种新的模型。如果成功,那么我们知道集合是一致的,因为我们有模型的存在作为证据。
我们通过创建Mace()
的一个实例并调用它的build_model()
方法来调用 Mace4 模式产生器,与调用 Prover9 定理证明器类似的方法。一种选择是将我们的候选的句子集合作为假设,保留目标为未指定。下面的交互显示了[a, c1]
和[a, c2]
都是一致的列表,因为 Mace 成功的为它们都建立了一个模型,而[c1, c2]
不一致。
>>> a3 = read_expr('exists x.(man(x) & walks(x))')
>>> c1 = read_expr('mortal(socrates)')
>>> c2 = read_expr('-mortal(socrates)')
>>> mb = nltk.Mace(5)
>>> print(mb.build_model(None, [a3, c1]))
True
>>> print(mb.build_model(None, [a3, c2]))
True
>>> print(mb.build_model(None, [c1, c2]))
False
我们也可以使用模型建立器作为定理证明器的辅助。假设我们正试图证明S
⊢ g
,即g
是假设S = [s1, s2, ..., sn]
的逻辑派生。我们可以同样的输入提供给 Mace4,模型建立器将尝试找出一个反例,就是要表明g
不 遵循从S
。因此,给定此输入,Mace4 将尝试为假设S
连同g
的否定找到一个模型,即列表S' = [s1, s2, ..., sn, -g]
。如果g
从S
不能证明出来,那么 Mace4 会返回一个反例,比 Prover9 更快的得出结论:无法找到所需的证明。相反,如果g
从S
是可以证明出来,Mace4 可能要花很长时间不能成功地找到一个反例模型,最终会放弃。
让我们思考一个具体的方案。我们的假设是列表[There is a woman that every man loves, Adam is a man, Eve is a woman]。我们的结论是 Adam loves Eve。Mace4 能找到使假设为真而结论为假的模型吗?在下面的代码中,我们使用MaceCommand()
检查已建立的模型。
>>> a4 = read_expr('exists y. (woman(y) & all x. (man(x) -> love(x,y)))')
>>> a5 = read_expr('man(adam)')
>>> a6 = read_expr('woman(eve)')
>>> g = read_expr('love(adam,eve)')
>>> mc = nltk.MaceCommand(g, assumptions=[a4, a5, a6])
>>> mc.build_model()
True
因此答案是肯定的:Mace4 发现了一个反例模型,其中 Adam 爱某个女人而不是 Eve。但是,让我们细看 Mace4 的模型,转换成我们用来估值的格式。
>>> print(mc.valuation)
{'C1': 'b',
'adam': 'a',
'eve': 'a',
'love': {('a', 'b')},
'man': {('a',)},
'woman': {('a',), ('b',)}}
这个估值的一般形式应是你熟悉的:它包含了一些单独的常量和谓词,每一个都有适当类型的值。可能令人费解的是C1
。它是一个“Skolem 常量”,模型生成器作为存在量词的表示引入的。也就是说,模型生成器遇到a4
里面的exists y
,它知道,域中有某个个体b
满足a4
中的开放公式。然而,它不知道b
是否也是它的输入中的某个地方的一个独立常量的标志,所以它为b
凭空创造了一个新名字,即C1
。现在,由于我们的假设中没有关于独立常量adam
和eve
的信息,模型生成器认为没有任何理由将它们当做表示不同的实体,于是它们都得到映射到a
。此外,我们并没有指定man
和woman
表示不相交的集合,因此,模型生成器让它们相互重叠。这个演示非常明显的隐含了我们用来解释我们的情境的知识,而模型生成器对此一无所知。因此,让我们添加一个新的假设,使 man 和 woman 不相交。模型生成器仍然产生一个反例模型,但这次更符合我们直觉的有关情况:
>>> a7 = read_expr('all x. (man(x) -> -woman(x))')
>>> g = read_expr('love(adam,eve)')
>>> mc = nltk.MaceCommand(g, assumptions=[a4, a5, a6, a7])
>>> mc.build_model()
True
>>> print(mc.valuation)
{'C1': 'c',
'adam': 'a',
'eve': 'b',
'love': {('a', 'c')},
'man': {('a',)},
'woman': {('c',), ('b',)}}
经再三考虑,我们可以看到我们的假设中没有说 Eve 是论域中唯一的女性,所以反例模型其实是可以接受的。如果想排除这种可能性,我们将不得不添加进一步的假设,如exists y. all x. (woman(x) -> (x = y))
以确保模型中只有一个女性。