Skip to content
lean
import SFLean4.LF.Basics
import SFLean4.LF.Induction
import SFLean4.LF.Maps
import SFLean4.LF.Imp
import SFLean4.PLF.Equiv
import SFLean4.PLF.Hoare

set_option linter.defProp false
set_option linter.ambiguousOpen false
set_option linter.unusedVariables false

《软件基础》(Software Foundations) 卷二:程序语言基础 (PLF) ​

第四章:作为形式逻辑的霍尔逻辑 (HoareAsLogic: Hoare Logic as a Logic) ​

在前面的章节中,我们对霍尔逻辑的呈现方式可以被称为**模型论(Model-Theoretic)**的:

  • 我们首先在状态转移语义的基础上给出了霍尔三元组有效性的语义定义 valid_hoare_triple;
  • 随后将各程序构造的证明法则表述为关于程序求值行为的元定理(Metatheorems)(如 hoare_seq、hoare_while 等)。

然而,数理逻辑中另一种更为常见、也更为纯粹的呈现范式是证明论(Proof-Theoretic):

  • 直接定义一个由形式公理(Axioms)与推理规则(Inference Rules)组成的形式演绎系统;
  • 一个霍尔三元组的证明就是该公理系统中的一棵合法推导树(Derivation Tree);
  • 在此视角下,断言与三元组纯粹是符合文法规则的语法符号,证明就是合法的语法变形过程。

本章核心目标: ​

  1. 形式化演绎系统 derivable:通过归纳类型将霍尔逻辑公理系统严格定义为关于断言与命令的推导关系。
  2. 证明论推导实战:构造推导树实例(如赋值序列的推导 sample_proof),证明恒真后置条件与矛盾前置条件的可推导性。
  3. 可靠性定理 (Soundness):证明在形式系统中可推导的任意三元组,在状态模型下必定是语义有效的(derivable P c Q → valid P c Q)。
  4. 完备性定理 (Completeness): 运用最弱前置条件(Weakest Preconditions, WP)构造关键中间断言与循环不变量, 形式化证明著名的相对完备性定理(Cook Completeness / Relative Completeness): 在底层断言语言表达力充足的前提下,任意语义有效的三元组必定可以在霍尔形式系统中推导得出(valid P c Q → derivable P c Q)!
  5. 判定性极限 (Decidability & Postscript):探讨为什么霍尔逻辑有效性的通用判定过程在本质上不可判定(等价于停机问题)。

模型论视角 (Hoare Logic and Model Theory) ​

lean
namespace PLF.HoareAsLogic

open Imp
open Maps
open aexp bexp com
open PLF.Hoare

1. 模型论有效性定义 ​

回顾模型论中三元组的语义含义: 若命令 c 在满足前置条件 P 的任意状态 st 下开始执行且终止于 st',则 st' 必定满足 Q。

证明论视角与推导关系 (Derivability) ​

lean
/-- 模型论三元组语义有效性 -/
def valid (P : Assertion) (c : com) (Q : Assertion) : Prop :=
  ∀ st st', st =[ c ]=> st' → P st → Q st'

2. 证明论公理与推理规则系统 ​

将霍尔逻辑规则视为形式逻辑系统中的公理与推导规则:

  • H_Skip:skip 公理
  • H_Asgn:赋值逆向代换公理
  • H_Seq:顺序复合规则
  • H_If:条件分支规则
  • H_While:循环规则
  • H_Consequence:包含前置条件强化与后置条件弱化的推论规则

可靠性与完备性 (Soundness and Completeness) ​

