---------------------------------------------------------------------------
-- FISL_One (C) David Wallace Croft 1994.
-- Demonstrates the FISL rule with one input, one weight, and one neuron.
--
-- Input          ==> Weight ==> Neuron
-- __/\__/\__/\__ ==> WE/WI  ==> __/| __/| __/| __
--                                  |/   |/   |/
-- FISL Learning = Frustrated Inhibitive Synaptic Localized Learning
-- The FISL rule states that when neurotransmitter is released at the
-- synaptic junction, the synaptic weight is potentiated if the neural
-- membrane potential is depolarized and the synaptic weight is depressed
-- if the neural membrane potential is hyperpolarized.
--
-- A neurotransmitter wave in the shape of the positive half of a sine wave
-- of frequency 1.0 is input to a synaptic junction.  Application of the
-- FISL rule results in the weight slowly increasing until the neuron
-- begins to just fire.  The weight then stabilizes to some value for that
-- input frequency and wave shape.  By increasing the frequency of the
-- input, we may increase or decrease the resultant weight harmonically.
--
-- The next step, not present in this file, is FIRE Training
-- (Forward Inculcated Relief of Excitation), which trains the weight by
-- varying the frequency of the input.  The FIRE Training rules states that
-- input frequency is set proportional to the input/output error.  As the
-- frequency is increased, the weight moves up and down in those strange
-- harmonics.  As the error is minimized, the input frequency is decreased
-- (though the wave shape remains the same) and the weight stabilizes.
---------------------------------------------------------------------------

with DC_Math; use DC_Math;
with Text_IO; use Text_IO;

procedure FISL_One is
---------------------------------------------------------------------------
---------------------------------------------------------------------------
  dT         : constant float := 0.01;          -- delta time
  Pi         : constant float := 3.14159;       -- Pi
  F          :          float := 1.0;           -- frequency of input
  W_Min      : constant float := 1.0e-10;       -- minimum weight value
  WE,                                           -- excitatory weight
  WI,                                           -- inhibitory weight
  W  :          float := 1.0;                   -- resultant weight
  T,                                            -- time
  N,                                            -- neurotransmitter input
  P    :          float := 0.0;                 -- membrane potential
  package Float_IO is new Float_IO ( float );   -- floating point i/o
  use Float_IO;
begin
  loop
    exit when T >= 100.0;
--    if T >= 1000.0 then      -- These commented out lines would slowly
--      T := 0.0;              -- raise the frequency from 1.0 to 10.0 Hz.
--      F := F + 0.01;         -- The results, shown in FISL_One.D1, reveal
--      Put ( W );             -- that the weight moves up and down in
--      Put_Line ( "" );       -- strange harmonics with the general
--    end if;                  -- trend being to increase.
--    exit when F > 10.0;
--    if T = 0.0 then
--      Put ( F , 3, 2, 0 );
--    end if;
    T := T + dT;
    N := Pos ( Sin ( 2.0 * Pi * F * T ) );  -- positive clipped sine wave
    W := WE / WI;                           -- inhibitory shunts excitatory
    P := ( P + W * N * dT ) * 0.9;          -- capacitance, input, leakage
    if P > 1.0 then                         -- depolarization causes...
      P := -P;                              -- hyperpolarization
    end if;
    WE := WE + P * N * WE * dt;             -- FISL rule for excitatory
    if WE < W_Min then
      WE := W_Min;                          -- prevents crashing program
    end if;
    WI := WI - P * N * WI * dt;             -- FISL rule for inhibitory
    if WI < W_Min then
      WI := W_Min;                          -- prevents crashing program
    end if;
    Put (  "F: "  ); Put ( F , 0, 2, 0 );   -- The results of this output,
    Put ( " T: "  ); Put ( T , 4, 2, 0 );   -- shown in FISL_One.D2, show
    Put ( " N: "  ); Put ( N , 0, 3, 0 );   -- the stabilization of the
    Put ( " P: "  ); Put ( P , 2, 2 );      -- weight as it move from 1.0
    Put ( " WE: " ); Put ( WE, 0, 2 );      -- to 38.4 somewhere around 25
    Put ( " WI: " ); Put ( WI, 0, 2 );      -- seconds.
    Put ( " W: "  ); Put ( W , 0, 2 );
    Put_Line ( "" );
  end loop;
end FISL_One;

