with Text_IO;

procedure ANN_FS1 is
---------------------------------------------------------------------------
---------------------------------------------------------------------------
package F_IO is new Text_IO.Float_IO ( float );
use F_IO;
use Text_IO;
Neuron_Count : constant integer := 3;
type Neuron_Array is array ( 1..Neuron_Count ) of float;
Net_Inputs, Net_Outputs : Neuron_Array := ( others => 0.0 );
type Net_Array is array ( 1..Neuron_Count ) of Neuron_Array;
Net_Weights : Net_Array := ( others => ( others => 0.0 ) );

procedure Pause is
---------------------------------------------------------------------------
  Dummy: string ( 1..1 );
begin
  Put ( "Please press C then ENTER to continue..." );
  Get ( Dummy );
end Pause;

procedure Inputs_Get ( Net_Inputs : in out Neuron_Array ) is
---------------------------------------------------------------------------
begin
  for index in 1..Neuron_Count loop
    Put ( "Enter the state of neuron" & integer'image ( index )
      & " [" );
    Put ( Net_Inputs ( index ), 2, 1, 0 );
    Put ( " ]:  " );
    Get ( Net_Inputs ( index ) );
    Put ( "You have entered" );
    Put ( Net_Inputs ( index ), 2, 1, 0 );
    Put_Line ( "." );
  end loop;
end Inputs_Get;

function Sgn ( X : float ) return float is
---------------------------------------------------------------------------
begin
  if X < 0.0 then return -1.0;    end if;
  if X = 0.0 then return  0.0;    end if;
  if X > 0.0 then return +1.0;    end if;
end Sgn;

function Thr ( X : float; T : float := 0.0 ) return float is
---------------------------------------------------------------------------
begin
  if X <  T then return 0.0;    end if;
  if X >= T then return   X;    end if;
end Thr;

function Weighted_Sum ( X, W : Neuron_Array ) return float is
---------------------------------------------------------------------------
  WS : float := 0.0;
begin
  for index in 1..W'last loop
    WS := WS + W ( index ) * Thr ( X ( index ) );
  end loop;
  return WS;
end Weighted_Sum;

procedure Neuron_Resolve ( X: in     Neuron_Array;
			   W: in out Neuron_Array;
			   Y: in out float ) is
---------------------------------------------------------------------------
  C : constant float := 0.1;
  A, L : float;
begin
  A := Sgn ( Thr ( Weighted_Sum ( X, W ) ) );
  Put ( "A=" ); Put ( A, 2, 1, 0 ); Put_Line ( "" );
  Put ( "Y=" ); Put ( Y, 2, 1, 0 ); Put_Line ( "" );
  Y := -Sgn ( abs ( Y ) + Y ) + ( 1.0 - abs ( Sgn ( Y ) ) ) * A;
  Put ( "Y=" ); Put ( Y, 2, 1, 0 ); Put_Line ( "" );
  for index in 1..W'last loop
--  L := Sgn ( Y * Thr ( X ( index ) ) );
    L := Thr ( Sgn ( X ( index ) ) ) * ( Y + C );
    Put ( "L=" ); Put ( L, 2, 1, 0 ); Put_Line ( "" );
--  W ( index ) := Sgn ( Sgn ( W ( index ) ) + L );
    W ( index ) := W ( index ) + L;
    Put ( "W=" ); Put ( W ( index ), 2, 1, 0 ); Put_Line ( "" );
  end loop;
end Neuron_Resolve;

procedure Neuron_Show ( W : in Neuron_Array; Y : in float ) is
---------------------------------------------------------------------------
begin
  for index in 1..W'last loop
    Put ( " " );
    Put ( W ( index ), 2, 1, 0 );
  end loop;
  Put ( " " );
  Put ( Y, 2, 1, 0 );
  Put_Line ( "" );
end Neuron_Show;

---------------------------------------------------------------------------
---------------------------------------------------------------------------
begin
  loop
    for index in 1..Neuron_Count loop
      Neuron_Show ( Net_Weights ( index ), Net_Outputs ( index ) );
    end loop;
    Net_Inputs := Net_Outputs;
    Inputs_Get ( Net_Inputs );
--  Pause;
--  Net_Outputs := Net_Inputs;
    for Neuron in 1..Neuron_Count loop
      Neuron_Resolve ( Net_Inputs, Net_Weights ( Neuron ),
	Net_Outputs ( Neuron ) );
    end loop;
--  Net_Weights ( 1 ) := ( others => 1.0 );
  end loop;
end ANN_FS1;
