#lang scheme

(define training_set
  (list
   (list 1 1)
   (list 1 0)
   (list 0 1)
   (list 0 0)
   (list 1 1)
   (list 1 0)
   (list 0 1)
   (list 0 0)
   ))
(define la_tabla
  (list
   (list 1 1 1 1 1)
   (list 1 1 0 0 0)
   (list 1 0 1 0 0)
   (list 1 0 0 1 1)
   (list 0 1 1 0 0)
   (list 0 1 0 1 1)
   (list 0 0 1 1 1)
   (list 0 0 0 0 0)
   ))
;;;Estructura formal de cada fila de una tabla:
;;; señal_1 señal_2 ... señal_n estado set-estado! set-respuesta!
;;;ejemplo
;;; 1 1 1 0 1 0

(define para-funciones
  (lambda (input estado tabla)
    (let go ((input+estado (append input (list estado)))
             (table tabla))
      (if (null? table)
          'raro
          (if (equal? input+estado
                      (take (first table) (length input+estado)))
              (list-tail (first table) (length input+estado))
              (go input+estado (rest table))
              )
          )
      )
    ))

;; CLASE AUTOMATA
(define automata%
  (class object%
    (init-field id)
    (field
;     (inputs '()); ver neurona
     (estado 0)
     (tabla 'una-tabla)
     (respuesta 0)
     )
    (define get-id
      (lambda ()
        id ))
    (define set-tabla
      (lambda (table)
        (set! tabla table) ))
    
    (define funcion-transicion
      (lambda (input)
        (let go ((input+estado (append input (list estado)))
                 (table tabla))
          (if (null? table)
              'raro
              (if (equal? input+estado
                          (take 
                           (first table) (length input+estado)))
                  (values
                   (list-ref 
                    (first table) (length input+estado))
                   )
                  (go input+estado (rest table))
                  )
              )
          )
        ))
    (define funcion-respuesta
      (lambda (input)
        (let go ((input+estado (append input (list estado)))
                 (table tabla))
          (if (null? table)
              'raro
              (if (equal? input+estado
                          (take 
                           (first table) (length input+estado)))
                  (values
                   (list-ref 
                    (first table) (add1 (length input+estado)))
                   )
                  (go input+estado (rest table))
                  )
              )
          )
        ))
    (define procesar!
      (lambda (señales)
        (let-values ([(state) (funcion-transicion señales)]
                     [(output) (funcion-respuesta señales)]
                     )
          (printf "Inputs ~a Estado ~a "
                  señales estado)
          (set! estado state)
          (set! respuesta output)
          (printf "Nuevo-estado ~a Respuesta ~a~n"
                  estado respuesta)
          respuesta) ))
    (public get-id set-tabla procesar!)
    (super-new) ))

;;;;;;;;;
(define q (make-object automata% 'q))
(send q set-tabla la_tabla)
(let go ((conj-e training_set))
  (if (null? conj-e)
      #t
      (begin
        (send q procesar! (car conj-e))
        (go (cdr conj-e))
        )
      )
  )