with
  DC_Neur,
  Text_IO;

use
  Text_IO;

procedure ANN2 is
---------------------------------------------------------------------------
---------------------------------------------------------------------------
package F_IO is new Float_IO ( float );
Layers: constant := 3;
View_Size: constant positive := 2;
View : DC_Neur.Inputs_Type ( 1..View_Size ) := ( others => 0.0 );
View_XOR: array ( 1..4 ) of DC_Neur.Inputs_Type ( 1..View_Size )
  :=  ( ( 0.0, 0.0 ), ( 0.0, 1.0 ), ( 1.0, 0.0 ), ( 1.0, 1.0 ) );
Output_Neurons_Count: constant positive := 3;
Net: DC_Neur.Net_Type ( 1..Layers )
  := (  -- Layers
       (  -- Layer 1
	 Neurons_Count => 4,
	 Neurons =>
	   (  -- Layer 1 Neurons
	     (  -- Layer 1 Neuron 1
	       Weights_Count => View'last,
	       Weights => ( 1.0, 0.0 ),
	       Charge => 1.0,
	       Last_Sum => 0.0,
	       Last_Output => 0.0
	     ), -- Layer 1 Neuron 1
	     (  -- Layer 1 Neuron 2
	       Weights_Count => View'last,
	       Weights => ( 0.0, 1.0 ),
	       Charge => 1.0,
	       Last_Sum => 0.0,
	       Last_Output => 0.0
	     ), -- Layer 1 Neuron 2
	     (  -- Layer 1 Neuron 3
	       Weights_Count => View'last,
	       Weights => ( 1.0, 0.0 ),
	       Charge => 1.0,
	       Last_Sum => 0.0,
	       Last_Output => 0.0
	     ), -- Layer 1 Neuron 3
	     (  -- Layer 1 Neuron 4
	       Weights_Count => View'last,
	       Weights => ( 0.0, 1.0 ),
	       Charge => 1.0,
	       Last_Sum => 0.0,
	       Last_Output => 0.0
	     )  -- Layer 1 Neuron 4
	   ) -- Layer 1 Neurons
       ), -- Layer 1
       (  -- Layer 2
	 Neurons_Count => 2,
	 Neurons =>
	   (  -- Layer 2 Neurons
	     (  -- Layer 2 Neuron 1
	       Weights_Count => 4,
	       Weights => ( 0.5, -0.1, 0.0, 0.0 ),
	       Charge => 1.0,
	       Last_Sum => 0.0,
	       Last_Output => 0.0
	     ), -- Layer 2 Neuron 1
	     (  -- Layer 2 Neuron 2
	       Weights_Count => 4,
	       Weights => ( 0.0, 0.0, -0.1, 0.5 ),
	       Charge => 1.0,
	       Last_Sum => 0.0,
	       Last_Output => 0.0
	     )  -- Layer 2 Neuron 2
	   )  -- Layer 2 Neurons
       ), -- Layer 2
       (  -- Layer 3
	 Neurons_Count => 1,
	 Neurons =>
	   (  -- Layer 3 Neurons
	     (  -- Layer 3 Neuron 1
	       Weights_Count => 2,
	       Weights => ( 0.5, 0.5 ),
	       Charge => 1.0,
	       Last_Sum => 0.0,
	       Last_Output => 0.0
	     ), -- Layer 3 Neuron 1
	     others => DC_Neur.Neuron_Type_Init
	   )  -- Layer 3 Neurons
       )  -- Layer 3
     ); -- Layers
Analysis : DC_Neur.Outputs_Type ( 1..Net ( Net'last ).Neurons_Count );

function  Net_Load return DC_Neur.Net_Type is
---------------------------------------------------------------------------
  Net: DC_Neur.Net_Type ( 1..10 );
  Net_File: File_Type;
begin
  Open ( Net_File, In_File, "NET.000" );
  DC_Neur.Get ( Net_File, Net );
  Close ( Net_File );
  return Net;
end Net_Load;

procedure Memorize ( Net: in DC_Neur.Net_Type ) is
---------------------------------------------------------------------------
  Net_File: File_Type;
begin
  Create ( Net_File, Out_File, "NET.000" );
  DC_Neur.Put ( Net_File, Net );
  Close ( Net_File );
end Memorize;

procedure See ( View: out DC_Neur.Inputs_Type ) is
---------------------------------------------------------------------------
  View_File: File_Type;
begin
  Open ( View_File, In_File, "VIEW.000" );
  for index in 1..View_Size loop
    F_IO.Get ( View_File, View ( index ) );
  end loop;
  Close ( View_File );
end See;

procedure Show ( View: in DC_Neur.Inputs_Type ) is
---------------------------------------------------------------------------
begin
  for index in View'range loop
    F_IO.Put ( View ( index ), 2, 2, 3 );
    Put ( ' ' );
    if index mod View_Size = 0 then
      Put_Line ( "" );
    end if;
  end loop;
end Show;

procedure Show ( Analysis: in DC_Neur.Outputs_Type ) is
---------------------------------------------------------------------------
begin
  for index in Analysis'range loop
    F_IO.Put ( Analysis ( index ), 2, 2, 3 );
    Put ( ' ' );
  end loop;
end Show;

procedure Show (
	    View: in DC_Neur.Inputs_Type;
	    Net: in DC_Neur.Net_Type ) is
---------------------------------------------------------------------------
begin
  for index1 in Net'range loop
    Put_Line ( "Layer" & integer'image ( index1 ) );
    for index2 in Net ( index1 ).Neurons'range loop
--      Put ( "N" & integer'image ( index2 ) & ": " );
      for index3 in 1..Net ( index1 ).Neurons ( index2 ).Weights'last loop
	if index1 = Net'first then
	  if index3 > View'last then
	    Put ( " ------" );
	  else
	    F_IO.Put ( View ( index3 ), 2, 1, 2 );
	  end if;
	else
	  F_IO.Put ( Net ( index1 - 1 ).Neurons ( index3 ).Last_Output,
	    2, 1, 2 );
	end if;
	Put ( "*" );
	F_IO.Put ( Net ( index1 ).Neurons ( index2 ).Weights ( index3 ),
	  2, 1, 2 );
	if index3 /= Net ( index1 ).Neurons ( index2 ).Weights'last then
	  Put ( "+" );
	else
	  Put ( " =" );
	end if;
      end loop;
      F_IO.Put ( Net ( index1 ).Neurons ( index2 ).Last_Sum, 2, 1, 2 );
--      Put ( "=>" );
--      F_IO.Put ( Net ( index1 ).Neurons ( index2 ).Last_Output,
--        2, 1, 2 );
      Put_Line ( "" );
    end loop;
  end loop;
end Show;

---------------------------------------------------------------------------
---------------------------------------------------------------------------
begin
--  See ( View );
  for index in 1..4 loop
    View := View_XOR ( index );
    Put_Line ( "" );
--    Show ( View, Net );
    DC_Neur.Net ( View, Net, Analysis, false );
    Memorize ( Net );
    declare
      Dummy_Str: string ( 1..1 );
      Dummy_Nat: natural;
    begin
      Get_Line ( Dummy_Str, Dummy_Nat );
    end;
    Put_Line ( "" );
  end loop;
end ANN2;
