feat: fixpoint base of weakest precondition#389
Conversation
Stuckness inductive + IrisGS typeclass + wp_pre (实定义,命题 1:1 自 Coq Iris
weakestpre.v) + wp/wp_unfold/wp_pre_contractive 接口签名。
Phase 1-A 出口:lake build OK + 4 个预期 sorry:
• COFE (WPFun) — Phase 1-B 用 OFE.discrete_funO
• wp_pre_contractive — Phase 1-B nl-proof
• wp body — Phase 1-B 用 fixpoint (wp_pre s)
• wp_unfold body — Phase 1-B 用 fixpoint_unfold
简化(vs Coq 原版,文件头有注释):
• num_laters_per_step = 0 (硬编码;Coq 原是 S (num_laters_per_step ns))
• IrisGS 暂不含 state_interp_mono 字段(Phase 1-B 按需补)
References (三参考交叉):
• Coq iris/program_logic/weakestpre.v (commit d663f775) — 命题来源(canonical)
• hxrts/iris-lean@fork/iris/vendor:src/Iris/ProgramLogic/WeakestPre.lean — 思路
• upstream Iris/Algebra/OFE.lean (Contractive/fixpoint) +
Iris/Instances/Lib/{WSat,FUpd}.lean (InvGS/uPred_fupd) +
Iris/BI/Updates.lean (|={E1,E2}=>, |={E}▷=∗^[n]) +
Iris/BI/BigOp/BigSepList.lean ([∗list]) — 算子来源
…rive
nl-proof:
- IProp GF = UPred (IResUR GF) → IsCOFE 实例 (Iris/Algebra/UPred.lean:93)
- 函数空间封闭:instance [∀ x, COFE (β x)] : COFE ((x : α) → β x)
(Iris/Algebra/OFE.lean:854) 套用 3 层 (CoPset → Expr → (Val → IProp GF))
修法:删除显式 sorry 实例,typeclass resolution 自动 derive。
Stage 1 sorry 数:4 → 3(剩 wp_pre_contractive / wp / wp_unfold)。
Phase 1-B 第 1 个 sorry 消除(按 D33 D34 nl-proof 纪律)。
…orry)
nl-proof v3:~25 行 tactic(模板 Iris/Examples/IProp.lean:131 wp_F_contractive
11 行同模式)。
结构:
- value case:unfold + simp + .rfl(W 不出现)
- non-value case:透过 5+3 层 forall_ne / 2 层 wand_ne / 4 次 BIFUpdate.ne /
sep_ne / Contractive.distLater_dist (▷ 关键步) / bigSepL_dist
upstream API 全部已验证存在:
• BI.forall_ne (DerivedLaws.lean:122)
• BI.{sep,wand}_ne (BI.lean:35-36)
• BIFUpdate.ne (Updates.lean:108)
• Contractive.distLater_dist (OFE.lean:132) — 用于 ▷ via sbi_later_contractive
(InternalEq.lean:408)
• Iris.BI.BigSepL.bigSepL_dist (BigSepList.lean:77)
工程问题:Nat.repeat _ 1 X = f X 由 rfl 自动 reduce,
{E,∅}=∗ X = wand _ (fupd E ∅ _) macro 展开后透过依次 wand_ne + BIFUpdate.ne。
Stage 1 sorry 数:3 → 2(剩 wp def + wp_unfold,可立即用 fixpoint + fixpoint_unfold)。
首次编译即通过,0 修复迭代——nl-proof v3 工程问题预解决方案有效。
…eanprover-community#3 leanprover-community#4) wp def: - wp s := fixpoint (fun W : WPFun => wp_pre s W) - 依赖 COFE (auto-derive) + Inhabited + wp_pre_contractive 全就位 wp_unfold: - 包装 ContractiveHom { f := fun W => wp_pre s W, contractive := inferInstance } - fixpoint_unfold 给 ≡ at WPFun level - 函数空间 OFE.Equiv pointwise → 应用 (E e Φ) 拿 IProp 层 Equiv - BI.equiv_iff.mp 转 ⊣⊢ Stage 1 全部 4 sorry 消除!0 sorry / 0 axiom 干净 build。 第一个完成真证明的 stage,PR-ready 候选(仍需 stage/2-4 真证明 + maintainer 沟通)。
为 upstream PR 做准备:IrisGS 补 state_interp_mono 字段(Coq weakestpre.v
irisGS_gen 第 5 字段)。
state_interp_mono (σ : State) (ns : Nat) (κs : List Obs) (nt : Nat) :
state_interp σ ns κs nt ⊢ iprop(|={∅}=> state_interp σ (ns + 1) κs nt)
调研结论(不补):
- num_laters_per_step:hxrts 同样省(precedent);Phase 1-2 swap/数组不需要
- hlc 参数化:upstream Examples/IProp.lean 不参数化
- Wp typeclass / WP notation:upstream Examples/IProp.lean 不注册
stage/1 现在 5/5 IrisGS 字段(vs Coq 6 字段,仅省 num_laters_per_step
sub-precedent)。0 sorry / 0 axiom build。
IrisGS 加 num_laters_per_step : Nat → Nat 字段(Coq 第 4 字段)。
wp_pre body 用 `={∅}▷=∗^[iG.num_laters_per_step ns + 1]` 替代硬编码 `^[1]`。
新增 helper `step_fupdN_ne`(10 行 induction):透过 step_fupdN k 层
NonExpansive(每层 BIFUpdate.ne + later_ne + BIFUpdate.ne)。
wp_pre_contractive proof 增加 step_fupdN_ne 调用(透过 num_laters_per_step ns
层后到达内层 inner);Nat.repeat (S k) X = f (Nat.repeat f k X) by rfl reduce。
stage/1 现在与 Coq Iris weakestpre.v irisGS_gen **6/6 字段全 1:1**:
• iris_invGS → extends InvGS GF
• state_interp ✓
• fork_post ✓
• num_laters_per_step ✓ (新补)
• state_interp_mono ✓ (上次补)
0 sorry / 0 axiom build。Phase 1-B 完整严格 1:1 PR-ready 状态。
…nces for PR Remove all references to hxrts/iris-lean (private fork; PR leanprover-community#149/leanprover-community#150 closed) and to project-internal terminology (Phase 1-A/B, stage/N, CLAUDE.md). Translate Chinese comments to English. All documentation now references only Coq Iris weakestpre.v and upstream iris-lean modules. Module remains 1:1 with Coq Iris weakestpre.v (commit d663f775): - 6/6 IrisGS fields - wp_pre with num_laters_per_step parameterization - wp_pre_contractive proof following Iris/Examples/IProp.lean wp_F_contractive - wp / wp_unfold via upstream fixpoint / fixpoint_unfold
Adds `(hlc : outParam Bool)` parameter to IrisGS, mirroring Coq's `irisGS_gen (hlc : has_lc)`. `extends InvGS GF` becomes `extends InvGS_gen hlc GF`. Also fixes Coq 1:1 match on bigSepL: `[∗list] ef ∈ efs, ...` (was `[∗list] _i ↦ ef ∈ efs, ...` to silence the linter, but upstream syntax supports the index-less form). stage/1 now strictly 1:1 with Coq weakestpre.v's irisGS_gen + wp_pre + wp_pre_contractive + wp + wp_unfold.
Tracks the fixpoint base scope ported in this PR: - Stuckness + IrisGS (all 5 fields) - wp_pre + Contractive instance - wp via fixpoint + wp_unfold via fixpoint_unfold Remaining items in weakestpre.v (wp_value_fupd, wp_strong_mono, wp_mono, fupd_wp, wp_fupd, wp_wand, wp_atomic, wp_frame_l/r, wp_bind/bind_inv) will follow in subsequent PRs.
…is FIXME)
Coq Iris weakestpre.v has a FIXME noting that wp_pre_contractive's proof
would simplify with a 'proper instance for step_fupdN'. This lifts the
NonExpansive lemma for `|={Eo}[Ei]▷=∗^[k]` to Iris/BI/Updates.lean (the
home of step_fupdN), generalized over any [BI PROP] [BIFUpdate PROP].
WeakestPre.lean now imports it from upstream rather than defining a
file-local helper. Also cleans up two small redundancies in opens
(removed redundant 'Iris.BI'; added 'Iris.BI.BigSepL' so the bigSepL_dist
call drops its fully-qualified path).
|
Thanks for the PR. Before reviewing it, can you clean up all the AI generated comments, and add |
- Removed verbose doc comments and section-level "Coq weakestpre.v: ..." blocks; kept only the file-level summary and per-field doc strings on IrisGS members. Inline tactic comments in wp_pre_contractive removed. - Added @[rocq_alias] to: - Stuckness (Coq: stuckness) - Stuckness.le (Coq: stuckness_le) - IrisGS (Coq: irisGS_gen) - wp_pre (Coq: wp_pre) - wp_pre_contractive (Coq: wp_pre_contractive) - wp (Coq: wp_def) - wp_unfold (Coq: wp_unfold) - step_fupdN_ne (Coq: step_fupdN_ne)
|
Thanks @lzy0505, addressed both points in
|
|
I think there's a lot of overlap between this PR and mine, see https://github.com/ayhon/iris-lean/tree/fele/feat/add-weakestpre. |
|
In particular, these seem to be all definitions I had already ported in my PR, although some of the proofs are a bit shorter, in particular I needed many more lines and auxiliary lemmas to prove |
|
@lihaokun I had paused development of this PR to develop the |
|
First — thanks @lzy0505 for the careful review on this PR; the feedback will carry over to the next round either way. And second, I'm sorry — I missed @ayhon's Some context on why I'm interested in this corner of iris-lean: I'm exploring whether VST (the Verified Software Toolchain for CompCert C) can be ported to Lean 4. For that I'll eventually need the full Iris program logic stack on Lean:
@ayhon — if you're taking on Happy to hear thoughts on how to coordinate. Sorry again for the duplicate effort. |
|
Hi @lihaokun. Thank you for your PR! I agree that we should discuss the splitting of program logic into chunks for unblocking purposes. @ayhon would you mind create a separate early PR for just a bare-bone definition of wp + wp-unfold from your branch (and probably some lemmas that you feel could be merged early on)? @lihaokun would you be okay with that? It might be easier to merge other things that @ayhon was working on, if the definition of wp comes from fele/feat/add-weakestpre. Just in case of concerns about merging, I can help with backporting and merging, when the need arises. |
|
@Kaptch I don't mind publishing my current PR as a draft. I need to rebase it so it sits on top of #387 though, since I intend to use the EDIT: I published my current draft in #393. I'll try to remember not to force push onto it to ease the work of people basing off of it. @lihaokun, I just got back form talking with my supervisors and we have no plans to work on |
|
Hi @ayhon — sounds good to me, and a week is completely fine. I'm still on the CompCert/VST translation side (currently So the division would be:
In the meantime I'll keep @Kaptch — the proposal works for me, thanks for offering to help with backports. |
按 PR leanprover-community#389 review 反馈套用同样规范: - 17 个顶级 decl 全部加 @[rocq_alias] 注解(wptp / steps_sum / wp_step / wptp_step / wp_not_stuck / wptp_preservation / wptp_postconditions / wptp_progress / wp_progress_gen / wp_strong_adequacy_gen / wp_strong_adequacy / adequate / adequate_alt / adequate_tp_safe / wp_adequacy_gen / wp_adequacy / wp_invariance_gen / wp_invariance) - 删除文件头大段 Contents / Depends-on 注释(重复 namespace 与 import 即可看出) - 删除内联 docstring 中 "Coq adequacy.v line N" 重复信息(保留必要的注解, 例如 `wp_progress_gen` 的 `_hwp : True` 占位说明) - 删除 section header `/-! ## §X ... -/` 装饰(按 PR leanprover-community#389 风格) - adequate record 字段 docstring 精简 度量:246 → 188 lines(-58)。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Description
Lean 4 port of the fixpoint base of Coq Iris's program logic weakest
precondition (
iris/program_logic/weakestpre.v). AddsStuckness, theIrisGStypeclass,wp_pre(withnum_laters_per_stepparameterization),its
Contractiveinstance, andwp/wp_unfoldvia the upstreamfixpoint/fixpoint_unfoldmachinery.Builds on #370 (
Languageinterface).Contributes to porting
weakestpre.vinPORTING.md.Iris/Iris/ProgramLogic/WeakestPre.leanStucknessinductive — 1:1 with CoqstucknessIrisGStypeclass — all 5 fields of CoqirisGS_gen:iris_invGSviaextends InvGS_gen hlc GFstate_interp/fork_postnum_laters_per_step/state_interp_monowp_pre(body 1:1 with Coq, using={∅}▷=∗^[num_laters_per_step ns + 1])wp_pre_contractiveContractive instancewp := fixpoint (wp_pre s)wp_unfoldvia upstreamfixpoint_unfoldAdds one private helper
step_fupdN_neto factor out theBIFUpdate.ne + later_ne + BIFUpdate.neinduction overnum_laters_per_step nsneeded by the Contractive proof.Adaptations vs Coq
Stucknessconstructors lowercase:notStuck/maybeStuckper Leanconvention.
CoPset → Expr → (Val → IProp GF) → IProp GFrather than Coq's explicit discrete-OFE arrows
-d>. The upstreamfunction-space COFE instance derives the equivalent OFE structure
automatically (and the source types here have no non-trivial OFE structure).
wp_pre_contractiveproof is manual: ~25 lines plus the small privatestep_fupdN_nehelper, since iris-lean doesn't yet have the equivalent ofCoq's
f_contractivetactic. Structure followsIris/Examples/IProp.lean:wp_F_contractive. Once tactic automation lands(cf. feat: iloeb #387 for
iLöb), this can likely be shortened.wp_unfoldproof: wrapswp_pre sinto aContractiveHom, thencombines
fixpoint_unfoldwith pointwise evaluation on the function-spaceOFE and
BI.equiv_iffto convert≡to⊣⊢. Same pattern asIris/Examples/IProp.lean:wp_unfold.Inhabited (WPFun)(required byfixpoint); set tothe constant
Trueproposition.Checklist
PORTING.mdas appropriateauthorssection of any appropriate files