Documentation

CslibFrontier.Algorithms.WordRAM.KargerMinCut

Karger's randomized global minimum cut algorithm on the word RAM #

Implements Karger's randomized contraction algorithm [Karger1993] on n-vertex weighted undirected multigraphs (n ≥ 2, IsMultigraph W) over Cslib.WordRAM.Basis.standard, providing three complete machine-level endpoints built on the workspace-relocatable subroutine contractDownTo:

  1. Single-trial contraction (singleProgram, r = 16): runs on n :: flattenMatrix W, computes row degrees at 2 + n ^ 2, contracts in place down to 2 supervertices in at most 42 * n ^ 2 + 12 * n + 21 steps and n - 2 rand calls, outputs a genuine non-trivial cut weight cutWeight W C ≥ minCut W on every supported branch, and achieves minCut W with probability at least 2 / (n * (n - 1)) whenever 0 < minCut W.
  2. Repeated-trial amplification (amplifiedProgram, r = 22): runs on R :: n :: flattenMatrix W (1 ≤ R), copies the immutable input matrix from [3, 3 + n ^ 2) into [3 + n ^ 2, 3 + 2 * n ^ 2) via Cslib.WordRAM.ArrayCopy before each of R independent contractions, halts within R * (50 * n ^ 2 + 12 * n + 30) + 16 steps and R * (n - 2) rand calls with a genuine non-trivial cut weight ≥ minCut W, and misses minCut W with probability at most (1 - 2 / (n * (n - 1))) ^ R whenever 0 < minCut W.
  3. Explicit O(n ^ 4 log n) high-probability global minimum cut (highProbProgram, r = 22): runs on n :: flattenMatrix W, computes highProbTrials n = (n * (n - 1) / 2) * (⌊log₂ n⌋ + 2) in registers using shifts and multiplication (without .div or .mod), halts within 33 * n ^ 4 * (Nat.log 2 n + 2) steps with a genuine non-trivial cut weight ≥ minCut W, and misses minCut W with probability at most 1 / (2 * n) whenever 0 < minCut W (and unconditionally at most 1 / n in highProbProgram_failure_le_inv_n), via an elementary Bernoulli power bound without Real.exp.

No probability is proved on machine states. Each program simulates a client of Cslib.Algorithms.Lean.Karger: the word it outputs has the law of the answer of Cslib.Algorithms.Lean.Karger.karger (singleCode_law), or of the amplification client Cslib.Algorithms.Lean.Karger.minRuns run against independent runs of karger (amplifiedCode_law, highProbCode_law). Each trial contracts as the client does (contractDownTo_law) and reads half the total weight of the two supervertices left (ContractState.mem_add_one), and the loop of trials keeps the least answer as minRuns does (ampTrialBody_law, ampLoop_law). The success and failure bounds and the cut realization are the specification's (Cslib.Algorithms.Lean.Karger.two_div_le_toOuterMeasure_karger, Cslib.Algorithms.Lean.Karger.minRuns_ne_minCut_le, Cslib.Algorithms.Lean.Karger.exists_cut_of_mem_support_answerLaw, Cslib.Algorithms.Lean.Karger.mem_support_minRuns), carried through those laws.

Source statements and notation mapping #

Main definitions #

Main results #

References #

Word-size sufficiency and Data.init matrix layout #

Under 2 ≤ n and logWidth 3 n ≤ w, workspace end-addresses up to 3 + 2 * (n * n) + n fit in w-bit words.

Under 2 ≤ n and logWidth 3 n ≤ w, highProbTrials n fits in w-bit words.

logWidth 3 n ≤ w and Fits w (totalDoubledWeight W) suffice for InputFits w (n :: flattenMatrix W).

logWidth 3 n ≤ w, Fits w R, and Fits w (totalDoubledWeight W) suffice for InputFits w (R :: n :: flattenMatrix W).

In Data.init (R :: n :: flattenMatrix W), memory holds W at base 3 with stride n.

Endpoint 1: Single-trial Basic Karger (r = 16) #

Setup for singleCode: read n from mem[1] and configure (wBase, dBase, stride, activeK, targetT) = (2, 2 + n * n, n, n, 2).

