Iter-4360dd15-0184-failure-left-split-overclaim
4360dd15 lesson failure predicate verification local insertion witness normalization
迭代 184:驳倒一个过强的“左侧独立分解”设想
本轮作为 critic,不去扩张结论,而是专门找当前积累里最可能失败的点。结果证伪了一个看起来很自然、但实际上过强的分解假设:
''错误命题'':固定唯一 marker μ 后,若一次相邻交换落在 μ 左侧,那么可行性总能分解为“S 的某个前缀匹配 L 的左半边,剩余后缀匹配 L 的右半边”。
反例
取:
-
S = ('a','b')- 先在
j=2 处插入 μ,得 B = ('a','b','μ')- 再在
i=0 做一次交换,得 L = ('b','a','μ')虽然这是一个合法的 insert + one swap witness,但不存在任何 k 使得:
- S[:k] 是 L[:j] 的子序列,且
- S[k:] 是 L[j+1:] 的子序列。
因为 L[j+1:] 为空,而 S=('a','b') 不能作为 ('b','a') 的子序列整体回收成一个单一前缀切分。
复现代码
from itertools import productalpha=('a','b')
marker='μ'
def insert(seq,p,x):
seq=list(seq)
return tuple(seq[:p]+[x]+seq[p:])
def swap(seq,i):
seq=list(seq)
seq[i],seq[i+1]=seq[i+1],seq[i]
return tuple(seq)
def is_subsequence(short,long):
it=iter(long)
try:
for x in short:
while next(it)!=x:
pass
return True
except StopIteration:
return False
S=('a','b')
j=2
B=insert(S,j,marker)
L=swap(B,0)
print(B, L)
ok=False
for k in range(len(S)+1):
if is_subsequence(S[:k], L[:j]) and is_subsequence(S[k:], L[j+1:]):
ok=True
print('found k', k)
print('split_exists', ok)
结论
- “交换只落在左侧纯字母串里”仍然成立;
- 但“因此可把可行性拆成锚点左右两个互不相关的子序列问题”是假的。
教训
后续证明不能只按
μ 做一次硬切分,然后试图用前缀/后缀各自独立地完成匹配;交换会改变左侧串内部顺序,导致需要的 embedding 可能整体跨越锚点边界。更安全的下一步,应改成:
1. 固定 μ,只讨论交换对左侧局部串的影响;
2. 保留完整的 subsequence embedding 视角;
3. 证明“左侧局部交换”可被归约为对左侧串本身的重排,不要求左右半边独立可判定。