lean
/-- 霍尔逻辑形式推导关系(归纳定义) -/
inductive derivable : Assertion → com → Assertion → Prop where
  | H_Skip (P : Assertion) :
      derivable P com.CSkip P
  | H_Asgn (Q : Assertion) (V : String) (a : aexp) :
      derivable (Q [ V ↦ a ]) (com.CAsgn V a) Q
  | H_Seq (P : Assertion) (c : com) (Q : Assertion) (d : com) (R : Assertion) :
      derivable Q d R → derivable P c Q → derivable P (com.CSeq c d) R
  | H_If (P Q : Assertion) (b : bexp) (c1 c2 : com) :
      derivable (fun st => P st ∧ bassertion b st) c1 Q →
      derivable (fun st => P st ∧ ¬ bassertion b st) c2 Q →
      derivable P (com.CIf b c1 c2) Q
  | H_While (P : Assertion) (b : bexp) (c : com) :
      derivable (fun st => P st ∧ bassertion b st) c P →
      derivable P (com.CWhile b c) (fun st => P st ∧ ¬ bassertion b st)
  | H_Consequence (P Q P' Q' : Assertion) (c : com) :
      derivable P' c Q' →
      (∀ st, P st → P' st) →
      (∀ st, Q' st → Q st) →
      derivable P c Q

/-- 前置条件强化推论规则引理 -/
theorem H_Consequence_pre : ∀ (P Q P' : Assertion) (c : com),
    derivable P' c Q →
    (∀ st, P st → P' st) →
    derivable P c Q := by
  intro P Q P' c hd h
  exact derivable.H_Consequence P Q P' Q c hd h (fun _ hq => hq)

/-- 后置条件弱化推论规则引理 -/
theorem H_Consequence_post : ∀ (P Q Q' : Assertion) (c : com),
    derivable P c Q' →
    (∀ st, Q' st → Q st) →
    derivable P c Q := by
  intro P Q Q' c hd h
  exact derivable.H_Consequence P Q P Q' c hd (fun _ hp => hp) h

/-- 示例推导树:双赋值递增至 3 的形式推导 -/
theorem sample_proof :
  derivable
    (((fun st : state => st X = 3) [ X ↦ APlus (AId X) (ANum 2) ]) [ X ↦ APlus (AId X) (ANum 1) ])
    (com.CSeq (com.CAsgn X (APlus (AId X) (ANum 1))) (com.CAsgn X (APlus (AId X) (ANum 2))))
    (fun st : state => st X = 3) := by
  apply derivable.H_Seq (Q := (fun st : state => st X = 3) [ X ↦ APlus (AId X) (ANum 2) ])
  · exact derivable.H_Asgn (fun st : state => st X = 3) X (APlus (AId X) (ANum 2))
  · exact derivable.H_Asgn ((fun st : state => st X = 3) [ X ↦ APlus (AId X) (ANum 2) ]) X (APlus (AId X) (ANum 1))

/--
**** 练习: 3 星, standard (provable_true_post)
证明后置条件为 True 的任意霍尔三元组均形式可推导。对命令 c 进行结构归纳。
-/
theorem provable_true_post : ∀ c P,
  derivable P c (fun _ => True) := by
  sorry

/--
**** 练习: 3 星, standard (provable_false_pre)
证明前置条件为 False 的任意霍尔三元组均形式可推导。对命令 c 进行结构归纳。
-/
theorem provable_false_pre : ∀ c Q,
  derivable (fun _ => False) c Q := by
  sorry

3. 霍尔逻辑的可靠性 (Soundness) ​

可靠性定理断言:形式系统绝不推导出虚假结论。 若一个三元组可推导,则它在状态求值模型下必然是语义有效的。

最弱前置条件与相对完备性 (Weakest Preconditions and Completeness) ​

lean
/--
**** 练习: 3 星, standard (hoare_sound)
证明霍尔推导系统的可靠性。对推导树 d 进行结构归纳。
-/
theorem hoare_sound : ∀ P c Q,
  derivable P c Q → valid P c Q := by
  sorry

4. 最弱前置条件 (Weakest Preconditions) ​

给定命令 c 与期望后置条件 Q,其语义最弱前置条件由下列谓词给出: wp c Q = fun s => ∀ s', s =[ c ]=> s' → Q s'。

结语:判定性极限 (Postscript: Decidability) ​

lean
/-- 语义最弱前置条件定义 -/
def wp (c : com) (Q : Assertion) : Assertion :=
  fun s => ∀ s', s =[ c ]=> s' → Q s'

/-- wp 确实构成有效的前置条件 -/
theorem wp_is_precondition : ∀ c Q,
  valid (wp c Q) c Q := by
  intro c Q st st' heval hwp
  exact hwp st' heval

/-- wp 是所有满足要求的前置条件中最弱的(被所有有效前置条件所蕴含) -/
theorem wp_is_weakest : ∀ c Q P',
  valid P' c Q →
  (P' ->> wp c Q) := by
  intro c Q P' hval st hp st' heval
  exact hval st st' heval hp

/--
**** 练习: 1 星, standard (wp_seq)
证明顺序复合命令中以 wp 为中间断言的可推导性。
-/
theorem wp_seq : ∀ P Q c1 c2,
  derivable P c1 (wp c2 Q) →
  derivable (wp c2 Q) c2 Q →
  derivable P (com.CSeq c1 c2) Q := by
  sorry

/--
**** 练习: 2 星, standard (wp_invariant)
证明 while 循环关于目标后置条件 Q 的最弱前置条件自身即为该循环的合法不变量。
-/
theorem wp_invariant : ∀ b c Q,
  valid (fun st => wp (com.CWhile b c) Q st ∧ bassertion b st) c (wp (com.CWhile b c) Q) := by
  sorry

/--
**** 练习: 4 星, standard (hoare_complete)
证明霍尔逻辑的相对完备性定理:任意语义有效的三元组均可在霍尔演绎系统中推导得出。
-/
theorem hoare_complete : ∀ P c Q,
  valid P c Q → derivable P c Q := by
  sorry

5. 霍尔逻辑为什么不可判定? ​

我们或许期望霍尔逻辑具备完全算法可判定性(即存在一个总能终止的决策过程判定任意给定三元组是否有效)。 然而在理论上,这样的算法绝不可能存在:

  1. 归约至停机问题(Halting Problem): 考虑三元组 {{ True }} c {{ False }}。该三元组有效若且唯若命令 c 在任意状态下绝不正常终止(死循环发散)。 若存在算法可判定该三元组的有效性,则该算法即可直接判定任意图灵完备程序 c 是否停机,直接违背停机问题不可判定定理!
  2. 归约至一阶逻辑真理(Gödel Incompleteness): 考虑三元组 {{ True }} skip {{ P }}。该三元组有效若且唯若数学断言 ∀ s, P s 在 Peano 算术中恒真。 由哥德尔不完备定理可知,包含自然数加法与乘法的一阶逻辑系统其真理性断言本身即为不可判定的。

因此,自动化程序验证的核心策略不是追求完全判定算法,而是发展带标注程序、验证条件生成器(VCGen)以及可满足性模理论(SMT)求解器等现代工程手段。

lean
end PLF.HoareAsLogic

基于 MIT 与 Software Foundations 原版教育许可协议开源