with DC_Neur, Text_IO;
use  DC_Neur, Text_IO;

procedure ANN3 is
----------------------------------------------------------------------
----------------------------------------------------------------------
  package Float_IO is new Float_IO ( float );
  use Float_IO;
  Inputs_Count : constant := 3;
  type Training_Inputs_Type is array ( positive range <> )
    of Float_Array ( 1..Inputs_Count );
  Training_Inputs : constant Training_Inputs_Type
    := ( ( 0.0, 0.0, 1.0 ),
	 ( 0.0, 1.0, 1.0 ),
	 ( 1.0, 0.0, 1.0 ),
	 ( 1.0, 1.0, 1.0 ) );
  Neuron : Neuron_Type ( Inputs_Count => Inputs_Count )
    := ( Inputs_Count => Inputs_Count,
	 Weights      => ( others => 0.0 ),
	 Excitation   => 0.0,
	 Charge       => 1.0,
	 Is_Trained   => true );
  NOT_Outputs  : constant Float_Array := ( 1.0, 1.0, 0.0, 0.0 );
  AND_Outputs  : constant Float_Array := ( 0.0, 0.0, 0.0, 1.0 );
  NAND_Outputs : constant Float_Array := ( 1.0, 1.0, 1.0, 0.0 );
  XOR_Outputs  : constant Float_Array := ( 0.0, 1.0, 1.0, 0.0 );
-- XOR is linearly inseparable
  type Training_Outputs_Array_Type is array ( positive range <> )
    of Float_Array ( 1..( Inputs_Count - 1 )**2 );
  Training_Outputs_Array : constant Training_Outputs_Array_Type
    := ( NOT_Outputs, AND_Outputs, NAND_Outputs, XOR_Outputs );
  Output : float;
  Is_Finished_Training : boolean := true;
begin
  for index4 in Training_Outputs_Array'range loop
  for index2 in 0..100 loop
    Is_Finished_Training := true;
    Put_Line ( "Training_Inputs count: " & integer'image ( index2 ) );
    for index in Training_Inputs'range loop
      Put_Line ( "Training_Input" & integer'image ( index ) );
      Neuron.Excitation := 0.0;
      Neuron.Is_Trained := false;
      loop
	Float_Array_Show ( Training_Inputs ( index ) );
	Neuron_Show ( Neuron );
	Neuron_Resolve ( Training_Inputs ( index ), Neuron, Output );
	Put ( " O:" );
	Put ( Output, 2, 1, 2 );
	Put_Line ( "" );
	for index3 in 1..Inputs_Count loop
	  Put ( "        " );
	end loop;
	Neuron_Show ( Neuron );
	Put_Line ( "" );
	declare
	  DumStr : string ( 1..1 );
	  DumNat : natural;
	begin
	  Get_Line ( DumStr, DumNat );
	end;
	if Output = Training_Outputs_Array ( index4 ) ( index ) then
	  Neuron.Charge := 1.0;
	  exit;
	else
	  Is_Finished_Training := false;
	  Neuron.Is_Trained := true;
	end if;
      end loop;
    end loop;
    if Is_Finished_Training then
      Put_Line ( "Finished training after" & integer'image ( index2 )
	& " application(s)." );
      exit;
    end if;
  end loop;
  declare
    Q : character := ASCII.Nul;
  begin
    Put_Line ( "Enter a 'q' to quit..." );
    loop
      Get ( Q );
      exit when ( Q = 'q' ) or ( Q = 'Q' );
    end loop;
  end;
  end loop;
----------------------------------------------------------------------
----------------------------------------------------------------------
end ANN3;


