逻辑编程里有一条教科书式的规则:x 是 y 的姐妹,y 是 z 的父母,那么 x 是 z 的姑姑或姨妈。用 Datalog 写出来是这样:
Aunt(x, z) :- Sister(x, y), Parent(y, z).而用 numpy 写,是这样一行:
Aunt = np.einsum("xy,yz->xz", Sister, Parent) > 0华盛顿大学的 Pedro Domingos 在 2025 年 10 月的论文《Tensor Logic: The Language of AI》里说,这两行不只是“结果碰巧一样”,它们本来就是同一种运算;而且神经网络、逻辑推理、核方法、概率图模型,全都可以只用这一种语句写出来1。他据此提出一门新语言,名字就叫张量逻辑(tensor logic),并且说它能在嵌入空间里做“可靠、透明、不会幻觉”的推理。
这话听上去很大。逻辑规则和矩阵乘法真的是一回事吗?如果是,为什么符号 AI 和神经网络各走各路走了几十年?只剩一种语句的语言长什么样,能不能真把规则学出来、真不幻觉?我们就从上面这一行 einsum 开始,边跑代码边往下看。
一、规则与 einsum 的对应
先认识两边
Datalog 是最简单的逻辑编程语言,可以看成去掉函数符号的 Prolog。一个 Datalog 程序由两样东西组成:事实,比如 Parent(舅舅, 表妹),说的是“舅舅是表妹的父母”;规则,比如上面那条 Aunt,箭头(:-)左边叫头,右边叫体,体里的逗号是“并且”。规则的意思是:只要能找到一组取值,让体里的每一项都是已知事实,头就成立。
einsum(爱因斯坦求和)是一种写张量运算的记号。张量就是多维数组:向量有一个下标,矩阵有两个。"xy,yz->xz" 的意思是:第一个矩阵的下标叫 x、y,第二个叫 y、z,结果保留 x、z;在箭头右边没出现的下标 y,要被求和掉。所以它就是矩阵乘法 。
现象:两边算出同样的五条
我们拿一个七口之家试一下:外婆有三个孩子,妈妈、小姨和舅舅;妈妈有“我”,舅舅有表妹和表弟。把 Sister 和 Parent 各写成一个 7×7 的 0/1 矩阵,第 x 行第 y 列是 1 就表示这条事实成立,再跑上面那行 einsum:
einsum[妈妈,表妹] = 1 经由 y = ['舅舅'] -> Aunt = 1einsum[妈妈,表弟] = 1 经由 y = ['舅舅'] -> Aunt = 1einsum[小姨,我] = 1 经由 y = ['妈妈'] -> Aunt = 1einsum[小姨,表妹] = 1 经由 y = ['舅舅'] -> Aunt = 1einsum[小姨,表弟] = 1 经由 y = ['舅舅'] -> Aunt = 1五条结果,和按 Datalog 规则一条条推出来的完全一样2。
原因:关系就是布尔张量
为什么会一样?把规则拆开看,每一部分都能在 einsum 里找到对应。
关系就是布尔张量。 一个二元关系 Parent(y, z) 等价于一个 0/1 矩阵,三元关系就是一个三维的 0/1 数组。论文把这句话反过来说:关系是稀疏布尔张量的一种紧凑写法,只列出值为 1 的那些格子。
体里的逗号是乘法,共享的变量是共享的下标。 两个 0/1 数相乘,只有都为 1 时才是 1,正好是“并且”。Sister(x, y) 和 Parent(y, z) 用的是同一个 y,对应到 einsum 里就是两边用同一个下标 y。数据库里把这叫连接(join):把两张表里 y 相同的行拼起来。
只在体里出现的变量被求和。 头里只有 x 和 z,y 没出现,einsum 就把 y 求和掉。数据库里这叫投影(projection):把不需要的列扔掉。逻辑上,它对应的是“存在某个 y”。
最后套一个阶跃函数。 求和得到的是“有几个 y 能连起来”,可能大于 1;比如表妹若同时是妈妈和舅舅的孩子,小姨就能经由两条路成为她的姨妈,这一格会数出 22。逻辑只关心真假,所以论文在外面套了一个阶跃函数 :大于 0 就是 1,否则是 0。写成公式就是:
这就是论文的核心观察:一条 Datalog 规则,等于在布尔张量上做一次 einsum,再逐元素过一个阶跃函数。体里有几项就是几个张量相乘,关系有几元就是几维;对应关系对任意多项、任意元数都成立。
递归规则:反复做到不动点
再看一条递归的规则,祖先:父母是祖先,祖先的孩子的祖先也是祖先。
Ancestor(x, y) :- Parent(x, y).Ancestor(x, z) :- Ancestor(x, y), Parent(y, z).Datalog 的标准算法叫前向链:把所有规则拿到已知事实上反复用,推出新事实,加进去,再用,直到一轮下来什么新东西都推不出为止。这个“推不出新东西”的状态叫不动点。换成矩阵,就是反复算 ,直到 不再变化。在那个七口之家上,第一轮新增了外婆是“我”、表妹、表弟的祖先这三条,第二轮什么也没新增,停下2。
到这里,“规则就是 einsum”是站得住的。而 einsum 本来就是神经网络里最常用的运算:全连接层、卷积、注意力,几乎都能写成 einsum3。那么,能不能干脆只保留这一种语句,用它把两边都写出来?
二、只有一种语句的语言
张量方程
论文的回答是能,并且把这当成整门语言的定义。张量逻辑程序就是一组张量方程,每条方程长这样:
Aunt[x, z] = H(Sister[x, y] Parent[y, z])左边是要算的张量,右边是几个张量的连接,加一个可选的逐元素非线性函数(阶跃、sigmoid、ReLU 都行)。规则只有这么几条:右边有、左边没有的下标被求和;没算出来的元素默认是 0;左边相同的几条方程结果相加(这正好对应 Datalog 里同名的几条规则取“或”)。用圆括号写的张量表示布尔张量,所以任何 Datalog 程序原样就是合法的张量逻辑程序1。
论文说这就是全部定义:没有关键字,没有别的语句。为了方便,可以加一些语法糖,比如下标里写 t+1、用 max= 代替默认的求和、softmax,但它们不增加表达能力。
现象:神经网络和图模型都写得进去
有了这一种语句,论文第 4 节把几类 AI 方法挨个写了一遍。挑几条放在一起看:
| 方法 | 张量方程 | 说明 |
|---|---|---|
| 感知机 | Y = step(W[i] X[i]) | i 被求和,就是点积 |
| 多层感知机 | X[i,j] = sig(W[i,j,k] X[i-1,k]) | i 是层号,一条方程写完所有层 |
| 卷积层 | F[x,y] = relu(K[dx,dy,ch] Img[x+dx,y+dy,ch]) | 下标里可以写加法 |
| 图神经网络聚合 | Agg[n,l,d] = Neig(n,n') Z[n',l,d] | 邻接关系是布尔张量,乘上就把非邻居清零 |
| 注意力 | Comp[p,p'.] = softmax(Q[p,dk] K[p',dk] / sqrt(Dk)) Attn[p,dv] = Comp[p,p'] V[p',dv] | 整个 Transformer 约十几条方程 |
| 核机器 | Y[Q] = f(A[i] Y[i] K[Q,i] + B) | 核函数另写一条方程 |
| 贝叶斯网络 | P_X[x] = CPT[x,p1,p2] P_1[p1] P_2[p2] | 边缘化是投影,因子相乘是连接 |
| Datalog 规则 | Aunt(x,z) = Sister(x,y) Parent(y,z) | 布尔张量,原样可用 |
论文还用带“虚拟下标”的 RNN 推出张量逻辑是图灵完备的。
这张表里,左边那一列来自完全不同的几个学派,右边的写法却是同一个模子。
推理和学习也只有一套
推理有两种方式,都是从 Datalog 搬过来的。前向链把方程当成一段顺序代码,挨个执行,能算的元素都算出来,重复到不动点或满足停止条件;后向链把每条方程当成函数,从要问的那个张量出发,递归地去调右边那些张量的方程,只算用得到的元素。
学习靠求导。因为只有一种语句,求导规则也只有一条:不看非线性,方程左边对右边某个张量的导数,就是右边其余张量的乘积。比如 ,。所以一个张量逻辑程序的梯度,本身也是一个张量逻辑程序。第六节学规则时,我们会用数值差分核对这一点。
第一次尝试的疑问:这不就是 einsum 吗
读到这里,很自然会有一个疑问:PyTorch 和 numpy 里早就有 einsum,上面那张表的每一行都能直接用它写出来,张量逻辑多了什么?
论文的回答是,Python 的张量库只管求导和 GPU,不管推理和知识;逻辑语言只管推理,不管学习和扩展。张量逻辑想做的是让同一个程序里,布尔的事实和规则、实数的权重和嵌入可以混在一起写、一起推理、一起求导。
可是反过来想,既然 einsum 在每个深度学习框架里都有,为什么没人拿它来跑 Datalog?用矩阵跑规则,代价在哪里?
三、稀疏关系的代价
现象:结果一样,速度差了上千倍
我们生成一个随机家谱:N 个人,每人平均有一个更早出生的父母,然后用两种办法算出全部祖先关系。一种是 Datalog 引擎常用的半朴素求值:存一个事实集合,每一轮只拿上一轮新推出的事实去连接;另一种是上面的稠密矩阵写法,每一轮做一次 N×N 的矩阵乘法。
| 人数 N | 父子事实 | 推出祖先 | 集合求值 | 稠密矩阵 | 矩阵里非零的比例 |
|---|---|---|---|---|---|
| 500 | 509 | 4,133 | 6.4 ms | 189 ms | 1.65% |
| 1,000 | 935 | 6,159 | 3.6 ms | 407 ms | 0.62% |
| 2,000 | 1,980 | 16,613 | 11.8 ms | 2.7 s | 0.42% |
| 4,000 | 4,049 | 45,555 | 27.6 ms | 24.4 s | 0.28% |
两种办法推出的祖先关系逐条比对完全一致。迭代轮数相同(4000 人时 40 轮)。numpy float32,4 核 CPU。
原因:矩阵要为不存在的事实付钱
原因就在最后一列。4000 个人的祖先关系有 4.5 万条,可 4000×4000 的矩阵有 1600 万个格子,99.7% 是 0。集合求值只碰真实存在的事实,事实多一倍,时间大约多一倍;矩阵乘法每轮要做 次乘加,人数翻倍,每轮就慢 8 倍,加上轮数也在增加,总时间涨了约 9 倍。
换到 GPU 上,常数会小很多,但阶数不变。更麻烦的是维数:一个三元关系是 个格子,论文自己也说,用元组列表代替稠密张量,省下的空间随元数指数增长。所以用稠密 einsum 跑规则,在“几个人的家谱”上很优雅,在真实的知识库上走不通。
论文给的两条路
论文第 6 节承认了这一点,给了两条路1。
第一条是分工:稠密的部分交给 GPU,稀疏的部分当成关系交给数据库查询引擎,用上数据库几十年的查询优化。这条路靠得住,但它其实就是今天大家在做的事:向量算在框架里,关系存在数据库里,中间写胶水代码。张量逻辑在这里的作用,是把两边写成同一种记号。
第二条是论文更看好的:把稀疏张量分解成稠密的小张量,全部放到 GPU 上算。论文说这比直接操作稀疏张量“指数级更高效”,而且随机的分解就够用,代价是有一点出错的概率。这条路通向论文第 5 节,也是论文自己说最有意思的部分:在嵌入空间里推理。把关系压进嵌入以后,推出来的东西还对吗?
四、在嵌入空间里推理
先从一个集合开始
嵌入就是给每个对象分配一个 D 维向量。论文先考虑最简单的情况:每个对象一个随机的单位向量。D 足够大时,两个随机单位向量几乎正交,点积在 0 附近,标准差约 ;一个向量和自己的点积是 1。
想存一个集合,比如“哪些人喜欢猫”,就把集合里每个人的向量加起来,得到一个向量 。问某人 A 在不在集合里,算 :A 在里面,结果约等于 1;不在,约等于 0。噪声来自集合里另外 N 个向量和 的点积,标准差约 。取 ½ 当阈值,就能判断在不在,出错的概率随 D 增大而减小。论文把它比作 Bloom filter:一种用固定大小的位数组判断“是否在集合里”的数据结构,可能误报,不会漏报4。
我们用 5000 个对象试了一下,集合外得分的标准差和 吻合得很好:D=1024、N=50 时实测 0.211,理论 0.221;这时错判率 0.92%。集合放到 200 个,错判率涨到 12%2。
再存一个关系
同样的办法可以存关系。一条事实 Parent(Bob, Carl) 用两个向量的外积 表示,得到一个 D×D 的矩阵;把所有事实的外积加起来,就是整个关系的嵌入:
这是 Smolensky 在 1990 年提出的张量积表示5。查询 Parent(A, B) 时,用 和 从两边各点一次:。展开后,每条事实贡献 ,只有 、 那条贡献约 1,其余都是接近 0 的噪声。
现象:误判率很低,假事实却很多
我们在 2000 个对象上扫了一遍维度 D 和事实数 |R|,阈值取 ½:
| 维度 D | D² | 事实数 |R| | 漏判 | 误判率 | 误判条数 |
|---|---|---|---|---|---|
| 64 | 4,096 | 100 | 0% | 0.148% | ≈ 5,932 |
| 128 | 16,384 | 100 | 0% | 0.000% | ≈ 5 |
| 128 | 16,384 | 1,000 | 3.8% | 2.79% | ≈ 111,701 |
| 256 | 65,536 | 1,000 | 0.10% | 0.028% | ≈ 1,122 |
| 256 | 65,536 | 4,000 | 3.5% | 3.57% | ≈ 142,438 |
误判条数 = 误判率 × 不在关系里的候选对数。
看百分比,D=256 存 1000 条事实只误判 0.028%,好像很准了。可换成条数就是另一回事:多出来约 1122 条假事实,比 1000 条真事实还多。逻辑推理里,一条假事实接着往下推,可能带出一串假结论。
问题出在分母上。这个误差和 Bloom filter 一样,单次查询出错的概率小,但“把整个关系取回来”要查 次。实验里要让假事实降到个位数,D² 大约要比事实数大两个数量级(D=128 存 100 条,误判约 5 条)。而 D×D 的稠密矩阵本身并不比元组列表省地方:存 1000 条事实,列表是 2000 个整数,D=256 的 EmbR 是 6.5 万个实数。嵌入真正省下的是相对 的稠密矩阵,以及“全部在 GPU 上做稠密运算”这件事。
规则在嵌入空间里连着用
规则也能搬进嵌入空间。Ancestor(x, z) :- Ancestor(x, y), Parent(y, z) 里,共享变量 y 在嵌入空间里变成共享的下标,两个关系嵌入直接做矩阵乘法:。展开后,中间多出来的是 这一项,y 和 y′ 相同时约为 1,不同时约为 0,所以近似成立。
每多连一次,就多一层近似。我们用 1000 个对象、611 条父子事实(含一条 12 代的长链),D=512,算“恰好 k 代”的祖先关系,看错判怎么随跳数变化。论文还建议了一个降噪办法:每推一步就把结果取出来、按 ½ 阈值化、再重新嵌入。两种做法都试了:
| 跳数 | 真事实 | 直接连乘,最后读出 | 每步阈值化再重嵌 | ||
|---|---|---|---|---|---|
| 漏判 | 误判 | 漏判 | 误判 | ||
| 1 | 611 | 0% | 0 | 0% | 0 |
| 2 | 377 | 0.3% | 78 | 0.3% | 78 |
| 3 | 287 | 0.3% | 1,351 | 0.7% | 340 |
| 4 | 213 | 4.2% | 7,376 | 0.5% | 1,780 |
| 5 | 162 | 10.5% | 25,163 | 4.9% | 26,592 |
| 6 | 136 | 22.1% | 61,932 | 17.6% | 337,792 |
D=128 时,直接连乘第 2 跳就有约 16 万条误判。
直接连乘时,第 1 跳完全正确,到第 6 跳漏掉了 22% 的真事实,还多出 6 万多条假的。每步阈值化在第 3、4 跳确实把误判压了下来,但到第 6 跳反而更糟:早期混进去的少量假事实被当成真事实重新嵌入,下一跳从它们出发又推出一批,越滚越多。
所以论文说的“出错概率随嵌入维度下降”是对的,但要读全:维度要跟着事实数、对象数和推理深度一起涨,降噪也只能延缓误差累积,挡不住它。随机嵌入下的“可靠”,是一个有代价的概率保证。
不过随机嵌入只是第一步,它和查表没有本质区别。论文真正想要的是学出来的嵌入:相似的对象向量相近,可以互相“借”结论。这时候,论文说的“不会幻觉”还成立吗?
五、温度与“不会幻觉”
论文的主张
嵌入是学出来的时候, 不再接近单位阵,而是一个衡量对象两两相似度的 Gram 矩阵。查询 Parent(Rob, Carl) 时,即使库里只有 Parent(Bob, Carl),只要 Rob 和 Bob 的向量相近,也会得到一个不小的分数。论文把这叫类比推理:相似的对象按相似程度分享推论。
接着论文在每条方程外面套一个带温度 T 的 sigmoid:。T 越大,曲线越平缓;T 趋于 0,曲线变成阶跃。论文的说法是:T 设为 0,等于把 Gram 矩阵变成单位阵,推理就成了纯演绎;“这和 LLM 不同,LLM 即使在 T=0 时也会幻觉”。T 调高,推理就越来越偏类比;每条规则还可以有自己的 T,数学定理用 0,积累弱证据的规则用高温1。
现象:T 趋于 0,相似的对象照样“借”到结论
我们用一个最小的例子检查。D=256,库里只存一条事实 Parent(Bob, Carl)。另造三个对象:Rob 和 Bob 余弦相似度 0.8(像学出来的近义对象),Bobby 是 0.4,Alice 和 Zed 是无关的随机向量。原始得分分别是:Bob 1.0、Rob 0.8、Bobby 0.4,无关的在 ±0.02 附近。再把得分过 sigmoid,看 T 变小时会怎样:
| 查询 | Bob → Carl | Rob → Carl | Bobby → Carl | Zed → Alice |
|---|---|---|---|---|
| 原始得分 | 1.000 | 0.800 | 0.400 | 0.005 |
| 论文原式 σ(x/T),阈值在 0 | ||||
| T = 0.3 | 0.966 | 0.935 | 0.791 | 0.504 |
| T = 0.0001 | 1 | 1 | 1 | 1 |
| 阈值挪到 ½:σ((x − ½)/T) | ||||
| T = 0.3 | 0.841 | 0.731 | 0.417 | 0.161 |
| T = 0.0001 | 1 | 1 | 0 | 0 |
按原式,2000 个无关对象在 T=0.0001 时有 50.5% 被判成 Carl 的父母;阈值挪到 ½ 后是 0%。
先看论文原式。阈值在 0,T 趋于 0 时得分只要大于 0 就判真,而无关对象的得分是围着 0 抖动的噪声,于是一半无关对象都被判成了 Carl 的父母。这显然不是论文本意,应该理解成方程里还有一个偏置,把阈值放在 ½,就像第四节的 Bloom filter 那样。
阈值挪到 ½ 以后,T 趋于 0 确实把弱相似(Bobby)和噪声都清掉了,但 Rob 仍然是 1。原因很简单:Rob 的原始得分是 0.8,已经越过了阈值,曲线再陡也只会把它推向 1,不会推向 0。
原因:演绎和类比的冲突在嵌入里,不在温度里
所以“T=0 让 Gram 矩阵变成单位阵”需要一个前提:任意两个不同对象的相似度都低于阈值。这在随机嵌入下成立(这就是第四节),而学出来的嵌入恰恰是要让相似的对象靠近,余弦 0.8 很平常。下面这段是我的推断,论文没有讨论:想要同一套嵌入既能类比又能在需要时严格演绎,可能得给演绎用的规则单独一套近乎正交的嵌入,或者在读出时把“是不是同一个对象”和“像不像”分开判断,光调 T 做不到。
再说和 LLM 的比较。张量逻辑的推理过程里,每一步推出的张量都能取出来看,这一点确实比 LLM 的推理过程透明。但“T=0 不会幻觉”成立的那个区间,正好是随机嵌入、不做类比的区间,而在那个区间里,它仍然有第四节看到的、随维度和推理深度变化的误判。把它说成“免疫幻觉”,是把一个概率保证说成了绝对保证。
前面讨论的都是事实和嵌入怎么存、怎么推。张量逻辑另一半的卖点是学习:规则本身能不能也学出来?
六、规则的学习
归纳逻辑编程与一条带权重的方程
从数据里学出逻辑规则,有一个专门的领域,叫归纳逻辑编程(ILP)。它难在搜索:可能的规则组合是天文数字。论文的思路是,把“候选规则”写成一条带权重的张量方程,让梯度下降来挑。论文原话是,一条方程可以表示连接结构相同的所有规则。
我们照这个思路,在家庭数据上学“姑姨”关系。候选方程是:
Aunt[x, z] = sig(W[r, s] Rel[r, x, y] Rel[s, y, z] + b)Rel 把四种基本关系(Parent、Sister、Brother、Spouse)叠成一个三维张量,r、s 取遍这四种。所以这一条方程同时代表了 16 条形如 Aunt(x, z) :- r(x, y), s(y, z) 的候选规则,W[r, s] 就是每条候选规则的权重。
现象:权重自己挑出了正确的规则
随机生成 40 个家庭(452 人,195 条真的姑姨关系)训练,20 个新家庭(232 人,84 条)测试。训练完的权重是这样的:
| r \ s | Parent | Sister | Brother | Spouse |
|---|---|---|---|---|
| Parent | −0.06 | −0.04 | −0.03 | −0.04 |
| Sister | 20.60 | −0.01 | −0.04 | −0.03 |
| Brother | −0.02 | −0.02 | −0.03 | −0.02 |
| Spouse | −0.08 | −0.01 | −0.01 | −0.03 |
阈值化(W + b > 0)后只剩 Aunt(x,z) :- Sister(x,y), Parent(y,z)。新家庭上 84 条全中,误判 0。
16 个权重里,只有 W[Sister, Parent] 长到了 20.6,其余都在 0 附近。阈值化以后,留下的正是 Aunt(x, z) :- Sister(x, y), Parent(y, z),拿到没见过的新家庭上 84 条全中,没有误判。学出来的不是一个黑盒,而是一条能读、能拿去推理任何家庭的规则。
顺便核对第二节说的求导规则。损失对 W[r, s] 的梯度写出来也是一个 einsum:,其中 是损失对 sigmoid 输入的导数。和数值差分比,W[Sister, Parent] 这一格是 −2.742338e-05 对 −2.742324e-05,前五位一致2。
不足:权重能学,结构要先写对
真实的“姑姨”还包括姻亲:舅舅的妻子是舅妈,叔叔的妻子是婶婶。这类关系是三段连接,Spouse(x, w), Brother(w, y), Parent(y, z)。我们把舅妈也加进训练目标(训练集里 134 条),候选方程仍然只有两段,再训一次:模型还是只学出了 Sister∘Parent,新家庭上 80 条舅妈全部漏掉。
这不是训练不够,而是两段连接的方程里根本没有三段的规则,权重怎么调都补不上。论文那句“一条方程表示连接结构相同的所有规则”,反过来读就是:连接结构得由人先写好。ILP 最难的那部分,正是在不同的结构之间搜索。论文提到可以用张量分解来“发明”新的中间谓词(比如自动发现“兄弟姐妹”这个概念),这是一个有意思的方向,但论文没有给出实验,我们也没有验证。
到这里,论文的几个主张都摸了一遍。最后还剩一个问题:这些想法里,哪些是新的?
七、这篇论文的位置
这个观察并不新
“规则就是矩阵乘法加阈值”这个观察,在 2013 到 2017 年之间就有好几个人写过,论文几乎都没有引用:
| 年份 | 工作 | 和本文的关系 |
|---|---|---|
| 1990 | Smolensky,张量积表示引 | 第四节关系嵌入的来源,论文引用了 |
| 2011 | Nickel 等,RESCAL | 每个关系一个矩阵,三元组打分 e_hᵀ M_r e_t,就是嵌入空间里的关系 |
| 2013 | Grefenstette,用张量模拟逻辑演算 | 把谓词逻辑的真值计算写成张量运算 |
| 2016 | Cohen,TensorLog | 把一类概率 Datalog 编译成可微的矩阵运算,交给 TensorFlow 训练;名字几乎一样 |
| 2016 | Sato,线性代数方法求值 Datalog | 矩阵乘法加阈值算传递闭包,就是第一节的 Ancestor |
| 2017 | Rocktäschel 与 Riedel,神经定理证明器 | 用嵌入相似度代替符号匹配,第五节的“类比推理” |
| 2026 | Shah 与 Zadrozny,第三方复现 | 按论文实现并在家谱和 FB15k-237 上做了实验 |
“引”表示 Domingos 的论文引用了这项工作。
具体来说,Smolensky 1990 年就用外积叠加表示符号结构5;RESCAL 用每个关系一个矩阵打分6;Grefenstette 2013 年把逻辑演算写成张量运算7;Cohen 2016 年的 TensorLog 把 Datalog 编译成可微的矩阵运算8;Sato 同年用矩阵乘法加阈值求值 Datalog9;神经定理证明器用嵌入相似度做软匹配10。
新的是什么,缺的是什么
论文新的地方,是把这个对应关系推到了极致:张量方程是整门语言唯一的语句,并且把神经网络、核方法、概率图模型、逻辑程序都写成这一种形式;再加上第五节“学出来的嵌入 + 温度”这个统一演绎与类比的设想。作为一种看问题的视角,这很有启发:GNN 的聚合就是“邻居关系”和特征的连接,贝叶斯网络的边缘化就是投影,读完再看这些模型,确实会觉得它们是一家人。
缺的东西也很明显。论文 17 页,没有图,没有一个实验;项目网站上只有论文、幻灯片和访谈,截至本文写作时没有官方实现11。语言层面也有不少空白,比如 Datalog 里很重要的否定(“x 没有孩子”)怎么写、递归和否定混在一起时怎么分层,论文都没讲。
目前能看到的实验来自第三方。2026 年 1 月 Shah 和 Zadrozny 按论文实现了一版:在 1972 人的圣经家谱上,用矩阵乘法加阶跃 74 轮算出 33945 条祖先关系;在知识图谱数据集 FB15k-237 上,按论文的关系矩阵写法做链接预测,MRR 0.3068,去掉直连边后的组合推理 MRR 0.33461213。前者验证的正是第一节的对应关系,后者是一个合格但不算突出的知识图谱嵌入结果。“嵌入空间里可靠推理”“治好 LLM 的幻觉”这些更大的主张,还没有实验支撑。
小结
- 逻辑规则和 einsum 是同一种运算吗? 在布尔张量上是。关系是 0/1 张量,体里的“并且”是相乘,共享变量是共享下标,只在体里出现的变量被求和,最后用阶跃函数把路径计数压回真假。递归规则就是反复做到不动点。
- 只有一种语句的语言长什么样? 一组张量方程。感知机、卷积、注意力、核机器、贝叶斯网络和 Datalog 都能写进去,推理是前向链和后向链,梯度也是张量方程。
- 直接用稠密矩阵跑规则行不行? 结果对,但稀疏关系里 99% 以上是 0。4000 人的家谱,集合求值 28 ms,稠密矩阵 24 s。论文的出路是交给数据库,或者压进嵌入。
- 压进嵌入以后推理还对吗? 近似对。误差随维度下降,但要和事实数、对象数、推理深度一起看:D=256 存 1000 条事实,多出约 1122 条假事实;连乘 6 跳,漏判 22%。每步阈值化只能延缓累积。
- 温度调到 0 就不会幻觉吗? 不能这么说。温度只管曲线陡不陡;相似度 0.8 的对象在任何温度下都会“借”到结论。纯演绎要求不同对象的相似度都低于阈值,这和学出来的嵌入的目的相冲突。
- 规则能学出来吗? 在给定的连接结构里能:16 条候选规则同时训练,权重集中到了正确的
Sister∘Parent,新家庭全中。结构之外的规则(三段的舅妈)学不出来。 - 哪些是新的? 对应关系本身 2016 年前后就有人写过;新的是把它当作唯一的语言构造、统一几大范式,以及嵌入空间推理的设想。论文没有实验和实现,更大的主张还有待验证。
本文所有实验都是几十行 numpy,可以在调研笔记目录里找到2。想自己体会一下,最短的版本就是这几行:
import numpy as nprng = np.random.default_rng(0)N, D = 2000, 256E = rng.standard_normal((N, D)); E /= np.linalg.norm(E, axis=1, keepdims=True)
R = np.zeros((N, N)); R[rng.integers(0, N, 1000), rng.integers(0, N, 1000)] = 1EmbR = E.T @ R @ E # EmbR[i,j] = R(x,y) Emb[x,i] Emb[y,j]Score = E @ EmbR @ E.T # D[x,y] = EmbR[i,j] Emb[x,i] Emb[y,j]
print("真事实", int(R.sum()), "判真", int((Score > 0.5).sum()), "其中假的", int(((Score > 0.5) & (R == 0)).sum()))# 真事实 1000 判真 2171 其中假的 1171参考资料
Footnotes
-
Tensor Logic: The Language of AIarxiv.org ↗文中引用的是 v3(2025-10-16),17 页,没有图,也没有实验。第 3 节定义语言,第 4 节实现各范式,第 5 节讲嵌入空间推理,第 6 节讲扩展。https://arxiv.org/abs/2510.12269 ↩ ↩2 ↩3 ↩4
-
本文的实验代码与调研笔记
/mnt/project-files/tensor-logic-research/:experiment/exp1_datalog.py到exp4_learn_rule.py,输出在logs/。numpy 2.5.3,4 核 CPU。 ↩ ↩2 ↩3 ↩4 ↩5 ↩6 -
Einsum is all you need: Einstein summation in deep learningrockt.ai ↗论文引用它来说明“神经网络里几乎所有线性和多线性运算都能写成 einsum”。https://rockt.ai/2018/04/30/einsum ↩
-
Space/time trade-offs in hash coding with allowable errorsdoi.org ↗https://doi.org/10.1145/362686.362692 ↩
-
Tensor product variable binding and the representation of symbolic structures in connectionist systemsdoi.org ↗张量积表示:用向量外积把“角色”和“填充物”绑在一起,再叠加起来。论文第 5 节的关系嵌入就是这种表示。https://doi.org/10.1016/0004-3702(90)90007-M ↩ ↩2
-
A Three-Way Model for Collective Learning on Multi-Relational Dataicml.cc ↗RESCAL:每个关系一个矩阵 M_r,三元组打分 e_hᵀ M_r e_t。凭领域知识整理,发文前需要核对。https://icml.cc/2011/papers/438_icmlpaper.pdf ↩
-
Towards a Formal Distributional Semantics: Simulating Logical Calculi with Tensorsarxiv.org ↗https://arxiv.org/abs/1304.5823 ↩
-
TensorLog: A Differentiable Deductive Databasearxiv.org ↗把一类概率 Datalog 编译成可微的矩阵运算,交给 TensorFlow / Theano 训练。名字和 Tensor Logic 几乎一样,论文没有引用。https://arxiv.org/abs/1605.06523 ↩
-
A Linear Algebraic Approach to Datalog Evaluationarxiv.org ↗在向量空间里求值 Datalog:矩阵乘法加阈值算传递闭包。https://arxiv.org/abs/1608.00139 ↩
-
End-to-End Differentiable Provingarxiv.org ↗神经定理证明器:用嵌入的相似度代替符号合一,相似的符号可以“软”匹配。https://arxiv.org/abs/1705.11040 ↩
-
tensor-logic.orgtensor-logic.org ↗截至 2026-10-24,站上只有论文、ECML/PKDD 2025 开幕报告的幻灯片、一个访谈视频和邮件订阅,没有官方实现。https://tensor-logic.org/ ↩
-
Implementing Tensor Logic: Unifying Datalog and Neural Reasoning via Tensor Contractionarxiv.org ↗第三方复现:圣经家谱 1972 人、1727 条父子关系,74 轮收敛出 33945 条祖先关系;FB15k-237 上链接预测 MRR 0.3068,去掉直连边的组合推理 MRR 0.3346。https://arxiv.org/abs/2601.17188 ↩
-
sshah100-clt/tensor_logic_implementationgithub.com ↗上一篇复现论文的代码。https://github.com/sshah100-clt/tensor_logic_implementation ↩