Documentation

Complexity.Algorithms.WordRAM.ElementDistinctness

Element distinctness in linear time on the word RAM #

In the comparison model, deciding whether n numbers are pairwise distinct needs Ω(n log n) comparisons, but on the word RAM numbers are also addresses. When the numbers are below n, a table of n flags decides distinctness in linear time by direct addressing Cormen et al., Section 11.1: allocate the table zeroed, then for each number check its flag, answering no if it is set and setting it otherwise.

Cslib.Algorithms.WordRAM.ElementDistinctness.decidesInTime_nodup formalizes this: on lists of naturals whose entries are below their length n, the compiled decider decides List.Nodup within 16 (n + 1) instructions, the final halt included, at every word size of at least 2 (⌊log₂ n⌋ + 1), with one binary digit at zero. Every instance fits at this threshold (Cslib.Algorithms.WordRAM.ElementDistinctness.inputFits). The decider allocates its table with Cslib.WordRAM.alloc and reads and writes it with Cslib.WordRAM.readAt and Cslib.WordRAM.writeAt; its correctness rests on the loop rule Cslib.WordRAM.ExecWithin.loop_invariant.

Main definitions #

Main results #

References #

The program #

Register names #

@[reducible, inline]

Register holding 0, as all registers do initially.

Instances For
    @[reducible, inline]

    Register holding 1.

    Instances For
      @[reducible, inline]

      Register holding the length n of the input.

      Instances For
        @[reducible, inline]

        The allocation frontier.

        Instances For
          @[reducible, inline]

          The number of cells to allocate.

          Instances For
            @[reducible, inline]

            The address n + 1 of the table of flags, just past the input.

            Instances For
              @[reducible, inline]

              Scratch register of the allocator.

              Instances For
                @[reducible, inline]

                The address i + 1 of the next input entry l[i].

                Instances For
                  @[reducible, inline]

                  The current input entry.

                  Instances For
                    @[reducible, inline]

                    Scratch register for table accesses.

                    Instances For
                      @[reducible, inline]

                      The flag of the current entry.

                      Instances For
                        @[reducible, inline]

                        The answer.

                        Instances For

                          Read the length, allocate a zeroed table of n flags just past the input, and start at the first entry with answer 1.

                          Instances For

                            Process one entry: if its flag is set, answer 0 and stop; otherwise set its flag and advance.

                            Instances For

                              The decision procedure for element distinctness: the answer is left in register ans.

                              Instances For

                                Additive-basis decision procedure for element distinctness.

                                Instances For
                                  @[reducible, inline]

                                  The instances: lists of naturals whose entries are below their length.

                                  Instances For

                                    Correctness #

                                    The loop invariant, after the first t = idx - 1 entries: the input is intact; either no duplicate has been found, the first t entries are distinct and the table flags exactly them, or a duplicate has been found, the answer is 0 and the loop is about to stop.

                                    Instances For

                                      Words of twice the number of binary digits of n hold 2 n + 1.

                                      Every instance fits at the logarithmic threshold used by the decider, and at every larger word size. Thus the input-fit premise in its uniform decision theorem is always satisfied.

                                      theorem Cslib.Algorithms.WordRAM.ElementDistinctness.body_spec {l : List ℕ} {w : ℕ} (hl : ∀ v ∈ l, v < l.length) (hw : WordRAM.Fits w (2 * l.length + 1)) {y : WordRAM.Data 12} (hy : Invariant l y) (hc : (WordRAM.Cond.lt Reg.idx Reg.base).Holds y) :

                                      One iteration of the loop takes at most 8 instructions, preserves the invariant, and either processes the next entry or stops.

                                      When the loop stops, the answer is 1 exactly if the input has no duplicates.

                                      theorem Cslib.Algorithms.WordRAM.ElementDistinctness.answers {l : List ℕ} {w : ℕ} (hl : ∀ v ∈ l, v < l.length) (hw : WordRAM.Fits w (2 * l.length + 1)) :

                                      Correctness and running time. On a list whose entries are below its length, at a word size that holds 2 n + 1, the decider leaves in register ans the answer to whether the list has no duplicates, within 14 n + 15 instructions.

                                      theorem Cslib.Algorithms.WordRAM.ElementDistinctness.decidesInTime_nodup :
                                      (decider.program Reg.ans).DecidesInTime (fun (x : ℕ) (l : Input) => ↑l) {l : Input | (↑l).Nodup} (fun (l : Input) (x : ℕ) => 16 * ((↑l).length + 1)) fun (l : Input) (w : ℕ) => WordRAM.logWidth 2 (↑l).length ≤ w

                                      Element distinctness in linear time. On lists of naturals whose entries are below their length n, the compiled decider decides whether there are no duplicates within 16 (n + 1) instructions, the final halt included, at every word size of at least 2 (⌊log₂ n⌋ + 1).

                                      Element distinctness is uniformly in linear time on the word RAM, for lists whose entries are below their length.

                                      Element distinctness also has a bounded nonuniform linear-time family.

                                      theorem Cslib.Algorithms.WordRAM.ElementDistinctness.decidesInTime_nodup_additive :
                                      (deciderAdditive.program Reg.ans).DecidesInTime (fun (x : ℕ) (l : Input) => ↑l) {l : Input | (↑l).Nodup} (fun (l : Input) (x : ℕ) => 16 * ((↑l).length + 1)) fun (l : Input) (w : ℕ) => WordRAM.logWidth 2 (↑l).length ≤ w

                                      Element distinctness in linear time over Basis.additive.

                                      Element distinctness is uniformly in linear time over Basis.additive, for lists whose entries are below their length.

                                      Element distinctness also has a bounded nonuniform linear-time family over Basis.additive.