Skip to content

Commit 7ad61cd

Browse files
feat: prove pathGraph distance lemmas (zero sorry)
Replace sorry stubs in PathGraphDist.lean with full proofs: pathGraph_edist, pathGraph_dist, pathGraph_dist_zero_last, pathGraph_edist_zero_last. Proof strategies discovered by Aristotle, rewritten into human-owned form. Update docs to reflect resolved debt. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c41ee3c commit 7ad61cd

5 files changed

Lines changed: 121 additions & 19 deletions

File tree

FdFormal/PathGraphDist.lean

Lines changed: 94 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,36 @@ set_option autoImplicit false
1212
/-!
1313
# Distance in path graphs
1414
15-
**Status: Stub.** Statements are frozen; proofs are pending (submitted to
16-
Aristotle automated prover).
17-
1815
The graph distance between vertices `i` and `j` in `pathGraph (n + 1)`
19-
equals `|i - j|`. These lemmas are building blocks for distance proofs
20-
in recursive graph constructions.
16+
equals the absolute difference `|i - j|`. These lemmas fill a gap in
17+
Mathlib's `pathGraph` API (which has adjacency and connectivity but no
18+
distance results) and serve as building blocks for distance proofs in
19+
recursive graph constructions.
20+
21+
Proof strategies discovered by Aristotle (Harmonic) automated proof search,
22+
rewritten into human-owned form.
23+
24+
## Main definitions
25+
26+
None — this file provides only lemmas about existing Mathlib definitions.
2127
2228
## Main statements
2329
30+
- `SimpleGraph.pathGraph_edist` — `edist i j = |i.val - j.val|`
2431
- `SimpleGraph.pathGraph_dist` — `dist i j = |i.val - j.val|`
2532
- `SimpleGraph.pathGraph_dist_zero_last` — `dist 0 (Fin.last n) = n`
2633
- `SimpleGraph.pathGraph_edist_zero_last` — `edist 0 (Fin.last n) = n`
2734
35+
## Implementation notes
36+
37+
The key step is constructing a walk of length `|i - j|` by induction on the
38+
target vertex, then showing no shorter walk exists via a triangle-inequality
39+
argument on `Fin.val`. The `edist` result follows by `le_antisymm` on `iInf`.
40+
41+
## References
42+
43+
None — fills a gap in Mathlib's `SimpleGraph.Hasse` / `SimpleGraph.Metric` API.
44+
2845
## Tags
2946
3047
path graph, graph distance, Hasse diagram
@@ -34,26 +51,92 @@ namespace SimpleGraph
3451

3552
/-! ### Walk construction -/
3653

