分类: 技术文章

经过整理的原理说明、源码分析与专题文章。

  • 固定功能、可编程与可重构:三种计算方式如何区分

    作者:lihao技术文章发布:可重构计算与软硬件协同 · 第 02 期

    以8位函数为共同任务,比较改变参数、改变指令与改变数据通路;从语义、合法性和总成本评价方案,避免把芯片标签当成性能结论。

    先问“什么可以改变”,再看芯片名字

    固定功能电路也可能允许修改系数;可编程处理器也有固定硬件;可重构器件里又可能嵌入CPU和固定DSP。若直接把ASIC、CPU、FPGA各贴上一个绝对标签,会漏掉混合系统。

    更有用的区分是:任务改变时,用户可以在哪一层做选择?固定功能主要在预先设计的操作范围内换参数;指令可编程在已有执行结构上换程序;可重构在既有资源范围内改变逻辑、操作与连接。三者描述的是可变能力,不是性能名次。

    固定一个小到能穷举的共同任务

    约定输入x为0到255的整数,输出为f(x)=(3x+1) mod 256。模256意味着只保留对应8位无符号结果;例如x=255时,766除以256余254。若任务改为饱和算术,结果就不同,必须另立契约。

    固定功能方案可以把这个函数直接做成专用逻辑,可能允许或不允许改系数;可编程方案用读取、乘法或移位加法、加一与输出等指令实现;可重构方案把对应操作或等价逻辑映射到资源,并配置连接。

    三条路径若都输出相同256项表,说明在这组有限输入下功能等价。它不能说明延迟相同,也不能说明系统对输入节拍、握手与错误的处理相同。功能关系只是契约的一部分。

    任务变化时,分别要改什么

    若新函数变为g(x)=(5x+2) mod 256,专用电路若没有设计系数接口,可能需要改硬件;若本来允许a、b参数,则可能只改参数。不能因为名字叫固定功能,就忽略其实际配置范围。

    可编程处理器通常可以换指令或常数;可重构实现可能调整逻辑、连接、流水与资源复用。若在FPGA里放一个软核CPU,运行时只是换它的程序,那么这次任务变化发生在指令层,并不等于每次都重构了整个数据通路。

    Intel对CPU、GPU与FPGA的架构介绍有助于识别指令执行与空间数据流的典型差异。[1] 但其中厂商的优势描述不能脱离负载、器件和实现条件变成普遍结论。

    比较方案时,别跳过总成本

    维度 需要核对的问题
    功能与数值 位宽、舍入、溢出与边界输入是否一致
    资源与合法性 操作、容量、连接与时序能否实现
    启动与变化 编译、配置、装载和缓存失效花多少
    运行 端到端延迟、吞吐、搬运与同步
    生命周期 设计、验证、升级、维护与生产规模

    固定功能可能为稳定任务优化,也可能因新需求而不适用;可编程路径覆盖广,但具体效率取决于指令与存储体系;可重构路径提供结构选择,也增加映射搜索、配置与验证工作。必须用真实候选比较,不能只比较三类抽象名称。

    若只执行几次小任务,准备开销可能主导;若有长时间稳定数据流,流水与数据驻留可能更重要。即使局部算术更快,主机搬运和排队也可能吃掉收益。没有端到端测量,就不应给出加速倍数。

    把功能检查与性能检查分开

    本例可枚举全部256个x,比较3x+1与x+(x<<1)+1在模256下是否一致。这是在数学整数模型下检查两种表达,尚未验证某种语言中的移位边界或真实电路。

    进一步落到硬件,需要明确目标、工具版本、综合约束与接口,再取得映射合法性和设备结果。模拟器通过、综合通过、时序通过和板上执行通过,各自支持不同结论;不能互相替代。[2]

    本篇没有执行FPGA综合、布局布线或板卡实验。穷举表覆盖的是规定的8位函数,既没有测功耗,也没有证明哪种硬件在真实产品中更优。

    把功能等价写成可检查的有限命题

    对本篇函数,参考定义是f(x)=(3x+1) mod256,候选形式为h(x)=(x+(x<<1)+1) mod256。对整数x,x<<1在这个数学记号下表示2x,因此两式代数上相同;枚举0至255又能独立检查实现这两式的教学脚本是否一致。

    这里特意把数学模型和语言执行分开。如果在某种语言中使用有符号类型,移位、溢出或整数提升的规则可能改变实际行为;如果硬件在每一步饱和而不是最终取模,等价关系也不成立。证明必须指明运算语义,而不是仅比较操作符的外形。

    再把功能提升到流接口,需要规定输入有效时刻、输出对应关系和复位。两套电路在每个x的算术结果相同,却可能因为一套丢掉背压下的输入而在系统上不等价。接口协议不是额外装饰,而是可观察行为的一部分。

    所以“256个值都对”能证明的,是该有限输入域、该纯函数定义下的结果一致。时序、状态与协议需要另一个明确定义的验证空间。

    同一负载下,准备成本怎样改变选择

    构造两个候选,全部时间单位相同且假定串行。通用方案准备2、每次计算10;可重构方案准备102、每次计算6。执行N次的总成本分别为2+10N和102+6N,后者在N>25时才更低。

    如果每次更换输入形状都要重新准备,N应该按同一配置可复用的次数计算,不能拿全年请求总量摊销一次配置。若准备阶段可与其他工作重叠,也应在真实依赖图上计算关键路径,而不是把所有时间盲目相加。

    再设可重构方案每次额外搬运5,成本变成102+11N,在这个假设下无论N多大,都不会优于通用方案。局部算术从10降到6,仍不足以支持端到端收益。这是一个明确反例,说明比较必须包括边界成本。

    这些数是用于检验推理的构造条件,没有预测某种器件的实际表现。真实选择还应覆盖冷启动、稳态、尾部时延、失败率和维护投入。某项平均收益若依赖极高复用而应用请求恰好不满足,结论就应撤回。

    混合系统的边界,可能比单元内部更重要

    当CPU调度、固定引擎和可重构区域共同处理任务时,数据由谁拥有、何时可复用、缓存何时可见、错误由谁观察,都需要约定。加速器返回一个句柄,不等于结果已经可以被下游读取。

    设CPU提交配置与输入后立即重用输入缓冲,而设备尚未完成读取,算术单元即使完全正确也可能得到错误数据。反过来,CPU等待过于保守,又可能消除原本可重叠的执行。正确同步与高效同步需要一起设计,但验证责任不能被性能目标替代。

    这一层也决定软件复用程度。共同的函数语义可能可复用,布局、路由、事件与装载产物却未必相同。一个通用接口若把全部特殊情形都藏在实现中,用户就难以理解失败与成本;若暴露每个细节,又会增加使用负担。

    评估时可以把契约拆成语义、资源和部署三类,再逐项列出支持与不支持。这样,“可编程”与“可重构”才成为具体能力描述,而不是对兼容性或性能的空泛保证。

    成本相同之外,还要比较能否持续演进

    一个实现对当前f(x)很高效,若下个月需要修改数值格式、增加状态或接入新接口,成本可能完全不同。固定功能的设计与制造成本、可编程软件的升级成本、可重构映射的验证成本,应按预期变化与产量分别计算,而不是只看一次运行。

    构造一个决策:工作负载长期稳定且产量很高,专门化投入可能被摊销;变化频繁且数量有限时,可编程或可重构方案可能减少重新设计成本。但如果可重构工具每次都需大量人工收敛时序,所谓更新灵活性也可能被软件工作抵消。

    因此可以要求第二个独立任务作为复用检验:沿用同一功能检查框架、错误分类与部署流程时,究竟保留了多少,哪些部分仍需重写。复用声明应同时列出不能复用之处,不能只统计共用代码行。

    这种生命周期比较不会给出跨任务永远正确的赢家。它把“灵活”转成可问责的变化成本,把“专用高效”转成限定负载下的收益,也使硬件选择与工程交付建立真实联系。

    选择可变层次,而不是选择一句口号

    最强反例是一个混合SoC:CPU负责控制,固定引擎处理成熟任务,可重构区域处理变化的数据通路。它没有服从三选一,却可能更符合需求;代价是跨单元接口、内存一致性与调试更复杂。

    实际选择应从变化频率、输入分布、可承担的准备时间与维护成本出发,再验证候选。判断“可重构改变了什么”,最终要落到资源和契约,而不是“硬件更灵活所以一定更快”。

    来源、证据与阅读路线

    1. Intel:Compare Benefits of CPUs, GPUs, and FPGAs for oneAPI Workloads,架构差异;不采用无条件性能外推
    2. Intel oneAPI Programming Guide 2023.2,FPGA Flow,不同产物与验证阶段

    证据范围:有限位宽算术等价与成本算例已核对;三种实现的真实吞吐、能耗与开发成本仍须在相同任务和目标系统中验证。

    版本1.2 · 2026-10-18:完成事实、条件与引用复核,逐篇明确证据方法;有实质缺口处补齐推导、反例或原题。原网址与首次发布日期保留。

  • 可重构计算到底是什么?“可重构”究竟改变了什么

    作者:lihao技术文章发布:可重构计算与软硬件协同 · 第 01 期

    从两输入查找表的完整真值表出发,解释配置怎样改变逻辑与连接;明确功能模型、映射结果与真实性能证据的不同层级。

    换一个程序,与换一条数据通路

    CPU可以换程序,FPGA也可以改变计算功能,它们的区别不能简单说成“一个可变,一个不可变”。关键在于可改变的层次:是在相对固定的指令执行结构上换指令序列,还是配置逻辑资源、操作选择与连接方式,使数据经过不同的计算结构。

    可重构计算利用可配置资源组织计算。FPGA是重要实例,粗粒度可重构阵列(CGRA)则常以字级功能单元与互连为配置对象。两者粒度、存储与调度方式不同,不能互相代称。

    这里的改变不意味着芯片制造后的晶体管任意移动;配置是在已有物理资源与可用连接之内选择。AMD 7系列UG474文档展示可编程互连如何连接逻辑块、DSP与块RAM等资源。[1]

    用一个两输入查找表看见配置

    构造一个两输入查找表,输入a、b各为0或1,地址约定为2a+b。表中只有4个位,分别给出输入00、01、10、11时的输出。

    输入ab AND配置 XOR配置
    00 0 0
    01 0 1
    10 0 1
    11 1 0

    按上述地址顺序,写入[0,0,0,1]实现AND,写入[0,1,1,0]实现XOR。输入仍是a、b,改变的是表所定义的逻辑函数。这个模型只有组合逻辑,没有时钟、寄存器、布线延迟或配置接口。

    它解释了查找表的基本思想,不对应某块真实器件的配置位排列。实际FPGA的LUT规模、分割方式、存储模式和连接规则,应按目标系列文档核对,不能把这4个位直接当成可下载bitstream。

    不只改变操作,还要安排数据怎么走

    设想先执行y=a×b+c,再执行z=y-d。空间映射可以把乘法、加法和减法放到不同单元,并安排中间结果的通路;也可能复用少量单元在多个周期内完成。选择由资源、依赖与输入输出带宽共同约束。

    可配置的操作不等于任意连接。两个节点分别能放进阵列,不保证它们之间有满足要求的路由;单个节点的延迟满足,也不保证整条路径时序收敛。存储端口、缓冲容量与同步同样可能限制合法性。

    Intel的FPGA编程指南把FPGA编译与CPU/GPU指令路径作了区分,说明器件映像与模拟器映像等产物不同。[2] 这些产物的区别也意味着,模拟执行成功不能代替实际实现与设备执行。

    配置发生在什么时候,会付出什么成本

    有些任务在开始运行前整体配置;有些架构允许运行中切换上下文或局部配置。动态部分重构并不意味着相关数据路径无条件不停顿,必须处理接口隔离、状态、配置完成与恢复。

    假设配置一次花100个时间单位,通用路径每次10,可重构路径每次6,忽略其余成本且配置只做一次,则100+6N<10N要求N>25。第25次只是持平;若每次都重新配置,就可能一直更差。

    这只是串行成本的假设算例,不是器件测量。真实系统还要计编译、装载、搬运、同步、缓存与资源竞争;有重叠时不能把各阶段简单相加。收益必须与同一任务、同一精度及可用基线比较。

    资源都够,为什么映射仍然可能不合法

    构造一个极小阵列,只有P0和P1两个计算单元,每周期各执行一个操作,二者有一条单向连接P0→P1。任务是先算m=a×b,再算y=m+c。假设P0能乘、P1能加,且乘法结果下一周期可用,那么m放P0、y放P1是一个候选安排。

    若把两者交换,算术资源数量仍够,但P1不能乘,首先违反操作能力;即使改成两者都会乘加,若中间结果需要P1→P0而阵列没有反向路径,也仍不合法。资源总数只是必要条件之一,不能替代操作支持、连接方向和时间约束。

    若增加第三个操作z=m+d,P1可能要在不同周期复用。此时还要问m是否被保留、扇出或重读是否允许、两个消费者是否争用输入端口。计算图上两条边存在,不意味着物理结构能在同一周期同时传输它们。

    这个两单元模型完全是本文构造,不代表某款CGRA。它揭示的检查次序可以复用:覆盖全部操作→满足数据依赖→满足资源与端口占用→找到合法路由→确认状态生命周期。每一项都应能给出失败原因。

    延迟、启动间隔与吞吐,为何要分别报告

    设一条理想流水线有乘法和加法两级,每级延迟1周期,级间寄存,输入输出都不阻塞。第一项结果在2周期后出现;填满后可以每周期产生一项,即启动间隔II=1。处理N项的理想周期数为2+(N-1),不是2N。

    另一种实现只用一个能乘或加的单元,按顺序为每项做两步。忽略额外开销时,单项延迟也可能是2周期,但每项占用2个操作槽,吞吐上限不同。相同单项延迟,不等于相同稳态吞吐。

    实际系统还要考虑时钟频率、访存、背压与依赖。若前一项输出参与后一项计算,递归依赖可能限制II;若输入每两周期才到一项,计算流水再深也不能凭空得到每周期一项的端到端吞吐。

    在每次启动处理一项、不受输入输出和其他瓶颈限制的稳态模型里,吞吐上限可写为 f_clk/II。[3] 构造方案 A 的时钟为 100MHz、II=1,上限是每秒 1 亿项;方案 B 为 300MHz、II=2,上限反而是每秒 1.5 亿项。可见 II 更小并不自动代表每秒结果更多。这里的频率是假设,不能在布局布线之前当成已经达到的器件频率;真实端到端吞吐仍要受访存、背压、批量和计时边界约束。

    综合报告给出的延迟与II,需要与约束和仿真条件一起读;设备测量又需要明确计时边界。本文只有理想离散时序推导,没有获得任何器件的频率、面积或能效。

    配置灵活性为何会转化为软件问题

    更多操作选择、路由和存储布局,增加了可能的实现方案,也扩大搜索空间。编译器不仅要找一个合法方案,还要在有限编译时间内找到足够好的方案,并对失败给出可解释诊断。

    合法性检查与性能估计可以分离。检查器能拒绝容量超限或不存在的路由,却未必知道两个合法方案谁更快;成本模型可以排序候选,也不能替代正确性验证。把一个预测分数高的候选当作“验证通过”,混淆了两种责任。

    若某种自由度只在极少数负载改善结果,却显著增加搜索与回归成本,它未必提升系统总价值。反例也应保留:关键工作流可能确实需要这项自由度,此时不能只为简化软件就删掉能力。决定需要工作负载证据与维护成本,而非抽象地追求最多可配置项。

    可重构计算的核心问题由此从“能不能变”推进为“哪些变化值得支持,工具能否稳定利用,验证能否覆盖”。这是评估硬件与编译协同的起点。

    从资源下界看II:先问理论上能否达到

    继续用离散时序模型。若每个输入需要2次乘法,阵列只有1个每周期可接收一次新乘法的单元,忽略依赖与通信,资源就要求平均至少每2周期接收一个输入,即II≥2。增加加法单元不能解除这个乘法资源下界。

    若增加第二个乘法单元,资源下界可能降到1,但路由、存储端口或循环依赖仍可能保持更大II。下界是必要条件,不是可实现调度;找到满足它的候选,还需逐周期检查占用与依赖。

    另一方面,一个乘法单元若本身是多级流水、每周期可接收新输入,其“延迟3周期”不等于每3周期只能启动一次。把延迟与发射能力混用,会错误估算资源下界。架构模型必须同时记录操作延迟、启动能力、端口与数据可用时刻。

    这类简单下界有筛选价值:若候选声称低于已明确的资源或依赖限制,应先检查模型或报告口径;若仅达到下界,也不能跳到真实性能结论,因为频率与外部系统尚未纳入。

    验证应分成哪些层级

    第一层是功能模型:输入与输出符合定义。第二层是映射合法性:资源、容量、连接与依赖满足目标约束。第三层是实现:综合、布局布线与时序结果。第四层才是设备执行的正确性、延迟、吞吐与能耗等测量。

    本文的两输入表可以穷举全部4种输入,检查AND和XOR的函数值;它仍然不证明任何硬件配置文件正确,也没有资源利用率或芯片性能结果。证据等级要跟着实际完成的层级走。

    最强反例是:许多任务变化快、规模小,重构成本可能超过计算节省。这个反例不否定可重构性本身,而是限制其适用域。下一篇将同一任务放到固定功能、可编程与可重构三个层次下比较。

    来源、证据与阅读路线

    1. AMD 7 Series FPGAs CLB User Guide,UG474 v1.9,2025-04-01,Interconnect Resources
    2. Intel oneAPI Programming Guide 2023.2,FPGA Flow;本文只引用该固定历史版本的流程定义
    3. AMD Vitis High-Level Synthesis User Guide,UG1399 v2021.2,Performance Metrics Example:延迟与启动间隔的周期定义;本文频率数字为构造算例

    证据范围:LUT真值、启动间隔与配置摊销按明确模型核对;频率为假设,没有完成器件映射、时序收敛或芯片性能测量。

    版本1.2 · 2026-10-18:完成事实、条件与引用复核,逐篇明确证据方法;有实质缺口处补齐推导、反例或原题。原网址与首次发布日期保留。

  • 写代码和做工程有什么区别:局部实现与系统责任

    作者:lihao技术文章发布:工程师方法论 · 第 02 期

    从一次格式转换扩展到可维护交付,说明错误传播、可观测性、版本、发布与恢复为何必须进入工程完成标准。

    函数返回正确,任务就结束了吗

    一个转换函数在正常样例上输出正确,但程序把结果写到一半时磁盘满了,下次运行又误把半成品当成完整文件。函数的局部计算可能没有问题,用户却已经失去可信的结果。

    写代码是实现行为的重要手段;做工程还要承担该行为进入完整环境后的责任。二者不是职业高低之分,也不是说程序员不做工程,而是看讨论范围:从局部输入输出,扩展到运行、交付、变化和失败。

    本篇延续上一篇的假设性文件转换任务,所有事故情境都是构造案例,没有虚构真实项目经验。

    先画出完整路径,再决定代码边界

    用户选择输入→解析→转换→校验→写入→通知完成。每一段都有接口,数据、错误和资源的责任必须沿路径传递。解析器拒绝未知编码,调用方就不能把拒绝当成空数据继续写“成功”。

    局部函数可以承诺合法记录转成合法记录;系统还要保证用对版本、实际读到全部输入、输出未损坏。单元测试覆盖局部性质,集成与端到端检查覆盖连接后的行为;任何一层都不能自动替代另一层。

    NASA关于产品实现的讨论把验证与最终用途确认分开,也强调集成与转移过程。[1] 这里借用的是责任分解方法,不把一个小工具冒充航天工程的复杂程度。

    失败发生时,结果应该处于什么状态

    一个候选设计是先写临时产物,校验通过后再提交为正式结果。若写入失败,保留原输入,标记失败并避免半成品被误读。实现时还要检查文件系统与平台语义:单个文件重命名的保证不能直接推广为整个目录树的事务。

    重试也不是“再跑一次”那么简单。若操作会发送通知或覆盖已有输出,必须考虑重复副作用;若恢复点记录不可靠,断点续跑可能跳过未完成的记录。应明确一次任务的身份、已完成范围与重复运行的规则。

    这是一份设计评审候选,不是已实现并验证的恢复机制。停止条件包括:无法确认输出完整性、输入版本发生变化、校验规则不兼容;此时应停止提交,而不是用成功提示遮住不确定状态。

    可观测性,是让故障变得可定位

    只写“转换失败”通常不够。可以记录任务版本、输入标识、处理阶段、已完成数量与错误类别;涉及私密文本时,不应为了诊断把完整内容写进公开日志。诊断信息也有最小化与权限边界。

    用户需要知道结果是否完成,维护者需要知道在哪里失败。两者的输出可以不同:界面给出明确下一步,内部日志保留定位所需细节。暴露堆栈不是完整用户体验,隐藏所有原因也不是稳健设计。

    指标同样要和目标对应。总耗时、失败比例、峰值内存可能有用;若只记录平均值,少数严重卡顿就可能被掩盖。选指标的目的是检验承诺,而不是装满一个仪表盘。

    修改与发布会创造新的责任

    格式从v1变成v2时,要知道旧输入能否继续读取、新输出由谁消费、是否需要迁移、怎样验证兼容和回退。代码在开发机运行,不代表依赖、权限与配置在部署环境都满足。

    Google SRE的Release Engineering章节讨论可重复构建、发布流程与配置管理。[2] 对本例可缩减为:记录源码版本与依赖;用固定样例核对产物;先在隔离输出目录运行;保留可重新执行的上一版本与原输入。

    回退也有边界:旧程序未必能读取新版本已经生成的数据。若迁移不可逆,回退代码本身不够,还需经过验证的数据恢复方案。不能写下“有回滚”三个字,就宣称恢复已验收。

    把错误处理写成状态机,遗漏就更容易看见

    为转换任务定义Created、Running、Validated、Committed与Failed五个状态。Created尚未处理,Running可能有临时输出,Validated表示约定检查已通过,Committed才允许把结果对外标为完成,Failed记录失败原因与可恢复范围。

    正常路径是Created→Running→Validated→Committed。解析或写入错误可从Running进入Failed;校验错误可从Validated之前进入Failed。若还没校验就直接写“完成”,系统绕过了完成条件;若进入Failed后仍暴露临时目录为正式结果,错误状态就没有隔离副作用。

    状态机不要求必须引入复杂框架。一份清晰枚举与几条转换规则就可能足够。重要的是每条转换的守卫条件与持久化时机:程序崩溃后,仅凭内存里的“已校验”标志,下一次运行未必能安全恢复。

    例如先把临时文件替换成正式结果,再写入 Committed 记录。若替换已经发生、记录写入前进程崩溃,重启后只看状态记录会把这次任务误判为未提交;盲目重跑又可能重复通知或覆盖结果。把顺序倒过来也不自动正确:若先写 Committed、再替换失败,就会宣称一个并不存在的结果已完成。

    设计必须规定正式产物、任务身份与完成记录之间怎样对应,以及恢复时怎样核对并消除这个不确定窗口。这里指出的是协议责任,不提供适用于所有文件系统和外部副作用的原子提交实现。

    它也帮助定义不变量:原件始终不被写入;只有Committed结果可供下游消费;相同任务身份不能同时产生两个互相矛盾的正式结果。验证可以围绕这些性质设计,而不只是逐个函数覆盖。

    重试、幂等与“恰好一次”不是同一个承诺

    如果某个步骤执行完,但确认消息丢失,调用方无法仅凭超时判断它没发生。直接重试可能重复写文件、重复记账或重复发送通知。超时描述的是等待结果的状态,不能自动推出远端没有副作用。

    对本例,可以给输入清单、转换版本与参数形成任务身份,并把正式输出与该身份绑定。相同任务再次到来时,若已经存在可验证的完成记录,就返回已有结果;若只有临时产物,就按恢复策略处理。输入内容改变而路径相同,不能误用旧结果。

    幂等表示重复操作在规定语义下不会增加新的效果;它依赖具体操作与状态,不是接口名字里加一个request_id就成立。“恰好一次”若覆盖多个外部系统,还需要讨论原子性与恢复边界,本篇不靠一个本地示例承诺它。

    这种分析说明工程责任为什么会超出局部实现:函数可能正确完成一次调用,而完整协议仍然在重复、丢失与中断时产生错误。

    从补丁到可交接版本,还应留下什么

    交付记录可以保持简短,但至少包括:源码与构建身份、依赖与配置、输入输出格式、支持范围、启动方式、验收证据、失败处理及回退限制。任何一项若只存在于开发者脑中,接手者都要重新支付发现成本。

    变更评审还要看兼容方向。新版本能读旧输入,是向后读取兼容;旧版本能否读新输出,是另一件事。只升级程序而改变持久化格式,可能让回退失败。发布时需要说明迁移是否可逆,以及旧数据和配置在哪里保留。

    有些证据可自动取得,有些必须人工确认。自动化适合重复、明确的性质;真实使用目的、可理解的诊断与组织责任仍需要评审。测试通过率不能代替完整验收,也不能因不能自动化就放弃记录。

    工程完成不等于永不失败,而是当前承诺有依据、失败可被识别、变化有路径。对一次性任务可缩减流程,但不能把不可逆风险留给用户在故障时才发现。

    可靠性投入,也需要停止条件

    给一个一次性、可重建的只读转换任务引入多机调度、复杂事务与完整监控平台,可能比原问题更难维护。工程责任不是无限增加防护,而是识别失败的概率、影响与恢复成本,再选择足够的措施。

    可以先列故障模式:输入非法、磁盘满、进程中断、版本不匹配、重复运行。对每一项问用户会失去什么、能否重新运行、能否检测错误、恢复需要多久。若原件保留且输出可重建,临时输出隔离与清晰失败报告可能已经承担主要风险。

    若任务进入多人长期使用、写入不可逆外部状态或承担更高影响,再提高审计、隔离与恢复证据。停止条件可以是:剩余风险已被明确接受,新增机制不再降低主要损失,或维护成本超过可避免损失。没有实际概率与成本数据时,应说明这是定性判断,不编造精确ROI。

    因此,写代码与做工程的差异不在文档厚度,而在是否对实际使用后果负责。一个很短的实现也能有清楚契约;一个流程繁多的项目也可能仍没回答失败由谁发现、谁来恢复。

    怎样防止工程变成无止境加流程

    最强异议是:这些事项会不会让一个小工具迟迟不能交付?答案取决于风险。一次性、可重建、原件只读的任务可以保持简单;长期服务、多人使用或不可逆写入需要更严格的证据。流程应随影响范围调整。

    一个合适的完成标准是:正常路径满足需求;关键失败有明确状态;版本与运行方式可重现;接手者知道支持边界;恢复方案与未验证项分别列清。若某项不适用,就说明理由,不机械补表。

    工程责任的目标是降低使用与变化的总成本。写出功能让工具开始有用,把条件、证据与恢复说清,才让它更可能长期可用。

    来源、证据与阅读路线

    1. NASA Systems Engineering Handbook,第5章,集成、验证、确认与移交
    2. Google Site Reliability Engineering,Release Engineering,构建、版本与发布流程

    证据范围:任务状态、重试与恢复场景为构造的设计分析;尚未实现所述转换工具,也未验证文件系统持久化、并发或故障恢复行为。

    版本1.2 · 2026-10-18:完成事实、条件与引用复核,逐篇明确证据方法;有实质缺口处补齐推导、反例或原题。原网址与首次发布日期保留。

  • 工程师到底在解决什么:需求、约束、权衡与可验证结果

    作者:lihao技术文章发布:工程师方法论 · 第 01 期

    以一个明确标为假设的文件转换任务,把模糊愿望变成输入输出、约束、验收和回退条件,展示工程决策怎样留下依据。

    “把它做快一点”还不是完整问题

    有人提出:做一个工具,把一批文本文件转换成另一种格式,越快越好。立即写一个循环当然可以开始,但我们还不知道:允许哪些输入,失败后原文件怎样处理,输出如何判定正确,速度是首个结果时间还是整批完成时间。

    工程师要把需求放到现实约束里,构造并交付可验证的结果。实现算法是其中一部分,界定目标、识别风险、比较方案、验证和维护也属于工作。NASA系统工程手册把需求、设计、实现、验证与确认组织为相关过程,可作为方法参考。[1]

    下面全部是构造案例,不是本人或任何企业的项目经历;数字是为说明决策而设定的假设,不是实测。

    先写任务约定的骨架

    假设需求是:把UTF-8文本中的某种字段结构转换为新格式。输入为一个明确文件清单,总量上限100MB;输出写入新目录,默认不改原件;转换失败必须报告文件、原因和已完成范围。

    “保留信息”也要具体:合法输入的字段值与顺序应按约定保留;未知字段不得静默丢弃;重复键、无效编码和过长记录要有明确处理。空文件应得到空结果还是错误,需要事先决定。

    验收不能只写“运行成功”。可以列出普通记录、空输入、边界长度、重复键、非法编码、磁盘写入失败等案例,规定每类预期。需求中的每一项重要承诺,应能对应到一个检查或明确的人工评审。

    约束和目标不要放在同一张模糊分数表里

    约束是方案必须满足的条件,例如不得覆盖原件、必须能识别不支持的编码;优化目标是在合法方案之间比较的指标,例如处理耗时和内存占用。不能用“快10%”抵消“偶尔悄悄丢数据”。

    若提出“1秒内完成”,还要说明输入大小、机器、是否包含读写、冷缓存或热缓存,以及多少次运行满足。否则不同测试条件下的数字没有可比性。对于本案例,我们只拟定评估方法,不声称已经达到某个耗时。

    NASA手册区分verification与validation:前者检查产品是否满足规定要求,后者关注产品能否实现预期用途。[2] 若用户真正需要增量处理,而我们把一次性批量转换做得完美,也可能通过了若干测试却没解决需求。

    权衡必须放在同一任务与基线上

    候选A一次把全部文件读入内存,实现较简单;候选B按记录流式处理,能限制峰值内存,但错误恢复和跨记录状态可能更复杂。先检查两者是否都满足语义,再在同一输入、配置和正确性要求下比较。

    若总量与内存预算很小,A可能足够;若最大输入无法装入内存,A就不是合法候选,不能继续拿平均速度争胜。若B让定位错误更困难,就要把诊断与维护成本一并记录。

    最强反例是:需求随时会变,何必先写?回应不是冻结一切,而是保留最小可修改约定。没有约定也会发生选择,只是选择被藏在代码和个人记忆里;一旦变化,很难知道哪些行为属于承诺。

    一份真正能复用的决策记录

    字段 本例填写方式
    目标与用户 谁用转换结果,保留哪些字段
    约束 原件只读、输入上限、错误可定位
    候选与基线 整批读取、流式读取;同一语义
    证据 样例、负例、资源测量;未做则留空
    停止与回退 输出校验失败不替换既有结果
    后续责任 版本、维护者、已知不支持项

    这张表不是要求每个小任务写厚报告,而是让关键承诺与证据有位置。对低风险、一次性工具,几行记录可能足够;对长期服务或安全关键系统,证据深度需要提高。

    把模糊需求改写成可以否定的承诺

    对前面的转换工具,先写三条具体要求。R1:在合法输入上,输出记录数、字段值与顺序符合映射规则。R2:处理过程中不改动输入文件。R3:遇到非法编码或不支持结构时,任务报告失败,不能留下被标为成功的正式结果。

    分别设计证据:R1使用独立预期文件或不同实现作对照;R2以只读方式打开输入,检查文件及所在目录的写入权限、全部写入路径和写入尝试;R3注入非法输入与写入失败,检查退出状态和输出目录。运行前后哈希在正确读取同一份完整输入、检查窗口内无并发修改、哈希实现正确且不考虑碰撞的假设下,只能支持两个检查时刻的字节一致,不能单独证明处理中从未改动。只读打开一个句柄也不能阻止经其他句柄或目录替换写入,因此保护承诺还要结合权限与运行条件。单一“进程退出0”不能覆盖三条要求。

    NASA的需求编写指南要求语句清晰、可核验,并避免fast、easy等没有操作定义的词。[3] 对本例而言,“快”可以先作为愿望保留,直到明确负载、机器与时延指标;不应随手填一个没有用户依据的秒数,制造虚假的精确性。

    还要区分需要与设计限制。用户需要不丢数据,不一定需要某一种数据库或队列;若过早把偏爱的实现写进需求,会排除其他可行方案。只有外部兼容、安全或环境确实要求时,才把具体技术设为硬约束。

    比较方案,先检查可行域,再讨论最优

    假设内存预算是64MB,最大输入100MB。整批读取方案如果确实需要把完整输入和输出同时驻留,峰值可能超过预算,就应先判为不满足约束;不能用平均输入只有1MB来绕过已经承诺的上限。

    流式方案也不自动可行。若转换需要全局排序,单条记录处理后立即写出可能不满足输出顺序;若存在跨记录引用,就可能需要额外索引或多遍处理。可行性来自任务语义与资源条件共同满足,不来自“流式更先进”的标签。

    在合法方案中,可以比较耗时、内存、实现复杂度与维护成本。若A比B快但占更多内存,且二者都在预算内,通常不能不交代偏好就宣布A全面更优。应先给出决策原则,例如优先满足交互时延,再在剩余方案中降低维护成本。

    如果没有一个方案同时满足全部硬要求,应回到需求方暴露冲突,讨论缩小输入、调整时限或增加资源。不能在实现中偷偷降低要求,交付后再用“工程总要权衡”解释。

    一个完整的失败—修订闭环

    假设初版采用逐文件写输出,正常样例全部正确,却在第37个文件遇到非法编码,前36个已写入。若需求只承诺每文件独立提交,这可能是合法部分成功;若需求承诺整批要么全有要么全无,就是缺陷。错误性质首先由契约决定。

    修订可以选择整批暂存后统一提交,也可以把用户可接受的“部分成功”明确纳入需求。前者增加临时空间与提交复杂度,后者增加用户处理未完成文件的负担。两者不是纯代码风格之争,而是不同使用承诺。

    记录应写明:触发输入、受影响输出、原要求、原因、选择、回归用例、恢复办法。若此前已交付错误结果,还要确定哪些使用者或产物受影响;把补丁合入并不自动修复历史数据。

    这个闭环的价值在于留下可追溯的判断。后来的维护者能看出为什么选择某种行为,也能在约束变化时重新评估,而不必从零猜测原设计动机。

    验收矩阵要填具体结果,不能只填“有测试”

    对R1的字段映射,写清输入含哪些字段,预期输出是什么,采用人工审查还是独立实现比较;对R2的原件保护,列出正常、失败和中断三个路径;对R3的错误报告,列出错误码、失败文件标识与是否存在正式输出。

    证据表应允许“未验证”这一状态。只有测试文件存在,还没有说明它被执行;只有执行日志,也要确认实际输入、断言与被测版本。覆盖率可以帮助发现空白,却不能证明断言本身正确或需求没有遗漏。

    若一条要求无法设计任何检验,先检查它是否含糊、不可达或层级不对。有些用途确认适合用户试用或评审,不必强行写成单元测试;但仍要明确参与者、问题、观察与结论,而不是留一个笼统的“体验通过”。

    验收的最终输出应是承诺与证据的对应关系。它让未完成项可见,也使下一次需求变化能定位受影响检查。指标越多不必越可靠,关键是重要承诺有没有独立、适当的支撑。

    交付结果,也交付判断的边界

    本例尚未实现工具,所以可交付的是需求与验收模板,不能把它登记为已通过测试的产品。真实实施时应保留输入样例、运行命令、原始结果和失败,并由独立检查核对输出。

    一个工程结果值得信任,不仅因为它在某次演示中工作,还因为别人知道它满足哪些条件、如何发现失败以及怎样恢复。下一篇会继续讨论:写出局部功能之后,系统责任还包括什么?

    来源、证据与阅读路线

    1. NASA Systems Engineering Handbook,第4章:利益相关方期望、需求与设计过程
    2. NASA Systems Engineering Handbook,第5章:产品实现、验证、确认与移交
    3. NASA Systems Engineering Handbook,Appendix C:How to Write a Good Requirement,需求清晰性与可核验性

    证据范围:本文以构造案例讨论需求、方案取舍与验收设计;尚未实现所述转换工具,也未执行性能测量或故障注入验证。

    版本1.2 · 2026-10-18:完成事实、条件与引用复核,逐篇明确证据方法;有实质缺口处补齐推导、反例或原题。原网址与首次发布日期保留。

  • 数字到底是什么?为什么 1 不是一根棍子

    作者:lihao技术文章发布:数学与物理直觉 · 第 02 期

    通过配对计数、不同进制和测量单位,区分对象、数目与记号;说明“一个什么”为什么是计数前必须回答的问题。

    棍子会断,数1会不会跟着断

    桌上放一根棍子,纸上写一个1。把棍子折成两段,桌上物体的计数可能改变;纸上的墨迹擦掉,数字记号消失了。但这些变化并不意味着数学中的数1被折断或擦掉。

    日常所说“数字”常混指三个层面:被数的对象,表示数量的数,以及书写数的记号。本文用“数”指数量或结构中的对象,用“数码、数词或数字记号”指表达形式;这是一项说明约定,不强迫所有日常用语都如此严格。

    区分它们,才能回答为什么一根棍子可以代表1,却不是数1本身。代表关系允许换材料:石子、刻痕和手指都可以用于计数。

    计数先选择单位与对象边界

    两只杯子、两本书和两次敲门,没有相同的物理材料,却可以分别与两个位置一一配对。对于有限集合,如果能和{甲、乙}建立一一对应,我们就可以说它有两个元素。

    这个做法抓住“同样多”,但没有在本篇解决全部自然数基础。集合论可以给出一种构造,其他理论也能采用别的基础;数是否就是某个特定集合,仍属于进一步的哲学问题。[1]

    再看那根被折断的棍子:若单位是完整原棍,它仍可能算一根原物的残件;若单位是分离的木段,就有两段。不是算术矛盾,而是计数对象与同一性条件改变。先问“一个什么”,才能确定该数哪些对象。

    把数与写法分开,进制就不神秘

    十进制的10与二进制的10写法相同,数值却分别是十与二。前者是1×10+0,后者是1×2+0。数十三可以写成十进制13,也可写成二进制1101,即8+4+1。

    进制规定位置的权重,数码是用于写数的符号。换进制通常改变表示,不改变被表示的整数。罗马数字、中文数词与现代位置记数法也有不同规则,不能只盯着字形判断数量。

    欧几里得《几何原本》第VII卷先定义单位,再把数界定为由单位组成的多。[2] 在这种古典安排里,单位与数的地位不同;现代通常把1也作为自然数。这个差异提醒我们,不要假定所有时代的“数”概念完全一样。

    计数与测量,又有什么不同

    计数杯子得到3,通常是一个无量纲的基数;测量棍长得到1米,表达的是某个长度与所选单位的关系。相同长度也可写成100厘米,数值改变,长度并未改变。

    两根各1米的棍子,只有在首尾对齐、不重叠且讨论总长度时,才自然相加为2米。若问把它们捆在一起有多长,结果不由1+1单独决定。算式正确与对象如何组合,是两个层次。

    物理长度还伴随测量不确定性。标称1米并不保证无限精度;若每次测量受刻度与方法影响,就要保留误差来源。有限集合的精确计数与连续量的有限精度测量,不能因为都写数字就混为一谈。

    零、负数与分数为什么值得单独解释

    空集合提供一种“没有元素”的计数情形;负数可以用来表达方向、差额或整数结构;分数可以表达分割后的比例或两个量的比。它们并非都能直接靠“拿几根棍子”解释。

    这说明最初的计数直觉是入口,而不是整个数系的完整定义。扩展数系时,需要说明新对象、相等关系和运算规则,以及旧规则在什么条件下保留。不能只说“现实里看不见,所以不存在”,也不能只说“能写出符号,所以一定有合理对象”。

    最强异议是:若数不是具体东西,以上不还是靠语言绕圈吗?回应是,本篇只建立了具体对象与表示的区分,并给出有限配对的可操作标准;抽象对象的存在地位仍然开放,不借一个计数例子宣称已经解决。

    不同的自然数集合构造,为什么不让算术分裂

    在一种常见集合论构造中,0取为空集,1取为只包含0的集合,2取为包含0与1的集合。另一种递归构造可以让每个后继只包住前一个对象。两者的0与1相同,但从2起集合结构已经不同;它们仍可承载相应的自然数次序与运算。

    这说明,选出一种方便的基础表示,不必就认定日常算术中的每个数只能“真正等于”那一个具体集合。我们可以通过结构中的对应关系比较实现,关注哪些运算与关系被保持。[1,关于集合论基础与结构主义的讨论]

    程序中的对象也有一种相似但有限的类比:同一抽象序列可以用数组或链表表示,表示不同不妨碍它们满足同一接口。数学对象的本体论并不因此化约为程序实现,但类比能帮助区分抽象性质与某个选定编码。

    所以,“1不是棍子”并不等于“1必须是某种唯一集合”。本篇要求的是分清层次,而不是把一个过于具体的答案替换成另一个未经辩护的答案。

    相等与一一对应,各自比较什么

    两个有限集合元素相同,叫集合相等;元素不同却能一一配对,叫具有相同基数。例如{甲、乙}与{杯子A、杯子B}不是同一个集合,但都含两个元素。计数抽取的是后一类数量关系。

    如果配对漏掉一件物品,或让一件物品对应两次,就没有建立一一对应。日常清点中的重复计数与遗漏,本质上就在破坏这项对应。先确定“同一件物品”怎样辨认,是精确计数的前提。

    排序又是另一种关系。同样两本书,可以有先读A再读B,也可以反过来;基数同为2,顺序不同。基数问题问有多少,序数或次序问题问排在何处,不能由同样多推出顺序相同。

    在无限集合上,一一对应还会产生超出有限直觉的结果,例如自然数与偶数可以配对。那需要更明确的集合与函数概念;本篇只把它作为后续问题,不用“部分一定少于整体”的有限口号阻止进一步分析。

    为什么1米加1秒没有普通的直接相加

    同样写着1,长度与时间是不同量。若要相加,必须先有同类量与共同单位;1米+100厘米可换成2米,1米+1秒却不是一个通常定义的长度或时间。这不是算术失败,而是运算对象没有满足规则。

    比例还需区分纯数与带单位比值。两段长度之比可以无量纲;速度是长度除以时间,保留相应量纲。把所有量都存成浮点数,并不会消除这些区别,只会把检查责任交给程序与使用者。

    由此可以回看最初的棍子:棍子的个数、长度、质量和价格都能用数表达,却是不同问题。说“这根棍子是1”,省略了所选属性与单位,不能作为完整定义。

    数让不同对象共享数量结构;单位和模型又把结构接回世界。理解这个来回关系,比只背“数是抽象概念”更能帮助我们识别实际推导中的错误。

    精确数与测量值混在一起,误差怎样被放大

    若一段长度的估计值记为L=1.00米,标准不确定度u(L)=0.01米,换成厘米后应写成100厘米,标准不确定度相应为1厘米。单位转换不能凭空提高精度;多写小数位也不会增加仪器提供的信息。标准不确定度以标准差的形式表达,并不是保证真值落入某区间的最大误差界。[3]

    再设正方形面积A=L²。按一阶不确定度传播,在不确定度相对较小、线性近似适用时,u(A)≈|2L|u(L),这里约为0.02平方米。若报告扩展不确定度,还应说明覆盖因子及覆盖概率所依据的假设;有覆盖概率的区间,不能直接写成绝不会越界的保证。[3]

    若另外构造一个确定区间,明确假定边长满足0.99米≤L≤1.01米,那么由平方函数在正数范围内的单调性,面积必在0.9801到1.0201平方米之间。后一结论依赖额外给定的区间约束,不能仅由u(L)=0.01米推出。

    这里1、2等整数在代数关系中可精确使用,测量得到的1.00却带有经验不确定性。两种数写在同一行,不代表它们具有相同证据地位。把测量值当成无限精度真值,会让后续计算看似严密却失去现实依据。

    这段推导不是重新定义数,而是展示抽象数怎样参与量的表达。数、单位、测量方法与模型条件共同决定我们能对结果说到多精确。

    一次可以自己完成的核对

    拿两组不同物件,不移动它们也尝试一一配对;把同一数写成不同进制;把同一长度换成不同单位。每次分别记录对象、规则与记号发生了什么变化。

    这些例子表明:数帮助我们抽出数量与结构,记号帮助我们表达,实物帮助我们建立联系。混淆三者,既会误读古代数学,也会在程序的数据表示和现实测量中误判结果。

    来源、证据与阅读路线

    1. Stanford Encyclopedia of Philosophy:Philosophy of Mathematics,基础与对象解释的争议
    2. 欧几里得《几何原本》第VII卷定义1、2;本文明确区分古典术语与现代自然数用法
    3. JCGM 100:2008,2.3.1、2.3.5—2.3.6及第5—6节:标准不确定度、扩展不确定度、覆盖因子与一阶传播;不把不确定度直接解释为确定误差界

    证据范围:计数、表示和单位以构造例子分析;不确定度传播与确定区间分别按各自假设推导,所列数值不是一次实际测量报告。

    版本1.2 · 2026-10-18:完成事实、条件与引用复核,逐篇明确证据方法;有实质缺口处补齐推导、反例或原题。原网址与首次发布日期保留。

  • 数学到底是什么?“发现”与“发明”为什么一直存在争论

    作者:lihao技术文章发布:数学与物理直觉 · 第 01 期

    从偶数与棋盘覆盖的推导出发,区分符号、规则、数学结论与现实应用,说明发现和发明之争为什么不能靠一句口号结束。

    数字符号可以换,结论能随意换吗

    人类可以选择用“2”、II或别的符号表示二,但不能仅靠换写法,就让两个有限偶数的和变成奇数。这种张力使“数学是发现还是发明”成为一个真实的哲学问题。

    若说数学全由人发明,必须解释为什么一旦接受某些规则,就会遇到不由个人意愿决定的约束;若说数学对象独立存在,必须解释人怎样认识不在时空中直接活动的对象。两边都有需要承担的解释责任。

    本文不裁定全部数学哲学,而是区分四层:符号怎样制定,对象与规则怎样界定,结论怎样推出,数学模型怎样用于现实。混在一起时,两个人可能只是在不同层面各说一句正确的话。[1]

    做一次不依赖测量的小推导

    在整数范围,定义偶数为可写成2k的数,其中k为整数。设a=2m、b=2n,则a+b=2m+2n=2(m+n)。因为m+n仍为整数,和仍然是偶数。

    这一步不需要把世界上所有偶数逐个相加。它依赖定义、整数的封闭性和代数规则,结论对这些条件下的任意m、n成立。符号可以更换,支持关系不会仅因改字体而变化。

    但若程序使用会溢出的有符号整数,或把“加法”另行定义,不能直接把这个整数证明当作程序行为证明。数学定理有适用结构,实现还要满足对应契约。这里的量是无量纲整数。

    发现式体验为什么那么强

    构造一张8×8棋盘,去掉两个对角角格。标准黑白交替着色下,两格同色,因此剩余两色数量为30与32。每个覆盖相邻两格的多米诺骨牌必覆盖一黑一白,所以无论怎样摆放,不能恰好覆盖剩余棋盘。

    棋盘、颜色和摆放规则由我们设定;一旦条件固定,不能覆盖的结果却不是投票能改变的。它说明证明可以揭示一类尝试共同受制的结构,而不是只有“我暂时没找到摆法”。

    这仍不单独证明柏拉图主义。一个形式主义者可以说,我们发现的是所定系统的后果;结构主义者可以强调位置关系;实在论者可以认为结构本身不依赖人。相同的数学推导并不自动选出唯一的对象理论。

    几种立场,各自保住了什么

    数学实在论通常强调数学真理不随人的信念改变;形式主义取向突出符号系统、规则与一致性;构造主义取向要求更严格地交代对象的构造与证明;结构主义则关注对象在关系结构中的位置。[1] 它们内部也有分支,不能用四个标签代替原著。

    最强的实在论压力是认识问题:若对象与我们没有普通物理因果联系,我们如何知道它们?最强的“任意发明”压力是约束问题:为什么同一规则下的结论会抵抗我们的愿望,甚至出现一开始没预见的结果?

    一个审慎的暂时回答是:人类确实创造记号、问题和形式系统,也会发现这些系统中不显然的关系。这个层次区分能减少误会,却没有消除“系统之外是否存在独立数学实在”的哲学争论。

    数学可用于现实,还要多做哪一步

    把地面看成平面,可以用矩形面积公式估算土地;若地形起伏很大或边界弯曲,模型误差就需要处理。公式在自己的几何条件下正确,不等于它自动精确描述任何实际地块。

    因此要分开证明误差、数值误差与建模误差。证明检查推导是否成立;有限精度计算可能舍入;把现实映射到模型又可能遗漏因素。数学应用成功,既体现结构的力量,也依赖假设与测量契合。

    本篇棋盘是离散数学构造,偶数结论是演绎推导,没有做物理测量。若有人换成可重叠骨牌、允许斜接或改变棋盘拓扑,就应重新检查覆盖条件,而不是沿用原结论。

    一个证明为什么比很多数值例子多说了一步

    检查2、4、6都是偶数,只能覆盖有限对象;用a=2m、b=2n推导a+b=2(m+n),则把任意性保留在变量中。证明的力量来自:每一步只用了对全部相应对象成立的规则,所以结论不依赖选中的几个例子。

    但证明也不是“写了字母就可靠”。必须说明对象属于什么结构、使用哪些公理、推理规则是否合法。若m、n不是整数,原来“m+n仍为整数”的理由就失去前提;若我们讨论的是某个有截断或例外规则的实现,又要重新建立对应关系。

    棋盘证明同样依赖不变量:每块骨牌消去相同数量的两色格子。只要覆盖规则保持,最终覆盖的两色数量必相同。反证只需发现目标状态违反这个必要条件,而不必枚举全部摆法。它说明结构如何约束可能性,也说明为什么“我试了很久没成功”弱于不可能性证明。

    “不由我决定”与“独立存在”,中间还隔着什么

    实在论者可以指出:我们在不知道结论时就已经受到数学关系约束,后来只是发现它。形式主义取向则可回应:规则被制定以后,其后果当然不受个人意愿改变,这并不需要另设一个独立对象世界。

    这两种解释都能承认上述偶数证明与棋盘不变量。争议因而不在算式是否成立,而在如何解释其客观性与必然性。若用“答案不能乱改,所以柏拉图主义已证明”,就把共同承认的现象直接当作唯一理论的证据。

    反方向的论证也需要谨慎:记号确实由人制定,不等于结论任意。语言里的“月球”是人为词语,但词语的人为性不能证明月球也是人为创造;类似地,数学记号的人为性不能直接决定对象的存在方式。类比只指出推论不充分,不证明两类对象完全相同。

    数学哲学因此要求分别处理语义、认识与对象问题。一个立场不能只解释最顺手的一面:强调独立真理时要面对知识如何可能,强调实践创造时也要解释跨个体可纠错的约束。

    不同公理体系,会不会让数学变成相对意见

    选择不同公理,可以研究不同结构。欧氏与非欧几何的差别,不等于同一条件下任意结论都可接受,而是某些公理条件改变后,可推结论也改变。讨论具体定理时,应把条件连同结论一起陈述。

    如果两人在不同系统中使用同一词,又省略系统差异,就可能出现假冲突。相反,在同一明确系统里,一个证明若违反规则,不能用“我选择了另一种真理”来辩护;改变系统必须显式提出并说明意义。

    应用到物理时,又多出经验选择:哪一种几何、概率或动力学模型适合当前对象,要由测量与预测比较判断。数学内部的有效推导,不能独自决定现实采用哪套结构。

    因此,发明与发现可以在不同层面并存,但这种调和也有边界。它说明实践中的创造与约束如何共处,尚未给所有数学本体论争论提供最终答案。

    一致性、真理与应用成功,为什么不能互相替代

    一个形式系统没有导出矛盾,至少避免了某类内部崩溃;这并不说明其中每个符号都已经对应到现实对象,也不说明它是研究者唯一应当选择的系统。形式一致性与经验适用是不同评价。

    反过来,一个公式在许多测量中表现良好,也不自动证明对数学对象存在方式的某种理论。物理模型可以依赖近似与有效域,实际应用成功不要求我们先裁定柏拉图主义与形式主义之间全部争论。

    可以把数学实践中的客观性理解为若干可辨性质:推理规则公开,证明可被批评,结论不依赖某个人的偏好,不同表示间可以建立结构对应。不同数学哲学会对这些性质作不同解释;共同承认实践事实,并不让解释争论失去意义。

    因此,发现与发明之争最值得保留的,不是二选一投票,而是三项责任:解释为什么规则具有约束,解释我们如何认识这些关系,解释它们怎样与世界建立有效联系。只回答其中一项,通常还不足以给出完整立场。

    把争论变成更具体的问题

    下次听到“数学当然是发明的”或“数学显然早就在那里”,可以追问:你说的是符号、规则、结论、结构,还是独立存在的对象?你准备怎样解释证明的约束力与数学知识的来源?

    这能把立场宣告变成可继续讨论的论证。下一篇从数字本身开始:一根棍子、符号1与数1,究竟哪里不同?

    来源、证据与阅读路线

    1. Stanford Encyclopedia of Philosophy:Philosophy of Mathematics,各主要立场及认识问题
    2. 欧几里得《几何原本》第VII卷定义1—2,单位与数的古典界定;用于历史对照

    证据范围:偶数相加证明与棋盘计数用于展示约束、证明和结构;有限算例不能替代一般证明,也不据此裁定数学对象存在的唯一哲学立场。

    版本1.2 · 2026-10-18:完成事实、条件与引用复核,逐篇明确证据方法;有实质缺口处补齐推导、反例或原题。原网址与首次发布日期保留。

  • 古代文明如何开始用数学描述天文、土地和时间

    作者:lihao技术文章发布:科学史与技术史 · 第 02 期

    通过莱因德纸草书、YBC 7289泥板和巴比伦观测记录,区分史料明载、现代重算与历史推测,理解量化知识的形成。

    计数解决的首先是可以反复遇到的问题

    一块地有多大,一批粮食怎样分,一轮季节什么时候回来:这些问题要求的不只是记住一次经验,还要采用可重复的单位、数量关系与记录方式。但我们不能直接拿今天的公式,想象古代所有人都按同样思路计算。

    本篇选择埃及与美索不达米亚的几个现存材料,讨论可核对的局部过程。它不涵盖中国、印度和其他地区的完整传统,也不声称找到了数学的唯一起源。把实践需求看成一个重要背景,与断言所有数学都由测田直接产生,是不同强度的主张。

    土地与分配:题目保存了怎样的算法

    莱因德数学纸草书现分为若干部分。英国博物馆EA10057的馆藏说明记载了分数、面积与体积等问题,并说明文本由书吏Ahmose抄写、按统治者纪年。[1] 该馆当前条目标注1550 BC;美国数学协会的文献介绍则采用约公元前1650年的估年。[4]本文不把相差约一世纪的标法伪装成精确到某一年。

    有日期也要区分抄写年代、所据更早材料的年代和现代推定年代。一个保存下来的算法,可以证明这种做法在文本中存在;它不能单独证明全社会日常都按同一算法操作,也不能证明抄写者就是最早发明者。

    构造一个现代重算例:长方形地块长30单位、宽20单位,按长乘宽得到600平方单位。它说明面积需要长度单位的平方,不能把结果写成600米;但这个数字例子并非纸草书原题,不据它推断古代测量误差。

    真实原题又怎样计算?莱因德纸草书第50题给了一块直径为9 khet的圆田。按Chace的原典英译,步骤是从直径中减去它的九分之一,9减1得8,再以8乘8,得到64 setat。[5,第50题,印刷页92] khet是长度单位,setat是相应的面积单位,1 setat等于1平方khet;这里保留原单位,不把数字未经转换写成米或平方米。[5,印刷页33]

    用现代记号概括,这项规则相当于A≈(8d/9)²。现代圆面积公式是A=πd²/4,因此前一种规则相当于用256/81≈3.16049代替π;同一直径下,面积结果约高0.60%。这些公式与百分比是现代重述和复算,不据此宣称书吏已经采用现代π符号、给出现代圆面积证明,或在实际测田中达到同样精度。

    原题保存的不只是一个答案,还有可以按顺序重做的操作。它让后来读者能检查数值怎样得出;至于规则如何发现、在多大范围实际使用,仍须其他材料。算法可以复做,与它的历史起源已经解释完,是两件事。

    一块泥板上的平方根近似

    纽约大学古代世界研究所的YBC 7289展览目录,将这块泥板归于古巴比伦时期,约公元前19—17世纪,出土地则保留疑问。泥板上有正方形与对角线,并写下与平方根2有关的六十进制近似。[2]

    用现代记号把其中数值记为1;24,51,10,即1+24/60+51/3600+10/216000,约等于1.414212963。与现代平方根2相比,绝对误差约为6.0×10⁻⁷。边长若按30读,对角线数值约42.4263889;与另一行六十进制数42;25,35相合。

    这里的分号、分数与误差都是现代转写和重算。泥板没有因此自动变成一份现代公理体系里的证明;它也没有告诉我们抄写者究竟怎样得到近似,相关推断需要其他材料。准确数值、算法重建和证明形式必须分别讨论。

    天文与时间:规律需要跨时比较

    巴比伦天文日记说明观测可以被连续写在泥板上,英国博物馆藏品1880,0617.654就登记为Astronomical Diary。[3] 一个馆藏标签能确认对象的文献类型,但不足以授权我们编造其中具体月份的星位、价格或天气。

    从数学上看,记录周期现象可帮助安排时间:若某现象近似每T天重复,已有一次时刻t₀,就可预测t₀+kT。但实际周期可能不等长,观测有误差,不同历法的月份与季节也需协调。这只是解释量化机制的现代模型,不是对某块泥板算法的翻译。

    制度与知识并不必然分离。天文观测可能同时服务历法、祭祀、占兆或行政;不能因为今天不接受其中某些解释,就抹去记录与计算的技术价值,也不能据计算准确就认定全部占兆解释成立。

    怎样避免把多个文明排成一条直线

    书吏的训练、材料的保存、政权的需求与文本之间的传播,都会影响我们现在看见什么。一个地区留下更多泥板,不代表其他地区没有口传或易腐材料上的知识;相似方法也不能仅凭相似就证明直接传播。

    本篇的有限时间线是:古巴比伦数学泥板在前二千纪已有复杂数值材料;埃及纸草书保存了抄写与教学传统;后来的巴比伦天文日记展示跨时记录。它描述几类证据,不主张它们构成一条单向、必然的文明接力。

    贡献的稳妥口径是“某文献保存了某种方法或数值”。若要改写为“某人首先发明某理论”,必须补人物身份、文本关系、定年与更早证据检索;不能靠一个醒目故事跳过这些步骤。

    六十进制不只是“把十换成六十”

    十进制位置记数中,123表示1×100+2×10+3;现代转写的六十进制1;24,51,10则按1、1/60、1/60²、1/60³理解。分号帮助现代读者标出整数与小数边界,但不能假定古代原件总有完全相同的符号。

    古巴比伦位置记数的数量级常依赖语境。读到一组数字,还要结合题目、单位与计算关系判断它代表多大。把现代转写当作原物上全部已明写的信息,会把解释者的工作藏起来。

    YBC 7289中,对角线系数与边长及另一行数值彼此对应,使读法受到内部算术约束。若仅给出一组无上下文数字,可容许的解释往往更多。这说明历史解释不是自由联想,它会被同一材料中的多处关系共同限制。[2]

    六十便于表示许多常见分数,例如1/2、1/3、1/4、1/5、1/6在六十进制中都能有限表示,因为这些分母的质因数包含在60里。但1/7不会因此自动变成有限表示。数制有计算便利,也有局限;便利不等于我们已经解释了它全部历史起源。

    从一个近似数,怎样走到算法问题

    平方根2的近似可以被现代人用多种方法得到。比如给定正数a,取新值(a+2/a)/2。若a比平方根2大,新值仍不小于平方根2,且误差通常减小;从a=1.5开始,可得到约1.4166667,再约1.4142157。

    这个迭代能够帮助理解为什么近似可以逐步改进,但本篇没有证据证明YBC 7289的抄写者正是这样计算。数值相似、一个算法可行和古人实际使用它,是三种不同命题。要主张最后一种,需要算法文本、相关泥板或更有力的历史联系。

    同样,一块泥板显示对角线近似,不等于它在现代欧氏公理体系里写出了毕达哥拉斯定理的证明。可以肯定数值关系与图形具有重要数学内容,同时保留证明形式、教学用途与知识来源的未决问题。

    这项区分特别适合读古代技术:现代重建让我们检查材料是否可理解;历史断言则必须继续问,这种重建是否由当时证据支持。

    土地、账目与历法为何需要共同约定

    即使会乘法,如果每个人的一“尺”不同,土地面积也难以比较;即使能记录月相,如果纪年、月份和观测地点不明确,跨年材料也可能无法正确对齐。量化知识因此不仅是数字,还包括单位、分类与记录规程。

    设两个地块面积都写成600,但一个以长度单位u的平方计,另一个以长度单位2u的平方计。后者实际面积是前者四倍,而不是两倍。平方单位随长度单位的平方变化。这是现代量纲推导,用来说明读史料时必须恢复单位;不声称某份古文献犯了这个错误。

    历法还涉及不同周期的协调。太阳年、朔望月与日不是天然整除的组合;一个以月为组织单位的制度若要跟随季节,就必须处理累计偏差。哪些文化采用什么办法,须分别核对原始材料,不能从一个抽象周期公式推出各文明都有相同历法。

    共同约定使材料可合并,保存与教学让方法跨代传递。它们解释了数学为什么能进入行政与天文实践,也提醒我们:数字的精确外观,不代表资料的单位、年代和解释已经没有不确定性。

    一份可追溯的史料表,应怎样标出置信差别

    对莱因德纸草书,可以分列“藏品身份:EA10057等”“馆藏描述:数学题与书吏教学”“年代:按纪年及现代估年”“本文推论:方法可被传授”。这四行的证据性质不同,最后一行不是原文直接说出的全部历史因果。

    对YBC 7289,可以分列“原物图形与数字”“学者的六十进制转写”“现代数值计算”“关于算法或教学场景的解释”。如果后来发现更可靠转写,先改对应行,再检查哪些推论受影响;不必把整段历史一概推翻,也不能只修一个数字而忽略下游结论。

    对天文日记,当前所核材料只支持藏品类型,不能详细复述尚未读到的正文。读者若要研究某次观测,还需取得具体泥板编号、转写、译文、日期与学术解释。知道存在一类文献,与已经读完其中一份,是不同阅读状态。

    这样的分层比列一串书名更有用:它把每个主张绑定到材料允许的范围,也为后续修订保留位置。历史写作的精细,不只在于年代多,而在于知道每一个年代、人物和贡献归属是怎样得到的。

    读古代数学,先问材料允许说到哪里

    可沿三列做笔记:原物上实际写了什么,现代学者怎样转写和解释,本文做了哪些重算。把看不清或有争议的地方留白,比用熟悉公式补成完美故事更可靠。

    本篇平方根与面积算例属于现代重算。我们由此理解的是一种知识实践:把对象量化,把步骤保存,让后来的人有机会重新检查。

    来源、证据与阅读路线

    1. 英国博物馆EA10057:性质、书吏、纪年与当前目录日期;不把馆藏日期当绝无争议的定年
    2. NYU ISAW:YBC 7289,古巴比伦时期、正方形对角线与平方根2近似
    3. 英国博物馆1880,0617.654:Astronomical Diary条目;仅核对文献类型
    4. Mathematical Association of America:The Rhind and Moscow Mathematical Papyri,约前1650年的常见估年;与馆藏目录分列
    5. Arnold Buffum Chace等《The Rhind Mathematical Papyrus》Volume I,MAA,1927,印刷页33的长度/面积单位及页92第50题(PDF第49、108页);原典英译与译注,本文现代公式和误差另行说明

    证据范围:古代算法依据原典译注与馆藏资料,现代记号、单位换算与误差为另行复算;未鉴定原物,也不由算法误差推断古代实际测量精度。

    版本1.2 · 2026-10-18:完成事实、条件与引用复核,逐篇明确证据方法;有实质缺口处补齐推导、反例或原题。原网址与首次发布日期保留。

  • 科学为什么会出现?观察、解释与可检验知识怎样形成

    作者:lihao技术文章发布:科学史与技术史 · 第 01 期

    借助古代计算文献与伽利略的木星卫星观测,讨论记录、解释、检验和交流如何共同形成可批评的知识。

    不能只给科学寻找一个生日

    人类很早就观察星空、计算土地和处理疾病,但这些活动并不自动等于今天制度化的科学。若把科学的出现讲成某个天才突然发现“要观察”,会漏掉记录工具、数学方法、知识传承与共同检验的长期积累。

    本文采用一条有限的观察线索:知识怎样从个人经验变成可保存、可比较、可批评的主张。它不是给所有文明排先后,也不把宗教、技术与理性画成一条必然替代的直线。古代人的知识分类与现代学科有明显差别。

    需要同时区分四件事:观察记录了什么,解释提出了什么关系,检验怎样区分候选解释,交流如何让别人追问或修正。每一环都可能独立发展,也可能与当时的政治、教育和信仰交织。

    记录让经验离开一个人的记忆

    古代数学文献首先提供了非常具体的证据。英国博物馆藏的莱因德数学纸草书包括分数、乘除、面积和体积等题目;馆方把它解释为可能用于书吏学习的数学教材。[1] 这说明算法与例题可以被保存和传授,却不能据此直接重建全部社会的计算活动。

    文献的存在也不等于它是最早一次发现。现存文本可能是抄本,原件可能散失,保存条件也极不均衡。科学史中的“最早”常常只能指“目前可确认的现存证据”,而不是人类历史的绝对起点。

    这样的边界很重要:若把留下文字最多的地方自动当成所有知识的唯一源头,就把史料可见度误当成历史事实的全貌。

    从看见亮点到主张它们绕木星运行

    1610年,伽利略在《星际信使》中发表了木星附近天体位置变化的观察。Museo Galileo的资料把木星卫星的发现与“不以地球为中心的绕转”联系起来。[2] 原典中连续记录的位置,是分析论证的重要材料,而非后来神话中的一次偶然凝视。[3]

    观察层面是:几个亮点相对木星的位置随时间变化。解释层面是:它们与木星存在绕转关系。两者之间还要处理仪器是否可靠、位置是否记录准确、其他解释能否说明变化等问题。画下亮点与证明一个宇宙体系,不是同一件事。

    这个例子可用来反驳“所有天体都必须直接绕地球”的强说法;它并不单独排除所有地心或混合宇宙模型。把一次发现写成完整日心体系的最终证明,会夸大证据。

    可检验不等于只许做实验

    历史天文学不能随意制造一颗新木星,但可以比较预测与后续观察;地质学、演化研究也会利用留下的痕迹与多条独立证据。检验的核心是让解释承担出错的风险,并给出别人能够检查的依据,不限于实验室里控制所有变量。

    同样,实验结果也不会自己讲话。测量依赖仪器、校准、误差模型和概念。一次偏差可能来自理论错误,也可能来自仪器、计算或边界条件;重要的是保留记录,提出可区分的排查,而不是一遇到反例就任意补救。

    若某种解释能把所有可能结果都说成支持,且拒绝交代什么观察会使它修改,它的经验内容就很难被检验。但科学的全部方法、价值与历史也不能缩成一句“能证伪即可”。

    为什么知识还需要共同体

    独立观察者需要知道看什么、怎样看、如何记录;读者需要接触数据和方法;批评需要被允许提出;错误还需要有修正渠道。印刷、通信、学院、仪器制造与专业分工会影响这些过程,但各地路径不必相同。

    这段机制说明是本文的历史解释框架,不是从两个案例推出的唯一因果定律。最强反例是:有些准确知识产生于封闭组织,有些公开争论也会长期坚持错误。这说明开放交流既不充分,也不能代替可靠方法;它提供的是更可见的纠错机会。

    因此,“科学为什么出现”没有一个由观察自动通向真理的单因答案。我们至少看到:需要能跨人、跨时保存的材料,需要有约束的解释,也需要持续比较与批评的实践。

    把观察、模型和背景假设拆成一条证据链

    木星卫星案例至少有四层:望远镜里看见光点;把不同时刻的图形识别为同一组对象;用绕转关系解释相对位置变化;据此重新评估更广的宇宙模型。每向上一层,都增加了并非由单张图像直接给出的判断。

    这种层次不表示推断不可靠,而是让我们看见它需要哪些支撑。多次位置变化能削弱“只是固定背景星”的解释;与其他观察者的结果比较,有助于检查仪器与记录;持续预测后续位置,则让解释承担更多约束。原典记录与现代复算也有不同身份:后者可以检查一致性,不能倒替当年的观察行为。[3,木星卫星记录部分]

    同样,观测与理论很少完全分离。要记录“某光点离木星几角分”,已经使用仪器尺度、角度概念和对象识别。承认这些依赖,不等于所有解释都任意;背景假设也可以被独立校准、比较和修正。

    科学史写作应保留从哪一层走向哪一层,而不是把最终被接受的理论塞回每一位观察者的头脑。否则,过程中的不确定性、争议和错误解释都会被胜利故事抹平。

    为什么“一次观察推翻一种理论”通常不够完整

    设理论T加上仪器与边界假设A推出预测O,而实际未观察到O。逻辑上,被否定的是T与A共同成立的组合;要把失败具体归给T,还需要独立检查A。若镜片、计时或计算出了问题,单次不符并不足以定位。

    这也不能成为无限保住理论的借口。补充假设若有独立依据、能带来新预测,并经进一步检查,可以推进研究;若每次只在结果出来后添加一个无法再检验的例外,就降低了理论的约束力。判断需要看整个修正过程,而非给“补丁”一概定罪。

    反过来,预测成功也不自动证明理论唯一正确。两套模型可能在现有观测范围内给出同样结果;要区分它们,需要找出差异预测,或比较解释结构、适用范围与独立证据。木星附近天体绕转的发现,不能单独判定所有太阳与地球运动关系,正是这种证据范围问题。

    这些是本文对证据结构的分析,并非把后来某套单一科学方法追认为全部历史参与者的自觉原则。方法的概括必须接受历史材料的约束。

    数学、技术与制度,各自怎样改变知识

    数学使某些模糊比较变成数量关系:不仅说“移动了”,还问多远、多久、按什么规律。技术让可观察对象和精度发生变化;制度决定谁能获得训练、保存材料、质疑权威与组织协作。它们可以相互加强,却不构成一条人人必经的公式。

    同一技术可能服务不同目标,同一制度也可能保护交流或排斥异见。不能因为后来的科学受益于某项工具,就倒推发明者从一开始只为现代科学服务。也不能把所有准确计算都称为完整自然理论,把所有理论讨论都称为脱离实践。

    因此,本篇对“出现”的回答是多层次的:某类可传授方法的形成,某类知识目标的确立,某种验证实践的稳定,以及专业共同体与职业制度的发展,不必发生在同一地点、同一世纪。

    一个更好的历史问题是:在这份具体材料里,哪种能力比此前更可见,依赖了谁的劳动,在哪些条件下传播,又有哪些人或观点被材料遮蔽?这样的提问比争抢唯一发明者,更接近对知识形成的解释。

    历史解释也需要反事实与反例,但不能伪造实验

    若说印刷促成了知识传播,就应追问:在没有印刷、只有手抄与口传时,哪些传播仍然存在;有了印刷以后,哪些错误也会更快扩散。这样可以把“有促进作用”与“单独足以产生可靠知识”分开。

    同样,若说商业或行政需要推动计算,应比较同时存在的教学、仪式与理论兴趣。一个实际用途可以解释需求,却未必解释方法的具体形式;一种思想主张可以解释目标,却未必解释材料为何保存下来。不同层次的原因不应互相冒名。

    反事实在这里帮助检验解释的强度,不是可随意填数字的替代历史。真正要判断某因素的作用,仍需文献、制度记录与比较案例。材料不够时,应该把主张留作有待加强的解释,而不是模拟一个世界后称为本人历史实证。

    现代科学哲学也不把“科学方法”普遍视为一条固定流水线;观察与理论关系有长期讨论。[4][5] 这些概念工具可以帮助提问,但不能遮蔽史料中的具体差异。

    如何继续读一项发现

    以后读到“某人证明了某事”,可以追问:原始记录是什么,发表时间与发现时间是否相同,证据支持到哪里,哪些工作来自仪器制造者、计算者或其他观察者,后来的解释是否被倒写回当时。

    本篇没有复做天文观测,也没有通过静态阅读给全部科学史下定论。下一篇回到更早的数学材料,具体看土地、天文与时间怎样被量化,同时保留史料断裂与年代争议。

    来源、证据与阅读路线

    1. 英国博物馆EA10057,莱因德数学纸草书馆藏说明;文献性质与数学题目
    2. Museo Galileo:Jupiter’s moons,1610年发表与发现意义
    3. 伽利略《星际信使》英译,木星卫星逐日观察部分;Reed College托管
    4. Stanford Encyclopedia of Philosophy:Theory and Observation in Science,观察的理论依赖与证据关系
    5. Stanford Encyclopedia of Philosophy:Scientific Method,方法的多样性与历史解释

    证据范围:本文核对原典英译、馆藏说明及方法论材料,分析证据的支持范围;未复做天文观测,不以少数案例建立科学形成的唯一历史因果律。

    版本1.2 · 2026-10-18:完成事实、条件与引用复核,逐篇明确证据方法;有实质缺口处补齐推导、反例或原题。原网址与首次发布日期保留。

  • 命题到底是什么?一句话怎样才有真假

    作者:lihao技术文章发布:逻辑学与批判性思维 · 第 02 期

    把句子、语境、命题与证据分开,辨认问句、开放句和含糊判断,说明“目前不知道”为什么不等于“没有真假”。

    同一句话,可能表达不同内容

    “我现在在这里。”你在上海说和朋友在北京说,字面相同,表达的内容却不同。反过来,“雪是白的”与相应的英文句子,可能表达同一内容。讨论真假时,仅盯着一串字还不够。

    命题可以暂时理解为陈述所表达、能够承担真假的内容。这个工作用法便于分析论证;命题究竟是什么对象、是否必须承认抽象命题,哲学上仍有不同理论。[1] 本篇不把一种本体论当成已经解决的常识。

    先抓住操作上的区别:句子是语言表达,命题是我们在给定意义和语境下用它说出的内容。明确了内容,才谈得上它与事实是否符合、由什么理由支持。

    哪些话不能直接填进真值表

    “请关门”在发出请求;“门关了吗”在提问。它们通常不是直接断言一个真假内容。“门已经关上”才是在陈述。亚里士多德《解释篇》第4章就把一般有意义的话语与具有真假属性的陈述区分开。[2]

    “x大于3”还留着变量。给定x=4,它为真;给定x=2,它为假;写成“存在一个数x,使x大于3”,又由量词形成完整陈述。这里要先说明变量的取值域,否则在自然数、实数或别的对象中,表达的内容可能不同。

    这不是说命令与问题不重要,而是说它们在交流中的作用不同,不能为了方便就把每句话都塞进真假二选一。

    把语境补齐,争论才有同一个对象

    “这台机器很快”至少缺少任务、输入规模、比较对象和指标。把它改成“在固定输入与配置下,这次运行耗时比基线少”,才更容易核对。即使如此,也不能由一次耗时直接推出所有负载都快。

    再看“今天下雨了”。说话日期、地点以及所指时间范围不同,表达的内容就可能变化。若双方各按自己的地点回答,表面上争同一句话,其实没有争同一命题。

    评价一个说法之前,先记录“谁在何种语境中,用哪些词义,断言了什么”。这一步比立刻搜证更早:如果目标命题不断变化,搜集再多材料也可能回答错问题。

    有真假,不等于我们现在知道真假

    “某个封闭盒子里有一枚硬币”在普通、语境明确的情形下可以有确定真假,即便你还没打开盒子。证据不足描述的是我们的认知状态,不等于事物本身没有情况可言。

    也不要把“可判断真假”理解为“必须已有可执行的判定程序”。数学中的命题可能很难证明,经验陈述也可能暂时没有可取得的证据。是否有真值、我们是否知道、能否有效判定,是三个不同问题。

    经典逻辑常在确定解释下使用真与假两种值。它是一种重要模型,但模糊表达、未来偶然事件以及语义悖论会引出更复杂讨论,不能以一个入门定义消除这些争议。

    模糊话语怎样修订,而不是伪装精确

    “这座山很高”依赖比较标准;“这个方案是最好的”依赖目标与约束。可以明确标准,例如海拔或某组验收指标,但新版本比原话更具体,不能宣称从此只有一种合理标准。

    构造一个评审案例:甲说“方案A更好”,意思是初次开发更快;乙说“不好”,意思是长期维护成本更高。两人未必在事实层面矛盾。先把两个命题分别写出,再讨论哪个目标应优先,才能分清经验争议与价值取舍。

    如果证据显示A的维护工时其实更少,乙应修订事实判断;如果工时资料没变,只是团队改变了目标权重,则是决策条件变化。记录修改位置,能避免把所有分歧都叫作“观点不同”。

    全称句的否定,为什么经常说错

    “所有样本都通过”可以写成:对本次样本集合中的每个x,P(x)都成立。它的否定是“至少有一个样本没有通过”,而不是“所有样本都没通过”。前者只需要一个失败,后者要求每个都失败,强度差得很远。

    同样,“有些样本通过”的否定是“没有样本通过”。如果把“尚未找到通过样本”直接当成后一句,就把搜索状态换成了对象事实。搜索是否覆盖全部集合、观察是否可靠,决定它能支持多强结论。

    空集合还会带来一个值得注意的情况:在标准经典量词语义下,若集合没有任何元素,“集合中所有元素都满足P”没有反例而为真。现实验收若只看这一条件,就可能把“一个测试也没运行”误当成全部测试成功。因此验收通常还需要“确实运行了规定数量与类别的测试”。

    这不是逻辑故意抬杠,而是显示一句话遗漏了存在或覆盖要求。把“所有已执行测试通过”与“规定测试均被执行且通过”分开,才能让状态描述准确。

    一句话的歧义,可能改变整条论证

    “每个人都喜欢一本书”至少可以有两种读法:每个人各有一本自己喜欢的书;存在同一本书,所有人都喜欢。用量词写,前者是∀人∃书,后者是∃书∀人。量词次序改变了内容。

    前者并不推出后者。甲只喜欢A、乙只喜欢B,就同时满足各自有一本喜欢的书,却没有共同喜欢的一本。若一份推荐方案凭前者承诺“必定能选出大家都喜欢的一本”,错误发生在内容变强,而不在调查样本是否足够大。

    “只要”“只有”“除非”也值得先改写再判断。自然语言还可能有省略、讽刺与共同背景,所以形式化应当回到原语境核对。一个精确公式若没有忠实表达原意,形式上再漂亮也没有分析原论证。

    同一个词在语境中改变意义,也会制造假推理。“这个方案很轻”可能指文件体积小,也可能指维护负担低。从文件小推出维护容易,需要额外根据;不能仅因都叫轻就当作同一命题。

    真假、可证性与断言责任

    在既定形式系统中,一个陈述可由公理与规则推导,叫在该系统中可证;它在某种解释下为真,则是语义问题。二者的关系需要具体讨论,不能无条件用“没证出来”代替“是假的”,或用“看起来真”代替“已经证明”。

    经验陈述也有类似区分:一件事发生过,与我们现在能否取得可靠材料,是不同层面。断言责任要求按现有证据表达置信与限制,而不是因为客观上可能有真假就表现得已经知道。

    对于“堆积到多少粒才算一堆”这类模糊表达,边界本身可能没有被日常语言精确固定。选择一个操作阈值可以帮助实验或管理,但那是增加约定,不能宣称它揭示了所有语境中唯一的本义。

    这些困难不取消命题分析的价值。恰恰因为有语境、歧义与证据差别,固定主张的内容才是认真讨论的起点。

    事实争议与价值争议,如何在同一段话里拆开

    “方案A更省时间,所以应该选A”至少包含两个承诺:A在相关任务中耗时更少;在当前条件下,节省这些时间足以支持选择A。第一项需要测量,第二项需要目标与约束。若A会丢数据,第二项通常还缺失重要限定。

    可以把它改成:“在正确性、预算与维护约束均满足时,我们优先选择端到端耗时较少的方案;A、B均满足约束;固定负载下A耗时更少;所以按这个决策原则选A。”现在每个前提都有明确身份,批评者也知道该查事实还是该讨论原则。

    若有人反对“少10毫秒不值得增加一年维护负担”,他未必否认测量结果,而是在挑战比较目标。反过来,若他说“你计时漏掉了搬运”,则是事实与模型边界问题。混在一起会让双方反复提供不相干证据。

    命题分析并不会自动解决价值冲突,却能使分歧稳定下来。只有当大家讨论的是同一个内容,论证、测量与协商才有机会分别推进。

    一张可实际使用的检查清单

    面对一句话,依次检查:它在陈述还是提问、请求?关键词与代词指什么?是否有未赋值变量?比较条件是否明确?我质疑的是内容、真假还是证据?

    本篇使用的是构造案例与概念分析,没有声称用实验解决命题本体论。把内容固定下来之后,才可以接着检查论证是否有效,以及证据是否足以让我们相信前提。

    来源、证据与阅读路线

    1. Stanford Encyclopedia of Philosophy:Propositions,句子、内容与命题理论争议
    2. 亚里士多德《解释篇》第4章,E. M. Edghill 英译;陈述与一般有意义话语的区别

    证据范围:本文以明确语境和构造例子区分句子、命题及真假条件;不把一种入门语义模型当作已经解决所有语言哲学争议。

    版本1.2 · 2026-10-18:完成事实、条件与引用复核,逐篇明确证据方法;有实质缺口处补齐推导、反例或原题。原网址与首次发布日期保留。

  • 逻辑到底是什么?“听起来有道理”为什么不等于推理有效

    作者:lihao技术文章发布:逻辑学与批判性思维 · 第 01 期

    通过“下雨与地面湿”的构造案例,区分前提真假、演绎有效性与经验支持,学会用反例定位推理缺口。

    一个很自然,却不可靠的推断

    如果下雨,地面就湿;现在地面湿了;所以刚才下雨了。这个推断听起来顺畅,但洒水车也能把地面弄湿。我们可以同时接受两个前提,却拒绝结论。

    逻辑研究的核心问题之一,是结论在什么意义上由前提支持。本文先讨论经典逻辑中的演绎有效性:不存在前提全真而结论为假的情形。它评价的是支持结构,不是句子好不好听、说话人是否自信,也不是听众是否同意。[1]

    这里假定“下雨”“地面湿”都针对同一个地点与时间条件。自然语言若省略这些限定,可能连命题都没有对齐。

    把内容暂时换成P和Q

    令P表示下雨,Q表示地面湿。有效的肯定前件形式是:如果P则Q;P;所以Q。无效的肯定后件形式是:如果P则Q;Q;所以P。

    P Q 如果P则Q 反例意义
    假 真 真 肯定后件的前提全真,结论P假
    真 真 真 肯定前件在此成立
    真 假 假 不满足该条件前提

    第一行已经足以推翻肯定后件的演绎有效性。这里把“如果”解释为经典命题逻辑的实质条件词;日常承诺、因果或反事实条件句有更丰富的语义,不能不加分析地都用同一个真值表处理。

    结论碰巧正确,也救不了结构

    假如昨晚确实下雨了,上述无效推理这一次也可能得出真结论。有效性要求的是结构上的保真,不是一次猜中。相反,有效结构也可能含假前提:所有鸟都会飞;企鹅是鸟;所以企鹅会飞。结构可以有效,第一前提却假。

    经典演绎中,健全论证要求有效且前提都真。评估时因此要分两道工作:先检查支持关系,再调查事实前提。用更多事实材料补充背景,不能自动修复一个没有补齐的逻辑缺口。

    一个实用做法是先问:“即使我暂时全部接受这些理由,结论是否仍可能不成立?”如果能构造一致的反例,争议就在结构或缺少的前提,而不必先攻击说话人的动机。

    无效推断是否完全没有用

    在日常调查中,地面湿可能确实增加下雨的可信度,特别是已经排除了洒水、漏水等原因时。但这是对最佳解释或概率支持的判断,结论应保留不确定性,而不是冒充演绎必然。

    把它改写成较谨慎的推断:观测到地面湿;下雨能解释这一现象;其他常见原因已被独立检查;所以有理由暂时把下雨列为较可信解释。新版本需要比较竞争解释及其证据,也需要在发现洒水记录时修订。

    最强异议是:“现实推理本来就不求必然,何必检查演绎?”回应是,检查有助于确定你究竟承诺了多强的结论,而不是要求所有日常判断都变成证明。一个不确定推断可以有价值,但应按它自己的证据标准评价。

    形式有效性,还需要一个明确的解释范围

    对于命题逻辑,给P、Q等命题符号赋真值后,联结词按规则确定复合句的真假。论证有效,要求每一种使前提全真的赋值都使结论真。我们搜索的反例因此是一种赋值,而不必是现实中实际发生的天气。

    如果进入谓词逻辑,情况更丰富。把“所有A都是B”写成∀x(A(x)→B(x)),还要指定论域与A、B的解释。前提“所有猫都是动物”“所有狗都是动物”不能推出“所有猫都是狗”:取一个含猫c和狗d的论域,让二者都属于动物而互不属于对方类别,就得到反模型。

    这里并没有否认猫与狗都是动物,而是说明共享一个上位类别不足以推出类别相同。反模型同时保护了全部前提,并让结论为假,所以恰好检验了支持结构。

    日常文本很少主动交代论域。比如“所有人都到了”,究竟是全体人类,还是本次会议的成员?若论域被偷换,同一句形式看似成立,实际却改变了内容。形式化之前的语义工作,与形式化之后的推理检查同样重要。[2]

    否定前件,为什么也会错

    另一个常见形式是:如果P则Q;不是P;所以不是Q。仍以天气为例,不下雨并不能推出地面不湿。赋值P假、Q真,使两个前提都真而结论假,所以这个形式也无效。

    与之相对,否定后件形式“如果P则Q;不是Q;所以不是P”在经典逻辑中有效。如果P真,条件前提要求Q真,就与不是Q冲突。因此满足前提的赋值不能让P真。

    这两个结果不应靠背名称记忆。每次都可以问:条件只排除了哪种情况?实质条件P→Q只排除P真而Q假的组合,并没有说Q只能由P造成。增加双条件P↔Q会改变结论,因为它额外要求Q→P。

    在真实因果解释中,把充分条件误当成必要条件,或把必要条件误当成充分条件,往往正是类似错误。比如“通过测试是发布的必要条件”,并不表示任何通过测试的版本都已经满足安全、兼容和运维等其余发布条件。

    结论强度必须与理由类型匹配

    演绎、归纳与溯因不是可靠程度从高到低的简单排行。演绎在前提被接受时提供必然约束;归纳从样本推及更广范围,需要抽样与稳定性条件;溯因比较对现象的解释,必须面对其他候选。

    一个有效演绎若以错误的全称前提开头,可能不如一份仔细设计的经验研究有助于认识世界。反过来,一份研究观察到高相关,也不能凭气势升级成“在任何情况下必然如此”。判断要同时看前提可靠性、结构和结论范围。

    因此,专家式审查不止给推理命名,还要问:作者真正主张的是必然、通常、可能还是目前最好的解释?哪些条件被固定,哪些替代解释被比较?若证据只够支持较弱版本,就明确缩小结论。逻辑帮助的是校准承诺,而不是制造确定性的外观。

    形式系统能保证什么,不能替研究者做什么

    语义层面,有效性考察所有合适解释下的保真;证明系统则用有限规则从前提推出结论。若一套证明系统健全,能按规则证明的结论不会超出相应语义后承;若还完备,则相应语义有效的推断也能在系统中证明。这里描述的是规则与语义的关系,不等于任意现实事实都能被算法轻易确定。[2]

    例如给P→Q和P,就可按肯定前件规则得到Q。规则节省了每次重列真值表的工作,但前提P是否描述现实,仍要依赖独立材料。形式证明保证“在这些前提之下”,不能悄悄去掉条件。

    日常争论还会把定义与事实混合。若“可靠系统”的定义已经包括不会静默丢数据,那么发现静默丢数据足以否定它满足该定义;但不能由此断言某个实现原因已经查明。分类结论与因果诊断仍是两件事。

    专家检查的重点,因而是把形式责任与经验责任连接起来:公式忠实表达了什么,哪些前提有何证据,规则支持多强结论,反例要求修改哪一步。只展示符号,可能同样掩盖薄弱内容。

    从一句话变成可修改的判断

    逻辑的用处不是快速给别人贴谬误标签,而是定位:词义是否改变、条件是否遗漏、全称判断是否过强、结论是否超出前提。如果“专家会这么说,所以一定真”被改成“这位相关领域专家提供了可核对理由,因此值得暂时重视”,讨论就更具体了。

    本篇所有天气、鸟与企鹅例子均为教学构造,真值表只是经典命题逻辑的有限枚举,不是现实天气调查。读下一篇前,可以先给自己的一个判断写出前提与结论,再试着寻找前提全真而结论假的情形。

    要完成这一步,还要知道究竟什么东西承担真假。下一篇从命题与句子的区别继续。

    来源、证据与阅读路线

    1. Stanford Encyclopedia of Philosophy:Logical Consequence,保真、形式性与逻辑后承
    2. forall x: Calgary,Open Logic Project,命题逻辑、有效性与健全性教材

    证据范围:命题形式的真值组合与反模型已核对;它们检查演绎支持关系,不代替对现实前提的事实调查。

    版本1.2 · 2026-10-18:完成事实、条件与引用复核,逐篇明确证据方法;有实质缺口处补齐推导、反例或原题。原网址与首次发布日期保留。