with
  Text_IO;

use
  Text_IO;

package body DC_Neur is
----------------------------------------------------------------------
----------------------------------------------------------------------

function  Net (
	    Initial_States : in States_Type;
	    File_Str       : in string;
	    Train_File     : in string := "" ) return States_Type is
----------------------------------------------------------------------
  package Float_IO is new Float_IO ( float );
  use Float_IO;
  Net_File,
  T_File: File_Type;
  Final_States    :  States_Type ( Initial_States'range );
  Weights         :  States_Type ( Initial_States'range );
  Weighted_Inputs :  States_Type ( Initial_States'range );
  Write_OK : boolean := false;
begin
  Open ( Net_File, In_File, File_Str );
  if Train_File /= "" then
    Create ( T_File, Out_File, Train_File );
  end if;
  for index1 in Initial_States'range loop
    Weights := ( others => 0.0 );
    for index2 in Weights'range loop
      exit when End_Of_Line ( Net_File );
      Get ( Net_File, Weights ( index2 ) );
    end loop;
    Neuron ( Initial_States, Weights, Final_States ( index1 ),
      Train_File /= "" );
    if Train_File /= "" then
      States_Write ( T_File, Weights, Write_OK );
    end if;
    Skip_Line ( Net_File );
  end loop;
  Close ( Net_File );
  if Train_File /= "" then
    Close ( T_File );
  end if;
  return Final_States;
end Net;

procedure Neuron (
	    Initial_States : in     States_Type;
	    Weights        : in out States_Type;
	    Output_State   :    out float;
	    Is_Trained     : in     boolean := false ) is
----------------------------------------------------------------------
  Temp_Output_State: float;
  Weighted_Inputs: States_Type ( Initial_States'range )
    := ( others => 0.0 );
begin
  for index in Weighted_Inputs'range loop
    Weighted_Inputs ( index )
      := Initial_States ( index ) * Weights ( index );
  end loop;
  Temp_Output_State := Threshhold ( Sum ( Weighted_Inputs ) );
  Output_State := Temp_Output_State;
  if Is_Trained then
    for index in Weights'range loop
      Weights ( index ) := Weights ( index )
	+ 0.02 * ( Temp_Output_State - 0.5 );
    end loop;
  end if;
end Neuron;

function  States_Count ( File_Str : in string ) return integer is
----------------------------------------------------------------------
  package Float_IO is new Float_IO ( float );
  use Float_IO;
  File     : File_Type;
  DumFloat : float;
  Temp     : integer := 0;
begin
  Open ( File, In_File, File_Str );
  loop
    exit when End_Of_Line ( File );
    Get ( File, DumFloat );
    Temp := Temp + 1;
  end loop;
  Close ( File );
  return Temp;
end States_Count;

procedure States_Read  (
	    File       : in  File_Type;
	    States     : out States_Type;
	    Read_OK    : out boolean ) is
----------------------------------------------------------------------
  package Float_IO is new Float_IO ( float );
  use Float_IO;
  DumNat: natural;
  DumStr: string ( 1..10 );
  Temp_States : States_Type ( States'range ) := ( others => 0.0 );
begin
  if End_Of_File ( File ) or End_Of_Line ( File ) then
    Read_OK := false;
    return;
  end if;
  for index in Temp_States'range loop
    exit when End_Of_Line ( File );
    Get ( File, Temp_States ( index ) );
  end loop;
  Get_Line ( File, DumStr, DumNat );
  States := Temp_States;
  Read_OK := true;
exception
  when others => Read_OK := false;
end States_Read;

procedure States_Write (
	    File     : in  File_Type;
	    States   : in  States_Type;
	    Write_OK : out boolean ) is
----------------------------------------------------------------------
  package Float_IO is new Float_IO ( float );
  use Float_IO;
begin
  for index in States'range loop
    Put ( File, States ( index ) );
    Put ( File, ' ' );
  end loop;
  Put_Line ( File, "" );
  Write_OK := true;
exception
  when others =>  Write_OK := false;
end States_Write;

function  Sum ( Weighted_Inputs: in States_Type ) return float is
----------------------------------------------------------------------
  Temp: float := 0.0;
begin
  for index in Weighted_Inputs'range loop
    Temp := Temp + Weighted_Inputs ( index );
  end loop;
  return Temp;
end Sum;

function  Threshhold ( Summed: in float ) return float is
----------------------------------------------------------------------
begin
  if Summed >= 0.5 then
    return 1.0;
  else
    return 0.0;
  end if;
end Threshhold;

----------------------------------------------------------------------
----------------------------------------------------------------------
end DC_Neur;
