@@ -15,12 +15,15 @@ In this file we formalize the answer and related results to [xkcd's "nerd snipin
1515
1616Here we state the problem in a more general form in aribtrary dimensions: On the $n$-dimensional
1717grid where each neighboring nodes are connected by an one-ohm resistor, what is the equivalent
18- resistance between the two marked nodes?
18+ resistance between the two specified nodes?
1919
2020This file formalizes the following result
21- * The translation to a formal mathematical problem and proof of the unique solution (if exists).
22- * The general formula in arbitrary dimensions and for any pair of specific nodes.
23- * Computation for the solution in the two-dimension case, and the answer to the original question.
21+ * `equivResistance`: formal mathematical model of the problem.
22+ * `equivResistance_eq`: proof of the unique solution (if exists).
23+ * `equivResistance_formula`: The general formula in arbitrary dimensions and for any pair of nodes.
24+ * `computeφ`: explicit computation for the solution in the two-dimension case.
25+ * `equivResistance_2_1`: the answer to the question in xkcd.
26+
2427
2528 Hopefully this can protect me from a car accident.
2629-/
@@ -1463,6 +1466,13 @@ theorem equivResistance_eq_two_mul_φ [NeZero n] (x : Fin n → ℤ) :
14631466 rw [equivResistance_eq (isValidCircuit_φ 0 x)]
14641467 simp [two_mul]
14651468
1469+ /-- We can also write out the full formula for the equivalent resistance. -/
1470+ theorem equivResistance_formula [NeZero n] (x : Fin n → ℤ) :
1471+ equivResistance x =
1472+ some (2 * (2 * π)⁻¹ ^ n * ∫ (w : Fin n → ℝ) in Set.Icc (fun _ ↦ -π) (fun _ ↦ π),
1473+ (1 - Real.cos (∑ i, x i * w i)) / ∑ i, (2 - 2 * Real.cos (w i))) := by
1474+ rw [equivResistance_eq_two_mul_φ, φ, ← mul_assoc]
1475+
14661476/-- Applying this to the neighbor of the center, we get that the equivalent resistance between
14671477two neighboring points is $1 / n$. -/
14681478theorem equivResistance_off_center [NeZero n] (e : Fin n) :
@@ -2490,40 +2500,116 @@ theorem computeφ_eq (x y : ℕ) :
24902500 exact φ_swap y x
24912501 · simp only [computeφ, h, ↓reduceDIte, (getφTable (x + 1 )).eq_φ]
24922502
2503+ theorem equivResistance_eq_of_computeφ (x y : ℕ) (a b : ℚ) (h : computeφ x y = (a / 2 , b / 2 )) :
2504+ equivResistance ![ofNat(x), ofNat(y)] = some (a * π⁻¹ + b) := by
2505+ change equivResistance ![x, y] = some (a * π⁻¹ + b)
2506+ rw [equivResistance_eq_two_mul_φ, ← computeφ_eq, h]
2507+ simp
2508+ ring
2509+
2510+ open Lean Qq in
2511+ meta def realToRatExpr (e : Q(ℝ)) : MetaM (TSyntax `term) := do
2512+ match e with
2513+ | ~q(OfNat.ofNat $n (self := _)) =>
2514+ let some n := n.rawNatLit? | throwError "{n} is not a natural number"
2515+ .pure <| quote n
2516+ | ~q(OfNat.ofNat $m (self := _) / OfNat.ofNat $n (self := _)) =>
2517+ let some m := m.rawNatLit? | throwError "{m} is not a natural number"
2518+ let some n := n.rawNatLit? | throwError "{n} is not a natural number"
2519+ `($(quote m) / $(quote n))
2520+ | _ => throwError "Unsupported expression {e}"
2521+
2522+ open Lean Lean.Elab.Tactic Qq in
2523+ elab "comput_resistance" : tactic =>
2524+ withMainContext do
2525+ let e ← getMainTarget
2526+ let ⟨u, α, e⟩ ← inferTypeQ e
2527+ match u, α, e with
2528+ | 1 , ~q(Prop ), ~q(equivResistance ![ofNat($x), ofNat($y)] = some ($rhs)) =>
2529+ let some x := x.rawNatLit? | throwError "{x} is not a natural number"
2530+ let some y := y.rawNatLit? | throwError "{y} is not a natural number"
2531+ let x : TSyntax `term := quote x
2532+ let y : TSyntax `term := quote y
2533+ let (a, b) : TSyntax `term × TSyntax `term ← match rhs with
2534+ | ~q($a * π⁻¹ + $b) =>
2535+ let a ← realToRatExpr a
2536+ let b ← realToRatExpr b
2537+ .pure (a, b)
2538+ | ~q($a * π⁻¹ - $b) =>
2539+ let a ← realToRatExpr a
2540+ let b ← realToRatExpr b
2541+ let nb ← `(-$b)
2542+ .pure (a, nb)
2543+ | ~q($b - $a * π⁻¹) =>
2544+ let a ← realToRatExpr a
2545+ let b ← realToRatExpr b
2546+ let na ← `(-$a)
2547+ .pure (na, b)
2548+ | ~q($a * π⁻¹) =>
2549+ let a ← realToRatExpr a
2550+ .pure (a, quote 0 )
2551+ | ~q($a) =>
2552+ let a ← realToRatExpr a
2553+ .pure (quote 0 , a)
2554+ | _ => throwError "Unsupported expression"
2555+ evalTactic (← `(tactic| rw [equivResistance_eq_of_computeφ $x $y $a $b ?_]))
2556+ evalTactic (← `(tactic| · congrm some ?_; ring))
2557+ evalTactic (← `(tactic| · decide +kernel))
2558+ | _, _, _ => throwError "Unsupported expression"
2559+
24932560/-! Now we can verify the value of `φ` at any point in the first quadrant with just kernel
24942561reduction. -/
24952562
2496- theorem φ_2d_1_1 : φ ![1 , 1 ] = π⁻¹ := by
2497- suffices computeφ 1 1 = (1 , 0 ) by
2498- simpa [this] using (computeφ_eq 1 1 ).symm
2499- decide
2500-
2501- theorem φ_2d_2_2 : φ ![2 , 2 ] = (4 / 3 ) * π⁻¹ := by
2502- suffices computeφ 2 2 = (4 / 3 , 0 ) by
2503- simpa [this] using (computeφ_eq 2 2 ).symm
2504- decide +kernel
2505-
2506- theorem φ_2d_3_3 : φ ![3 , 3 ] = (23 / 15 ) * π⁻¹ := by
2507- suffices computeφ 3 3 = (23 / 15 , 0 ) by
2508- simpa [this] using (computeφ_eq 3 3 ).symm
2509- decide +kernel
2510-
2511- theorem φ_2d_2_1 : φ ![2 , 1 ] = 2 * π⁻¹ - 4 ⁻¹ := by
2512- suffices computeφ 2 1 = (2 , -4 ⁻¹) by
2513- simpa [this, ← sub_eq_add_neg] using (computeφ_eq 2 1 ).symm
2514- decide +kernel
2515-
2516- theorem φ_2d_42_7 : φ ![42 , 7 ] =
2517- 76593647770027443784355182739895062090786294026 / 200507537800595025 * π⁻¹ -
2518- 486376034966331052956526218433 / 4 := by
2519- suffices computeφ 42 7 =
2520- (76593647770027443784355182739895062090786294026 / 200507537800595025 ,
2521- -486376034966331052956526218433 / 4 ) by
2522- simpa [this, ← sub_eq_add_neg, neg_div] using (computeφ_eq 42 7 ).symm
2523- decide +kernel
2524-
2525- /-! Finally, let's answer the original question: the equivalent resistance is $4/\pi - 1/2$ -/
2526-
2527- theorem equivResistance_2_1 : equivResistance ![2 , 1 ] = some (4 * π⁻¹ - 2 ⁻¹) := by
2528- rw [equivResistance_eq_two_mul_φ, φ_2d_2_1]
2529- congrm some $(by ring)
2563+ theorem equivResistance_0_0 : equivResistance ![0 , 0 ] = some (0 ) := by
2564+ comput_resistance
2565+
2566+ theorem equivResistance_1_0 : equivResistance ![1 , 0 ] = some (1 / 2 ) := by
2567+ comput_resistance
2568+
2569+ theorem equivResistance_1_1 : equivResistance ![1 , 1 ] = some (2 * π⁻¹) := by
2570+ comput_resistance
2571+
2572+ theorem equivResistance_2_0 : equivResistance ![2 , 0 ] = some (2 - 4 * π⁻¹) := by
2573+ comput_resistance
2574+
2575+ /-- ✅ This is the answer of the original question: the equivalent resistance is $4 / \pi - 1 / 2$.
2576+ -/
2577+ theorem equivResistance_2_1 : equivResistance ![2 , 1 ] = some (4 * π⁻¹ - 1 / 2 ) := by
2578+ comput_resistance
2579+
2580+ theorem equivResistance_2_2 : equivResistance ![2 , 2 ] = some (8 / 3 * π⁻¹) := by
2581+ comput_resistance
2582+
2583+ theorem equivResistance_3_0 : equivResistance ![3 , 0 ] = some (17 / 2 - 24 * π⁻¹) := by
2584+ comput_resistance
2585+
2586+ theorem equivResistance_3_1 : equivResistance ![3 , 1 ] = some (46 / 3 * π⁻¹ - 4 ) := by
2587+ comput_resistance
2588+
2589+ theorem equivResistance_3_2 : equivResistance ![3 , 2 ] = some (4 / 3 * π⁻¹ + 1 / 2 ) := by
2590+ comput_resistance
2591+
2592+ theorem equivResistance_3_3 : equivResistance ![3 , 3 ] = some (46 / 15 * π⁻¹) := by
2593+ comput_resistance
2594+
2595+ theorem equivResistance_4_0 : equivResistance ![4 , 0 ] = some (40 - 368 / 3 * π⁻¹) := by
2596+ comput_resistance
2597+
2598+ theorem equivResistance_4_1 : equivResistance ![4 , 1 ] = some (80 * π⁻¹ - 49 / 2 ) := by
2599+ comput_resistance
2600+
2601+ theorem equivResistance_4_2 : equivResistance ![4 , 2 ] = some (6 - 236 / 15 * π⁻¹) := by
2602+ comput_resistance
2603+
2604+ theorem equivResistance_4_3 : equivResistance ![4 , 3 ] = some (24 / 5 * π⁻¹ - 1 / 2 ) := by
2605+ comput_resistance
2606+
2607+ theorem equivResistance_4_4 : equivResistance ![4 , 4 ] = some (352 / 105 * π⁻¹) := by
2608+ comput_resistance
2609+
2610+ /-- As a show case, the result can go really complicated for points far away. -/
2611+ theorem equivResistance_42_7 :
2612+ equivResistance ![42 , 7 ] =
2613+ some (153187295540054887568710365479790124181572588052 / 200507537800595025 * π⁻¹ -
2614+ 486376034966331052956526218433 / 2 ) := by
2615+ comput_resistance
0 commit comments