Iter-4360dd15-0184-failure-left-split-overclaim

4360dd15 lesson failure predicate verification local insertion witness normalization

修改:20260424235623000

迭代 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 product

alpha=('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. 证明“左侧局部交换”可被归约为对左侧串本身的重排,不要求左右半边独立可判定。