Instances For

    Postprocessing for singleCode: load the contracted superedge weight mem[wBase + 1] into val1.

    Instances For

      Structured 16-register single-trial Karger contraction program on n :: flattenMatrix W.

      Instances For

        Compiled 16-register single-trial Karger contraction program.

        Instances For

          Worst-case instruction bound 42 * n ^ 2 + 12 * n + 21 for singleProgram.

          Instances For
            theorem Cslib.Algorithms.WordRAM.Karger.singlePost_exec {w wb : ℕ} {x : WordRAM.Data 16} (hwBase : x.regs Reg.wBase = wb) (h1 : WordRAM.Fits w 1) (hwb1 : WordRAM.Fits w (wb + 1)) :
            ∃ (y : WordRAM.Data 16), WordRAM.Exec w singlePost x y 3 ∧ y.mem = x.mem ∧ y.regs Reg.val1 = x.mem (wb + 1)
            theorem Cslib.Algorithms.WordRAM.Karger.singleCode_law {n w : ℕ} {W : Fin n → Fin n → ℕ} (hn : 2 ≤ n) (hW : WeightedCut.IsMultigraph W) (hw : WordRAM.logWidth 3 n ≤ w) (htot : WordRAM.Fits w (WeightedCut.totalDoubledWeight W)) :
            WordRAM.ExecRandLaw w singleCode (WordRAM.Data.init (n :: flattenMatrix W)) (fun (y : WordRAM.Data 16) => WordRAM.Modifies (Finset.Ico 2 (2 + n * n + n)) (WordRAM.Data.init (n :: flattenMatrix W)).mem y.mem) (42 * n ^ 2 + 12 * n + 20) (n - 2) (fun (y : WordRAM.Data 16) => y.regs Reg.val1) (Lean.Karger.answerLaw { size := n, weight := W })

            A single trial runs karger. At word size w ≥ logWidth 3 n with totalDoubledWeight W < 2 ^ w, singleCode on n :: flattenMatrix W runs within singleTime n - 1 instructions and n - 2 rand calls and writes only [2, 2 + n * n + n). The weight it leaves in val1 has the law of the answer of Lean.Karger.karger on ⟨n, W⟩: contractDownTo contracts as the client does (contractDownTo_law), and singlePost reads the weight between the last two supervertices, half their total weight.

            Single-trial Basic Karger specification (singleProgram). At word size w ≥ logWidth 3 n when totalDoubledWeight W < 2 ^ w:

            1. singleProgram halts within singleTime n = 42 * n ^ 2 + 12 * n + 21 steps;
            2. executes at most n - 2 rand calls;
            3. on every supported branch, outputs cutWeight W C ≥ minCut W for a genuine non-trivial cut C of W while modifying memory only in [2, 2 + n * n + n);
            4. when 0 < minCut W (excluded only for proof convenience; S = 0 contraction still halts fault-free with a valid cut weight), outputs minCut W with probability at least 2 / (n * (n - 1)).

            Shared R-trial amplification engine (r = 22) #

            @[reducible, inline]

            Constant register 0 (Reg.zero embedded into Fin 22).

            Instances For
              @[reducible, inline]

              Constant register 1 (Reg.one embedded into Fin 22).

              Instances For
                @[reducible, inline]

                Working matrix base address (Reg.wBase embedded into Fin 22).

                Instances For
                  @[reducible, inline]

                  Working degree-array base address (Reg.dBase embedded into Fin 22).

                  Instances For
                    @[reducible, inline]

                    Working matrix row stride (Reg.stride embedded into Fin 22).

                    Instances For
                      @[reducible, inline]

                      Active supervertex count k (Reg.activeK embedded into Fin 22).

                      Instances For
                        @[reducible, inline]

                        Target supervertex count t (Reg.targetT embedded into Fin 22).

                        Instances For
                          @[reducible, inline]

                          Active doubled edge weight S (Reg.totS embedded into Fin 22).

                          Instances For
                            @[reducible, inline]

                            Loop index scratch register (Reg.idx embedded into Fin 22).

                            Instances For
                              @[reducible, inline]

                              Loop counter / remainder scratch register (Reg.rem embedded into Fin 22).

                              Instances For
                                @[reducible, inline]

                                Primary scratch address register (Reg.addr1 embedded into Fin 22).

                                Instances For
                                  @[reducible, inline]

                                  Primary scratch value register (Reg.val1 embedded into Fin 22).

                                  Instances For
                                    @[reducible, inline]

                                    Secondary scratch value register (Reg.val2 embedded into Fin 22).

                                    Instances For
                                      @[reducible, inline]

                                      Base address of the immutable input matrix W.

                                      Instances For
                                        @[reducible, inline]

                                        Original vertex count n, preserved across all trials.

                                        Instances For
                                          @[reducible, inline]

                                          Word count n * n of the flattened matrix.

                                          Instances For
                                            @[reducible, inline]

                                            Total number R of independent trials to execute.

                                            Instances For
                                              @[reducible, inline]

                                              Number of trials completed so far (0 .. R).

                                              Instances For
                                                @[reducible, inline]

                                                Minimum cut weight seen across completed trials.

                                                Instances For

                                                  Injective register map embedding Cslib.WordRAM.ArrayCopy (r = 7) into Fin 22 with (src, dst, len, idx, addr, value, one) = (srcBase, wBase, matLen, idx, addr1, val1, one).

                                                  Instances For

                                                    Postprocessing at the end of each trial: extract mem[wBase + 1], update bestVal (replacing it unconditionally on trial 0 and taking the minimum thereafter), and increment trialIdx.

                                                    Instances For

                                                      Single amplification trial: copy [srcBase, srcBase + n * n) into wBase, initialize row degrees at dBase, contract down to 2 supervertices, and update bestVal.

                                                      Instances For

                                                        Loop running numTrials independent contractions.

                                                        Instances For

                                                          Shared amplification core assuming srcBase, nOrig, and numTrials are initialized in registers.

                                                          Instances For
                                                            structure Cslib.Algorithms.WordRAM.Karger.AmpInv (w sb n R i : ℕ) (W : Fin n → Fin n → ℕ) (mem₀ : ℕ → ℕ) (x : WordRAM.Data 22) :

                                                            Loop invariant for ampLoop at trialIdx = i ≤ R.

                                                            Instances For
                                                              theorem Cslib.Algorithms.WordRAM.Karger.ampTrialBody_law {w sb n R i : ℕ} {W : Fin n → Fin n → ℕ} {mem₀ : ℕ → ℕ} {x : WordRAM.Data 22} (hn : 2 ≤ n) (hW : WeightedCut.IsMultigraph W) (hiR : i < R) (h1 : WordRAM.Fits w 1) (hdEnd : WordRAM.Fits w (sb + 2 * (n * n) + n)) (hR_fit : WordRAM.Fits w R) (htot : WordRAM.Fits w (WeightedCut.totalDoubledWeight W)) (hinv : AmpInv w sb n R i W mem₀ x) :
                                                              WordRAM.ExecRandLaw w ampTrialBody x (AmpInv w sb n R (i + 1) W mem₀) (49 * n ^ 2 + 12 * n + 27) (n - 2) (fun (y : WordRAM.Data 22) => y.regs AmpReg.bestVal) (PMF.map (fun (v : ℕ) => if i = 0 then v else min v (x.regs AmpReg.bestVal)) (Lean.Karger.answerLaw { size := n, weight := W }))

                                                              One trial runs karger. From AmpInv at trial i < R, ampTrialBody runs within 49 n² + 12 n + 27 instructions and n - 2 rand calls and keeps the invariant at trial i + 1. Its new bestVal has the law of the answer v of Lean.Karger.karger on ⟨n, W⟩, taken as is on the first trial and as min v bestVal after: contractDownToAt contracts the fresh copy of W as the client does (contractDownToAt_law), and ampTrialPost reads the weight between the last two supervertices, half their total weight.

                                                              theorem Cslib.Algorithms.WordRAM.Karger.ampLoop_law {w sb n R : ℕ} {W : Fin n → Fin n → ℕ} {mem₀ : ℕ → ℕ} (hR : 1 ≤ R) (hn : 2 ≤ n) (hW : WeightedCut.IsMultigraph W) (h1 : WordRAM.Fits w 1) (hdEnd : WordRAM.Fits w (sb + 2 * (n * n) + n)) (hR_fit : WordRAM.Fits w R) (htot : WordRAM.Fits w (WeightedCut.totalDoubledWeight W)) (rem i : ℕ) (x : WordRAM.Data 22) :
                                                              i + rem = R → AmpInv w sb n R i W mem₀ x → WordRAM.ExecRandLaw w ampLoop x (AmpInv w sb n R R W mem₀) (rem * (50 * n ^ 2 + 12 * n + 30) + 2) (rem * (n - 2)) (fun (y : WordRAM.Data 22) => y.regs AmpReg.bestVal) (OracleComp.evalWith (fun (x : Unit) => Lean.Karger.answerLaw { size := n, weight := W }) (if i = 0 then Lean.Karger.minRuns rem else OracleComp.iterate rem Lean.Karger.minStep (x.regs AmpReg.bestVal)))

                                                              The loop of trials runs amplified Karger. From AmpInv at trial i, with rem = R - i trials left, ampLoop runs within rem (50 n² + 12 n + 30) + 2 instructions and rem (n - 2) rand calls and ends at trial R. Its bestVal has the law of the amplification client run against independent runs of Lean.Karger.karger on ⟨n, W⟩: of Lean.Karger.minRuns rem on the first trial, and of rem more Lean.Karger.minSteps from bestVal after.

                                                              theorem Cslib.Algorithms.WordRAM.Karger.ampCore_law {w sb n R : ℕ} {W : Fin n → Fin n → ℕ} {x : WordRAM.Data 22} (hR : 1 ≤ R) (hn : 2 ≤ n) (hW : WeightedCut.IsMultigraph W) (hsb : x.regs AmpReg.srcBase = sb) (hnOrig : x.regs AmpReg.nOrig = n) (hnumT : x.regs AmpReg.numTrials = R) (h1 : WordRAM.Fits w 1) (hdEnd : WordRAM.Fits w (sb + 2 * (n * n) + n)) (hR_fit : WordRAM.Fits w R) (htot : WordRAM.Fits w (WeightedCut.totalDoubledWeight W)) (hsrc_mat : HoldsMatrix x.mem sb n W) :
                                                              WordRAM.ExecRandLaw w ampCore x (fun (y : WordRAM.Data 22) => WordRAM.Modifies (Finset.Ico (sb + n * n) (sb + 2 * (n * n) + n)) x.mem y.mem) (R * (50 * n ^ 2 + 12 * n + 30) + 8) (R * (n - 2)) (fun (y : WordRAM.Data 22) => y.regs AmpReg.bestVal) (OracleComp.evalWith (fun (x : Unit) => Lean.Karger.answerLaw { size := n, weight := W }) (Lean.Karger.minRuns R))

                                                              The amplification core runs amplified Karger. For 1 ≤ R trials, from a state with srcBase = sb, nOrig = n, numTrials = R and HoldsMatrix x.mem sb n W, ampCore runs within R (50 n² + 12 n + 30) + 8 instructions and R (n - 2) rand calls and writes only the workspace. Its bestVal has the law of Lean.Karger.minRuns R against independent runs of Lean.Karger.karger on ⟨n, W⟩.

                                                              Endpoint 2: Amplified R-trial Karger (r = 22) #

                                                              Setup for amplifiedCode on R :: n :: flattenMatrix W: load R = mem[1], n = mem[2], and set srcBase = 3.

                                                              Instances For

                                                                Structured 22-register R-trial Karger program on R :: n :: flattenMatrix W.

                                                                Instances For

                                                                  Compiled 22-register R-trial Karger program.

                                                                  Instances For

                                                                    Worst-case instruction bound R * (50 * n ^ 2 + 12 * n + 30) + 16 for amplifiedProgram.

                                                                    Instances For
                                                                      theorem Cslib.Algorithms.WordRAM.Karger.amplifiedCode_law {R n w : ℕ} {W : Fin n → Fin n → ℕ} (hR : 1 ≤ R) (hn : 2 ≤ n) (hW : WeightedCut.IsMultigraph W) (hw : WordRAM.logWidth 3 n ≤ w) (hR_fit : WordRAM.Fits w R) (htot : WordRAM.Fits w (WeightedCut.totalDoubledWeight W)) :
                                                                      WordRAM.ExecRandLaw w amplifiedCode (WordRAM.Data.init (R :: n :: flattenMatrix W)) (fun (y : WordRAM.Data 22) => WordRAM.Modifies (Finset.Ico (3 + n * n) (3 + 2 * (n * n) + n)) (WordRAM.Data.init (R :: n :: flattenMatrix W)).mem y.mem) (R * (50 * n ^ 2 + 12 * n + 30) + 15) (R * (n - 2)) (fun (y : WordRAM.Data 22) => y.regs AmpReg.bestVal) (OracleComp.evalWith (fun (x : Unit) => Lean.Karger.answerLaw { size := n, weight := W }) (Lean.Karger.minRuns R))

                                                                      amplifiedCode runs amplified Karger. At word size w ≥ logWidth 3 n with 1 ≤ R, R < 2 ^ w and totalDoubledWeight W < 2 ^ w, amplifiedCode on R :: n :: flattenMatrix W runs within amplifiedTime R n - 1 instructions and R (n - 2) rand calls and writes only [3 + n * n, 3 + 2 * (n * n) + n). Its bestVal has the law of Lean.Karger.minRuns R against independent runs of Lean.Karger.karger on ⟨n, W⟩.

                                                                      R-trial amplified Karger specification (amplifiedProgram). At word size w ≥ logWidth 3 n when 1 ≤ R, R < 2 ^ w, and totalDoubledWeight W < 2 ^ w:

                                                                      1. amplifiedProgram halts within amplifiedTime R n = R * (50 * n ^ 2 + 12 * n + 30) + 16 steps;
                                                                      2. executes at most R * (n - 2) rand calls;
                                                                      3. on every supported branch, outputs cutWeight W C ≥ minCut W for a genuine non-trivial cut C of W while modifying memory only in [3 + n * n, 3 + 2 * (n * n) + n);
                                                                      4. when 0 < minCut W (excluded only for proof convenience; S = 0 contraction still halts fault-free with a valid cut weight), misses minCut W with probability at most (1 - 2 / (n * (n - 1))) ^ R.

                                                                      Endpoint 3: Explicit O(n ^ 4 log n) high-probability global minimum cut (r = 22) #

                                                                      Body of logLoop: halve rem via right-shift by 1 and increment idx.

                                                                      Instances For

                                                                        Loop computing idx = Nat.log 2 n from rem = n (n ≥ 1), idx = 0, one = 1.

                                                                        Instances For

                                                                          Setup for highProbCode on n :: flattenMatrix W: load n = mem[1], compute numTrials = highProbTrials n = (n * (n - 1) / 2) * (Nat.log 2 n + 2) using shifts and multiplications, and set srcBase = 2.

                                                                          Instances For

                                                                            Structured 22-register O(n ^ 4 log n) high-probability Karger program on n :: flattenMatrix W.

                                                                            Instances For

                                                                              Compiled 22-register O(n ^ 4 log n) high-probability Karger program.

                                                                              Instances For

                                                                                Worst-case instruction bound 33 * n ^ 4 * (Nat.log 2 n + 2) for highProbProgram.

                                                                                Instances For
                                                                                  theorem Cslib.Algorithms.WordRAM.Karger.logLoop_exec {w n : ℕ} {x : WordRAM.Data 22} (hn : 1 ≤ n) (hone : x.regs AmpReg.one = 1) (hrem : x.regs AmpReg.rem = n) (hidx : x.regs AmpReg.idx = 0) (hnOrig : x.regs AmpReg.nOrig = n) (hn_fit : WordRAM.Fits w n) (hlg_fit : WordRAM.Fits w (Nat.log 2 n)) :

                                                                                  The setup's 4 log₂ n + 13 instructions, the highProbTrials n trials' highProbTrials n (50 n² + 12 n + 30) + 8 and the final halt fit in highProbTime n.

                                                                                  highProbCode runs amplified Karger. At word size w ≥ logWidth 3 n with totalDoubledWeight W < 2 ^ w, highProbCode on n :: flattenMatrix W runs within 4 log₂ n + highProbTrials n (50 n² + 12 n + 30) + 21 instructions and highProbTrials n (n - 2) rand calls and writes only [2 + n * n, 2 + 2 * (n * n) + n). Its bestVal has the law of Lean.Karger.minRuns (highProbTrials n) against independent runs of Lean.Karger.karger on ⟨n, W⟩.

                                                                                  Explicit O(n ^ 4 log n) high-probability global minimum cut (highProbProgram). At word size w ≥ logWidth 3 n when 2 ≤ n and totalDoubledWeight W < 2 ^ w:

                                                                                  1. highProbProgram halts within highProbTime n = 33 * n ^ 4 * (Nat.log 2 n + 2) steps;
                                                                                  2. executes at most highProbTrials n * (n - 2) rand calls;
                                                                                  3. on every supported branch, outputs cutWeight W C ≥ minCut W for a genuine non-trivial cut C of W while modifying memory only in [2 + n * n, 2 + 2 * (n * n) + n);
                                                                                  4. when 0 < minCut W (excluded only for proof convenience; S = 0 contraction still halts fault-free with a valid cut weight), misses minCut W with probability at most 1 / (2 * n).

                                                                                  highProbProgram misses minCut W with probability at most 1 / n, unconditionally without 2 ≤ n or 0 < minCut W: for n < 2 the bound 1 / n is at least 1, and for 2 ≤ n with minCut W = 0 every contraction trial outputs 0.