|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 54741 (0xd5d5)
Types: TextFile
Notes: R1k Text-file segment
└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000
└─⟦5a81ac88f⟧ »Space Info Vol 1«
└─⟦3948734d4⟧
└─⟦this⟧
with Bounded_String, Text_Io;
package T_Value is
Error_Integer_Value : exception;
Error_Boolean_Value : exception;
Error_Real_Value : exception;
Error_String_Value : exception;
Error_Equal_Value : exception;
Max_Value_String : constant := 80;
type Kind_Of_Values is (Undefined_Value, Integer_Value,
String_Value, Boolean_Value);
type Object (Kind : Kind_Of_Values := Undefined_Value) is private;
NULL_VALUE:Constant object;
subtype V_File is Text_Io.File_Type;
--Creation
procedure New_Value (V : out T_Value.Object);
--Liberation
procedure Dispose (V : in out T_Value.Object);
--Access
function Kind_Of_Value (V : in T_Value.Object) return Kind_Of_Values;
function Get (V : in T_Value.Object) return Integer;
function Get (V : in T_Value.Object) return Boolean;
function Get (V : in T_Value.Object) return String;
function Equal (V1 : in T_Value.Object; V2 : in T_Value.Object)
return Boolean;
function Image (V : in T_Value.Object) return String;
procedure Value_To_File (V : in T_Value.Object; F : V_File);
--Modification
procedure Undefine (V : in out T_Value.Object);
procedure Set (V : in out T_Value.Object; I : in Integer);
procedure Set (V : in out T_Value.Object; S : in String);
procedure Set (V : in out T_Value.Object; B : in Boolean);
procedure Copy (To_Value : in out T_Value.Object;
The_Value : in T_Value.Object);
procedure Set_Value_Using_File (V : in out T_Value.Object; F : V_File);
private
type String_Access is access String;
type Object (Kind : Kind_Of_Values := Undefined_Value) is
record
case Kind is
when Integer_Value =>
The_Integer : Integer;
when String_Value =>
The_String : String_Access;
when Boolean_Value =>
The_Boolean : Boolean;
when Undefined_Value =>
null;
end case;
end record;
NULL_VALUE :Constant Object:= (Kind => Undefined_Value);
end T_Value;
with Unchecked_Deallocation, Text_Io;
package body T_Value is
procedure Free is new Unchecked_Deallocation (String, String_Access);
--Creation
procedure New_Value (V : out T_Value.Object) is
begin
V := (Kind => Undefined_Value);
end New_Value;
--Liberation
procedure Dispose (V : in out Object) is
begin
if V.Kind = String_Value then
Free (V.The_String);
end if;
V := (Kind => Undefined_Value);
end Dispose;
--Access
function Kind_Of_Value (V : in Object) return Kind_Of_Values is
begin
return (V.Kind);
end Kind_Of_Value;
function Get (V : in T_Value.Object) return Integer is
begin
if (V.Kind = Integer_Value) then
return (V.The_Integer);
else
raise Error_Integer_Value;
end if;
end Get;
function Get (V : in T_Value.Object) return Boolean is
begin
if (V.Kind = Boolean_Value) then
return (V.The_Boolean);
else
raise Error_Boolean_Value;
end if;
end Get;
function Get (V : in T_Value.Object) return String is
begin
if (V.Kind = String_Value) then
return (V.The_String.all);
else
raise Error_String_Value;
end if;
end Get;
function Equal (V1 : in Object; V2 : in Object) return Boolean is
begin
if (V1.Kind = V2.Kind) then
case V1.Kind is
when Integer_Value =>
return (V1.The_Integer = V2.The_Integer);
when Boolean_Value =>
return (V1.The_Boolean = V2.The_Boolean);
when String_Value =>
return (V1.The_String.all = V2.The_String.all);
when Undefined_Value =>
return True;
end case;
else
return False;
end if;
exception
when Constraint_Error =>
raise Error_Equal_Value;
end Equal;
function Image (V : in T_Value.Object) return String is
begin
case V.Kind is
when Integer_Value =>
return (Integer'Image (V.The_Integer));
when Boolean_Value =>
return (Boolean'Image (V.The_Boolean));
when String_Value =>
return (V.The_String.all);
when Undefined_Value =>
return ("Undefined Value");
end case;
end Image;
procedure Value_To_File (V : in T_Value.Object; F : V_File) is
begin
-- Text_IO.Put(F,T_Value_Image(V));
Text_Io.Put_Line ("Function not yet implemented");
end Value_To_File;
-- Modification
procedure Undefine (V : in out Object) is
begin
Dispose (V);
New_Value (V);
end Undefine;
procedure Set (V : in out Object; I : in Integer) is
begin
Undefine (V);
V := (Kind => Integer_Value, The_Integer => I);
exception
when Constraint_Error =>
raise Error_Integer_Value;
end Set;
procedure Set (V : in out Object; S : in String) is
Ptr : String_Access;
begin
Undefine (V);
if not (S'Length > Max_Value_String) then
Ptr := new String (1 .. S'Length);
V := (Kind => String_Value, The_String => Ptr);
V.The_String.all := S;
else
raise Error_String_Value;
end if;
exception
when Constraint_Error =>
raise Error_String_Value;
end Set;
procedure Set (V : in out Object; B : in Boolean) is
begin
Undefine (V);
V := (Kind => Boolean_Value, The_Boolean => B);
exception
when Constraint_Error =>
raise Error_Boolean_Value;
end Set;
procedure Copy (To_Value : in out T_Value.Object;
The_Value : in T_Value.Object) is
begin
if (The_Value.Kind = String_Value) then
Set (To_Value, The_Value.The_String.all);
else
Undefine (To_Value);
To_Value := The_Value;
end if;
end Copy;
procedure Set_Value_Using_File (V : in out Object; F : V_File) is
begin
-- Text_IO.Get(F,Value_Image(V));
Text_Io.Put_Line ("Function not yet implemented");
end Set_Value_Using_File;
end T_Value;
with T_Value, Text_Io, Bounded_String,binary_trees_pkg;
package Dynamic_Object is
Error_Attribute_Store : exception;
Error_Attribute_Index : exception;
type Dynamic_Object is private;
type Attribute_Index is private;
subtype D_File is Text_Io.File_Type;
Max_Attribute_String : constant := 32;
--Creation
procedure New_Object (D : in out Dynamic_Object);
--Access
function Has_Attribute
(D : in Dynamic_Object; Name : in String) return Boolean;
procedure Get_Attribute_By_Name
(D : Dynamic_Object; Name : String; V : in out T_Value.Object);
procedure Dump_Number_Of_Attribute(D : in Dynamic_Object);
procedure Dump_Object_Attributes (D : in Dynamic_Object);
function Object_Image (D : in Dynamic_Object) return String;
procedure Object_To_File (D : Dynamic_Object; F : D_File);
function Equal (Left,Right:Dynamic_Object) return Boolean;
--Modification
procedure Store_Attribute
(D : in out Dynamic_Object; Name : String; V : T_Value.Object);
procedure Store_Attribute
(D : in out Dynamic_Object; Name : String; I : Integer);
procedure Store_Attribute
(D : in out Dynamic_Object; Name : String; S : String);
procedure Store_Attribute
(D : in out Dynamic_Object; Name : String; B : Boolean);
procedure Delete_Attribute (D : in out Dynamic_Object; Name : String);
procedure Object_From_File (D : in out Dynamic_Object; F : D_File);
procedure Copy_Object (To_Object : in out Dynamic_Object;
The_Object : Dynamic_Object);
procedure Surface_Copy(To_Object : in out Dynamic_Object;
The_Object : Dynamic_Object);
--Liberation
procedure Dispose_Object (D : in out Dynamic_Object);
--Iteration
procedure Open_Attribute_Indexation
(D : Dynamic_Object; I : in out Attribute_Index);
procedure Next_Attribute_Index (I : in out Attribute_Index);
function Get_Indexed_Attribute_Name (I : Attribute_Index) return String;
procedure Get_Indexed_Attribute_Value
(I : Attribute_Index; V : in out T_Value.Object);
function No_More_Attributes (I : Attribute_Index) return Boolean;
private
type Attribute is
record
Name : Bounded_String.Variable_String (Max_Attribute_String);
Value : T_Value.Object;
end record;
function Compare (A, B : Attribute) return integer;
package Object_Tree is new binary_Trees_pkg(Attribute,Compare);
type Dynamic_Object is
record
Node : Object_Tree.Tree;
end record;
type Attribute_Index is
record
Node : Object_Tree.Iterator;
end record;
end Dynamic_Object;
with T_Value,
Text_Io,
Bounded_String,
binary_trees_pkg;
package body Dynamic_Object is
Use Object_Tree;
INF :constant Integer := -1;
EQU :constant Integer := 0;
SUP :constant Integer := 1;
Current_Attribute :Attribute;
LookAhead :Boolean;
function Create_Attribute(N: String;V : T_Value.Object) return Attribute is
A:Attribute;
begin
Bounded_string.free(A.Name);
Bounded_string.Copy(A.Name,N);
T_Value.New_Value (A.Value);
T_Value.Copy (A.Value,V);
return A;
end;
function Compare (A, B : Attribute) return integer is
begin
declare
Use Bounded_String;
begin
if image(A.name) < image(B.name) then
return INF;
elsif image(A.name) = image(B.name) then
return EQU;
else return SUP;
end if;
end;
end Compare;
procedure Dispose_Attribute (The_Attribute : in out Attribute) is
begin
T_Value.Dispose (The_Attribute.Value);
Bounded_String.Free(The_Attribute.Name);
end Dispose_Attribute;
procedure Destroy_Object is New Destroy_Deep(Free_Value =>Dispose_Attribute);
function Copy_Attribute ( A : Attribute ) return Attribute is
begin
return Create_Attribute(Bounded_String.Image(A.Name),A.Value);
end Copy_Attribute;
function Copy_Object_Tree is new Copy_Tree ( Copy_Value => Copy_Attribute ) ;
procedure Dump_An_Attribute ( A : Attribute ) is
begin
Text_Io.Put_Line ( Bounded_String.image(A.Name) &" : "& T_Value.Image (A.Value));
end Dump_An_Attribute ;
procedure Dump is new Visit ( Process => Dump_An_Attribute ) ;
--Creation
procedure New_Object (D : in out Dynamic_Object) is
begin
D.Node := Object_Tree.Create;
end New_Object;
--Access
procedure Dump_Number_Of_Attribute(D : in Dynamic_Object) is
begin
text_io.put_line("Number of Attribute:"&natural'image(Object_Tree.size(D.Node)));
end;
function Has_Attribute
(D : in Dynamic_Object; Name : in String) return Boolean is
A : Attribute;
begin
A:=Create_Attribute(Name,T_Value.NULL_VALUE);
return Object_Tree.Is_Found (A,D.node);
Dispose_Attribute(A);
end Has_Attribute;
procedure Get_Attribute_By_Name (D : Dynamic_Object;
Name : String;
V : in out T_Value.Object) is
Found : Boolean := False;
A : Attribute;
begin
A:=Create_Attribute(Name,V);
Object_Tree.Find(A,D.node,Found,A);
T_Value.New_Value (V);
T_Value.Copy (V,A.Value);
if not Found then T_Value.Undefine (V); end if;
Dispose_Attribute(A);
end Get_Attribute_By_Name;
function Equal (Left,Right:Dynamic_Object) return Boolean is
Index : Attribute_Index;
Val_R : T_Value.Object;
Val_L : T_Value.Object;
memo :boolean:=LookAhead; -- memorize to avoid modification on Lookahead
begin
if Object_Tree.size(Left.Node) /= Object_Tree.size(Right.Node)
then return False;
end if;
Open_Attribute_Indexation (Left , Index);
TEST_EQUAL:
while not No_More_Attributes(Index) loop
if Has_Attribute(Right,Get_Indexed_Attribute_Name (Index))
then
Get_Attribute_By_Name(Right,
Get_Indexed_Attribute_Name (Index),
Val_R);
Get_Indexed_Attribute_Value (Index,Val_L);
if not T_value.Equal (Val_L,Val_R)
then LookAhead:=Memo; return false; end if;
else LookAhead:=Memo; return false;
end if;
Next_Attribute_Index (Index);
end loop TEST_EQUAL;
LookAhead:=Memo;
return true;
end;
procedure Dump_Object_Attributes (D : in Dynamic_Object) is
begin
Dump ( D.Node,Object_Tree.preorder);
end Dump_Object_Attributes;
function Object_Image (D : in Dynamic_Object) return String is
begin
return ("Function not yet implemented");
end Object_Image;
procedure Object_To_File (D : Dynamic_Object; F : D_File) is
begin
Text_Io.Put_Line ("function not yet implemented");
end Object_To_File;
--Modification
procedure Store_Attribute (D : in out Dynamic_Object;
Name : String;
V : T_Value.Object) is
Found : Boolean := False;
A : Attribute;
begin
Object_Tree.Replace_If_Found (Create_Attribute(Name,V),D.Node,Found,A);
if Found then Dispose_Attribute(A);end if;
exception
when others =>
raise Error_Attribute_Store;
end Store_Attribute;
procedure Store_Attribute
(D : in out Dynamic_Object; Name : String; I : Integer) is
V : T_Value.Object;
begin
T_Value.New_Value (V);
T_Value.Set (V, I);
Store_Attribute (D, Name, V);
T_Value.Dispose (V);
end Store_Attribute;
procedure Store_Attribute
(D : in out Dynamic_Object; Name : String; S : String) is
V : T_Value.Object;
begin
T_Value.New_Value (V);
T_Value.Set (V, S);
Store_Attribute (D, Name, V);
T_Value.Dispose (V);
end Store_Attribute;
procedure Store_Attribute
(D : in out Dynamic_Object; Name : String; B : Boolean) is
V : T_Value.Object;
begin
T_Value.New_Value (V);
T_Value.Set (V, B);
Store_Attribute (D, Name, V);
T_Value.Dispose (V);
end Store_Attribute;
procedure Delete_Attribute (D : in out Dynamic_Object; Name : String) is
begin
Text_Io.Put_Line ("function not yet implemented");
end Delete_Attribute;
procedure Object_From_File (D : in out Dynamic_Object; F : D_File) is
begin
Text_Io.Put_Line ("function not yet implemented");
end Object_From_File;
procedure Copy_Object (To_Object : in out Dynamic_Object;
The_Object : Dynamic_Object) is
begin
To_Object.Node:= Copy_Object_Tree(T=>The_Object.Node);
end Copy_Object;
procedure Surface_Copy (To_Object : in out Dynamic_Object;
The_Object : Dynamic_Object) is
begin
To_Object.Node:= The_Object.Node;
end;
--Liberation
procedure Dispose_Object (D : in out Dynamic_Object) is
begin
Destroy_Object(D.Node);
end Dispose_Object;
--Iteration
procedure Open_Attribute_Indexation
(D : Dynamic_Object; I : in out Attribute_Index) is
begin
I.Node := Object_Tree.Make_Iter(D.Node);
LookAhead:=FALSE;
Next_Attribute_Index(I);
end Open_Attribute_Indexation;
procedure Next_Attribute_Index (I : in out Attribute_Index) is
begin
if not Lookahead then
if Object_Tree.More (I.Node) then
Object_Tree.Next(I.Node,Current_Attribute);
else
raise Error_Attribute_Index;
end if;
end if;
end Next_Attribute_Index;
function Get_Indexed_Attribute_Name (I : Attribute_Index) return String is
begin
return Bounded_String.Image (Current_Attribute.Name);
exception
when others=> raise Error_Attribute_Index;
end Get_Indexed_Attribute_Name;
procedure Get_Indexed_Attribute_Value
(I : Attribute_Index; V : in out T_Value.Object) is
begin
T_Value.Copy (V, Current_Attribute.Value);
exception
when others=> raise Error_Attribute_Index;
raise Error_Attribute_Index;
end Get_Indexed_Attribute_Value;
function No_More_Attributes (I : Attribute_Index) return Boolean is
More:Boolean:=TRUE;
begin
More:= Object_Tree.More (I.Node);
if More then return (False); end if;
if (not More AND not LookAhead) then
Lookahead:=TRUE;
return(FALSE);
elsif (not More AND LookAhead) then
return(TRUE);
end if;
end No_More_Attributes;
end Dynamic_Object;
generic
type Value_Type is private; --| Type of values stored in the tree.
with function Difference(P, Q: Value_Type) return integer is <>;
--| Must return a value > 0 if P > Q, 0 if P = Q, and less than
--| zero otherwise.
package binary_trees_pkg is --| Efficient implementation of binary trees.
--| OVERVIEW
--| This package is an efficient implementation of unbalanced binary trees.
--| These trees have the following properties:
--|-
--| 1. Inserting a value is cheap (log n Differences per insertion).
--| 2. Finding a value is cheap (log n Differences per querey).
--| 3. Can iterate over the values in sorted order in linear time.
--| 4. Space overhead is moderate (2 "pointers" per value stored).
--|+
--| They are thus useful both for sorting sequences of indeterminate size
--| and for lookup tables.
--|
--| OPERATIONS
--|
--|-The following operations are provided:
--|
--| Insert Insert a node into a tree
--| Insert_if_not_Found Insert a node into a tree if not there already
--| Replace_if_Found Replace a node if duplicate exists, else insert.
--| Destroy Destroy a tree
--| Destroy_Deep* Destroy a tree and its contents
--| Balanced_Tree* Create a balanced tree from values supplied in order
--| Copy* Copy a tree. The copy is balanced.
--|
--| Queries:
--| Is_Empty Return TRUE iff a tree is empty.
--| Find Search tree for a node
--| Is_Found Return TRUE iff tree contains specified value.
--| Size Return number of nodes in the tree.
--|
--| Iterators:
--| Visit* Apply a procedure to every node in specified order
--| Make_Iter Create an iterator for ordered scan
--| More Test for exhausted iterator
--| Next Bump an iterator to the next element
--|
--| * Indicates generic subprogram
--|
--| USAGE
--|
--| The following example shows how to use this package where nodes in
--| the tree are labeled with a String_Type value (for which a natural
--| Difference function is not available).
--|-
--| package SP renames String_Pkg;
--|
--| type my_Value is record
--| label: SP.string_type;
--| value: integer;
--| end record;
--|
--| function differ_label(P, Q: SP.string_type) return integer is
--| begin
--| if SP."<"(P, Q) then return -1;
--| elsif SP."<"(Q, P) then return 1;
--| else return 0;
--| end if;
--| end differ_label;
--|
--| package my_Tree is new Binary_Trees_pkg(my_Value, differ_Label);
--|
--| Note that the required Difference function may be easily written in terms
--| of "<" if that is available, but that frequently two comparisons must
--| be done for each Difference. However, both comparisons would have
--| to be done internally by this package for every instantiation if the
--| generic parameter were "<" instead of Difference.
--|
--| PERFORMANCE
--|
--| Every node can be visited in the tree in linear time. The cost
--| of creating an iterator is small and independent of the size
--| of the tree.
--|
--| Recognizing that comparing values can be expensive, this package
--| takes a Difference function as a generic parameter. If it took
--| a comparison function such as "<", then two comparisons would be
--| made per node visited during a search of the tree. Of course this
--| is more costly when "<" is a trivial operation, but in those cases,
--| Difference can be bound to "-" and the overhead in negligable.
--|
--| Two different kinds of iterators are provided. The first is the
--| commonly used set of functions Make_Iter, More, and Next. The second
--| is a generic procedure called Visit. The generic parameter to Visit is
--| a procedure which is called once for each value in the tree. Visit
--| is more difficult to use and results in code that is not quite as clear,
--| but its overhead is about 20% of the More/Next style iterator. It
--| is therefore recommended for use only in time critical inner loops.
----------------------------------------------------------------------------
-- Exceptions --
----------------------------------------------------------------------------
Duplicate_Value: exception;
--| Raised on attempt to insert a duplicate node into a tree.
Not_Found: exception;
--| Raised on attempt to find a node that is not in a tree.
No_More: exception;
--| Raised on attempt to bump an iterator that has already scanned the
--| entire tree.
Out_Of_Order: exception;
--| Raised if a problem in the ordering of a tree is detected.
Invalid_Tree: exception;
--| Value is not a tree or was not properly initialized.
----------------------------------------------------------------------------
-- Types --
----------------------------------------------------------------------------
type Scan_Kind is (inorder, preorder, postorder);
--| Used to specify the order in which values should be scanned from a tree:
--|-
--| inorder: Left, Node, Right (nodes visited in increasing order)
--| preorder: Node, Left, Right (top down)
--| postorder: Left, Right, Node (bottom up)
type Tree is private;
type Iterator is private;
----------------------------------------------------------------------------
-- Operations --
----------------------------------------------------------------------------
Function Create --| Return an empty tree.
return Tree;
--| Effects: Create and return an empty tree. Note that this allocates
--| a small amount of storage which can only be reclaimed through
--| a call to Destroy.
----------------------------------------------------------------------------
Procedure Insert( --| Insert a value into a tree.
V: Value_Type; --| Value to be inserted
T: Tree --| Tree to contain the new value
);
--| Raises: Duplicate_Value, Invalid_Tree.
--| Effects: Insert V into T in the proper place. If a value equal
--| to V (according to the Difference function) is already contained
--| in the tree, the exception Duplicate_Value is raised.
--| Caution: Since this package does not attempt to balance trees as
--| values are inserted, it is important to remember that inserting
--| values in sorted order will create a degenerate tree, where search
--| and insertion is proportional to the N instead of to Log N. If
--| this pattern is common, use the Balanced_Tree function below.
----------------------------------------------------------------------------
procedure Insert_if_not_Found(
--| Insert a value into a tree, provided a duplicate value is not already there
V: Value_Type; --| Value to be inserted
T: Tree; --| Tree to contain the new value
Found: out boolean; --| Becomes True iff V already in tree
Duplicate: out Value_Type --| the duplicate value, if there is one
); --| Raises: Invalid_Tree.
--| Effects: Insert V into T in the proper place. If a value equal
--| to V (according to the Difference function) is already contained
--| in the tree, Found will be True and Duplicate will be the duplicate
--| value. This might be a sequence of values with the same key, and
--| V can then be added to the sequence.
----------------------------------------------------------------------------
procedure Replace_if_Found(
--| Replace a value if label exists, otherwise insert it.
V: Value_Type; --| Value to be inserted
T: Tree; --| Tree to contain the new value
Found: out boolean; --| Becomes True iff L already in tree
Old_Value: out Value_Type --| the duplicate value, if there is one
); --| Raises: Invalid_Tree.
--| Effects: Search for V in T. If found, replace the old value with V,
--| and return Found => True, Old_Value => the old value. Otherwise,
--| simply insert V into T and return Found => False.
----------------------------------------------------------------------------
procedure Destroy( --| Free space allocated to a tree.
T: in out Tree --| The tree to be reclaimed.
);
--| Effects: The space allocated to T is reclaimed. The space occupied by
--| the values stored in T is not however, recovered.
----------------------------------------------------------------------------
generic
with procedure free_Value(V: in out Value_Type) is <>;
procedure Destroy_Deep( --| Free all space allocated to a tree.
T: in out Tree --| The tree to be reclaimed.
);
--| Effects: The space allocated to T is reclaimed. The values stored
--| in T are reclaimed using Free_Value, and the tree nodes themselves
--| are then reclaimed (in a single walk of the tree).
----------------------------------------------------------------------------
generic
with function next_Value return Value_Type is <>;
--| Each call to this procedure should return the next value to be
--| inserted into the balanced tree being created. If necessary,
--| this function should check that each value is greater than the
--| previous one, and raise Out_of_Order if necessary. If values
--| are not returned in strictly increasing order, the results are
--| unpredictable.
Function Balanced_Tree(
Count: natural
) return Tree;
--| Effects: Create a balanced tree by calling next_Value Count times.
--| Each time Next_Value is called, it must return a value that compares
--| greater than the preceeding value. This function is useful for balancing
--| an existing tree (next_Value iterates over the unbalanced tree) or
--| for creating a balanced tree when reading data from a file which is
--| already sorted.
----------------------------------------------------------------------------
generic
with function Copy_Value(V: Value_Type) return Value_Type is <>;
--| This function is called to copy a value from the old tree to the
--| new tree.
Function Copy_Tree(
T: Tree
) return Tree; --| Raises Invalid_Tree.
--| Effects: Create a balanced tree that is a copy of the tree T.
--| The exception Invalid_Tree is raised if T is not a valid tree.
----------------------------------------------------------------------------
Function Is_Empty( --| Check for an empty tree.
T: Tree
) return boolean;
--| Effects: Return TRUE iff T is an empty tree or if T was not initialized.
----------------------------------------------------------------------------
Function Find( --| Search a tree for a value.
V: Value_Type; --| Value to be located
T: Tree --| Tree to be searched
) return Value_Type; --| Raises: Not_Found, Invalid_Tree.
--| Effects: Search T for a value that matches V. The matching value is
--| returned. If no matching value is found, the exception Not_Found
--| is raised.
Procedure Find( --| Search a tree for a value.
V: Value_Type; --| Value to be located
T: Tree; --| Tree to be searched
Found: out Boolean; --| TRUE iff a match was found
Match: out Value_Type --| Matching value found in the tree
); --| Raises: Invalid_Tree;
--| Effects: Search T for a value that matches V. On return, if Found is
--| TRUE then the matching value is returned in Match. Otherwise, Found
--| is FALSE and Match is undefined.
----------------------------------------------------------------------------
function is_Found( --| Check a tree for a value.
V: Value_Type; --| Value to be located
T: Tree --| Tree to be searched
) return Boolean; --| Raises: Invalid_Tree;
--| Effects: Return TRUE iff V is found in T.
----------------------------------------------------------------------------
function Size( --| Return the count of values in T.
T: Tree --| a tree
) return natural;
--| Effects: Return the number of values stored in T.
----------------------------------------------------------------------------
generic
with procedure Process(V: Value_Type) is <>;
procedure Visit(
T: Tree;
Order: Scan_Kind
); --| Raises: Invalid_Tree;
--| Effects: Invoke Process(V) for each value V in T. The nodes are visited
--| in the order specified by Order. Although more limited than using
--| an iterator, this function is also much faster.
----------------------------------------------------------------------------
function Make_Iter( --| Create an iterator over a tree
T: Tree
) return Iterator; --| Raises: Invalid_Tree;
----------------------------------------------------------------------------
function More( --| Test for exhausted iterator
I: Iterator --| The iterator to be tested
) return boolean;
--| Effects: Return TRUE iff unscanned nodes remain in the tree being
--| scanned by I.
----------------------------------------------------------------------------
procedure Next( --| Scan the next value in I
I: in out Iterator; --| an active iterator
V: out Value_Type --| Next value scanned
); --| Raises: No_More.
--| Effects: Return the next value in the tree being scanned by I.
--| The exception No_More is raised if there are no more values to scan.
----------------------------------------------------------------------------
private
type Node;
type Node_Ptr is access Node;
type Node is
record
Value: Value_Type;
Less: Node_Ptr;
More: Node_Ptr;
end record;
type Tree_Header is
record
Count: natural := 0;
Root: Node_Ptr := Null;
end record;
type Tree is access Tree_Header;
type Iter_State is (Left, Middle, Right, Done);
type Iterator_Record;
type Iterator is access Iterator_Record;
type Iterator_Record is
record
State: Iter_State;
Parent: Iterator;
subtree: Node_Ptr;
end record;
end binary_trees_pkg;
with unchecked_deallocation;
Package body Binary_Trees_Pkg is
--| Efficient implementation of binary trees.
----------------------------------------------------------------------------
-- Local Operations --
----------------------------------------------------------------------------
procedure Free_Node is
new unchecked_deallocation(Node, Node_Ptr);
procedure Free_Tree is
new unchecked_deallocation(Tree_Header, Tree);
procedure Free_Iterator is
new unchecked_deallocation(Iterator_Record, Iterator);
----------------------------------------------------------------------------
-- Visible Operations --
----------------------------------------------------------------------------
Function Create --| Return an empty tree.
return Tree is
begin
return new Tree_Header'(0, Null);
end Create;
----------------------------------------------------------------------------
Procedure Insert_Node(
V: Value_Type;
N: in out Node_Ptr;
Found: out boolean;
Duplicate: out Value_Type
)
is
D: integer;
begin
Found := False;
if N = null then
N := new Node'(V, Null, Null);
else
D := Difference(V, N.Value);
if D < 0 then
Insert_Node(V, N.Less, Found, Duplicate);
elsif D > 0 then
Insert_Node(V, N.More, Found, Duplicate);
else
Found := True;
Duplicate := N.Value;
end if;
end if;
end Insert_Node;
Procedure Replace_Node(
V: Value_Type;
N: in out Node_Ptr;
Found: out boolean;
Duplicate: out Value_Type
)
is
D: integer;
begin
Found := False;
if N = null then
N := new Node'(V, Null, Null);
else
D := Difference(V, N.Value);
if D < 0 then
Replace_Node(V, N.Less, Found, Duplicate);
elsif D > 0 then
Replace_Node(V, N.More, Found, Duplicate);
else
Found := True;
Duplicate := N.Value;
N.Value := V;
end if;
end if;
end Replace_Node;
Procedure Insert( --| Insert a value into a tree.
V: Value_Type; --| Value to be inserted
T: Tree --| Tree to contain the new value
) --| Raises: Duplicate_Value, Invalid_Tree.
is
Found: boolean;
Duplicate: Value_Type;
begin
if T = null then
raise Invalid_Tree;
end if;
Insert_Node(V, T.Root, Found, Duplicate);
if Found then
raise Duplicate_Value;
end if;
T.Count := T.Count + 1;
end Insert;
Procedure Insert_if_not_Found(
--| Insert a value into a tree, provided a duplicate value is not already there
V: Value_Type; --| Value to be inserted
T: Tree; --| Tree to contain the new value
Found: out boolean;
Duplicate: out Value_Type
) --| Raises: Invalid_Tree.
is
was_Found: boolean;
begin
if T = null then
raise Invalid_Tree;
end if;
Insert_Node(V, T.Root, was_Found, Duplicate);
Found := was_Found;
if not was_Found then
T.Count := T.Count + 1;
end if;
end Insert_if_Not_Found;
procedure Replace_if_Found(
--| Replace a value if label exists, otherwise insert it.
V: Value_Type; --| Value to be inserted
T: Tree; --| Tree to contain the new value
Found: out boolean; --| Becomes True iff L already in tree
Old_Value: out Value_Type --| the duplicate value, if there is one
) --| Raises: Invalid_Tree.
is
was_Found: boolean;
Duplicate: Value_Type;
begin
if T = null then
raise Invalid_Tree;
end if;
Replace_Node(V, T.Root, was_Found, Duplicate);
Found := was_Found;
if was_Found then
Old_Value := Duplicate;
else
T.Count := T.Count + 1;
end if;
end Replace_if_Found;
----------------------------------------------------------------------------
procedure Destroy_Nodes(
N: in out Node_Ptr
) is
begin
if N /= null then
Destroy_Nodes(N.Less);
Destroy_Nodes(N.More);
Free_Node(N);
end if;
end Destroy_Nodes;
procedure Destroy( --| Free space allocated to a tree.
T: in out Tree --| The tree to be reclaimed.
) is
begin
if T /= Null then
Destroy_Nodes(T.Root);
Free_Tree(T);
end if;
end Destroy;
----------------------------------------------------------------------------
procedure Destroy_Deep( --| Free all space allocated to a tree.
T: in out Tree --| The tree to be reclaimed.
)
is
procedure Destroy_Nodes(
N: in out node_Ptr
) is
begin
if N /= null then
Free_Value(N.Value);
Destroy_Nodes(N.Less);
Destroy_Nodes(N.More);
Free_Node(N);
end if;
end Destroy_Nodes;
begin
if T /= Null then
Destroy_Nodes(T.Root);
Free_Tree(T);
end if;
end Destroy_Deep;
----------------------------------------------------------------------------
Function Balanced_Tree(
Count: natural
) return Tree
is
new_Tree: Tree := Create;
procedure subtree(Count: natural; N: in out Node_Ptr)
is
new_Node: Node_Ptr;
begin
if Count = 1 then
new_Node := new Node'(next_Value, Null, Null);
elsif Count > 1 then
new_node := new Node;
subtree(Count/2, new_Node.Less); -- Half are less
new_Node.Value := next_Value; -- Median value
subtree(Count - Count/2 - 1, new_Node.More); -- Other half are more
end if;
N := new_Node;
end subtree;
begin
new_Tree.Count := Count;
subtree(Count, new_Tree.Root);
return new_Tree;
end Balanced_Tree;
----------------------------------------------------------------------------
Function Copy_Tree(
T: Tree
) return Tree
is
I: Iterator;
function next_Val return Value_type
is
V: Value_Type;
begin
Next(I, V);
return copy_Value(V);
end next_Val;
function copy_Balanced is new Balanced_Tree(next_Val);
begin
I := Make_Iter(T); -- Will raise Invalid_Tree if necessary
return copy_Balanced(Size(T));
end Copy_Tree;
----------------------------------------------------------------------------
Function Is_Empty( --| Check for an empty tree.
T: Tree
) return boolean is
begin
return T = Null or else T.Root = Null;
end Is_Empty;
----------------------------------------------------------------------------
procedure Find_Node(
V: Value_Type; --| Value to be located
N: Node_Ptr; --| subtree to be searched
Match: out Value_Type; --| Matching value found in the tree
Found: out Boolean --| TRUE iff a match was found
)
is
D: integer;
begin
if N = null then
Found := False;
return;
end if;
D := Difference(V, N.Value);
if D < 0 then
Find_Node(V, N.Less, Match, Found);
elsif D > 0 then
Find_Node(V, N.More, Match, Found);
else
Match := N.Value;
Found := TRUE;
end if;
end Find_Node;
Function Find( --| Search a tree for a value.
V: Value_Type; --| Value to be located
T: Tree --| Tree to be searched
) return Value_Type --| Raises: Not_Found.
is
Found: Boolean;
Match: Value_Type;
begin
if T = Null then
raise Invalid_Tree;
end if;
Find_Node(V, T.Root, Match, Found);
if Found then
return Match;
else
raise Not_Found;
end if;
end Find;
Procedure Find( --| Search a tree for a value.
V: Value_Type; --| Value to be located
T: Tree; --| Tree to be searched
Found: out Boolean; --| TRUE iff a match was found
Match: out Value_Type --| Matching value found in the tree
) is
begin
if T = Null then
raise Invalid_Tree;
end if;
Find_Node(V, T.Root, Match, Found);
end Find;
----------------------------------------------------------------------------
function is_Found( --| Check a tree for a value.
V: Value_Type; --| Value to be located
T: Tree --| Tree to be searched
) return Boolean
is
Found: Boolean;
Match: Value_Type;
begin
if T = Null then
raise Invalid_Tree;
end if;
Find_Node(V, T.Root, Match, Found);
return Found;
end is_Found;
----------------------------------------------------------------------------
function Size( --| Return the count of values in T.
T: Tree --| a tree
) return natural is
begin
if T = Null then
Return 0;
else
Return T.Count;
end if;
end Size;
----------------------------------------------------------------------------
procedure Visit(
T: Tree;
Order: Scan_Kind
) is
procedure visit_Inorder(N: Node_Ptr) is
begin
if N.Less /= null then
visit_Inorder(N.Less);
end if;
Process(N.Value);
if N.More /= null then
visit_Inorder(N.More);
end if;
end visit_Inorder;
procedure visit_preorder(N: Node_Ptr) is
begin
Process(N.Value);
if N.Less /= null then
visit_preorder(N.Less);
end if;
if N.More /= null then
visit_preorder(N.More);
end if;
end visit_preorder;
procedure visit_postorder(N: Node_Ptr) is
begin
if N.Less /= null then
visit_postorder(N.Less);
end if;
if N.More /= null then
visit_postorder(N.More);
end if;
Process(N.Value);
end visit_postorder;
begin
if T = Null then
raise Invalid_Tree;
else
case Order is
when inorder =>
Visit_Inorder(T.Root);
when preorder =>
Visit_preorder(T.Root);
when postorder =>
Visit_postorder(T.Root);
end case;
end if;
end Visit;
----------------------------------------------------------------------------
function subtree_Iter( --| Create an iterator over a subtree
N: Node_Ptr;
P: Iterator
) return Iterator is
begin
if N = Null then
return new Iterator_Record'(State => Done, Parent => P, subtree => N);
elsif N.Less = Null then
return new Iterator_Record'(State => Middle, Parent => P, subtree => N);
else
return new Iterator_Record'(State => Left, Parent => P, subtree => N);
end if;
end subtree_Iter;
function Make_Iter( --| Create an iterator over a tree
T: Tree
) return Iterator is
begin
if T = Null then
raise Invalid_Tree;
end if;
return subtree_Iter(T.Root, Null);
end Make_Iter;
----------------------------------------------------------------------------
function More( --| Test for exhausted iterator
I: Iterator --| The iterator to be tested
) return boolean is
begin
if I = Null then
return False;
elsif I.Parent = Null then
return I.State /= Done and I.subtree /= Null;
elsif I.State = Done then
return More(I.Parent);
else
return True;
end if;
end More;
----------------------------------------------------------------------------
procedure pop_Iterator(
I: in out Iterator
)
is
NI: Iterator;
begin
loop
NI := I;
I := I.Parent;
Free_Iterator(NI);
exit when I = Null;
exit when I.State /= Done;
end loop;
end pop_Iterator;
procedure Next( --| Scan the next value in I
I: in out Iterator; --| an active iterator
V: out Value_Type --| Next value scanned
) --| Raises: No_More.
is
NI: Iterator;
begin
if I = Null or I.State = Done then
raise No_More;
end if;
case I.State is
when Left => -- Return the leftmost value
while I.subtree.Less /= Null loop -- Find leftmost subtree
I.State := Middle; -- Middle is next at this level
I := subtree_Iter(I.subtree.Less, I);
end loop;
V := I.subtree.Value;
if I.subtree.More /= Null then -- There will be more...
I.State := Right; -- ... coming from the right
else -- Nothing else here
pop_Iterator(I); -- Pop up to parent iterator
end if;
when Middle =>
V := I.subtree.Value;
if I.subtree.More /= Null then -- There will be more...
I.State := Right; -- ... coming from the right
else -- Nothing else here so...
pop_Iterator(I); -- ... Pop up to parent iterator
end if;
when Right => -- Return the value on the right
I.State := Done; -- No more at this level
I := subtree_Iter(I.subtree.More, I);
Next(I, V);
when Done =>
pop_Iterator(I);
Next(I, V);
end case;
end Next;
----------------------------------------------------------------------------
end binary_trees_pkg;
with Dynamic_Object,Text_Io, Bounded_String,binary_trees_pkg;
package Symbols is
Error_Symbol_Store : exception;
Error_Symbol_Index : exception;
Error_Symbol_Search: exception;
type Object is limited private;
type Symbol_Index is limited private;
Max_Symbol_String : constant := 32;
--Creation
procedure Create (D : in out Object);
--Access
function Has_Symbol
(D : in Object; Name : in String) return Boolean;
function Get_Symbol_Type_By_Name(D : Object; Name : String)return String;
Procedure Get_Symbol_Value_By_Name(D : Object; Name : String;F:in out Dynamic_Object.Dynamic_Object);
procedure Dump_Symbols (D : in Object);
procedure Dump_Number_Of_Symbol(D : in Object);
--Modification
procedure Store_Symbol
(D : in out Object; aName : String;aType :String;F :Dynamic_Object.Dynamic_Object);
--Liberation
procedure Dispose_Object (D : in out Object);
--Iteration
procedure Open_Symbol_Indexation
(D : Object; I : in out Symbol_Index);
procedure Next_Symbol_Index (I : in out Symbol_Index);
function Get_Indexed_Symbol_Name (I : Symbol_Index) return String;
function Get_Indexed_Symbol_Type (I : Symbol_Index) return String;
procedure Get_Indexed_Symbol_Value(I : Symbol_Index;F:in out Dynamic_Object.Dynamic_Object);
function No_More_Symbols (I : Symbol_Index) return Boolean;
private
type Symbol is
record
Symbol_Name : Bounded_String.Variable_String (Max_Symbol_String);
Symbol_Type : Bounded_String.Variable_String (Max_Symbol_String);
Symbol_Value : Dynamic_Object.Dynamic_Object;
end record;
function Compare (A, B : Symbol) return integer;
package Symbols_Tree is new binary_Trees_pkg(Symbol,Compare);
type Object is
record
Node : Symbols_Tree.Tree;
end record;
type Symbol_Index is
record
Node : Symbols_Tree.Iterator;
end record;
end Symbols;
with Dynamic_Object, Text_Io, Bounded_String,binary_trees_pkg;
package body Symbols is
Use Symbols_Tree;
INF :constant Integer := -1;
EQU :constant Integer := 0;
SUP :constant Integer := 1;
Current_Symbol :Symbol;
LookAhead :Boolean;
function Create_Symbol(N: String;T: String; F : Dynamic_Object.Dynamic_Object) return Symbol is
A:Symbol;
begin
Bounded_string.free(A.Symbol_Name);
Bounded_string.Copy(A.Symbol_Name,N);
Bounded_string.free(A.Symbol_Type);
Bounded_string.Copy(A.Symbol_Type,T);
Dynamic_Object.Surface_copy(A.Symbol_Value,F);
return A;
end;
function Compare (A, B : Symbol) return integer is
begin
declare
Use Bounded_String;
begin
if image(A.Symbol_name) < image(B.Symbol_name) then
return INF;
elsif image(A.Symbol_name) = image(B.Symbol_name) then
return EQU;
else return SUP;
end if;
end;
end Compare;
procedure Dispose_Symbol (The_Symbol : in out Symbol) is
begin
Dynamic_Object.Dispose_Object(The_Symbol.Symbol_Value);
Bounded_String.Free(The_Symbol.Symbol_Name);
Bounded_String.Free(The_Symbol.Symbol_Type);
end Dispose_Symbol;
procedure Destroy_Object is New Destroy_Deep(Free_Value =>Dispose_Symbol);
procedure Dump_An_Symbol ( A : Symbol ) is
begin
Text_IO.Put_Line("........................................");
Text_Io.Put_Line ( Bounded_String.image(A.Symbol_Name) &" "&
Bounded_String.image(A.Symbol_Type) &"With Object:");
Dynamic_Object.Dump_Object_Attributes(A.Symbol_Value);
end Dump_An_Symbol ;
procedure Dump is new Visit ( Process => Dump_An_Symbol ) ;
--Creation
procedure Create (D : in out Object) is
begin
D.Node := Symbols_Tree.Create;
end ;
--Access
procedure Dump_Number_Of_Symbol(D : in Object) is
begin
text_io.put_line("Number of Symbol:"&natural'image(Symbols_tree.size(D.Node)));
end;
function Has_Symbol
(D : in Object; Name : in String) return Boolean is
A : Symbol;
F : Dynamic_Object.Dynamic_Object;
begin
Dynamic_Object.New_Object(F);
A:=Create_Symbol(Name,Name,F); -- Only the first param. is important
return Symbols_tree.Is_Found (A,D.node);
end Has_Symbol;
function Get_Symbol_Type_By_Name(D : Object; Name : String)return String is
Found : Boolean := False;
A : Symbol;
B :Dynamic_Object.Dynamic_Object;
begin
Dynamic_Object.New_Object(B);
A:=Create_Symbol(Name,Name,B); -- Only the first param. is important
Symbols_tree.Find(A,D.node,Found,A);
if found then
return Bounded_String.Image(A.Symbol_Type);
else return "";
end if;
exception
when others =>
raise Error_Symbol_Search;
end;
Procedure Get_Symbol_Value_By_Name(D : Object; Name : String;F:in out Dynamic_Object.Dynamic_Object) is
Found : Boolean := False;
A : Symbol;
B :Dynamic_Object.Dynamic_Object;
begin
Dynamic_Object.New_Object(B);
A:=Create_Symbol(Name,Name,B); -- Only the first param. is important
Symbols_tree.Find(A,D.node,Found,A);
if found then
Dynamic_Object.Copy_Object(F,A.Symbol_Value);
end if;
exception
when others =>
raise Error_Symbol_Search;
end;
procedure Dump_Symbols (D : in Object) is
begin
Dump ( D.Node,Symbols_tree.inorder);
end Dump_Symbols;
--Modification
procedure Store_Symbol
(D : in out Object; aName : String;aType :String;F :Dynamic_Object.Dynamic_Object)is
Found : Boolean := False;
A : Symbol;
B :Dynamic_Object.Dynamic_Object;
begin
Dynamic_Object.New_Object(B);
Dynamic_Object.Copy_Object(B,F);
Symbols_tree.Replace_If_Found (Create_Symbol(aName,aType,B),D.Node,Found,A);
if Found then Dispose_Symbol(A); end if;
exception
when others =>
raise Error_Symbol_Store;
end Store_Symbol;
--Liberation
procedure Dispose_Object (D : in out Object) is
begin
Destroy_Object(D.Node);
end Dispose_Object;
--Iteration
procedure Open_Symbol_Indexation
(D : Object; I : in out Symbol_Index) is
begin
I.Node := Symbols_tree.Make_Iter(D.Node);
LookAhead:=FALSE;
Next_Symbol_Index(I);
end Open_Symbol_Indexation;
procedure Next_Symbol_Index (I : in out Symbol_Index) is
begin
if not Lookahead then
if Symbols_tree.More (I.Node) then
Symbols_tree.Next(I.Node,Current_Symbol);
else
raise Error_Symbol_Index;
end if;
end if;
end Next_Symbol_Index;
function Get_Indexed_Symbol_Name (I : Symbol_Index) return String is
begin
return Bounded_String.Image (Current_Symbol.Symbol_Name);
exception
when others=> raise Error_Symbol_Index;
end Get_Indexed_Symbol_Name;
function Get_Indexed_Symbol_Type (I : Symbol_Index) return String is
begin
return Bounded_String.Image (Current_Symbol.Symbol_Type);
exception
when others=> raise Error_Symbol_Index;
end Get_Indexed_Symbol_Type;
procedure Get_Indexed_Symbol_Value(I : Symbol_Index;F:in out Dynamic_Object.Dynamic_Object) is
begin
Dynamic_Object.Copy_Object (F, Current_Symbol.Symbol_Value);
exception
when others=> raise Error_Symbol_Index;
raise Error_Symbol_Index;
end Get_Indexed_Symbol_Value;
function No_More_Symbols (I : Symbol_Index) return Boolean is
More:Boolean:=TRUE;
begin
More:= Symbols_tree.More (I.Node);
if More then return (False); end if;
if (not More AND not LookAhead) then
Lookahead:=TRUE;
return(FALSE);
elsif (not More AND LookAhead) then
return(TRUE);
end if;
end No_More_Symbols;
end Symbols;
with Symbols,dynamic_object,text_io;
procedure main is
D1,D2,D3 : dynamic_object.Dynamic_object;
S : Symbols.object;
procedure Print_With_Index(D :Symbols.Object) is
Index : Symbols.Symbol_Index;
Val : dynamic_object.Dynamic_object;
begin
Symbols.Open_Symbol_Indexation (D , Index);
while not Symbols.No_More_Symbols(Index) loop
Text_IO.Put_Line("****************************************");
Text_Io.Put_Line (Symbols.Get_Indexed_Symbol_Name (Index) &
" : " & Symbols.Get_Indexed_Symbol_Type(Index)&"-> WITH:");
dynamic_object.New_Object(val);
Symbols.Get_Indexed_Symbol_Value(Index,val);
dynamic_object.Dump_Object_Attributes(val);
dynamic_object.Dispose_Object(val);
Symbols.Next_Symbol_Index (Index);
end loop;
end Print_With_Index;
begin
dynamic_object.New_Object(D1);
dynamic_object.New_Object(D2);
dynamic_object.New_Object(D3);
Symbols.Create(S);
dynamic_object.Store_Attribute(D1,name=>"Nom ",S=>"Asterix");
dynamic_object.Store_Attribute(D1,name=>"Age ",I=>45);
dynamic_object.Store_Attribute(D1,name=>"Est un ",S=>"Gaulois");
dynamic_object.Store_Attribute(D1,name=>"Moustachu",B=>TRUE);
dynamic_object.Store_Attribute(D1,name=>"Poids ",I=>58);
text_io.put_line("....................................");
dynamic_object.Dump_Number_Of_Attribute(D=>D1);
dynamic_object.Dump_Object_Attributes(D1);
dynamic_object.Store_Attribute(D2,name=>"Nom ",S=>"Obelix ");
dynamic_object.Store_Attribute(D2,name=>"Force ",I=>99);
text_io.put_line("....................................");
dynamic_object.Dump_Number_Of_Attribute(D=>D2);
dynamic_object.Dump_Object_Attributes(D2);
dynamic_object.Store_Attribute(D3,name=>"Nom ",S=>"Idefix ");
dynamic_object.Store_Attribute(D3,name=>"Est un ",S=>"Chien ");
dynamic_object.Store_Attribute(D3,name=>"Chien ",B=>TRUE);
dynamic_object.Store_Attribute(D3,name=>"Couleur ",I=>1);
text_io.put_line("....................................");
dynamic_object.Dump_Number_Of_Attribute(D=>D3);
dynamic_object.Dump_Object_Attributes(D3);
Symbols.Store_Symbol(S,"ASTERIX ","GAULOIS ",D1);
Symbols.Store_Symbol(S,"OBELIX ","GAULOIS ",D2);
Symbols.Store_Symbol(S,"IDEFIX ","ANIMAL ",D3);
Text_IO.Put_Line("----------------------------------------");
Text_IO.Put_Line("--- Print Table des Symbols ----------");
Symbols.Dump_Symbols(S);
Symbols.Dump_Number_Of_Symbol(S);
text_io.put_line("....................................");
Text_Io.Put_Line ( "Print Using an Iterator -> ");
Print_With_Index(S);
text_io.put_line("....................................");
Text_Io.Put_Line ( "Destroy Dynamic Object");
dynamic_object.Dispose_Object(D1);
dynamic_object.Dispose_Object(D2);
dynamic_object.Dispose_Object(D3);
dynamic_object.Dump_Number_Of_Attribute(D1);
dynamic_object.Dump_Number_Of_Attribute(D2);
dynamic_object.Dump_Number_Of_Attribute(D3);
Symbols.Dispose_Object(S);
Symbols.Dump_Number_Of_Symbol(S);
end main