-- This program is the last attempt of artificial intelligency with Ada.
-- Elhoim is Copyright (C) 2023 Manuel ; 
--
--   This program is free software; you can redistribute it and/or modify
--   it under the terms of the GNU General Public License as published by
--   the Free Software Foundation; either version 2 of the License, or
--   (at your option) any later version.
--
--   This program is distributed in the hope that it will be useful,
--   but WITHOUT ANY WARRANTY; without even the implied warranty of
--   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--   GNU General Public License for more details.
--
--   You should have received a copy of the GNU General Public License
--   along with this program; if not, write to the Free Software
--   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
--
-- Date := "2023-05-01 20:03:01"
-- Version := "1.0.0a"

---------------------------------------------------------------------------
--               client->termin->inter->config->center->G consol
--                                      |
-- hander->cyborg->intell->engine  ->	acces server_record
---------------------------------------------------------------------------
--           Neural network (Layer 0 -> Hander
--                          |   \/               cyborg -> Search->Path_Finding
--                         /\   |                intell -> Manual
--           Neural network (layer 1 -> Engine /
--                           |                 /  \
--                          /\               \/     \
--                               [ server ]           Lexic
---------------------------------------------------------------------------

with Ada.Wide_Text_Io;
with Ada.Text_Io;
use Ada;

with Lib.Strings;

with Ada.Streams.Stream_Io;
use Ada.Streams;
with Ada.Strings.Wide_Fixed;
use Ada.Strings.Wide_Fixed;
with Ada.Characters.Handling;
with Ada.Wide_Characters.Handling;
use Ada.Strings;
use Ada.Characters.Handling;
use Ada.Characters.Handling;

with Ada.Tags;
use Ada.Tags;

with Ada.Calendar.Formatting;
use Ada.Calendar;


use Ada;
with Lib.Attrib ;
with Lib.Outils ;
with Lib.Naming ;

with Ada.Containers.Vectors;
use Ada.Containers;
with Ada.Characters.Handling;
use Ada.Characters;
with Ada.Calendar.Formatting;
with Ada.Calendar.Arithmetic;
use Ada.Calendar.Arithmetic;

use Ada.Calendar;
package body Lib.Engine is
   
   use Attrib ;
   use Errors ;   
   use Outils ;
   use Naming ;
   
   use Intelligency.Classes;   
   use Lib.Strings;
   
   
   use Intelligency;
   use Intelligency.Accountings;   
   use Intelligency.Universes;
   use Intelligency.Notes;
   use Intelligency.Events;
   use Intelligency.Contacts;
   use Intelligency.Animals;
   use Intelligency.Account_Lines;
   use Intelligency.Cars;
   use Intelligency.Houses;
   use Intelligency.Contents;
   use Intelligency.Activities;
   use Intelligency.Deallines;
   use Intelligency.Plannings;
   use Intelligency.Plans;
   use Intelligency.Define ;
   use Intelligency.Account;
   
   
   function equal (Left, Right : in Abstracted_Access) return Boolean is
   begin
      
      if Lib."="(Left.Tag, Right.Tag)  and (Left.Name = Right.Name) then
	 
	 case Left.Tag is
	    when Event =>
	       declare
		  Left_Event : Time := Formatting.Value(Handling.To_String(Event_Class(Left.all).Event_Date));
		  Right_Event : Time := Formatting.Value(Handling.To_String(Event_Class(Right.all).Event_Date));
	       begin
		  if ((Left_event <= (Right_Event + Duration(600.0))) and
			(Left_Event >= (Right_Event - Duration(600.0))))
		    or
		    
		    ((Right_event <= (Left_Event + Duration(600.0))) and
		       (Right_Event >= (Left_Event - Duration(600.0)))) then
		     
		     return True;
		  end if;
	       end;
	       
	    when Planning =>
	       if Planning_Class(Left.all).Description =
		 Planning_Class(Right.all).Description then
		  
		  declare
		     Left_From : Time := Planning_Class(Left.all).From;
		     Right_From : Time := Planning_Class(Right.all).From;
		     Left_To : Time := Planning_Class(Left.all).To;
		     Right_To : Time := Planning_Class(Right.all).To;
		  begin
		     if (((Left_From <= Right_From + 1200.0) and
			    (Left_From >= (Right_From - 1200.0))) or
			   
			   ((Right_From <= Left_From + 1200.0) and
			      (Right_From >= Left_From - 1200.0))) then
			
			if (Left_To - Left_From) <
			  (Right_To - Right_From)  +  3600.0 or
			  (Left_To - Left_From) >
			  (Right_To - Right_From)  -  3600.0 then
			   return True;
			end if;
		     end if;
		  end;
	       end if;
	       
	    when Plan =>
	       
	       if Plan_Class(Left.all).Description =
		  Plan_Class(Right.all).Description then
		  
		  if ((Plan_Class(Left.all).Plan_Date <=  
			Plan_Class(Right.all).Plan_Date - 600.0) or
		     (Plan_Class(Left.all).Plan_Date >=  
			Plan_Class(Right.all).Plan_Date + 600.0)) and
		    
		   ((Plan_Class(Left.all).End_Date <=  
			Plan_Class(Right.all).End_Date - 600.0) or
		     (Plan_Class(Left.all).End_Date >=  
			Plan_Class(Right.all).End_Date + 600.0)) then
		     if Plan_Class(Left.all).Period >= 1800.0 and
		       Plan_Class(Right.all).Period >= 1800.0 then
			
			return True;
		     end if;
		  end if;
	       end if;
	       
	    when Activity =>
	       if (Activity_Class(Left.all).Ste_Type =
		     Activity_Class(Right.all).Ste_Type) and
		 (Activity_Class(Left.all).Fiscal =
		    Activity_Class(Right.all).Fiscal) and
		 (Activity_Class(Left.all).Affilia =
		    Activity_Class(Right.all).Affilia) then
		  return True;
	       end if;
	    when others =>
	       
	       return True;
	 end case;
	 
	 return True;
      end if;
      return False;
   end equal;
   
   
   function "<" (Left, Right : in Abstracted_Access) return Boolean is
   begin
      if (Left.Hcost + Left.Ucost) >= (Right.Hcost + Right.Ucost) then
	 return False;
      end if;
      return True;
   end "<";
   
   function uniform  (E : in Abstracted_Access) return Float is
      U : Float := 0.0;
      Hcost : Float := 0.0;
   begin
      
      if E /= null then
	 --Valuate_Tree(E);
	 --U := E.Ucost + Lib.Default_Ranking(E.Tag).Ucost;
	 
	 return Lib.Default_Ranking(E.Tag).Ucost;
	 
      end if;
      return U;
   end Uniform;
   
   
   
   function Heuristic (E : in Abstracted_Access) return Float is
      H : Float := 0.0;
      Ucost : Float := 0.0;
   begin
      
      
      if E /= null then
	 --Valuate_Tree(E);
	 --H := E.Hcost + Lib.Default_Ranking(E.Tag).Hcost;
	 
	 return Lib.Default_Ranking(E.Tag).Hcost;
      end if;
      return H;
   end Heuristic;
   
   
   procedure This_Successors (E : in Abstracted_Access) is      
      
      Ucost, Hcost : Float := 0.0;
      
      N : Positive := 1;
   begin
      if E = null then
	 W_Io.Put_Line("This successors : E = null");
	 raise Spec_Error;
      end if;
      
      Evaluate_Tree(E, Ucost, Hcost);
      case E.Tag is
	 
	 when Lib.Universe =>		  
	    W_Io.Put_Line("univers :");
	    N :=  Tag_Name'Pos(Lib.Def_Class) - (Tag_Name'Pos(Lib.Animal) - 1);
	    declare	       
	       A : E_Array (1 .. N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Animal .. Lib.Def_Class loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  
		  Pos := Pos + 1;
	       end loop;
	       W_Io.Put_Line("univers : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       
	    end;
	    
	 when Lib.Animal =>
	    W_Io.Put_Line("animal :");
	    N :=  Tag_Name'Pos(Saved_Ac) - (Tag_Name'Pos(Lib.Contact) - 1);
	    declare
	       A : E_Array (1..N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Contact .. Saved_Ac loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  Pos := Pos + 1;
	       end loop;
	       W_Io.Put_Line("animal : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       
	       
	    end;
	    
	 when Lib.content =>		  
	    W_Io.Put_Line("content :");
	    N :=  Tag_Name'Pos(Lib.Entep_Ac) - (Tag_Name'Pos(Lib.Plan) - 1);
	    declare
	       A : E_Array (1..N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Plan .. Lib.Entep_Ac loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  Pos := Pos + 1;
	       end loop;
	       W_Io.Put_Line("content : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       
	    end;
	    
	 when Lib.Car =>
	    W_Io.Put_Line("car :");
	    N :=  Tag_Name'Pos(Saved_Ac) - (Tag_Name'Pos(Lib.House) - 1);
	    declare
	       A : E_Array (1..N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.house .. Saved_Ac loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  Pos := Pos + 1;
	       end loop;
	       W_Io.Put_Line("car : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       
	    end;
	    
	 when Lib.Planning =>		  
	    W_Io.Put_Line("planning :");
	    N :=  Tag_Name'Pos(Lib.Contact) - (Tag_Name'Pos(Lib.Planning) - 1);
	    declare
	       A : E_Array (1..N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Planning .. Lib.Contact loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  
		  
		  case Tag is
		     when Plan =>
						
			--  --  Wide_Fixed.Move(Planning_Class(E.all).Description
			--  --  		  (1..Index_Non_Blank(Planning_Class(E.all).Description, Backward)) & "-plan "
			--  --  		  & Handling.To_Wide_String(Natural'Image(Pos + 1)),
			--  --  		Plan_Class(A(Pos + 1).all).Description);
			Plan_Class(A(Pos + 1).all).Plan_Date := Planning_Class(E.all).From + (600.0 * Pos);
			Plan_Class(A(Pos + 1).all).Period := (Planning_Class(E.all).To - Planning_Class(E.all).From) - (3600.0 * Pos);
		     when Planning =>
			
			--  --  Wide_Fixed.Move(Planning_Class(E.all).Description
			--  --  		  (1..Index_Non_Blank(Planning_Class(E.all).Description, Backward))& "-planning " 
			--  --  		  & Handling.To_Wide_String(Natural'Image(Pos + 1)),
			--  --  		Planning_Class(A(Pos + 1).all).Description);
			Planning_Class(A(Pos + 1).all).From := Planning_Class(E.all).To + (3600.0 * Pos);
			Planning_Class(A(Pos + 1).all).To := (Planning_Class(E.all).To + (((Planning_Class(E.all).To - Planning_Class(E.all).From) + (86400.0 * Pos)) - 3600.0));
		     when Event =>
			
			Wide_Fixed.Move(Handling.To_Wide_String(Formatting.Image(Planning_Class(E.all).From)), Event_Class(A(Pos + 1).all).Event_Date);
			
		     when others =>
			null;
		  end case;
		  
		  Pos := Pos + 1;
	       end loop;
	       W_Io.Put_Line("planning : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       
	    end;
	    
	 when Lib.house =>
	    W_Io.Put_Line("house :");
	    N :=  Tag_Name'Pos(Lib.Saved_Ac) - (Tag_Name'Pos(Lib.Activity) - 1);
	    declare
	       A : E_Array (1..N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Activity .. Saved_Ac loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;

		  Pos := Pos + 1;
	       end loop;
	       W_Io.Put_Line("house : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       
	    end;
	    
	    
	 when Lib.Plan =>		  
	    W_Io.Put_Line("plan :");
	    N :=  Tag_Name'Pos(Lib.Saved_Ac) - (Tag_Name'Pos(Lib.planning) - 1);
	    declare
	       A : E_Array(1 .. N);
	       Pos : Natural := 0;
	       
	    begin
	       
	       for Tag in Lib.Planning .. Lib.Saved_Ac loop
		  
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  
		  
		  case Tag is
		     when Plan =>
			--  --  Wide_Fixed.Move(Plan_Class(E.all).Description
			--  --  		  (1..Index_Non_Blank(Plan_Class(E.all).Description, Backward)) & "-plan "
			--  --  		  & Handling.To_Wide_String(Natural'Image(Pos + 1)),
			--  --  		Plan_Class(A(Pos + 1).all).Description);
			
			Plan_Class(A(Pos + 1).all).Plan_Date := Plan_Class(E.all).Plan_Date + (600.0 * Pos);
			
			Plan_Class(A(Pos + 1).all).Period := (600.0 * Pos);
			
		     when Planning =>
					  
			--  --  Wide_Fixed.Move(Plan_Class(E.all).Description
			--  --  		  (1..Index_Non_Blank(Plan_Class(E.all).Description, Backward))& "-planning " 
			--  --  		  & Handling.To_Wide_String(Natural'Image(Pos + 1)),
			--  --  		Planning_Class(A(Pos + 1).all).Description);
			
			Planning_Class(A(Pos + 1).all).From := Plan_Class(E.all).Plan_Date - (600.0 * Pos);
			
			
			Planning_Class(A(Pos + 1).all).To := Plan_Class(E.all).Plan_Date + Plan_Class(E.all).Period + (600.0 * Pos) + 600.0;
			
		     when Event =>
			
			Wide_Fixed.Move(Handling.To_Wide_String(Formatting.Image(Plan_Class(E.all).Plan_Date)), Event_Class(A(Pos + 1).all).Event_Date);
			
		     when Activity =>
			
			
			
			Move(Plan_Class(E.all).Description(1..Index(Plan_Class(E.all).Description, " ")-1), Activity_Class(A(Pos + 1).all).Raison);
			
			Move("Self", Activity_Class(A(Pos + 1).all).Ste_Type);
			
			Move("Real", Activity_Class(A(Pos + 1).all).Fiscal);
			
			Move("URSSAF", Activity_Class(A(Pos + 1).all).Affilia);
			
		     when others =>
			null;
		  end case;
		  
		  Pos := Pos + 1;
		  
	       end loop;
	       W_Io.Put_Line("plan : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       
	    end;
	    
	 when Lib.Acc_line =>
	    W_Io.Put_Line("acc_line :");
	    N :=  Tag_Name'Pos(Lib.Perso_Ac) - (Tag_Name'Pos(Lib.Event) - 1);
	    declare
	       A : E_Array(1..N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Event .. Lib.Perso_Ac loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  Pos := Pos + 1;
	       end loop;
	       W_Io.Put_Line("content : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       
	    end;
	    
	 when Lib.Deal =>		  
	    W_Io.Put_Line("deal :");
	    N :=  Tag_Name'Pos(Lib.Saved_Ac) - (Tag_Name'Pos(Lib.Event) - 1);
	    declare
	       A : E_Array(1 .. N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Event .. Lib.Saved_Ac loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  
		  
		  Pos := Pos + 1;
	       end loop;
	       W_Io.Put_Line("deal : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       
	    end;
	    
	 when Lib.Activity =>
	    W_Io.Put_Line("activity :");
	    N :=  Tag_Name'Pos(Lib.Contact) - (Tag_Name'Pos(Lib.content) - 1);
	    declare
	       A : E_Array(1 .. N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Content .. Lib.Contact loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  Pos := Pos + 1;
	       end loop;
	       W_Io.Put_Line("activity : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       
	    end;
	 when Lib.Saved_Ac =>
	    W_Io.Put_Line("saved_ac :");
	    N :=  Tag_Name'Pos(Lib.house) - (Tag_Name'Pos(Lib.Animal) - 1);
	    declare
	       A : E_Array(1 .. N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Animal .. Lib.House loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  case Tag is
		     
		     when others =>
			null;
		  end case;
		  Pos := Pos + 1;
	       end loop;
	       W_Io.Put_Line("saved_ac : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       
	    end;
	    
	 when Lib.Entep_Ac =>
	    W_Io.Put_Line("Entep_ac :");
	    declare
	       A : E_Array(1 .. 9);
	    begin
	       
	       A (1) := Id(Planning);
	       A (1).Ucost := Uniform(A(1));
	       A (1).Hcost := Uniform(A(1));
	       A (1).Name := E.Name;
	       
	       A (2) := Id(Plan);
	       A (2).Ucost := Uniform(A(2));
	       A (2).Hcost := Uniform(A(2));
	       A (2).Name := E.Name;
	       
	       A (3) := Id(Event);
	       A (3).Ucost := Uniform(A(3));
	       A (3).Hcost := Uniform(A(3));
	       A (3).Name := E.Name;
	       
	       A (4) := Id(Acc_line);
	       A (4).Ucost := Uniform(A(4));
	       A (4).Hcost := Uniform(A(4));
	       A (4).Name := E.Name;
	       
	       A (5) := Id(Deal);
	       A (5).Ucost := Uniform(A(5));
	       A (5).Hcost := Uniform(A(5));
	       A (5).Name := E.Name;
	       
	       A (6) := Id(Content);
	       A (6).Ucost := Uniform(A(6));
	       A (6).Hcost := Uniform(A(6));
	       A (6).Name := E.Name;
	       
	       A (7) := Id(Contact);
	       A (7).Ucost := Uniform(A(7));
	       A (7).Hcost := Uniform(A(7));
	       A (7).Name := E.Name;
	       
	       A (8) := Id(Entep_Ac);
	       A (8).Ucost := Uniform(A(8));
	       A (8).Hcost := Uniform(A(8));
	       A (8).Name := E.Name;
	       
	       A (9) := Id(Note);
	       A (9).Ucost := Uniform(A(9));
	       A (9).Hcost := Uniform(A(9));
	       A (9).Name := E.Name;
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       W_Io.Put_Line("End Entep_ac :");
	    end;
	    
	 when Event =>
	    W_Io.Put_Line("Event :");
	    declare
	       A : E_Array(1 .. 5);
	    begin
	       A (1) := Id(Acc_line);
	       A (1).Ucost := Uniform(A(1));
	       A (1).Hcost := Uniform(A(1));
	       A (1).Name := E.Name;
	       
	       A (2) := Id(Deal);
	       A (2).Ucost := Uniform(A(2));
	       A (2).Hcost := Uniform(A(2));
	       A (2).Name := E.Name;
	       
	       A (3) := Id(contact);
	       A (3).Ucost := Uniform(A(3));
	       A (3).Hcost := Uniform(A(3));
	       A (3).Name := E.Name;
	       
	       A (4) := Id(note);
	       A (4).Ucost := Uniform(A(4));
	       A (4).Hcost := Uniform(A(4));
	       A (4).Name := E.Name;
	       
	       A (5) := Id(event);
	       A (5).Ucost := Uniform(A(5));
	       A (5).Hcost := Uniform(A(5));
	       A (5).Name := E.Name;
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       W_Io.Put_Line("end Event :");
	    end;
	    
	    
	 when Note =>
	    W_Io.Put_Line("Note :");
	    declare
	       A : E_Array(1 .. 1);
	    begin
	       A (1) := Id(Note);
	       A (1).Ucost := Uniform(A(1));
	       A (1).Hcost := Uniform(A(1));
	       A (1).Name := E.Name;
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       W_Io.Put_Line("end Note :");
	    end;
	    
	 when Perso_Ac =>
	    W_Io.Put_Line("Perso_ac :");
	    declare
	       A : E_Array(1 .. 1);
	    begin
	       A (1) := Id(Acc_Line);
	       A (1).Ucost := Uniform(A(1));
	       A (1).Hcost := Uniform(A(1));
	       A (1).Name := E.Name;
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       
	    end;
	 when Def_Class =>
	    W_Io.Put_Line("Define :");
	    declare
	       A : E_Array(1 .. 1);
	    begin
	       A (1) := Id(Plan);
	       A (1).Ucost := Uniform(A(1));
	       A (1).Hcost := Uniform(A(1));
	       A (1).Name := E.Name;
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       W_Io.Put_Line("End Define :");
	    end;
	    
	 when Contact =>
	    W_Io.Put_Line("Contact :");
	    declare
	       A : E_Array(1 .. 3);
	    begin
	       A (1) := Id(Event);
	       A (1).Ucost := Uniform(A(1));
	       A (1).Hcost := Uniform(A(1));
	       A (1).Name := E.Name;
	       
	       A (2) := Id(Plan);
	       A (2).Ucost := Uniform(A(2));
	       A (2).Hcost := Uniform(A(2));
	       A (2).Name := E.Name;
	       
	       A (3) := Id(Acc_line);
	       A (3).Ucost := Uniform(A(3));
	       A (3).Hcost := Uniform(A(3));
	       A (3).Name := E.Name;
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     Append(E.Vector, O);
		  end;
	       end loop;
	       W_Io.Put_Line("End Contact :");
	    end;
	    
	 when others =>
	    null;
      end case;
      
	    
   end This_Successors;
   

   
   function Successors (E : in Abstracted_Access) return E_Array is      
      
      Ucost, Hcost : Float := 0.0;
      
      N : Positive := 1;
   begin
      if E = null then
	 W_Io.Put_Line("Successors : E = null");
	 raise Spec_Error;
      end if;
      Valuate_Tree(E);
      Evaluate_Tree(E, Ucost, Hcost);
      case E.Tag is
	 
	 when Lib.Universe =>		  
	    --W_Io.Put_Line("univers :");
	    N :=  Tag_Name'Pos(Lib.Def_Class) - (Tag_Name'Pos(Lib.Animal) - 1);
	    declare	       
	       A : E_Array (1 .. N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Animal .. Lib.Def_Class loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  
		  Pos := Pos + 1;
	       end loop;
	       --W_Io.Put_Line("univers : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       return A;
	    end;
	    
	 when Lib.Animal =>
	    --W_Io.Put_Line("animal :");
	    N :=  Tag_Name'Pos(Saved_Ac) - (Tag_Name'Pos(Lib.Contact) - 1);
	    declare
	       A : E_Array (1..N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Contact .. Saved_Ac loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  Pos := Pos + 1;
	       end loop;
	       --W_Io.Put_Line("animal : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       return A;
	    end;
	    
	 when Lib.content =>		  
	    --W_Io.Put_Line("content :");
	    N :=  Tag_Name'Pos(Lib.Entep_Ac) - (Tag_Name'Pos(Lib.Plan) - 1);
	    declare
	       A : E_Array (1..N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Plan .. Lib.Entep_Ac loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  Pos := Pos + 1;
	       end loop;
	       --W_Io.Put_Line("content : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       return A;
	    end;
	    
	 when Lib.Car =>
	    --W_Io.Put_Line("car :");
	    N :=  Tag_Name'Pos(Saved_Ac) - (Tag_Name'Pos(Lib.House) - 1);
	    declare
	       A : E_Array (1..N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.house .. Saved_Ac loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  Pos := Pos + 1;
	       end loop;
	       --W_Io.Put_Line("car : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       return A;
	    end;
	    
	 when Lib.Planning =>		  
	    --W_Io.Put_Line("planning :");
	    N :=  Tag_Name'Pos(Lib.Contact) - (Tag_Name'Pos(Lib.Planning) - 1);
	    declare
	       A : E_Array (1..N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Planning .. Lib.Contact loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  
		  
		  case Tag is
		     when Plan =>
			
			--  Wide_Fixed.Move(Planning_Class(E.all).Description
			--  		  (1..Index_Non_Blank(Planning_Class(E.all).Description, Backward)) & "-plan "
			--  		  & Handling.To_Wide_String(Natural'Image(Pos + 1)),
			--  		Plan_Class(A(Pos + 1).all).Description);
			Plan_Class(A(Pos + 1).all).Plan_Date := Planning_Class(E.all).From + (600.0 * Pos);
			Plan_Class(A(Pos + 1).all).Period := (Planning_Class(E.all).To - Planning_Class(E.all).From) - (3600.0 * Pos);
		     when Planning =>
			
			--  Wide_Fixed.Move(Planning_Class(E.all).Description
			--  		  (1..Index_Non_Blank(Planning_Class(E.all).Description, Backward))& "-planning " 
			--  		  & Handling.To_Wide_String(Natural'Image(Pos + 1)),
			--  		Planning_Class(A(Pos + 1).all).Description);
			Planning_Class(A(Pos + 1).all).From := Planning_Class(E.all).To + (3600.0 * Pos);
			Planning_Class(A(Pos + 1).all).To := (Planning_Class(E.all).To + (((Planning_Class(E.all).To - Planning_Class(E.all).From) + (86400.0 * Pos)) - 3600.0));
		     when Event =>
			
			Wide_Fixed.Move(Handling.To_Wide_String(Formatting.Image(Planning_Class(E.all).From)), Event_Class(A(Pos + 1).all).Event_Date);
			
		     when others =>
			null;
		  end case;
		  
		  Pos := Pos + 1;
	       end loop;
	       --W_Io.Put_Line("planning : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       return A;
	    end;
	    
	 when Lib.house =>
	    --W_Io.Put_Line("house :");
	    N :=  Tag_Name'Pos(Lib.Saved_Ac) - (Tag_Name'Pos(Lib.Activity) - 1);
	    declare
	       A : E_Array (1..N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Activity .. Saved_Ac loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;

		  Pos := Pos + 1;
	       end loop;
	       --W_Io.Put_Line("house : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       return A;
	    end;
	    
	    
	 when Lib.Plan =>		  
	    --W_Io.Put_Line("plan :");
	    N :=  Tag_Name'Pos(Lib.Saved_Ac) - (Tag_Name'Pos(Lib.planning) - 1);
	    declare
	       A : E_Array(1 .. N);
	       Pos : Natural := 0;
	       
	    begin
	       
	       for Tag in Lib.Planning .. Lib.Saved_Ac loop
		  
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  
		  
		  case Tag is
		     when Plan =>
			--  Wide_Fixed.Move(Plan_Class(E.all).Description
			--  		  (1..Index_Non_Blank(Plan_Class(E.all).Description, Backward)) & "-plan "
			--  		  & Handling.To_Wide_String(Natural'Image(Pos + 1)),
			--  		Plan_Class(A(Pos + 1).all).Description);
			
			Plan_Class(A(Pos + 1).all).Plan_Date := Plan_Class(E.all).Plan_Date + (600.0 * Pos);
			
			Plan_Class(A(Pos + 1).all).Period := (600.0 * Pos);
			
		     when Planning =>
					  
			--  Wide_Fixed.Move(Plan_Class(E.all).Description
			--  		  (1..Index_Non_Blank(Plan_Class(E.all).Description, Backward))& "-planning " 
			--  		  & Handling.To_Wide_String(Natural'Image(Pos + 1)),
			--  		Planning_Class(A(Pos + 1).all).Description);
			
			Planning_Class(A(Pos + 1).all).From := Plan_Class(E.all).Plan_Date - (600.0 * Pos);
			
			
			Planning_Class(A(Pos + 1).all).To := Plan_Class(E.all).Plan_Date + Plan_Class(E.all).Period + (600.0 * Pos) + 600.0;
			
		     when Event =>
			
			Wide_Fixed.Move(Handling.To_Wide_String(Formatting.Image(Plan_Class(E.all).Plan_Date)), Event_Class(A(Pos + 1).all).Event_Date);
			
		     when Activity =>
			
			
			
			Move(Plan_Class(E.all).Description(1..Index(Plan_Class(E.all).Description, " ")-1), Activity_Class(A(Pos + 1).all).Raison);
			
			Move("Self", Activity_Class(A(Pos + 1).all).Ste_Type);
			
			Move("Real", Activity_Class(A(Pos + 1).all).Fiscal);
			
			Move("URSSAF", Activity_Class(A(Pos + 1).all).Affilia);
			
		     when others =>
			null;
		  end case;
		  
		  
		  --  if A(Pos+1) = null then
		  --      W_io.Put_Line("Object : " & To_Wide_String(Integer'Image(Pos + 1)) & " = null ");
		  --  end if;
		  
		  Pos := Pos + 1;
		  
	       end loop;
	       --W_Io.Put_Line("plan : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     
		     
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       return A;
	    end;
	    
	 when Lib.Acc_line =>
	    --W_Io.Put_Line("acc_line :");
	    N :=  Tag_Name'Pos(Lib.Perso_Ac) - (Tag_Name'Pos(Lib.Event) - 1);
	    declare
	       A : E_Array(1..N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Event .. Lib.Perso_Ac loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  Pos := Pos + 1;
	       end loop;
	       --W_Io.Put_Line("content : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       return A;
	    end;
	    
	 when Lib.Deal =>		  
	    --W_Io.Put_Line("deal :");
	    N :=  Tag_Name'Pos(Lib.Saved_Ac) - (Tag_Name'Pos(Lib.Event) - 1);
	    declare
	       A : E_Array(1 .. N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Event .. Lib.Saved_Ac loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  
		  
		  Pos := Pos + 1;
	       end loop;
	       --W_Io.Put_Line("deal : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       return A;
	    end;
	    
	 when Lib.Activity =>
	    --W_Io.Put_Line("activity :");
	    N :=  Tag_Name'Pos(Lib.Contact) - (Tag_Name'Pos(Lib.content) - 1);
	    declare
	       A : E_Array(1 .. N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Content .. Lib.Contact loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  Pos := Pos + 1;
	       end loop;
	       --W_Io.Put_Line("activity : end");
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       return A;
	    end;
	 when Lib.Saved_Ac =>
	    --W_Io.Put_Line("saved_ac :");
	    N :=  Tag_Name'Pos(Lib.house) - (Tag_Name'Pos(Lib.Animal) - 1);
	    declare
	       A : E_Array(1 .. N);
	       Pos : Natural := 0;
	    begin
	       
	       for Tag in Lib.Animal .. Lib.House loop
	 	  A (Pos + 1) := Id(Tag);
	 	  A (Pos + 1).Ucost := Uniform (A (Pos + 1));
	 	  A (Pos + 1).Hcost := Heuristic (A (Pos + 1));
		  A(Pos + 1).Name := E.Name;
		  case Tag is
		     
		     when others =>
			null;
		  end case;
		  Pos := Pos + 1;
	       end loop;
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       --W_Io.Put_Line("end saved_ac : end");
	       return A;
	    end;
	    
	 when Lib.Entep_Ac =>
	    --W_Io.Put_Line("Entep_ac :");
	    declare
	       A : E_Array(1 .. 9);
	    begin
	       
	       A (1) := Id(Planning);
	       A (1).Ucost := Uniform(A(1));
	       A (1).Hcost := Uniform(A(1));
	       A (1).Name := E.Name;
	       
	       A (2) := Id(Plan);
	       A (2).Ucost := Uniform(A(2));
	       A (2).Hcost := Uniform(A(2));
	       A (2).Name := E.Name;
	       
	       A (3) := Id(Event);
	       A (3).Ucost := Uniform(A(3));
	       A (3).Hcost := Uniform(A(3));
	       A (3).Name := E.Name;
	       
	       A (4) := Id(Acc_line);
	       A (4).Ucost := Uniform(A(4));
	       A (4).Hcost := Uniform(A(4));
	       A (4).Name := E.Name;
	       
	       A (5) := Id(Deal);
	       A (5).Ucost := Uniform(A(5));
	       A (5).Hcost := Uniform(A(5));
	       A (5).Name := E.Name;
	       
	       A (6) := Id(Content);
	       A (6).Ucost := Uniform(A(6));
	       A (6).Hcost := Uniform(A(6));
	       A (6).Name := E.Name;
	       
	       A (7) := Id(Contact);
	       A (7).Ucost := Uniform(A(7));
	       A (7).Hcost := Uniform(A(7));
	       A (7).Name := E.Name;
	       
	       A (8) := Id(Entep_Ac);
	       A (8).Ucost := Uniform(A(8));
	       A (8).Hcost := Uniform(A(8));
	       A (8).Name := E.Name;
	       
	       A (9) := Id(Note);
	       A (9).Ucost := Uniform(A(9));
	       A (9).Hcost := Uniform(A(9));
	       A (9).Name := E.Name;
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       --W_Io.Put_Line("End Entep_ac :");
	       return A;
	    end;
	    
	 when Event =>
	    --W_Io.Put_Line("Event :");
	    declare
	       A : E_Array(1 .. 5);
	    begin
	       A (1) := Id(Acc_line);
	       A (1).Ucost := Uniform(A(1));
	       A (1).Hcost := Uniform(A(1));
	       A (1).Name := E.Name;
	       
	       A (2) := Id(Deal);
	       A (2).Ucost := Uniform(A(2));
	       A (2).Hcost := Uniform(A(2));
	       A (2).Name := E.Name;
	       
	       A (3) := Id(contact);
	       A (3).Ucost := Uniform(A(3));
	       A (3).Hcost := Uniform(A(3));
	       A (3).Name := E.Name;
	       
	       A (4) := Id(note);
	       A (4).Ucost := Uniform(A(4));
	       A (4).Hcost := Uniform(A(4));
	       A (4).Name := E.Name;
	       
	       A (5) := Id(event);
	       A (5).Ucost := Uniform(A(5));
	       A (5).Hcost := Uniform(A(5));
	       A (5).Name := E.Name;
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       --W_Io.Put_Line("End Event :");
	       return A;
	    end;
	    
	    
	 when Note =>
	    --W_Io.Put_Line("Note :");
	    declare
	       A : E_Array(1 .. 1);
	    begin
	       A (1) := Id(Note);
	       A (1).Ucost := Uniform(A(1));
	       A (1).Hcost := Uniform(A(1));
	       A (1).Name := E.Name;
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       --W_Io.Put_Line("End note :");
	       return A;
	    end;
	    
	 when Perso_Ac =>
	    --W_Io.Put_Line("Parso acc :");
	    declare
	       A : E_Array(1 .. 1);
	    begin
	       A (1) := Id(Acc_Line);
	       A (1).Ucost := Uniform(A(1));
	       A (1).Hcost := Uniform(A(1));
	       A (1).Name := E.Name;
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       --W_Io.Put_Line("End Perso_ac :");
	       return A;
	    end;
	 when Def_Class =>
	    --W_Io.Put_Line("Define :");
	    declare
	       A : E_Array(1 .. 1);
	    begin
	       A (1) := Id(Plan);
	       A (1).Ucost := Uniform(A(1));
	       A (1).Hcost := Uniform(A(1));
	       A (1).Name := E.Name;
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       --W_Io.Put_Line("End define :");
	       return A;
	    end;
	    
	 when Contact =>
	    --W_Io.Put_Line("Contact :");
	    declare
	       A : E_Array(1 .. 3);
	    begin
	       A (1) := Id(Event);
	       A (1).Ucost := Uniform(A(1));
	       A (1).Hcost := Uniform(A(1));
	       A (1).Name := E.Name;
	       
	       A (2) := Id(Plan);
	       A (2).Ucost := Uniform(A(2));
	       A (2).Hcost := Uniform(A(2));
	       A (2).Name := E.Name;
	       
	       A (3) := Id(Acc_line);
	       A (3).Ucost := Uniform(A(3));
	       A (3).Hcost := Uniform(A(3));
	       A (3).Name := E.Name;
	       for Object in A ' range loop
		  declare
		     O : Abstracted_Access := A(Object);
		  begin
		     O.Ucost := Ucost;
		     O.Hcost := Hcost;
		     O.Vector := E.Vector;
		     --   This_Successors(O);
		     Valuate_Tree(O);
		  end;
	       end loop;
	       --W_Io.Put_Line("End Contact :");
	       return A;
	    end;
	    
	 when others =>
	    null;
      end case;
      
	    
   end Successors;
   

   
   
   procedure Astar (Start : in Abstracted_Access;
   		    Goal : in Abstracted_Access;
   		    Close  : out Abstracted_Vectors.vector) is
            
      
      Openned : Path_Finding.Element_List;
      Closed : Path_Finding.Element_List;
      Closed_Curs : Path_Finding.Element_Lists.Cursor;
   begin
      
      
      Path_Finding.Element_Lists.Append(Openned, Start);
      Path_Finding.Element_Lists.Append(Openned, Goal);
            
      Path_Finding.Astar(Openned, Closed);
      if Path_Finding.Element_Lists.Length(Closed) /= 0 then
   	 Closed_Curs := Path_Finding.Element_Lists.First(Closed);
   	 for El in 1..Path_Finding.Element_Lists.Length(Closed) loop
   	    declare
   	       E : Abstracted_Access := Path_Finding.Element_Lists.Element(Closed_Curs);
   	    begin
   	       Abstracted_Vectors.Append(Close, E);
   	       Path_Finding.Element_Lists.Next(Closed_Curs);
   	    end;
   	 end loop;
      end if;
   end Astar;
   
   
   
   
   
   task body Astar_Process is

      State : Boolean := False;
      End_Of_Program : Boolean := False;
      End_Of_Task    : Boolean := True;
      
      Openned : Path_Finding.Element_List;
      Closed : Path_Finding.Element_List;
      Closed_Curs : Path_Finding.Element_Lists.Cursor;
   begin
      while not End_Of_Program loop	 
	 loop
	    select
	       accept Init (Start : in Abstracted_Access;
			    Goal : in Abstracted_Access) do
		  Path_Finding.Element_Lists.Clear(Openned);
		  Path_Finding.Element_Lists.Clear(Closed);
		  Path_Finding.Element_Lists.Append(Openned, Start);
		  Path_Finding.Element_Lists.Append(Openned, Goal);      
		  
		  Path_Finding.Astar_Task.Init(Openned);
		  End_Of_Task := False;
	       end Init;
	       exit;
	    or
	       when End_Of_Task = True =>
		  accept Close_Set(Closed_Out : out Abstracted_Vectors.Vector; End_Of_Task : out Boolean) do
		     
		     if Path_Finding.Element_Lists.Length(Closed) /= 0 then
			Closed_Curs := Path_Finding.Element_Lists.First(Closed);
			for El in 1..Path_Finding.Element_Lists.Length(Closed) loop
			   declare
				 E : Abstracted_Access := Path_Finding.Element_Lists.Element(Closed_Curs);
			   begin
			      Abstracted_Vectors.Append(Closed_Out, E);
			      Path_Finding.Element_Lists.Next(Closed_Curs);
			   end;
			end loop;
		     end if;
		     End_Of_Task := True;
		  end Close_Set;
	    or
	       accept Halt do
		  
		  End_Of_Program := True;
		  
	       end Halt;
	       exit;
	    end select;
	 end loop;
	 while not End_Of_Program loop	 

	    select
	       accept Init (Start : in Abstracted_Access;
			    Goal : in Abstracted_Access) do
		  Path_Finding.Element_Lists.Clear(Openned);
		  Path_Finding.Element_Lists.Clear(Closed);
		  Path_Finding.Element_Lists.Append(Openned, Start);
		  Path_Finding.Element_Lists.Append(Openned, Goal);      
		  
		  Path_Finding.Astar_Task.Init(Openned);
		  End_Of_Task := False;
	       end Init;
	    or
	       when End_Of_Task = False =>
		  accept Close_Set(Closed_Out : out Abstracted_Vectors.Vector; End_Of_Task : out Boolean) do
		     
		     
		     End_Of_Task := False;
		     
		     select
			Path_Finding.Astar_Task.Close_Set(Closed, State);
		     or
			delay 0.05;
		     end select;
		     
		     if Path_Finding.Element_Lists.Length(Closed) /= 0 then
			Closed_Curs := Path_Finding.Element_Lists.First(Closed);
			for El in 1..Path_Finding.Element_Lists.Length(Closed) loop
			   declare
			      E : Abstracted_Access := Path_Finding.Element_Lists.Element(Closed_Curs);
			   begin
			      Abstracted_Vectors.Append(Closed_Out, E);
			      Path_Finding.Element_Lists.Next(Closed_Curs);
			   end;
			end loop;
		     end if;
		     Astar_Process.End_Of_Task := State;
		  end Close_Set;
		  if End_Of_Task then
		     exit;
		  end if;
	    or
	       accept Halt do
		  
		  End_Of_Program := True;
		  
	       end Halt;
	       exit;
	    end select;
	 end loop;
      end loop;
      Text_Io.New_Line;
      Text_Io.Put_Line("Engine : Astar processk halted.");
   end Astar_Process;
   
   
   
   
   
   
   
   
   task body Engine_Process is
      End_Of_Task : Boolean := False;
   begin
      while not End_Of_Task loop
	 loop
	    select
	       accept Halt (End_Of_Program : out Boolean) do
		  
		  End_Of_Task := True;
		  End_Of_Program := True;
		  
		  Text_Io.Put_Line("Engine : Going to halting the Astar process");	       
		  
		  Engine.Astar_Proc.Halt;
		  
		  Engine.Hander_Lock.Seize;
		  
		  Text_Io.Put_Line("Halting Engine");	       
		  
		  Engine.Hander_Lock.Release;
		  
		  
		  
	       end Halt;
	       exit;
	    or
	       accept Initialize;	       
	       exit;
	    end select;
	 end loop;
	 
	 while not End_Of_Task loop
	    select
	       accept Halt (End_Of_Program : out Boolean) do
		  
		  End_Of_Program := True;
		  End_Of_Task := True;
		  Text_Io.Put_Line("Engine : Going to halting the Astar process");	       
		  Engine.Astar_Proc.Halt;
		  
		  
		  
		  Engine.Hander_Lock.Seize;
		  Text_Io.Put_Line("Halting Engine");	       
		  Engine.Hander_Lock.Release;
		  
	       end Halt;
	       exit;
	    or
	       accept Initialize;
	    or
	       accept Receive (Wchar : in Wide_Character);
	    or
	       accept Mode(Mode : out Mode_Enum);
	    or
	       accept Reset;
	    or
	       accept Switch (Mode : in Mode_Enum);
	    or
	       accept Lock;
	    or
	       accept Unlock;
	    or
	       accept Set_On_Esc(Is_Escape : in Boolean);      
	    or
	       accept Page_Down;
	    or
	       accept Page_Up;
	    or
	       accept Up_Arrow;
	    or
	       accept Down_Arrow;
	    or
	       accept Left_Arrow;
	    or
	       accept Right_Arrow;
	    or
	       accept Full_Screen;
	    or
	       accept Del;
	    or
	       accept Begin_Of;
	    or
	       accept End_Of;
	    or
	       accept Overwrite;
	    or
	       accept Screen_Print;
	    or
	       accept Shutdown;
	    or
	       accept Send (Who, Where, How, Why, How_Mutch, How_Many : in Wide_String; Objects : out Object_Set) do
		  
		  declare
		     Objects : Object_Set(1);
		     O       : Object_Info_Access := new Object_Info_Record ' 
		       (Plan, 1.0, 0.99, Name => (1 => 'd', 2 => 'e', 3 => 'v', 4 => 'e', 5 => 'l', others => ' '),
			Old => 53.06, X => 0.1, Y => 0.1, Z => 0.1);
		  begin
		     Objects.Object_Last := 1;
		     Objects.Set(1) := O;
		  end;
	       end Send;
	    end select;
	    
	 end loop;
      end loop;
      Engine.Hander_Lock.Seize;
      Text_Io.Put_Line("Engine halted");
      Engine.Hander_Lock.Release;
   end Engine_Process;
   
     
   
   procedure Global_Read(File : W_Io.File_Type;
   			 End_Of_File : out Boolean;
   			 Object : out Abstracted_Access) is
      Tag : Tag_Name := Null_Tag;
      Name : Wide_String(1..8) := (others => Wide_Character'Val(32));
      Name_Last : Natural := 0;
      Index : Natural := 0;
   begin
                  
      while not W_Io.End_Of_File(File) loop
   	 begin
   	    W_Io.Get_Line(File, Name, Name_Last);
   	    Index := Wide_Fixed.Index_Non_Blank(Name(Name'First..Name_Last), backward);
   	    if index = 0 then
   	       raise Constraint_Error;
   	    else
   	       if Ada.Wide_Characters.Handling.Is_Control(Name(Index)) then
   		  raise Constraint_Error;
   	       end if;
   	    end if;
   	    Tag := Tag_Name'Value(To_String(Name(Name'First..Name_Last)));
   	    exit;
   	 exception
   	    when Constraint_Error =>
   	       W_Io.Get_Line(File, Name, Name_Last);
   	       begin
   		  Tag := Tag_Name'Value(To_String(Name(Name'First..Name_Last)));
		  
   		  exit;
		  
   	       end;
   	 end;
      end loop;
      

      Object := Id(Tag);

      Object.Read(File);
      Object.Ucost := Uniform(Object);
		  
      Object.Hcost := Heuristic(Object);
		  
      End_Of_File := W_Io.End_Of_File(File);
   exception
      when Constraint_Error =>
   	 raise;
      when others =>
   	 null;
   end Global_Read;
   
   
   
   procedure Global_Print(Object : Abstracted_Access;
   			  Win       : in Classes.Windows.Window_Type;
   			  Win_Index : in out Positive) is
      Name : Name_Type;
   begin
      if Object.all'Tag = Universe_Class'Tag then
      	 Universe_Class(Object.all).Print(Win, Win_Index, Name);
      elsif Object.all'Tag = animal_Class'Tag then
      	 Animal_Class(Object.all).Print(Win, Win_Index, Name);
      elsif Object.all'Tag = deal_Class'Tag then
   	    deal_Class(Object.all).Print(Win, Win_Index, Name);
      elsif Object.all'Tag = car_Class'Tag then
      	 car_Class(Object.all).Print(Win, Win_Index, Name);
      elsif Object.all'Tag = Plan_Class'Tag then
      	 Plan_Class(Object.all).Print(Win, Win_Index, Name);
      elsif Object.all'Tag = Planning_Class'Tag then
      	 Planning_Class(Object.all).Print(Win, Win_Index, Name);
      elsif Object.all'Tag = Activity_Class'Tag then
      	 Activity_Class(Object.all).Print(Win, Win_Index, Name);
      elsif Object.all'Tag = Content_Class'Tag then
      	 Content_Class(Object.all).Print(Win, Win_Index, Name);
      elsif Object.all'Tag = House_Class'Tag then
      	 House_Class(Object.all).Print(Win, Win_Index, Name);
      elsif Object.all'Tag = Contact_Class'Tag then
   	 Contact_Class(Object.all).Print(Win, Win_Index, Name);      	 
      elsif Object.all'Tag = Event_Class'Tag then
   	 Event_Class(Object.all).Print(Win, Win_Index, Name);      	 
      elsif Object.all'Tag = Note_Class'Tag then
   	 Note_Class(Object.all).Print(Win, Win_Index, Name);	 
      elsif Object.all'Tag = Acc_line_Class'Tag then
   	 Acc_line_Class(Object.all).Print(Win, Win_Index, Name);      	 
      elsif Object.all'Tag = Saving_Account_Class'Tag then
      	 Saving_Account_Class(Object.all).Print(Win, Win_Index, Name);      	 
      elsif Object.all'Tag = Personal_Account_Class'Tag then
   	 Personal_Account_Class(Object.all).Print(Win, Win_Index, Name);      	 
      elsif Object.all'Tag = Enteprise_Account_Class'Tag then
      	 Enteprise_Account_Class(Object.all).Print(Win, Win_Index, Name);      	 
      elsif Object.all'Tag = Define_Class'Tag then
	 Define_Class(Object.all).Print(Win, Win_Index, Name);      	 
      end if;      
   end Global_Print;
   


   procedure Parent(T : in out Terminal_Record;
   		    Prompt : out Name_Type);
   
   procedure Restore_Vector(T : in out Terminal_Record;
   			    Win : in Classes.Windows.Window_Type;
   			    State : in Classes.Windows.Window_Type;
   			    File : W_Io.File_Type) is
      
      
      Line_Index : positive := 1;	 
      Is_End : Boolean := False;
      Wchar : Wide_Character;

      Prompt : Name_Type;
      Success : Boolean := True;
      O : Abstracted_Access;	 
      End_Of_File : Boolean := False;
      
      P  : Natural := 0;
      
   begin
      while not W_Io.End_Of_File(File) loop
   	 begin
   	    W_Io.Look_ahead(File, Wchar, Is_end);
   	    if Is_Graphic(To_Character(Wchar)) then
   	       exit;	       
   	    end if;
	    
   	    W_Io.Get_Immediate(File, Wchar);
   	    if Wchar = Wide_Character'Val(7) then
   	       P := P + 1;	       	       
   	    end if;
   	 end;
      end loop;
      --Classes.Windows.Draw(Win, Line_Index+1, 1, Cyan, "Section 1 :" & To_Wide_String(Integer'Image(P)));
      if not W_Io.End_Of_File(File) then
   	 Global_Read(File, End_Of_File, O);
   	 Line_Index := 1;
   	 Classes.Windows.Draw_Window(Win);
   	 -- Classes.Windows.Draw(Win, Line_Index+1, 1, Cyan, "new Obj :");
   	 Global_Print(O, Win, Line_index);
	 
	 
	 
   	 if P > 0 and P <= Natural(Length(T.V_Switch)) then
	    
   	    --Classes.Windows.Draw(Win, Line_Index+2, 1, Cyan, "Section 2 :");
   	    for I in 1..P-1 loop
   	       Parent(T, Prompt);
   	       Line_Index := 2;
   	       Global_Print(T.Obj_cur, state, Line_index);
   	    end loop;	       		  
	    
	    
   	    Success := False;
   	 elsif P > 0 then
	    
   	    --Classes.Windows.Draw(Win, Line_Index+3, 1, Cyan, "Section 3 :");
   	    for I in 1..P loop
   	       Parent(T, Prompt);
   	    end loop;
	    
	    
   	 end if;
   	 Line_Index := 1;
   	 if not Success then	       		  
   	    if O.Index /= 1 then
	       
   	       --Classes.Windows.Draw(Win, Line_Index+4, 1, Cyan, "Section 4 :");
   	       T.Obj_Cur.Vector := T.Obj_Cur.Vector & O;

   	    elsif not Is_Empty (T.Obj_Cur.Vector) and O.Index = 1 then	       
   	       Switch(T, Last_Index(T.Obj_Cur.Vector), Prompt, Success);
	       
   	       --Classes.Windows.Draw(Win, Line_Index+5, 1, Cyan, "Section 5 :");
   	       --raise Program_Error;
   	       T.Obj_Cur.Vector := T.Obj_Cur.Vector & O;
	       
   	    end if;
	    
   	 elsif not Is_Empty (T.Obj_Cur.Vector) and O.Index = 1 then	       
   	    Switch(T, Last_Index(T.Obj_Cur.Vector), Prompt, Success);
   	    if Success then
   	       --Classes.Windows.Draw(Win, Line_Index+4, 1, Cyan, "Section 6 :");
   	       T.Obj_Cur.Vector := T.Obj_Cur.Vector & O;		 		  
   	    else
   	       raise Program_Error;
   	    end if;	       	    	    
   	 else
   	    --Classes.Windows.Draw(Win, Line_Index+3, 5, Cyan, "Section 7 :");
   	    T.Obj_Cur.Vector := T.Obj_Cur.Vector & O;
   	 end if;
	 
   	 --W_Io.Skip_Line;
	 
	 
	 
   	 if not W_Io.End_Of_File(File) then
   	    Restore_Vector(T, Win, State, File);
   	 end if;	    
	 
      end if;	 
      
   end Restore_Vector;

   
   procedure Restore_Object (T : in out Terminal_Record;
   			     Win : in Classes.Windows.Window_Type;
   			     State : in Classes.Windows.Window_Type;
   			     File : W_Io.File_Type) is
      End_Of_File : Boolean := False;
      Vector : Objects_Vector;
   begin

      if not W_Io.End_Of_File(File) then
	 
   	 Global_Read(File, End_Of_File, T.Obj);
	 
      end if;
      
      T.Obj_Cur := T.Obj;
      
      if not W_Io.End_Of_File(File) then
	 
	 
   	 Restore_Vector(T, Win, State, File);
	 
      end if;            
      
   end Restore_Object;
   
   
   
   procedure Restore(T : in out Terminal_Record;
   		     Win : in Classes.Windows.Window_Type;
   		     State : in Classes.Windows.Window_Type;
   		     Filename : in String) is
      
      File : W_Io.File_Type;
   begin

      W_Io.Open(File, W_Io.in_File, Filename);
      if not W_Io.End_Of_File(File) then
   	 Restore_Object(T, Win, State, File);
      end if;
      
      W_Io.Close(File);
   end Restore;
   
   
   procedure Update(T : in out Terminal_Record;
   		    Prompt : in Name_Type;
   		    Expr   : in Intelligency.Expression_Type) is
   begin
      T.Expr_List := T.Expr_List & Expr;	 
      T.Prompt_List := T.Prompt_List & Prompt;	 
      if T.Line + 1 > V_Win_Max-1 then
   	 null;
      else
   	 T.Line := 1 + T.V_Win_Last - (T.V_Win_First - 1);	    
	 
      end if;	 
      T.V_Win_Last := T.V_Win_Last + 1;
      if T.V_Win_Last >= Line_Range'Last-1 then
   	 T.V_Win_First := T.V_Win_First + 1;
      end if;
   end Update;
   
   
   use Ada.Calendar.Formatting;
   
   procedure State_Draw(Where : in Classes.Windows.Window_Type;
			State : in Intelligency.Account.Account_State_Type) is
            
      WStr_Date : constant Wide_String := To_Wide_String(Formatting.Image(State.Date));
      WStr_Ht_Deal_In : constant Wide_String := To_Wide_String(Fixed_Out'Image(State.HT_Deal_In));
      WStr_TTC_Deal_In : constant Wide_String :=To_Wide_String(Fixed_Out'Image(State.TTC_Deal_In));
      WStr_TVA_In : constant Wide_String :=To_Wide_String(Fixed_out'Image(State.Tva_out));
      WStr_Ht_Deal_Out : constant Wide_String :=To_Wide_String(Fixed_in'Image(State.HT_Deal_Out));
      WStr_TTC_Deal_Out : constant Wide_String :=To_Wide_String(Fixed_in'Image(State.TTC_Deal_Out));
      WStr_TVA_Out : constant Wide_String:=To_Wide_String(Fixed_in'Image(State.Tva_In));
      WStr_Result  : constant Wide_String :=To_Wide_String(Fixed_Account'Image(State.Result));
      
      
      
   begin
      Classes.Windows.Draw(Where, 
	   1, 17,
	   white, WStr_Date);
      
      Classes.Windows.Draw(Where, 
	   2, 17,
	   white, WStr_Ht_Deal_In);
      
      Classes.Windows.Draw(Where, 
	   3, 17,
	   white, WStr_TTC_Deal_In);
      
      
      Classes.Windows.Draw(Where, 
	   4, 17,
	   white, WStr_TVA_Out);
      
      
      Classes.Windows.Draw(Where, 
	   5, 17,
	   white, WStr_Ht_Deal_Out);
      
      Classes.Windows.Draw(Where, 
	   6, 17,
	   white, WStr_TTC_Deal_Out);
      
      Classes.Windows.Draw(Where, 
	   7, 17,
	   white, WStr_TVA_In);
      
      Classes.Windows.Draw(Where, 
	   8, 17,
	   white, WStr_Result);
      
   end State_Draw;

   
   
   procedure Global_Content_Print (Object : Abstracted_Access;
   				   Win       : in Classes.Windows.Window_Type;
   				   Win_Index : in out Natural) is

      
      Objects : Objects_Vector := Object.Vector;
      
      Counter : Object_Counter := (others => 0);
      
      Account_Line_Index : Index_Line_range := 1;
      
      
      Initialized : Boolean := False;
      
      State : Account_State_Type;
      
      
      	       

      
   begin
      
      Classes.Windows.Draw(Win, Win_Index+1, 3, White, "Content of " & Object.Name);
      Win_Index := Win_Index + 1;
      if not Is_Empty(Objects) then
   	for I in 1..Last_Index(Objects) loop
   	   declare
   	      E : Abstracted_Access := Abstracted_Vectors.Element(Objects, I);
   	   begin
   	      for J in Tag_Name'Succ(Null_Tag)..Tag_Name'Last loop
   		 if E.Tag = J then
   		    Counter(J) := Counter(J) + 1;
   		    if E.Tag = Deal then
   		       Account_Line_Draw(Accounting_Wins, Account_Line_Index, Deal_Class(E.all).Line);
   		       Account_Line_Index := Account_Line_Index + 1;
		       
   		       State.Date  := Deal_Class(E.all).Create_Date;
		       
		       		       
		       
		       
   		       if not Initialized then			  			  			  
			  
			  
   			  State_Draw(Where => Wins_Main.Start_State_Win_Ptr.all,
   				     State => State);
   			  Initialized := True;
   		       else
			  
   			  State_Draw(Where => Wins_Main.End_State_Win_Ptr.all,
   				     State => State);
   		       end if;
   		       if Account_Line_Index >= Index_Line_Range'last then
   			  Account_Line_Index := 1;
   		       end if;
   		    end if;
   		 end if;
   	      end loop;
   	   end;
   	end loop;
      end if;
      for I in Tag_Name'Succ(Null_Tag)..Tag_Name'Last loop
   	 Classes.Windows.Draw(Win, Win_Index+1, 3, White, To_Wide_String(Tag_Name'Image(I)) &
   		Wide_Fixed."*"((16 - Tag_Name'Image(I)'Length),' ') &
   		" : Total  = " & To_Wide_String(Natural'Image(Counter(I))) &
   		" " & To_Wide_String(Tag_Name'Image((i))));
	 
	 
	    
	 
	 
   	 Win_Index := Win_Index + 1;
	 
      end loop;
   end Global_Content_Print;

   procedure Search(T : in out Terminal_Record;
   		    name : in Name_Type;
   		    Path_Index : in out Natural;
   		    Prompt : out Name_Type;
   		    Success : out boolean);
   
   
   
   
   procedure Rank_Sum (Object  : in Abstracted_Access;
		       Ucost   : in out Float;
		       Hcost   : in out float) is
   begin
      
      if not Is_Empty(Object.Vector) then
	 
   	 for I in 1..Last_Index(Object.Vector) loop
	    
   	    declare
   	       E : constant Abstracted_Access :=
   		 Element(Object.Vector, I);
   	    begin
	       
	       Ucost := Ucost + E.Ucost;
	       Hcost := Hcost + E.Hcost;
	       
   	       Rank_Sum(E, Ucost, Hcost);	       
	       
	       
   	    end;
   	 end loop;	 	 
	 
      end if;
      
   end Rank_Sum;
   
   
   procedure Evaluate_Tree (Object  : in Abstracted_Access;
			    Ucost   : out Float;
			    Hcost   : out float) is
      
   begin
      Ucost := 0.0;
      Hcost := 0.0;
      
      if Object /= null then
	 
	 Rank_Sum (Object, Ucost, Hcost);
	 
      end if;
   end Evaluate_Tree;
   
   
   
   procedure Adjust_Rank (Object  : in Abstracted_Access;
			  Ucost   : in out Float;
			  Hcost   : in out float) is
   begin
      
      if not Is_Empty(Object.Vector) then
	 
   	 for I in 1..Last_Index(Object.Vector) loop
	    
   	    declare
   	       E : constant Abstracted_Access :=
   		 Element(Object.Vector, I);
   	    begin
	       
	       Ucost := Lib.Default_Ranking(E.Tag).Ucost;
	       
	       Hcost := Lib.Default_Ranking(E.Tag).Hcost;
	       
   	       Adjust_Rank(E, Ucost, Hcost);
	       E.Ucost := Ucost;
	       E.Hcost := Hcost + Ucost;
	       
	       
   	    end;
   	 end loop;	 	 
	 
      end if;
      
   end Adjust_Rank;
   
   
   procedure Valuate_Tree (Object  : in Abstracted_Access) is
      Ucost : Float := 0.0;
      Hcost : Float := 0.0;
   begin
      Adjust_Rank (Object, Ucost, Hcost);
      Object.Ucost := Ucost;
      Object.Hcost := Hcost - Ucost;
   end Valuate_Tree;
   
   
   
   
   procedure Right_Exec (T : in out Terminal_Record;
   			 Win : in Classes.Windows.Window_Type;
   			 Prompt : out Name_Type) is
      
      Nothing : Name_Type;
      Objects : Objects_Vector;
      Win_First  : Natural := 0;
      Line_Index : Positive := 1;
      Success : Boolean := False;
      
      Ucost : Float := 0.0;
      Hcost : Float := 0.0;
      
      E : Expression_Type;
      Expression : Wide_String_Access;
      
      O : Abstracted_Access;
      Num : natural := 0;
      Name    : Name_Type := (others => Wide_Character'Val(32));
      Tag_val : Tag_Name := Null_Tag;
      Cmd     : Cmd_Name := Null_Item;
      Arity   : Arity_Range := 3;
      -- arity for universe
      Genre   : Genre_Type;
      -- genre for animal male or female
      Obj     : Abstracted_Access;
      Tmp     : Abstracted_Access;
      Tel_Num : Tel_Num_Type;
      -- tel num for contact
      Date    : Date_Wstring := (others => Wide_Character'Val(32));
      Event_Date : Time;
      line    : Note_line := (others => Wide_Character'Val(32));
      
      Design : Designation_Line := (others => Wide_Character'Val(32));
      -- designation for Account line
      
      Sum    : Fixed_Sum := 0.0;
      -- for account line
      
      
      Delays : Days_Delay := 0;
      -- for account line
      
      Mark   : Name_type := (others => Wide_Character'Val(32));
      -- for car
      
      Car_Genre : Name_Type  := (others => Wide_Character'Val(32));
      -- for car
      
      Car_Immat : Name_Type := (others => Wide_Character'Val(32));
      -- for car
      
      Description : Description_Type := (others => Wide_Character'Val(32));
      -- for content
      
      Price : Price_Type := 0.0;
      -- for content
      
      surface : Name_Type := (others => ' ');
      -- for house
      
      address  : Address_Type := (others => ' ');
      -- for house 
      City_Code  : Name_Type := (others => ' ');
      -- for house
      City_name : Address_type := (others => ' ');
      -- for house
      
      
      -- activity.
      Raison    : Wstring_38 := (others => ' ');
      Full_Address : Wstring_38 := (others => ' ');
      Ste_Type  : Wstring_24 := (others => ' ');
      Fiscal    : Wstring_24 := (others => ' ');
      Affilia   : Wstring_24 := (others => ' ');
      
      
      
      -- dealline
      Desc     : wstring_16;
      Acc_Num : account_num_range;
      U_Ht    : fixed_unit_ht;
      Tva     : fixed_factor;
      Qt      : quantity_range;
      Peer    : wstring_16;
      
      
      -- planning
      Ressources : Wstring_32 := (others => ' ');
      From       : Time := Clock;
      To         : Time := Clock;
      
      
      -- plan
      Plan_Date : Time := Clock;
      Period    : Duration := 0.0;
      Plan_Description : Wstring_64 := (others => ' ');
      
      
      Att_enum  : Attribut_Enum := Nil;
      Att_Name  : String_Access;
      Image     : String_Access;
      
   begin
      --Name := T.Prompt;	 
      Classes.Windows.Draw_Window(Win);
      
      if T.V_Win_Last > 0 then
	 
	 E := Expr_Vectors.Last_Element(T.Expr_List);
	 
	 Expression := new Wide_String ' (E(E'First..Wide_Fixed.Index_Non_Blank(E, Backward)));
	 
   	 -- Exec --
   	 
	 Cmd := Cmd_Value(Expression.all);
	 
	 case Cmd is
	    when Word =>
	       
	       raise Is_Word;
	    when Dump =>
	       null;
	    when Attribute =>
	       Parse(Expression.all, Att_Name, Image);
	       if T.Obj_Cur /= null and then
		 T.Obj_Cur.Def.Index < 4 then
		  T.Obj_Cur.Def.list(T.Obj_Cur.Def.Index + 1) := Make(Att_Name.all, Image.all);
		  T.Obj_Cur.Def.Index := T.Obj_Cur.Def.Index + 1;
	       end if;		     
	    when List =>
	       if T.Obj_cur /= null then
		  declare
		     Object : Abstracted_Access := T.Obj_cur;
		     
		  begin
		     begin
			Tag_Val := class_Value(Expression.all);			      
		     exception
			when others =>
			   null;
		     end;
		     if Object /= null then
			
			Objects := Object.Vector;
			
			
			if not Abstracted_Vectors.Is_Empty(Objects) then
			   declare
			      Old_Index : Natural := Line_Index;
			      
			   begin
			      Line_Index := 1;
			      Classes.Windows.Draw_Window(Win);
			      for I in T.Page_Index+1..Integer'min(Abstracted_Vectors.Last_index(Objects), T.Page_Index+1) loop
				 declare
				    E : constant Abstracted_Access :=
				      Abstracted_Vectors.Element(Objects, I);
				 begin
				    if Tag_Val /= Null_Tag and
				      E.Tag = Tag_val then
				       Global_Print(E, Win, Line_index);
				    elsif Tag_val = Null_Tag then
				       Global_Print(E, Win, Line_Index);
				    end if;
				    if Line_Index <= V_Line_Range'Last  then			   
				       Line_Index := Line_Index + 1;
				    else
				       
				       exit;
				    end if;
				 end;
				 
				 
			      end loop;
			      Line_Index := Old_Index;
			   end;
			end if;					  
		     end if;			
		  end;
	       end if;
	    when Print =>		     
	       
	       begin
		  Num := Num_Value(Expression.all);
	       exception
		  when others =>
		     null;
	       end;
	       if Num /= 0 then
		  if T.Obj_Cur /= null and then
		    Last_Index(T.Obj_Cur.Vector) >= Num then
		     O := Abstracted_Vectors.Element(T.Obj_Cur.Vector, Num);
		     case O.Tag is
			when Universe =>
			   Universe_Class(O.all).Print(Win, Line_Index, nothing);
			when Animal =>
			   Animal_Class(O.all).Print(Win, Line_Index, nothing);			      
			when Deal =>
			   Deal_Class(O.all).Print(Win, Line_Index, nothing);			      
			when car =>
			   car_Class(O.all).Print(Win, Line_Index, nothing);			      
			when Content =>
			   Content_Class(O.all).Print(Win, Line_Index, nothing);
			when Plan =>
			   Plan_Class(O.all).Print(Win, Line_Index, nothing);
			when Planning =>
			   Planning_Class(O.all).Print(Win, Line_Index, nothing);
			when Activity =>
			   Activity_Class(O.all).Print(Win, Line_Index, nothing);
			when House =>
			   House_Class(O.all).Print(Win, Line_Index, nothing);
			when Contact =>
			   Contact_Class(O.all).Print(Win, Line_Index, nothing);
			when Event =>
			   Event_Class(O.all).Print(Win, Line_Index, nothing);
			when Note =>			      
			   Note_Class(O.all).Print(Win, Line_Index, nothing);
			when Saved_Ac =>			      
			   Saving_Account_Class(O.all).Print(Win, Line_Index, nothing);
			when Perso_Ac =>			      
			   Personal_Account_Class(O.all).Print(Win, Line_Index, nothing);
			when Entep_Ac =>			      
			   Enteprise_Account_Class(O.all).Print(Win, Line_Index, nothing);			      
			when Acc_line =>			      
			   Acc_Line_Class(O.all).Print(Win, Line_Index, nothing);
			when others =>
			   null;
		     end case;
		  end if;
		  
	       elsif T.Obj_Cur /= null then
		  
		  case T.Obj_Cur.Tag is
		     when Universe =>
			Universe_Class(T.Obj_Cur.all).Print(Win, Line_Index, nothing);
		     when Animal =>
			Animal_Class(T.Obj_Cur.all).Print(Win, Line_Index, nothing);
		     when Deal =>
			Deal_Class(T.Obj_Cur.all).Print(Win, Line_Index, nothing);
		     when car =>
			car_Class(T.Obj_Cur.all).Print(Win, Line_Index, nothing);
		     when Content =>
			Content_Class(T.Obj_Cur.all).Print(Win, Line_Index, nothing);			   
		     when Plan =>
			Plan_Class(T.Obj_Cur.all).Print(Win, Line_Index, nothing);
		     when Planning =>
			Planning_Class(T.Obj_Cur.all).Print(Win, Line_Index, nothing);			   
		     when Activity =>
			Activity_Class(T.Obj_Cur.all).Print(Win, Line_Index, nothing);
		     when House =>
			House_Class(T.Obj_Cur.all).Print(Win, Line_Index, nothing);
		     when Contact =>
			Contact_Class(T.Obj_Cur.all).Print(Win, Line_Index, nothing);
		     when Event =>
			Event_Class(T.Obj_Cur.all).Print(Win, Line_Index, nothing);
		     when Note =>			      
			Note_Class(T.Obj_Cur.all).Print(Win, Line_Index, nothing);
		     when Saved_Ac =>			      
			Saving_Account_Class(T.Obj_Cur.all).Print(Win, Line_Index, nothing);
		     when Perso_Ac =>			      
			Personal_Account_Class(T.Obj_Cur.all).Print(Win, Line_Index, nothing);
		     when Entep_Ac =>			      
			Enteprise_Account_Class(T.Obj_Cur.all).Print(Win, Line_Index, nothing);
		     when Acc_line =>			      
			Acc_Line_Class(T.Obj_cur.all).Print(Win, Line_Index, nothing);
		     when others =>
			null;
		  end case;
	       end if;	       
	    when Switch =>
	       declare
		  Num : Abstracted_Index := 1;
		  
	       begin
		  Num := Num_Value(Expression.all);
		  Switch(T, Num, Prompt, Success);
	       end;
	       
	    when Intelligency.Search =>
	       
	       Name  := Object_name(Expression.all);
	       T.Top := T.Obj_Cur;		     
	       if T.Top /= null then
		  Prompt := T.Obj_Cur.Name;
	       end if;
	       begin
		  Search(T, Name, T.Path_Index, Prompt, Success);
	       exception
		  when Spec_Error =>
		     if Name /= Prompt then			
			declare
			   
			   Curs : Abstracted_Vectors.Cursor;
			begin
			   T.Obj_Cur := T.Top;
			   if Last_Index(T.V_Switch) >= (T.Path_Index)  then
			      Curs := Abstracted_Vectors.To_Cursor(T.V_Switch, Last_Index(T.V_Switch) - (T.Path_Index-1));
			      Delete(T.V_Switch, Curs,  Count_Type(T.Path_Index-1));
			   end if;
			   Prompt := T.Obj_Cur.Name;
			end;			      
		     end if;
	       end;
	       
	       if Name /= Prompt then
		  declare
		     
		     Curs : Abstracted_Vectors.Cursor;
		  begin
		     T.Obj_Cur := T.Top;
		     if Last_Index(T.V_Switch) >= (T.Path_Index)  then
			Curs := Abstracted_Vectors.To_Cursor(T.V_Switch, Last_Index(T.V_Switch) - (T.Path_Index-1));
			Delete(T.V_Switch, Curs,  Count_Type(T.Path_Index-1));
		     end if;
		     Prompt := T.Obj_Cur.Name;
		  end;			
	       end if;
	       
	    when Root =>		     
	       Parent(T, Prompt);
	    when Null_Item =>
	       raise Cmd_Error;
	    when others =>
	       declare
		  
	       begin
		  
		  Tag_Val := Class_Value(Expression.all);
		  Obj := Id(Tag_Val); 
	       exception
		  when Spec_Error =>
		     null;
	       end;
	       if (Obj /= null) then
		  if Obj.all'tag = Animal_Class'tag then
		     case Cmd is
			when Help =>
			   Line_Index := 1;
			   Animal_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>			      			      
			   
			   Genre := Genre_Value(Expression.all);
			   Name  := Name_Value(Expression.all);
			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, Genre, Name);
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;				    
			      
			   else
			      
			      T.Obj := Create(Win, Line_Index, Genre, Name);
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			when others =>
			   raise Program_Error;
		     end case;
		     
		  elsif Obj.all'tag = Deal_Class'tag then
		     case Cmd is
			when Help =>
			   Line_Index := 1;
			   Deal_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>			      
			   Name  := Acc_name_Value(Expression.all);
			   Desc  := Denom_Value(Expression.all);
			   Acc_Num := Account_Num_Value(Expression.all);
			   U_Ht    := U_Ht_Value(Expression.all);
			   Tva     := Tva_Value(Expression.all);
			   Qt      := Quantity_Value(Expression.all);
			   Peer    := Peer_Name(Expression.all);
			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, Name, Desc, Acc_Num, U_Ht, Tva, Qt,
					    Payment_Delays_Value(Expression.all), Peer);
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;				    
			      
			   else
			      
			      T.Obj := Create(Win, Line_Index, Name, Desc, Acc_Num, U_Ht, Tva, Qt, 
					      Payment_Delays_Value(Expression.all), peer);
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			   
			when others =>
			   raise Program_Error;
		     end case;
		     
		     
		  elsif Obj.all'tag = Content_Class'tag then
		     
		     case Cmd is
			when Help =>
			   Line_Index := 1;
			   Content_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>
			   Name  := Event_value(Expression.all);
			   
			   description := description_Value(Expression.all);
			   price := Price_Value(Expression.all);
			   
			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, Name, Price, description);
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;				    
			      
			   else
			      
			      T.Obj := Create(Win, Line_Index, Name, Price, description);
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			   
			when others =>
			   raise Program_Error;
		     end case;
		  elsif Obj.all'tag = Planning_Class'tag then
		     
		     case Cmd is
			when Help =>
			   Line_Index := 1;
			   Planning_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>
			   
			   Name  := Event_value(Expression.all);
			   ressources := ressources_Value(Expression.all);
			   From := Get_Date_From(Expression.all);
			   To := Get_Date_To(Expression.all);
			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, Name, Ressources, From, To);
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;				    
			      
			   else
			      
			      T.Obj := Create(Win, Line_Index, Name, Ressources, From, To);
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			   
			when others =>
			   raise Program_Error;
		     end case;
		  elsif Obj.all'tag = Activity_Class'tag then
		     
		     case Cmd is
			when Help =>
			   Line_Index := 1;
			   Activity_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>
			   
			   Name  := Event_value(Expression.all);
			   Raison := Raison_Value(Expression.all);
			   Full_Address := Full_Address_Value(Expression.all);
			   Ste_type := Ste_type_Value(Expression.all);
			   Affilia := Affilia_Value(Expression.all);
			   Fiscal := Fiscal_Value(Expression.all);
			   
			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, Name, Raison, Full_Address, Ste_Type, Affilia, Fiscal);
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;				    
			      
			   else
			      
			      T.Obj := Create(Win, Line_Index, Name, Raison, Full_Address, Ste_Type, Affilia, Fiscal);
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			   
			when others =>
			   raise Program_Error;
		     end case;
		     
		  elsif Obj.all'tag = Car_Class'tag then
		     
		     case Cmd is
			when Help =>
			   Line_Index := 1;
			   car_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>
			   Name  := Event_value(Expression.all);
			   mark  := Mark_Value(Expression.all);
			   Car_Genre := Car_genre_Value(Expression.all);
			   Car_Immat := Car_immat_Value(Expression.all);
			   
			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, Name, mark, Car_genre, Car_immat);
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;				    
			      
			   else
			      
			      T.Obj := Create(Win, Line_Index, Name, mark, Car_genre, Car_immat);
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			   
			when others =>
			   raise Program_Error;
		     end case;
		  elsif Obj.all'tag = Plan_Class'tag then
		     
		     case Cmd is
			when Help =>
			   Line_Index := 1;
			   Plan_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>
			   Name  := Event_value(Expression.all);
			   Plan_Date := Get_Date_from(Expression.all);
			   Period := Period_Value(Expression.all);
			   Plan_Description := Plan_Description_Value(Expression.all);
			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, Name, Plan_date, period, Plan_description);
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;				    
			      
			   else
			      
			      T.Obj := Create(Win, Line_Index, Name, Plan_date, period, Plan_description);
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			   
			when others =>
			   raise Program_Error;
		     end case;
		  elsif Obj.all'tag = House_Class'tag then
		     
		     case Cmd is
			when Help =>
			   Line_Index := 1;
			   House_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>
			   Name  := Event_value(Expression.all);			      
			   surface  := surface_Value(Expression.all);
			   address  := address_Value(Expression.all);
			   City_Code := City_code_Value(Expression.all);
			   City_name := City_name_Value(Expression.all);
			   
			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, Name, Surface, Address, City_Code, City_name);
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;				    
			      
			   else
			      
			      T.Obj := Create(Win, Line_Index, Name, Surface, Address, City_Code, City_name);
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			   
			when others =>
			   raise Program_Error;
		     end case;
		     
		  elsif Obj.all'tag = Acc_Line_Class'tag then
		     
		     case Cmd is
			when Help =>
			   Line_Index := 1;
			   Acc_Line_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>
			   Name  := line_name_Value(Expression.all);
			   design  := designation_Value(Expression.all);			      
			   sum  := sum_Value(Expression.all);
			   Delays := delays_Value(Expression.all);
			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, Name, Design, Sum, delays);
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;				    
			      
			   else
			      
			      T.Obj := Create(Win, Line_Index, Name, Design, Sum, delays);
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			   
			when others =>
			   raise Program_Error;
		     end case;
		     
		  elsif Obj.all'tag = Saving_Account_Class'tag then
		     case Cmd is
			when Help =>
			   Line_Index := 1;
			   Saving_Account_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>
			   
			   Name  := account_Name(Expression.all);
			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, Saving_Account_Range'First, Saving_Account_Range'Last, Name);
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;				    
			      
			   else
			      
			      T.Obj := Create(Win, Line_Index, Saving_Account_Range'First, Saving_Account_Range'Last, Name);
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			   
			when others =>
			   raise Program_Error;
		     end case;
		  elsif Obj.all'tag = Personal_Account_Class'tag then
		     case Cmd is
			when Help =>
			   Line_Index := 1;
			   Personal_Account_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>
			   
			   Name  := Account_Name(Expression.all);
			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, Personal_Account_Range'First, Personal_Account_Range'Last, Name);
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;				    
			      
			   else
			      
			      T.Obj := Create(Win, Line_Index, Personal_Account_Range'First, Personal_Account_Range'Last, Name);
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			   
			when others =>
			   raise Program_Error;
		     end case;
		  elsif Obj.all'tag = Enteprise_Account_Class'tag then
		     case Cmd is
			when Help =>
			   Line_Index := 1;
			   Enteprise_Account_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>
			   
			   Name  := Account_Name(Expression.all);
			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, Enteprise_Account_Range'First, Enteprise_Account_Range'Last, Name);
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;				    
			      
			   else
			      
			      T.Obj := Create(Win, Line_Index, Enteprise_Account_Range'First, Enteprise_Account_Range'Last, Name);
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			   
			when others =>
			   raise Program_Error;
		     end case;
		  elsif Obj.all'tag = Universe_Class'Tag then
		     
		     case Cmd is
			when Help =>
			   Line_Index := 1;
			   Universe_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>
			   Arity := Arity_Value(Expression.all);				       
			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, "Universe        ");
			      
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;
			   else
			      
			      T.Obj := Create(Win, Line_Index, "Universe        ");
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			when others =>
			   raise Program_Error;
		     end case;
		  elsif Obj.all'tag = Contact_Class'tag then
		     case Cmd is
			When Help =>
			   Line_Index := 1;
			   Contact_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>
			   name := contact_Value(Expression.all);
			   Tel_num := Tel_Num_Value(Expression.all);
			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, Tel_Num, Name);
			      
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;
			   else
			      
			      T.Obj := Create(Win, Line_Index, Tel_Num, Name);
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			   
			when others =>
			   raise Program_Error;
		     end case;
		     
		  elsif Obj.all'tag = Event_Class'tag then
		     case Cmd is
			When Help =>
			   Line_Index := 1;
			   Event_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>
			   name := event_Value(Expression.all);
			   Date := Date_Value(Expression.all);
			   Event_Date := Value(To_String(Date));
			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, Event_Date, Name);
			      
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;
			   else
			      
			      T.Obj := Create(Win, Line_Index, Event_Date, Name);
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			   
			when others =>
			   raise Program_Error;
		     end case;
		  elsif Obj.all'tag = Note_Class'tag then

		     case Cmd is
			When Help =>
			   Line_Index := 1;
			   Note_Class(Obj.all).Help(Win, Line_Index, Nothing);
			when Create =>				 				 				 

			   name := Note_Value(Expression.all);

			   Line := Line_value(Expression.all);

			   if T.Obj_cur /= null then
			      
			      Tmp := Create(Win, Line_Index, Name, Line);
			      
			      if Tmp /= null then
				 Tmp.Index := Abstracted_Vectors.Last_Index(T.Obj_cur.Vector) + 1;
				 T.Obj_cur.Vector := 
				   Abstracted_Vectors."&"(T.Obj_cur.Vector, Tmp);
			      end if;
			   else
			      
			      T.Obj := Create(Win, Line_Index, Event_Date, Name);
			      T.Obj_Cur := T.Obj;
			      T.V_Switch := T.V_Switch & T.Obj;
			   end if;
			   
			when others =>
			   raise Program_Error;
		     end case;
		  end if;			      
	       else			
		  case Cmd is
		     when Help =>
			Line_Index := 1;
			Help(Win, Line_Index, Nothing);				    
		     when others =>
			null;
		  end case;						
	       end if;			   
	 end case;
	 
	 if not Classes."="(T.Obj, null) then
	    
	    Valuate_Tree(T.Obj);
	 end if;

      end if;
   exception
      when Is_Word =>
	 Text_Io.Put_Line("Right Exec : exception : Is word");
	 raise;
   end Right_Exec;

   
   procedure Switch(T : in out Terminal_Record;
   		    Num : in Abstracted_Index;
   		    Prompt : out Name_Type;
   		    Success : out boolean) is
      Vector : Objects_Vector;	 
   begin
      Success := False;
      Prompt := (others => Wide_Character'Val(32));
      if T.Obj_Cur /= null then
   	 Vector := T.Obj_Cur.Vector;
   	 if not Is_Empty(Vector) then
   	    if Num <= Last_Index(Vector) then
   	       T.V_Switch := T.V_Switch & T.Obj_Cur;
   	       T.Obj_Cur := Abstracted_Vectors.Element(Vector, Num);
   	       if T.Obj_Cur /= null then
   		  Prompt := T.Obj_Cur.Name;		     
   		  Success := True;
   	       else
   		  raise Program_Error;		     
   	       end if;
   	    end if;
   	 end if;
      end if;	 
   end Switch;
   
   procedure Search(T : in out Terminal_Record;
   		    name : in Name_Type;
   		    Path_Index : in out Natural;
   		    Prompt : out Name_Type;
   		    Success : out boolean) is
      
      
      
      Vector : Objects_Vector := T.Obj_Cur.vector;
      
   begin
      Success := False;
      if T.Obj_Cur.Name = Name then	    
   	 Prompt := Name;	   	    
   	 Success := True;
      else	    
   	 if not Is_Empty(Vector) then
   	    for I in 1..Last_Index(Vector) loop
   	       declare
   		  E : Abstracted_Access := Abstracted_Vectors.Element(Vector, I);
   		  Term : Terminal_Record := T;
   	       begin
   		  if E /= null then						
   		     Switch(Term, I,  Prompt, success);
   		     Path_Index := Path_Index + 1;
   		     if Success then
   			Search(Term, Name, Path_Index, Prompt, success);
   			if Success then
   			   T := Term;
   			   exit;
   			end if;
   		     end if;	
   		  else
   		     raise Program_Error;
   		  end if;
   	       end;
   	    end loop;
	    
   	 end if;
      end if;
   end Search;
   
   
   
   
   
   
   procedure Parent(T : in out Terminal_Record;
   		    Prompt : out Name_Type) is
      
      V : Objects_Vector := T.V_Switch;
   begin
      if not Is_Empty(V) then
   	 if Last_Index(V) >= 1 then
   	    T.Obj_Cur := Last_Element(V);
   	    if T.Obj_Cur /= null then
   	       Prompt := T.Obj_Cur.Name;
   	       if Last_Index(V) > 1 then
   		  Delete(V, Last_Index(V));
   	       end if;
   	    end if;
   	 end if;
      end if;
      T.V_Switch := V;
   end Parent;
   
   
   procedure Save(T : in Terminal_Record) is
   begin
      if Expr_Vectors.length(T.Expr_List) /= 0 then
   	 declare
   	    File : Ada.Wide_Text_Io.File_Type;
   	 begin
   	    begin
   	       Ada.Wide_Text_Io.Open(File, Ada.Wide_Text_Io.Out_File, "organizer-listing.txt");
   	    exception
   	       when Ada.Wide_Text_Io.Name_Error =>
   		  Ada.Wide_Text_Io.Create(File, Ada.Wide_Text_Io.Out_File, "organizer-listing.txt");
   	    end;
	    
	    declare
	       E : constant Expression_type := Expr_Vectors.Last_Element(T.Expr_List);
	    begin
	       Ada.Wide_Text_Io.Put_Line(File, E);
	    end;
   	    Ada.Wide_Text_Io.Close(File);
   	 end;
      end if;
   end Save;   
   
   procedure Save_Object (Object : Abstracted_Access;			  
   			  File : W_Io.File_Type;
   			  Index  : Natural := 0) is
      O : Abstracted_Access := Object;                  
      New_Index : Natural := Index;
   begin      
      
      O.all.Write(File);
      
      W_Io.Put_Line(File, Wide_Character'Val(7) & "");
      
      
      if not Is_Empty(O.Vector) then
	 
	 
   	 for I in 1..Last_Index(O.Vector) loop
   	    declare
   	       E : constant Abstracted_Access :=
   		 Abstracted_Vectors.Element(O.Vector, I);
   	    begin
	       
   	       Save_Object(E, File, New_Index+1);	       
	       
   	       
   	    end;
   	 end loop;	 	 
	 
   	 for I in 1..Index loop
   	    W_Io.Put_Line(File, Wide_Character'Val(7) & "");
   	 end loop;
	    
	 
	 
      end if;
      
      
   end Save_Object;
   
   procedure Save (Object : in Abstracted_Access;
		   Filename : in String) is
      File : W_Io.File_Type;
      
   begin
      W_Io.Create(File, W_Io.Out_File, Filename);
      Save_Object(Object, File);
      W_Io.Close(File);
   end Save;
   
   
   use Path_Finding;
   use Path_Finding.Element_Lists;
   
   procedure Add_To_Path (Object : Abstracted_Access;
			  Path        : in out Path_Finding.Element_List) is
      
      O : Abstracted_Access := Object;

   begin

      Path_Finding.Element_Lists.Append(Path, O);

      if not Is_Empty(O.Vector) then

   	 for I in 1..Last_Index(O.Vector) loop

   	    declare
   	       E : constant Abstracted_Access :=
   		 Element(O.Vector, I);
   	    begin

   	       Add_To_path(E, Path);	       

   	    end;
   	 end loop;	 	 
	 
      end if;
   end Add_To_Path;
   
   
   procedure Goal_Path_Initialization (Object_Tree : Classes.Abstracted_Access;
				       Path        : out Path_Finding.Element_List) is
   begin

      Add_To_Path(Object_Tree, Path);

   end Goal_Path_Initialization;
   
   
      
   package body Users_Manager is
      
      -- User define --
      procedure Initialize(User : out User_Type;
			   Name : in String) is
	 
      begin
	 User.Logname(1..Name'Length) := Name;
      end Initialize;
      -- Get player named "Name".
      
      procedure Set_Pass(User : in out User_Type;
			 Pass : in Sha1.Message_Digest) is
      begin
	 User.Passwd := Pass;
      end Set_Pass;
      -- Set password for player.
      
      function Check_Pass(User : in User_Type;
			  Pass : in Sha1.Message_Digest) return Boolean is
      begin
	 return User.Passwd = Pass;
      end Check_Pass;
      -- Return True is getted password is valid. False else.      

      
      Users_Filename : constant String_Access := new String ' (".users");
      
      
      function Add_User(Logname : in String;
			Passwd : in Sha1.Message_Digest) return Boolean is

	 Users_File : Stream_Io.File_Type;
	 Users_Stream : Stream_Io.Stream_Access;

	 Old, Current : User_Type;

      begin

	 Initialize(Current, Logname);

	 Set_Pass(Current, Passwd);
	 
	 begin
	    Stream_IO.open(users_File, Stream_Io.In_File, Users_Filename.all);
	    
	    users_stream := Stream_IO.Stream(users_File);
	    while not Stream_Io.End_Of_File(Users_File) loop
	       User_Type'read(Users_Stream, old);
	       if Current.Logname = Old.Logname then
		  Stream_IO.Close(Users_File);
		  return False;
	       end if;
	    end loop;
	    Stream_IO.Close(Users_File);
	 exception
	    when Stream_Io.Name_Error =>
	       Stream_IO.create(users_File, Stream_Io.out_File, Users_Filename.all);
	       Stream_IO.Close(Users_File);
	 end;

	 Stream_IO.open(users_File, Stream_Io.append_File, Users_Filename.all);
	 users_stream := Stream_IO.Stream(users_File);
	 User_Type'write(Users_Stream, Current);
	 Stream_IO.Close(Users_File);
	 return True;
      end add_user;


      function Check_passwd(Logname : in String;
			    Passwd : in Sha1.Message_Digest) return Boolean is
	 Users_File : Stream_Io.File_Type;
	 Users_Stream : Stream_Io.Stream_Access;
	 

	 Old, Current : User_Type;

      begin
	 
	 
	 Initialize(Current, Logname);
	 Set_Pass(Current, Passwd);
	 
	 Stream_IO.open(users_File, Stream_Io.In_File, Users_Filename.all);
	 
	 users_stream := Stream_IO.Stream(users_File);
	 
	 while not Stream_Io.End_Of_File(Users_file) loop
	    User_Type'read(Users_Stream, old);
	    
	    if Current.Logname = Old.Logname then
	       
	       if Check_Pass(Old, passwd) then
		  

		  Stream_IO.Close(Users_File);

		  return True;

	       else

		  Stream_IO.Close(Users_File);
		  return False;
	       end if;
	    end if;
	 end loop;
	 
	 Stream_IO.Close(Users_File);
	 return False;
      exception
	 when others =>
	    return False;
      end Check_passwd;

      
   end Users_Manager;
   
   
   procedure Help(Win       : in Classes.Windows.Window_Type;
   		  Win_Index : in out Positive;
   		  Name      : out Name_Type) is
      Index : Natural := 0;
   begin
      Classes.Windows.Draw(Win, Win_Index, 3, Red, "help : ");
      Classes.Windows.Draw(Win, Win_Index+1, 3, Cyan, "Classes : (");
      for I in 1..Tag_Name'Pos(Tag_Name'Last) loop
   	 Classes.Windows.Draw(Win, Win_Index+2+index, 3, Cyan, To_Wide_String(Tag_Name'Image(Tag_Name'Val(i))));
   	 Index := Index + 1;
      end loop;      
      Classes.Windows.Draw(Win, Win_Index+2+Index, 3, Cyan, ")");
      Index := 0;
      Classes.Windows.Draw(Win, Win_Index+2, 15, Cyan, "Commands : (");
      for I in 1..Cmd_Name'Pos(Cmd_Name'Last) loop
   	 Classes.Windows.Draw(Win, Win_Index+3+index, 15, Cyan, To_Wide_String(Cmd_Name'image(Cmd_Name'Val(I))));
   	 Index := Index + 1;
      end loop;      
      Classes.Windows.Draw(Win, Win_Index+3+Index, 15, Cyan, ")");      
      
      Wide_Fixed.Move("help", Name, Error, Left, ' ');
      
      Index := 0;
      Classes.Windows.Draw(Win, Win_Index+2, 29, Cyan, "Attributs : (");
      for I in 1..Attribut_Enum'Pos(Attribut_Enum'Last) loop
   	 Classes.Windows.Draw(Win, Win_Index+3+index, 29, Cyan, To_Wide_String(Attribut_enum'image(Attribut_Enum'Val(I))));
   	 Index := Index + 1;
      end loop;      
      Classes.Windows.Draw(Win, Win_Index+3+Index, 29, Cyan, ")");      
      
      
      Index := 0;
      Classes.Windows.Draw(Win, Win_Index+2, 43, Cyan, "BOOL : (");
      for I in 0..boolean'Pos(Boolean'Last) loop
   	 Classes.Windows.Draw(Win, Win_Index+3+index, 43, Cyan, To_Wide_String(boolean'image(boolean'Val(I))));
   	 Index := Index + 1;
      end loop;      
      Classes.Windows.Draw(Win, Win_Index+3+Index, 43, Cyan, ")");      
      
      
      
      
   end Help;
   
   
   
   procedure Wins_Draw(Main_Wins : Main_Windows_Type) is
   begin
      Classes.Windows.Draw_Window(Wins_Main.Main_Win_ptr.all);
      
      Classes.Windows.Draw(Wins_Main.Main_Win_ptr.all, 2, 2, Magenta, "Input/Command");
      Classes.Windows.Draw_Window(Wins_Main.Input_Win_ptr.all);
      
      Classes.Windows.Draw(Wins_Main.Main_Win_ptr.all, 7, 2, cyan, "Output/Error");
      Classes.Windows.Draw_Window(Wins_Main.Output_Win_ptr.all);
      
      Classes.Windows.Draw(Wins_Main.Main_Win_ptr.all, 13, 2, yellow, "Response/Internal");
      Classes.Windows.Draw_Window(Wins_Main.Internal_Win_ptr.all);
      
      Classes.Windows.Draw(Wins_Main.Main_Win_ptr.all, 18, (cols-2)/4/2-5, White, "User views");
      Classes.Windows.Draw(Wins_Main.Main_Win_ptr.all, 18, (cols-2)/4+(cols-2)/4/2-4, White, "Ai views");
      
      Classes.Windows.Draw(Wins_Main.Main_Win_ptr.all, 19, 2, White, "Objects tree");
      Classes.Windows.Draw_Window(Wins_Main.User_Objects_Tree_Win_Ptr.all);
      
      Classes.Windows.Draw(Wins_Main.Main_Win_ptr.all, 
   	   21+Lines_Left/2-1, 2, White, "Objects view");
      Classes.Windows.Draw_Window(Wins_Main.User_Objects_View_Win_Ptr.all);
      
      
      Classes.Windows.Draw(Wins_Main.Main_Win_ptr.all, 19, (cols-2)/4+3, White, "Objects tree");
      Classes.Windows.Draw_Window(Wins_Main.Ai_Objects_Tree_Win_Ptr.all);
      
      Classes.Windows.Draw(Wins_Main.Main_Win_ptr.all, 
   	   21+Lines_Left/2-1, (cols-2)/4+3, White, "Objects view");
      Classes.Windows.Draw_Window(Wins_Main.Ai_Objects_View_Win_Ptr.all);
      
      
      
      
      Classes.Windows.Draw(Wins_Main.Main_Win_ptr.all, 
   	   7, (cols-2)/2+3,
   	   White, "Start state");
      Classes.Windows.Draw_Window(Wins_Main.Start_State_Win_Ptr.all);
            
      Classes.Windows.Draw(Wins_Main.Start_State_Win_Ptr.all, 
   	   1, 1,
   	   White, "From          : ");
      
      Classes.Windows.Draw(Wins_Main.Start_State_Win_Ptr.all, 
   	   2, 1,
   	   White, "Deal in  HT   : ");
      
      Classes.Windows.Draw(Wins_Main.Start_State_Win_Ptr.all, 
   	   3, 1,
   	   White, "Deal in  TTC  :");
      
      
      Classes.Windows.Draw(Wins_Main.Start_State_Win_Ptr.all, 
   	   4, 1,
   	   White, "TVA  out      : ");
      
      
      Classes.Windows.Draw(Wins_Main.Start_State_Win_Ptr.all, 
   	   5, 1,
   	   White, "Deal out HT   :");
      
      Classes.Windows.Draw(Wins_Main.Start_State_Win_Ptr.all, 
   	   6, 1,
   	   White, "Deal out TTC  :");
      
      Classes.Windows.Draw(Wins_Main.Start_State_Win_Ptr.all, 
   	   7, 1,
   	   White, "TVA  in       : ");
            
      Classes.Windows.Draw(Wins_Main.Start_State_Win_Ptr.all, 
   	   8, 1,
   	   White, "Result        :");
      
      
      
      
      Classes.Windows.Draw(Wins_Main.Main_Win_ptr.all, 
   	   7, (cols-2)/2+3+(cols-2)/4,
   	   yellow, "End state");
      Classes.Windows.Draw_Window(Wins_Main.End_State_Win_Ptr.all);
      
      
      Classes.Windows.Draw(Wins_Main.End_State_Win_Ptr.all, 
   	   1, 1,
   	   White, "To            : ");
      
      Classes.Windows.Draw(Wins_Main.End_State_Win_Ptr.all, 
   	   2, 1,
   	   White, "Deal in  HT   : ");
      
      Classes.Windows.Draw(Wins_Main.End_State_Win_Ptr.all, 
   	   3, 1,
   	   White, "Deal in  TTC  :");
      
      
      Classes.Windows.Draw(Wins_Main.End_State_Win_Ptr.all, 
   	   4, 1,
   	   White, "TVA  out      : ");
      
      
      Classes.Windows.Draw(Wins_Main.End_State_Win_Ptr.all, 
   	   5, 1,
   	   White, "Deal out  HT  :");
      
      Classes.Windows.Draw(Wins_Main.End_State_Win_Ptr.all, 
   	   6, 1,
   	   White, "Deal out  TTC :");
      
      Classes.Windows.Draw(Wins_Main.End_State_Win_Ptr.all, 
   	   7, 1,
   	   White, "TVA  in       : ");
            
      Classes.Windows.Draw(Wins_Main.End_State_Win_Ptr.all, 
   	   8, 1,
   	   White, "Result        :");
      
      
      
      
      Classes.Windows.Draw(Wins_Main.Main_Win_ptr.all, 
   	   19, (cols-2)/2+3,
   	   White, "Accounting");
      Classes.Windows.Draw(Wins_Main.Main_Win_ptr.all, 
   	   20, (cols-2)/2+2,
   	   Cyan, "+----------------------------------------------------------" &
   	     "----------------------------------------------------------+");
      Classes.Windows.Draw(Wins_Main.Main_Win_ptr.all, 
   	   21, (cols-2)/2+2,
   	   cyan, "     Designation        Account   Unit HT price    TVA   " & 
   	     "  Qt    Total HT price  Total TTC price      Peer Name  ");
      
      Accounting_Wins_Draw(Wins_Main.Accounting_Wins);
      
   end Wins_Draw;

   
   procedure Accounting_Wins_Draw(Wins : Accounting_Windows_Type) is
      
   begin
      Classes.Windows.Draw_Window(Wins.Tags_Win);
      Classes.Windows.Draw_Window(Wins.Acc_Num_Win);
      Classes.Windows.Draw_Window(Wins.Unit_Ht_Price_Win);
      Classes.Windows.Draw_Window(Wins.TVA_factor_Win);
      Classes.Windows.Draw_Window(Wins.Qt_Win);
      Classes.Windows.Draw_Window(Wins.Total_Ht_Win);
      Classes.Windows.Draw_Window(Wins.Total_Ttc_Win);
      Classes.Windows.Draw_Window(Wins.Peer_Win);
   end Accounting_Wins_Draw;      
   
   
   
end Lib.Engine ;