54+
/-- Walk from `0` to any vertex `i` in `pathGraph (n + 1)`, of length `i.val`. -/
55+
private theorem pathGraph_walk_from_zero {n : ℕ} (i : Fin (n + 1)) :
56+
∃ w : (pathGraph (n + 1)).Walk 0 i, w.length = i.val := by
57+
induction i using Fin.inductionOn with
58+
| zero => exact ⟨.nil, rfl⟩
59+
| succ i ih =>
60+
obtain ⟨w, hw⟩ := ih
61+
have hadj : (pathGraph (n + 1)).Adj i.castSucc i.succ := by
62+
rw [pathGraph_adj]; left; simp [Fin.val_succ, Fin.val_castSucc]
63+
exact ⟨w.append (.cons hadj .nil), by simp [hw]⟩
64+
3765
/-- There is a walk of length `n` from `0` to `Fin.last n` in `pathGraph (n + 1)`. -/
3866
theorem pathGraph_exists_walk_zero_last (n : ℕ) :
39-
∃ w : (pathGraph (n + 1)).Walk 0 (Fin.last n), w.length = n := by
40-
sorry
67+
∃ w : (pathGraph (n + 1)).Walk 0 (Fin.last n), w.length = n :=
68+
(pathGraph_walk_from_zero (Fin.last n)).imp fun _ h ↦ by simpa [Fin.val_last] using h
69+
70+
/-! ### Walk bounds -/
71+
72+
/-- Walk from `i` to `j` of length `j.val - i.val` when `i.val ≤ j.val`. -/
73+
private theorem pathGraph_walk_le {n : ℕ} {i j : Fin (n + 1)} (hij : i.val ≤ j.val) :
74+
∃ w : (pathGraph (n + 1)).Walk i j, w.length = j.val - i.val := by
75+
induction j using Fin.inductionOn with
76+
| zero =>
77+
have hi : i = 0 := by ext; exact Nat.le_zero.mp hij
78+
exact hi ▸ ⟨.nil, by simp⟩
79+
| succ j ih =>
80+
by_cases h : i.val ≤ j.val
81+
· obtain ⟨w, hw⟩ := ih h
82+
have hadj : (pathGraph (n + 1)).Adj j.castSucc j.succ := by
83+
rw [pathGraph_adj]; left; simp [Fin.val_succ, Fin.val_castSucc]
84+
exact ⟨w.append (.cons hadj .nil), by simp [hw]; omega⟩
85+
· have hval : j.succ.val = j.val + 1 := Fin.val_succ j
86+
have hi : i = j.succ := Fin.ext (by omega)
87+
subst hi; exact ⟨.nil, by simp⟩
88+
89+
/-- Any walk in `pathGraph` has length ≥ the index difference between endpoints.
90+
Each step changes the index by exactly 1, so `|i - j|` steps are needed. -/
91+
private theorem pathGraph_walk_length_ge {n : ℕ} {i j : Fin (n + 1)}
92+
(p : (pathGraph (n + 1)).Walk i j) :
93+
(if i.val ≤ j.val then j.val - i.val else i.val - j.val) ≤ p.length := by
94+
induction p with
95+
| nil => simp
96+
| @cons u v w hadj p ih =>
97+
have : u.val + 1 = v.val ∨ v.val + 1 = u.val := by
98+
rw [pathGraph_adj] at hadj; exact hadj
99+
simp only [Walk.length_cons]
100+
split_ifs at ih ⊢ <;> omega
101+
102+
/-! ### Extended distance formula -/
103+
104+
/-- Extended distance in a path graph equals the absolute difference of indices. -/
105+
theorem pathGraph_edist {n : ℕ} (i j : Fin (n + 1)) :
106+
(pathGraph (n + 1)).edist i j =
107+
↑(if i.val ≤ j.val then j.val - i.val else i.val - j.val) := by
108+
-- Exhibit an optimal walk
109+
obtain ⟨w, hw⟩ : ∃ w : (pathGraph (n + 1)).Walk i j,
110+
w.length = if i.val ≤ j.val then j.val - i.val else i.val - j.val := by
111+
split_ifs with hij
112+
· exact pathGraph_walk_le hij
113+
· obtain ⟨w', hw'⟩ := pathGraph_walk_le (show j.val ≤ i.val by omega)
114+
exact ⟨w'.reverse, by rw [Walk.length_reverse, hw']⟩
115+
apply le_antisymm
116+
· -- Upper: edist ≤ walk length = target
117+
calc (pathGraph (n + 1)).edist i j
118+
≤ ↑w.length := edist_le w
119+
_ = _ := by exact_mod_cast hw
120+
· -- Lower: target ≤ every walk length → target ≤ iInf
121+
simp only [edist]
122+
exact le_iInf fun w' ↦ by exact_mod_cast pathGraph_walk_length_ge w'
41123

42124
/-! ### Distance formula -/
43125

44126
/-- Distance in a path graph equals the absolute difference of indices. -/
45127
theorem pathGraph_dist {n : ℕ} (i j : Fin (n + 1)) :
46-
(pathGraph (n + 1)).dist i j = if i.val ≤ j.val then j.val - i.val else i.val - j.val := by
47-
sorry
128+
(pathGraph (n + 1)).dist i j =
129+
if i.val ≤ j.val then j.val - i.val else i.val - j.val := by
130+
simp only [SimpleGraph.dist, pathGraph_edist, ENat.toNat_coe]
48131

49132
/-- Distance from `0` to `Fin.last n` in `pathGraph (n + 1)` is `n`. -/
50133
theorem pathGraph_dist_zero_last (n : ℕ) :
51134
(pathGraph (n + 1)).dist (0 : Fin (n + 1)) (Fin.last n) = n := by
52-
sorry
135+
rw [pathGraph_dist]; simp [Fin.val_last]
53136

