with Ada.Characters.Handling;
with Ada.Characters.Latin_1; use Ada.Characters;
with Ada.Wide_Text_Io; use Ada.Wide_Text_Io;
package body Prophet.Neural_Network is
type T_Node;
type Node_Access is access T_Node;
type T_Connector is
record
Left, Right : Node_Access;
end record;
type Connector_Access is access T_Connector;
type T_Get_Handler is access
procedure (Input : out Wide_String; Last : out Natural);
type T_Put_Handler is access
procedure (Output : in Wide_String);
type T_Mode is (In_Put, Out_Put);
type T_Action(Mode : T_Mode) is
record
Register : Wide_String(1..4096);
Length : Natural := 0;
case Mode is
when In_Put =>
Get_Action : T_Get_Handler;
when Out_Put =>
Put_Action : T_Put_Handler;
end case;
end record;
type Action_Access is access T_Action;
type T_Action_Handler is access procedure (Action : in out Action_Access);
procedure Action (Action : in out Action_Access);
subtype T_Key is Integer range -131071..131071;
type T_Node is
record
Action : Action_Access;
Key : T_Key := 0;
run : T_Action_Handler;
Connector : Connector_Access;
end record;
task Life_Cycle is
entry Ctrl_C;
private
entry Switch(Node : in Node_Access);
end Life_Cycle;
procedure Ctrl_C is
Ctrl_C_Message : constant Wide_String :=
Handling.To_Wide_String(Latin_1.Cr & " Interruption, please wait!" );
begin
Put_Line(Ctrl_C_Message);
Life_Cycle.Ctrl_C;
end Ctrl_C;
procedure Put_line(Output : in Wide_String);
procedure Get_line(Input : out Wide_String; Last : out Natural);
Input : Action_Access :=
new T_Action' (Register => (others => Wide_Character'Val(0)),
Length => 0,
Mode => In_Put,
Get_Action => Prophet.Neural_Network.Get_Line'Access);
output : Action_Access :=
new T_Action' (Register => (others => Wide_Character'Val(0)),
Length => 0,
Mode => Out_Put,
Put_Action => Prophet.Neural_Network.put_Line'Access);
task body Life_Cycle is
task type T_Cortex is
entry Initialize(Root : in Node_Access; Env : in Node_access);
entry Reset;
end T_Cortex;
task body T_Cortex is
Root, Env, Current_Node : Node_Access;
function Next_Key(Key : in Integer) return Integer is
begin
return Root.Key * (abs(Key) + 1);
end Next_Key;
begin
accept Initialize(Root : in Node_Access; Env : in Node_access) do
T_Cortex.Root := Root;
T_Cortex.Current_Node := Root;
T_Cortex.Env := Env;
end Initialize;
loop
select
accept Reset do
Current_Node := Root;
end Reset;
or
delay 0.01;
if Current_Node.Action.Mode /= Env.Action.Mode then
Current_Node.Run(Current_Node.Action);
Life_Cycle.Switch(Current_Node);
if Current_Node.Key < 0 then
Current_Node.Connector :=
new T_Connector ' ((new T_Node '
(Current_Node.Action,
Next_Key(Current_Node.Key),
Action'Access,
null)),
null);
Current_Node := Current_Node.Connector.Left;
elsif Current_Node.Key > 0 then
Current_Node.Connector :=
new T_Connector ' (
null,
(new T_Node '
(Current_Node.Action,
Next_Key(Current_Node.Key),
Action'Access,
null))
);
Current_Node := Current_Node.Connector.Right;
else
raise Program_Error;
end if;
end if;
end select;
end loop;
exception
when Program_Error =>
Put_Line("Cortex : id " &
Handling.To_Wide_String(Integer'Image(Current_Node.Key)) &
" := Program_Error" );
end T_Cortex;
L_Root : Node_Access :=
new T_Node ' (output,
-1,
Action'Access,
null);
R_Root : Node_Access :=
new T_Node ' (input,
1,
Action'Access,
null);
L_Env : Node_Access :=
new T_Node ' (input,
0,
Action'Access,
new T_Connector '
(null, R_Root));
R_Env : Node_Access :=
new T_Node ' (output,
0,
Action'Access,
new T_Connector '
(L_Root, null));
Left : T_Cortex;
Right : T_Cortex;
Current_L_Env : Node_Access := L_Env;
Current_R_Env : Node_Access := R_Env;
begin
Left.Initialize(L_Root, L_Env);
Right.Initialize(R_Root, R_Env);
loop
select
accept Ctrl_C do
null;
--Left.Reset;
--Right.Reset;
end Ctrl_C;
or
accept Switch(Node : in Node_Access) do
if Node.Key < 0 then
Put("From left key : " &
Handling.To_Wide_String(Integer'Image(Node.Key))
& ":" );
Node.Run(Node.Action);
elsif Node.Key > 0 then
Put("From right key : " &
Handling.To_Wide_String(Integer'Image(Node.Key)) &
":" );
Node.Run(Node.Action);
else
raise Program_Error;
end if;
end Switch;
end select;
end loop;
exception
when Program_Error =>
Put_Line("Life_Cycle ::= Program_Error" );
end Life_Cycle;
procedure Action (Action : in out Action_Access) is
begin
case Action.Mode is
when In_Put =>
if Action.Get_Action /= null then
Action.Get_Action(Action.Register, Action.length);
end if;
Action :=
new T_Action' (Register => Action.Register,
Length => Action.Length,
Mode => Out_Put,
Put_Action => Prophet.Neural_Network.put_Line'Access);
when Out_Put =>
if Action.Put_Action /= null then
if Action.Length /= 0 then
Action.Put_Action(Action.Register(1..Action.length));
else
Action.Put_Action("String is left empty." );
end if;
end if;
Action := Input;
end case;
end Action;
procedure Put_line(Output : in Wide_String) is
begin
Ada.Wide_Text_Io.Put_Line(" Prophet > " & Output);
end Put_Line;
procedure Get_line(Input : out Wide_String; Last : out Natural) is
begin
Put(" Prophet < " );
Ada.Wide_Text_Io.Get_Line(Input, Last);
end Get_Line;
end Prophet.Neural_Network;