#lang scheme/gui

;;;;;;;;;;PARA HACER DIBUJOS
(define x-ancho 600)
(define y-alto 300)
(define offset 40)
(define voffset 8)
;;;;;;;;;
(define ventana2
  (make-object frame% 
    "" 
    #f 
    (+ 10 x-ancho) (+ 10 (* y-alto 2))
    1300 0))

(define lienzo1
  (instantiate canvas% 
    (ventana2) 
    (style '(border)) ))

(define dc1 (send lienzo1 get-dc))

(define lienzo2
  (instantiate canvas% 
    (ventana2) 
    (style '(border)) ))

(define dc2 (send lienzo2 get-dc))
;;;;;;;;;
(define ventana1
  (make-object frame% 
    "" 
    #f 
    (+ 15 (* voffset 9)) 1200;(+ (* voffset 100) 150) 
    1800 0))

(define lienzo3
  (instantiate canvas% 
    (ventana1) 
    (style '(border)) ))

(define dc3 (send lienzo3 get-dc))
;;;;;;;;;;;
;;;;;ENTRENAMIENTO
;;;
(require "Graficos.rkt")
(require "Hopfield-2-Entrenamiento.rkt")
(require "Tablas-estimulos.rkt")
(require "Hopfield-4-version.rkt")

;;;LOS DATOS
(define matriz-ini
  (list
   '(1 0 0 0 0 0 0 0 0)
   '(0 1 0 0 0 0 0 0 0)
   '(0 0 1 0 0 0 0 0 0)
   '(0 0 0 1 0 0 0 0 0)
   '(0 0 0 0 1 0 0 0 0)
   '(0 0 0 0 0 1 0 0 0)
   '(0 0 0 0 0 0 1 0 0)
   '(0 0 0 0 0 0 0 1 0)
   '(0 0 0 0 0 0 0 0 1)
   ))
;;;;
(define training_set
  (list
   ;;cuadradas
   '(1 1 1 1 -1 1 1 1 1)
   ;;triangulares
   '(1 1 1 1 1 -1 1 -1 -1)
   '(1 1 1 -1 1 1 -1 -1 1)
   '(1 -1 -1 1 1 -1 1 1 1)
   '(-1 -1 1 -1 1 1 1 1 1)
   ;;líneas verticales simples
   '(1 -1 -1 1 -1 -1 1 -1 -1)
   '(-1 1 -1 -1 1 -1 -1 1 -1)
   '(-1 -1 1 -1 -1 1 -1 -1 1)
   ;;líneas horizontales simples
   '(1 1 1 -1 -1 -1 -1 -1 -1)
   '(-1 -1 -1 -1 -1 -1 1 1 1)
   '(-1 -1 -1 1 1 1 -1 -1 -1)
   ))
(define working_subset_estimulos
  (list
   ;;cuadradas
   '(1 1 1 1 1 1 1 1 1)
   '(1 1 1 1 -1 1 1 1 1)
   ;;en u
   '(1 -1 1 1 -1 1 1 1 1)
   '(1 1 1 1 -1 1 1 -1 1)
   '(1 1 1 1 -1 -1 1 1 1)
   '(1 1 1 -1 -1 1 1 1 1)
   ;;triangulares
   '(1 1 1 1 1 -1 1 -1 -1)
   '(1 1 1 -1 1 1 -1 -1 1)
   '(1 -1 -1 1 1 -1 1 1 1)
   '(-1 -1 1 -1 1 1 1 1 1)
   ;;una cruz
   '(-1 1 -1 1 1 1 -1 1 -1)
   ;;líneas verticales simples
   '(1 -1 -1 1 -1 -1 1 -1 -1)
   '(-1 1 -1 -1 1 -1 -1 1 -1)
   '(-1 -1 1 -1 -1 1 -1 -1 1)
   ;;líneas horizontales simples
   '(1 1 1 -1 -1 -1 -1 -1 -1)
   '(-1 -1 -1 -1 -1 -1 1 1 1)
   '(-1 -1 -1 1 1 1 -1 -1 -1)
   ;;diagonales
   '(1 -1 -1 -1 1 -1 -1 -1 1)
   '(-1 -1 1 -1 1 -1 1 -1 -1)
   ;;un punto central
   '(-1 -1 -1 -1 1 -1 -1 -1 -1)
   ;;sin estímulos
   '(-1 -1 -1 -1 -1 -1 -1 -1 -1)
   ))
(define training (genera-tabla-estimulos '(1 2 3 4 5 6 7 8 9) '(-1 1)))
;;
(define hopfield 
  (make-object red% (list n_0 n_1 n_2 n_3 n_4 n_5 n_6 n_7 n_8)))

(send hopfield set-datos-draw metodo-pintar dc3 voffset)
;;;ENTRENAMIENTO
(define proceso-estimulos
  (lambda (estimulos)
    (let go ((i 0)
             (j (length estimulos))
             )
      (if (= i j)
          #t
          (begin
            (printf "~a ~n"
                    (send hopfield proceso! (list-ref estimulos i)))
            (go (add1 i) j)
            )
          )
      )
    ))
;(proceso-estimulos training_set)
;(proceso-estimulos training)

(matriz-pesos training_set matriz-ini)
;(matriz-pesos training matriz-ini)
;
(define actualiza-matriz
  (lambda (neuronas matriz)
    (if (null? neuronas)
        #t
        (begin
          (send (car neuronas) set-pesos (car matriz))
          (actualiza-matriz (cdr neuronas) (cdr matriz))
          )
        )
    ))
    
(actualiza-matriz (send hopfield get-neuronas) (matriz-pesos training_set matriz-ini))
;(actualiza-matriz (send hopfield get-neuronas) (matriz-pesos training matriz-ini))

;;;;;;;;;EJECUCIÓN
;;;Las Ventanas
(send ventana2 show #t)
(send ventana1 show #t)
(sleep/yield 1)

;;;;

(define procesar-conjunto_estimulos
  (lambda (estimulos)
    (let go ((i 0)
             (j (length estimulos))
             )
      (if (= i j)
          #t
          (let* ((input (list-ref estimulos i))
                 (resp '())
                 )
            (sleep/yield 0.5)
            (send dc1 clear)
            (send dc1 draw-text "Estímulo" 240 20)
            (grid dc1 3 x-ancho y-alto offset)
            (pintar input x-ancho y-alto 3 3 offset dc1)
            (sleep/yield 0.5)
            (send dc2 clear)
            (send dc2 draw-text "Red" 240 20)
            (grid dc2 3 x-ancho y-alto offset)
            (set! resp (send hopfield proceso! input))
            (sleep/yield 0.5)
            (pintar 
             resp 
             x-ancho y-alto 3 3 offset dc2)
            (sleep/yield 2)
            ;(read-char)
            (go (add1 i) j)
            )
          )
      )
    ))

(procesar-conjunto_estimulos working_subset_estimulos)
;(procesar-conjunto_estimulos 
; (genera-tabla-estimulos '(1 2 3 4 5 6 7 8 9) '(-1 1)))