Rudimentary to creating Hopfield nets is a system of files for holding our lisp code = mathematics. We will explore departing from it later, but here there be idiomatic common lisp.

We are going to do literally every single thing. I am going to say exactly what I have typed and had work in all cases. I'm on openbsd current (7.3).

I am giving this project the name binry-hop = binary hopfield nets, pronounced bunny-hop.

I'm not going to try hard to justify every single thing I do. Use your imagination. In openbsd, pkg_add adds packages. ecl(1) is a famous lisp compiler. You could learn about it through man 1 ecl. rlwrap buffers terminal input to ecl so in rlwrap ecl inputting lines in the terminal has all the terminal stuff (C-a C-h C-k C-e.. Backspace etc). I figure you can learn more about a topic that puzzles you or catches your eye yourself.

#+BEGIN_SRC sh
pkg_add ecl rlwrap

printf "(require :asdf)" >> ~/.eclrc

mkdir -p ~/common-lisp/
#+END_SRC

A working hopfield net is just some mathematics and memory storage/retrieval, which needs no dependencies beyond our language. Systems of files for lisp projects are not specified in the standard, since there have been different ones but modern ASDF is what I want to use. So we are setting up an ASDF 3.1+ project.

#+BEGIN_SRC sh
mkdir ~/common-lisp/binry-hop
cd ~/common-lisp/binry-hop/

touch binry-hop.asd
mkdir src
touch src/util.lisp
touch src/all.lisp
#+END_SRC

Alright! This is a good little filesystem layout so we can see exactly how to make a new :package-inferred-system common lisp ASDF project which we can require easily in other projects and running lisp images, and load or recompile/reload specific changed files of without restarting a lisp image.

The binry-hop/binry-hop.asd file is our system configuration file

cat >> ~/common-lisp/binry-hop/binry-hop.asdf <<"EOF"
(defsystem "binry-hop"
:class :package-inferred-system
:depends-on ("binry-hop/src/all"))

(register-system-packages "binry-hop/src/util" '(:binry-hop/util))
(register-system-packages "binry-hop/src/all" '(:binry-hop))
"EOF"

:package-inferred-system infers packages from file paths relative to the project folder. Our idea here is that the package in path "binry-hop/src/all" that pulls in all the standard functionality packages in the project, under the name :binry-hop since it's not useful to say that it's the catch-all package and its src is in src in that case.

util is going to be our package for sm0l functions that don't have a particularly deep meaning in isolation that are useful in more than one place.

cat >> ~/common-lisp/binry-hop/src/util.lisp <<"EOG"
(uiop:define-package :binry-hop/util^M
(:export #:make-rectified-polynomial ^M
 #:bit-to-sign^M
 #:sign-to-bit^M
 #:b2s ^M
 #:s2b^M
 #:make-reread-stream^M
 #:diff-diff-signs^M
 #:make-re/write-stream)^M
(:nicknames :hop-util))^M
^M
(in-package :binry-hop/util)^M
^M
(defun make-rectified-polynomial (n) "^M
(make-rect-poly 3) ->^M
lambda (x) rectified (expt x 3)^M
"^M
(lambda (x)^M
 (cond ((<= x 0) '0) ((<  0 x) (expt x n))^M
       (t (error "unknown condition")))))^M
^M
(defun bit-to-sign (bit) "^M
(bit-to-sign 0) -> -1, 1 otherwise.^M
"^M
(cond ((zerop bit)       (values '-1))^M
      ((not (zerop bit)) (values '1) )^M
 (t (error "unknown condition"))))^M
^M
(defun b2s (b) "bit-to-sign" (bit-to-sign b))^M

"EOG"