54137
/-- The extended distance from `0` to `Fin.last n` in `pathGraph (n + 1)` is `n`. -/
55138
theorem pathGraph_edist_zero_last (n : ℕ) :
56139
(pathGraph (n + 1)).edist (0 : Fin (n + 1)) (Fin.last n) = n := by
57-
sorry
140+
rw [pathGraph_edist]; simp [Fin.val_last]
58141

59142
end SimpleGraph

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ FdFormal/
6767
FlowerLog.lean — Log identities and squeeze-sandwich bounds (all proofs complete)
6868
FlowerLogRatio.lean — HasLogRatioDimension definition (bridge target)
6969
FlowerDimension.lean — Headline theorem: log-ratio limit = log(u+v) / log(u)
70-
PathGraphDist.lean — pathGraph distance lemmas (building block for F2)
70+
PathGraphDist.lean — pathGraph distance lemmas (all proofs complete)
7171
FlowerConstruction.lean — F2 bridge construction (sketch, exploratory)
7272
Verify.lean — #print axioms dashboard (17 declarations)
7373
```

ROADMAP.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ construction sketch with five layers:
6060
giving the final `flowerGraph_dist_hubs` bridge statement.
6161
- Projection map `FlowerVert.project` is defined (not sorry).
6262

63-
Building block: `PathGraphDist.lean` provides sorry-stub lemmas for
63+
Building block: `PathGraphDist.lean` provides fully proved lemmas for
6464
`SimpleGraph.pathGraph` distance (`pathGraph_dist`, `pathGraph_dist_zero_last`,
6565
`pathGraph_edist_zero_last`). These have no Mathlib counterpart and are a
6666
candidate for a second upstream PR.

debt.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,6 @@
3333
- [ ] **GraphBall finite cardinality lemmas**`card_ball_mono` etc. require
3434
`[Fintype V]`. Separated from base definition by design. *(GraphBall.lean)*
3535

36-
- [ ] **pathGraph distance lemmas**`pathGraph_dist`, `pathGraph_dist_zero_last`,
37-
`pathGraph_edist_zero_last`, `pathGraph_exists_walk_zero_last`. These fill a
38-
Mathlib gap: distance in `pathGraph (n+1)` equals `|i - j|`. Currently sorry
39-
stubs. Needed as building blocks for recursive graph distance proofs.
40-
*(PathGraphDist.lean)*
41-
4236
### Deferred (future milestones)
4337

4438
- [ ] **Transfractal case u = 1** — Infinite d_B. Separate theorem with
@@ -84,3 +78,8 @@
8478
(squeeze). Zero sorry, zero custom axioms. Proves the limit, not yet
8579
formally connected to box-counting dimension.
8680
*(FlowerDimension.lean)*
81+
82+
- [x] **pathGraph distance lemmas**`pathGraph_dist`, `pathGraph_dist_zero_last`,
83+
`pathGraph_edist_zero_last`, `pathGraph_exists_walk_zero_last`. Distance in
84+
`pathGraph (n+1)` equals `|i - j|`. Zero sorry.
85+
*(PathGraphDist.lean)*
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/-
2+
This file was edited by Aristotle (https://aristotle.harmonic.fun).
3+
4+
Lean version: leanprover/lean4:v4.24.0
5+
Mathlib version: f897ebcf72cd16f89ab4577d0c826cd14afaafc7
6+
This project request had uuid: 7366dae4-aa7d-4c8a-a02f-40d2a6eee3a9
7+
8+
To cite Aristotle, tag @Aristotle-Harmonic on GitHub PRs/issues, and add as co-author to commits:
9+
Co-authored-by: Aristotle (Harmonic) <aristotle-harmonic@harmonic.fun>
10+
11+
The following was proved by Aristotle:
12+
13+
- theorem pathGraph_exists_walk_zero_last
14+
- theorem pathGraph_dist
15+
- theorem pathGraph_dist_zero_last
16+
- theorem pathGraph_edist_zero_last
17+
18+
NOTE: Proved on Lean 4.24.0, our project uses 4.28.0.
19+
Proofs need manual rewriting before integration.
20+
-/

0 commit comments

Comments
 (0)