(in-package "binry-hop")
(defun closure-hop-net (number-bits)
(let ((potential (make-array number-bits :element-type '(integer 0 1)
:initial-contents (loop repeat number-bits collect '0)))
(memories (list))
(formatting-output "Potential: ~s~%Memories:~%~{~s~%~}"))
(labels ((rect-poly-2 (x) (if (< x 0) 0 (expt x 4)))
(b2s (x) (expt -1 (1+ x)))
(get-some (memory idx)
(loop for pot across potential
for mem across memory
for count from 0
summing
(cond
((= count idx) 0)
(t (* (b2s mem) (b2s pot))))))
(signed-idx (sgn memory idx some)
(rect-poly-2
(+ (* sgn (b2s (aref memory idx)))
some)))
(local-update (idx)
(setf
(aref potential idx)
(if
(minusp
(loop for memory in memories
for some = (get-some memory idx)
summing
(- (signed-idx +1 memory idx some)
(signed-idx -1 memory idx some))))
0 1))))
(lambda (&key push-memory pop-memory format-pot-mems update set-potential)
(cond
(set-potential
(loop for n below (length potential)
for s across set-potential
when s do (setf (aref potential n) s)))
(push-memory (push push-memory memories))
(pop-memory (pop memories))
(format-pot-mems
(if (stringp format-pot-mems)
(setf formatting-output format-pot-mems)
(format format-pot-mems
formatting-output potential memories)))
(update (if (numberp update) (local-update update)
(loop for idx below (length potential)
do (local-update idx)))))))))