TorchLean API

NN.Spec.Models.Hopfield

Hopfield networks (spec-level) #

This file gives a Hopfield network model as a set of explicit mathematical definitions.

Intended use: mathematical scalars (, , etc.) and theorem statements/proofs. For computation, instantiate α := ℚ (or Rat) and evaluate seqStates / energy via #eval in an example file.

Note: we also provide Tensor-shaped wrappers (TensorState, TensorParams) so users can work with Tensor _ [n] instead of raw Fin n → _.

References #

Relationship to the Hopfield formalization case study #

This file provides the definitions (update rule, energy, trajectories). The global-dynamics results (energy monotonicity, fixed-point convergence bounds, tie-handling lemmas, etc.) are proved in NN/MLTheory/Proofs/Hopfield/* against these definitions.

If you’re reading this alongside “Formalized Hopfield Networks and Boltzmann Machines” (2025), the correspondence is:

Implementation status #

No API builder implements this model; it is used only by the proofs in NN/MLTheory/Proofs/Hopfield/* described above (Basic, Dynamics, Energy, Progress, Convergence).

Core data #

def Spec.Hopfield.act {α : Type} [One α] [Neg α] :
Boolα

Boolean activations interpreted as ±1.

We intentionally store Hopfield states as Bool (instead of α) because many proofs are simpler when the only possible activations are +1 and -1. The embedding into a numeric scalar α is explicit via act.

Instances For
    @[simp]
    theorem Spec.Hopfield.act_true {α : Type} [One α] [Neg α] :

    A true unit activates to +1.

    @[simp]
    theorem Spec.Hopfield.act_false {α : Type} [One α] [Neg α] :

    A false unit activates to -1; the network is the classical bipolar Hopfield model.

    @[reducible, inline]

    Hopfield state as a Boolean activation vector.

    Instances For
      @[reducible, inline]

      Hopfield state as a vector Tensor Bool [n].

      This representation connects the functional Hopfield state with TorchLean's tensor-shaped spec APIs.

      Instances For

        Convert a tensor state to the underlying function representation.

        Instances For

          Convert a function state to a tensor state.

          Instances For
            @[simp]

            Packing a state into a tensor and reading it back returns the same function.

            @[simp]

            Reading a tensor state out and packing it back returns the same tensor.

            The two directions together say the function and tensor views of a state carry the same information, so an energy argument written over Fin n → Bool transfers to the executable representation.

            def Spec.Hopfield.actVec {α : Type} [One α] [Neg α] {n : } (s : State n) :
            Fin nα

            The ±1 activation vector associated to a Boolean state.

            Instances For
              def Spec.Hopfield.dot {α : Type} [AddCommMonoid α] [Mul α] {n : } (x y : Fin nα) :
              α

              Dot product on vectors indexed by Fin n.

              This is a Fin-indexed sum, independent from any concrete matrix representation.

              Instances For
                def Spec.Hopfield.mulVec {α : Type} [AddCommMonoid α] [Mul α] {n : } (W : Fin nFin nα) (x : Fin nα) :
                Fin nα

                Matrix-vector product (as a function, not an array-backed matrix).

                Instances For
                  structure Spec.Hopfield.Params (α : Type) (n : ) :

                  Hopfield parameters:

                  • W is the weight matrix
                  • θ is the per-unit threshold / bias

                  Classic convergence results typically assume W is symmetric and has a zero diagonal. Those assumptions are not baked into this structure; they are stated and proved where needed.

                  • W : Fin nFin nα

                    Weight from unit j to unit i, indexed as W i j.

                  • θ : Fin nα

                    Activation threshold for each unit.

                  Instances For

                    Hopfield parameters as tensor-shaped weights and thresholds.

                    • Weight matrix, with destination units on the first axis and source units on the second.

                    • Rank-one tensor of per-unit activation thresholds.

                    Instances For

                      Convert tensor-shaped parameters to the function representation.

                      Instances For

                        Hopfield update dynamics #

                        def Spec.Hopfield.net {α : Type} [AddCommMonoid α] [Mul α] [One α] [Neg α] {n : } (p : Params α n) (s : State n) (u : Fin n) :
                        α

                        Net input to unit u: (W * x)_u, where x = actVec s is the ±1 encoding of the state.

                        Instances For
                          def Spec.Hopfield.netTensor {α : Type} [TorchLean.Storage α] [AddCommMonoid α] [Mul α] [One α] [Neg α] {n : } (p : TensorParams α n) (s : TensorState n) (u : Fin n) :
                          α

                          Tensor-shaped wrapper for net (useful for interop with TorchLean tensor APIs).

                          Instances For
                            def Spec.Hopfield.updateAt {α : Type} [AddCommMonoid α] [Mul α] [One α] [Neg α] [LE α] [DecidableRel fun (x1 x2 : α) => x1 x2] {n : } (p : Params α n) (s : State n) (u : Fin n) :

                            Asynchronous update at a single coordinate u.

                            We implement the standard thresholded sign rule:

                            s[u] := (θ_u ≤ net_u)

                            Interpreting true ↦ +1 and false ↦ -1, this corresponds to:

                            x_u := +1 if net_u ≥ θ_u, otherwise x_u := -1.

                            Tie-handling (net_u = θ_u) matters for formal convergence arguments; we pick the convention "ties go to +1" via .

                            Instances For
                              def Spec.Hopfield.updateAtTensor {α : Type} [TorchLean.Storage α] [AddCommMonoid α] [Mul α] [One α] [Neg α] [LE α] [DecidableRel fun (x1 x2 : α) => x1 x2] {n : } (p : TensorParams α n) (s : TensorState n) (u : Fin n) :

                              Tensor-shaped wrapper for updateAt.

                              Instances For
                                def Spec.Hopfield.IsStable {α : Type} [AddCommMonoid α] [Mul α] [One α] [Neg α] [LE α] [DecidableRel fun (x1 x2 : α) => x1 x2] {n : } (p : Params α n) (s : State n) :

                                A state is stable (a fixed point) if updating any single coordinate does nothing.

                                Instances For
                                  def Spec.Hopfield.pluses {n : } (s : State n) :

                                  Count how many units are in the true (+1) state.

                                  Instances For

                                    Hopfield energy #

                                    def Spec.Hopfield.energy {α : Type} [Field α] {n : } (p : Params α n) (s : State n) :
                                    α

                                    The classical Hopfield energy for a state s (quadratic term + linear threshold term).

                                    With x = actVec s the ±1 encoding, the energy is:

                                    E(s) = -1/2 * Σ_i Σ_j W_ij x_i x_j + Σ_i θ_i x_i.

                                    When W is symmetric and has a zero diagonal, asynchronous updates are known to monotonically decrease (or not increase) E, which is the classic Lyapunov-style argument for convergence.

                                    Instances For
                                      def Spec.Hopfield.energyTensor {α : Type} [TorchLean.Storage α] [Field α] {n : } (p : TensorParams α n) (s : TensorState n) :
                                      α

                                      Tensor-shaped wrapper for energy.

                                      Instances For
                                        def Spec.Hopfield.seqStates {α : Type} [AddCommMonoid α] [Mul α] [One α] [Neg α] [LE α] [DecidableRel fun (x1 x2 : α) => x1 x2] {n : } (p : Params α n) (useq : Fin n) (s0 : State n) :
                                        State n

                                        State sequence induced by an asynchronous update schedule useq.

                                        useq : NatFin n picks which coordinate to update at each discrete time step.

                                        PyTorch analogy: there is no direct equivalent in typical NN libraries, but you can think of it as an explicit, deterministic "update schedule" for coordinate descent.

                                        Instances For
                                          def Spec.Hopfield.seqStatesTensor {α : Type} [TorchLean.Storage α] [AddCommMonoid α] [Mul α] [One α] [Neg α] [LE α] [DecidableRel fun (x1 x2 : α) => x1 x2] {n : } (p : TensorParams α n) (useq : Fin n) (s0 : TensorState n) :

                                          Tensor-shaped wrapper for seqStates.

                                          Instances For
                                            def Spec.Hopfield.cyclicUseq (n : ) (hn : 0 < n) :
                                            Fin n

                                            A cyclic update schedule (0,1,2,...,n-1,0,1,...) for n > 0.

                                            Instances For

                                              Executable Hopfield (backend-friendly) #

                                              The definitions above (net, energy, …) are written in a math-first style using over Fin n. That is the right presentation for proofs, but it bakes in algebraic typeclasses like AddCommMonoid and uses Finset sums.

                                              When we execute Hopfield over IEEE-like scalars (e.g. Float, ExecFloat.Binary 8 23), we do not want to pretend those algebraic laws hold exactly: NaNs and rounding make addition non-associative and non-commutative in general. So for runtime execution we provide a “plain loop” variant that:

                                              This is the same model, written with the runtime arithmetic assumptions exposed.

                                              References:

                                              @[inline]
                                              def Spec.Hopfield.Exec.act {α : Type} [Context α] :
                                              Boolα

                                              Bipolar activation, re-exported here so the tensor-facing API needs no namespace prefix.

                                              Instances For
                                                @[inline]
                                                def Spec.Hopfield.Exec.theta {α : Type} [TorchLean.Storage α] {n : } (p : TensorParams α n) (i : Fin n) :
                                                α

                                                Threshold of unit i.

                                                Instances For
                                                  @[inline]
                                                  def Spec.Hopfield.Exec.weight {α : Type} [TorchLean.Storage α] {n : } (p : TensorParams α n) (i j : Fin n) :
                                                  α

                                                  Coupling weight between units i and j.

                                                  Instances For
                                                    def Spec.Hopfield.Exec.net {α : Type} [TorchLean.Storage α] [Context α] {n : } (p : TensorParams α n) (s : TensorState n) (u : Fin n) :
                                                    α

                                                    Net input to unit u computed by explicit iteration.

                                                    This matches Hopfield.netTensor, but avoids Finset sums so it can execute over IEEE-like scalars.

                                                    Instances For
                                                      def Spec.Hopfield.Exec.updateAt {α : Type} [TorchLean.Storage α] [Context α] [DecidableRel fun (x1 x2 : α) => x1 x2] {n : } (p : TensorParams α n) (s : TensorState n) (u : Fin n) :

                                                      Asynchronous update of a single coordinate u, using the same “ties go to +1” convention as the spec definition (θ_u ≤ net_u).

                                                      Instances For
                                                        def Spec.Hopfield.Exec.seqStates {α : Type} [TorchLean.Storage α] [Context α] [DecidableRel fun (x1 x2 : α) => x1 x2] {n : } (p : TensorParams α n) (useq : Fin n) (s0 : TensorState n) :

                                                        State sequence induced by an update schedule useq : NatFin n (loop-based).

                                                        Instances For
                                                          def Spec.Hopfield.Exec.energy {α : Type} [TorchLean.Storage α] [Context α] {n : } (p : TensorParams α n) (s : TensorState n) :
                                                          α

                                                          Hopfield energy computed by explicit iteration.

                                                          This matches the standard formula: E(s) = -1/2 * Σ_i Σ_j W_ij x_i x_j + Σ_i θ_i x_i, with x_i ∈ {+1,-1} obtained from the Boolean state.

                                                          Instances For