Google Answers Logo
View Question
 
Q: Ada program using generic package ( Answered 5 out of 5 stars,   0 Comments )
Question  
Subject: Ada program using generic package
Category: Computers > Programming
Asked by: loeric18-ga
List Price: $100.00
Posted: 19 Dec 2002 14:11 PST
Expires: 18 Jan 2003 14:11 PST
Question ID: 127046
I am working on a project to write a Ada program using a generic
package to solve a problem. More detail information please check the
following website
http://www.cs.fit.edu/~ryan/cse4250/ns.html 

I have 3 files now. One is main.adb , one is list.adb , the other one
is list.abs. The problem I have now is that I can not compile it.
Please help me to make it run by tomorrow noon. Also please put the
comment that I can understand whole the program. Thanks!!

Here are my files:
http://www.geocities.com/loeric18/list.adb.txt
http://www.geocities.com/loeric18/list.ads.txt
http://www.geocities.com/loeric18/main.adb.txt

Clarification of Question by loeric18-ga on 19 Dec 2002 16:52 PST
You don't need to make the project perfect, but at least can be
compiled without any error, that's my only requirement. please give it
a try!

Clarification of Question by loeric18-ga on 19 Dec 2002 18:28 PST
If it is harder to modify the program, it is fine to write a new one.

Request for Question Clarification by maniac-ga on 20 Dec 2002 07:17 PST
Hello loeric18,

I worked on this a while and can make it compile error free, but it
won't quite work in its current form (by noon). I have a few
alternatives for you to consider:
 1 - use an existing linked list package and add what you need to it.
A pretty complete generic list package w/ test program is at
  http://www.cs.fiu.edu/~weiss/ada.html
If you want to use this I can suggest a few changes that can help you.
 2 - Answer with what I have (it does compile error free and I can
suggest further fixes).
 3 - I can continue to work on your code (but won't make the noon
deadline).

Please advise me how you would like to proceed.
  --Maniac

Clarification of Question by loeric18-ga on 20 Dec 2002 07:32 PST
Thank you for your help..
I would like to choose the third way, but first please give me what
you have done now (with detail comment), because I can discuss with my
group with that code,and You can keep working on it, how do you think
about?
Answer  
Subject: Re: Ada program using generic package
Answered By: maniac-ga on 20 Dec 2002 09:10 PST
Rated:5 out of 5 stars
 
Hello loeric18,

I will first summarize what I found and then list the current version
of the source code at the end of this answer.As requested in your
first clarification, the code right now compiles error and warning
free with
  gnatmake -gnaty main
If you have additional parameters for the command line, let me know
those as well. Based on your feedback to this answer, I can make some
more changes and make this answer complete in a clarification. Please
don't rate the answer until you are satisifed with the clarification.

General fixes:
 - the instructions indicated to use -gnaty for style. The code below
compiles w/o error or warning using -gnaty. Lots of little spacing and
spelling fixes as a result. [all files]
 - added begin and/or null; statements in a couple places to fix
compilation errors. [both bodies]
 - started to add comments - expect to need more before we are done.
Note -gnaty requires "--  " as the prefix for each comment.

List package changes:
 - removed with/use to Ada.Strings.Unbounded; with the other changes,
this package should not be referred to directly. Use Element_Type
instead.
 - removed the array and index types (and variables using them). The
instructions said to use a "linked list" and the access to Node type
(Node_Access) takes the place of such an index. This also eliminates a
parameter to the generic package. Affects several function / procedure
declarations as well as types of data.
 - swapped the order of Next and Info in the declaration. This is was
not necessary but makes it easier to review / debug the code. The
generated code is often more efficient as well this way because the
link is always first with the (arbitrary length) data following.
 - use "null" instead of our_null for the comparisons for an empty
list (or end of list).
 - added Draw_Graph to the specification
 - removed the declaration of Node from the body; this conflicted with
the data type in the specification. Removed most references to Node in
the code; they also caused compile errors.
 - made the code easier to read and print by adding line breaks -
mostly in procedure declarations
 - Initialized Free to null. Assuming the global variable is
initialized is not recommended.
 - If the free list (Free) is null, use "new" to create a new node
instead of raising Program_Error.
 - I added FIXME to a few places where code must still be fixed. See
next section for questions / suggestions
 - There are several places where to code does not check for null. I
did't fix them all but will do so in the next version. Especially
affects both Empty and Count.
 - Insert needs more review once Find is fixed; I didn't work it out
by hand yet. Note the notation used to pass the parameter to New_Node.
 - Retrieve needs more review once Find is fixed. I suggest setting
Element to null if the item is not found.
 - Neither Count nor Empty assume the data at "List" is part of the
list. Since Node_Acc is an access to Node (or pointer), you can refer
to Node_Acc.Info. Suggest a slight revision to consider "Node_Acc" as
part of the list. Let me know if you want that change, it is an easy
fix.
 - Remove deletes a node (puts it on the free list). It does not
remove it from a list and any subsequent nodes are on the free list as
well. Is that what you want or do you need both "Remove" and "Delete"?
 - A thought, the nodes in the lower level list should be "Removed" as
well. Hmm. The example I referred to at
  http://www.cs.fiu.edu/~weiss/ada.html
uses a finalization routine to "make it so". Do you want the same here
or can you require the main program to clean up the lower level list
before removing the upper level list? Since you may not understand
finalization - I won't add it unless you ask.

FIXME code:
 - Find does not appear to have the right parameters nor does it do a
comparison to "find" the value you are looking for. Suggested changes
include:
  o Add a value parameter to the call. Something like
     Value : in Element_Type;
  o Add a comparison in the loop. Something like
     if (Element_Type."="(Value, Current.Info))
    would work, but requires you to define an "=" function in List.
I think I know what you want here, but I wanted some feedback before
coding it up.
 - Draw_Graph can be quite simple, but may require an additional
function added to the generic declaration. Something like
"Draw_Me(Value: in Element_Type)" that either returns a string or
prints a string using Text_IO. The recursive nature of this makes it a
little tricky to get the output to look "right". A simple suggestion
is to use => to show links and () to show groupings [or a lower level
list]. Would you like an example of this included as well?

I am thinking perhaps one or two more iterations will do once I get
your clarification request. Also, check that other reference - if
there are functions there you need, let me know.

--Maniac

main.adb
with List; -- with our generic pavkage
with Ada.Command_Line, Ada.Strings.Unbounded, Ada.Integer_Text_IO,
Text_IO;
use Ada.Command_Line, Ada.Strings.Unbounded, Ada.Integer_Text_IO,
Text_IO;
 
procedure main is
   --  initialize first link list
   package List1 is new List (Unbounded_String);
   --  use List1;
   --  now initialize link list off first linked list
   package List2 is new List (List1.Node);
   --  use List2;
 
 
begin
 
   if Argument_Count = 0 then
      Put_Line (Current_Error, "Files don't exist");
      Set_Exit_Status (Failure);
   else
      for Arg in 1 .. Argument_Count loop
         null;
      --   Draw_Graph(possibly pass file as string argument);
      end loop;
 
   end if;
 
end main;

list.ads

generic

   --  Element_Type is the data to be stored into the linked list
   type Element_Type is private;

package List is

   type Node; -- is private;
   type Node_Acc is access Node;

   --  Node is a simple linked list element with two parts
   --  X.Next is the link to the next element of the list
   --  X.Info is the data to be stored
   type Node is
      record
         Next : Node_Acc;
         Info : Element_Type;
      end record;

   --  Create (or reuse) a new node with initial value as provided

   function New_Node (Initial_Value : in Node) return Node_Acc;

   --  Find an element in the list

   procedure Find (List : in Node_Acc;
                   Found : out Boolean;
                   Pred_Loc : out Node_Acc;
                   Location : out Node_Acc);
 
   --  Draw a graph of the current list
 
   procedure Draw_Graph (Fname : String);
 
 
   --  Insert an element into the list
 
   procedure Insert (List : in out Node_Acc;
                     Item : in Element_Type);
 
   --  Retrieve an element from the list that matches the value
provided
 
   procedure Retrieve (List : in Node_Acc;
                       Element : out Element_Type);
 
   --  Return true if the list is empty
 
   function Empty (List : Node_Acc) return Boolean;
 
   --  Return the length of the list
 
   function Length (List : in Node_Acc) return Natural;
 
   --  Delete an element from the list
   --  Deleted element retained in the free list for reuse
 
   procedure Delete (X : in out Node_Acc);
 
end List;

list.adb

with Text_IO;
use  Text_IO;


package body List is

   --  Free list, initially empty
   Free : Node_Acc := null;

   --  Pull an item from the free list or create a new one
   --  if none are available

   function New_Node (Initial_Value : in Node) return Node_Acc is

      Result : Node_Acc;

   begin
      if Free = null then
         Result := new Node;
      else
         Result := Free;
         Free := Free.Next;
      end if;
      Result.all := Initial_Value;
      return Result;
   end New_Node;


   --  FIXME: Find an element in the list

   procedure Find (List : in Node_Acc;
                   Found : out Boolean;
                   Pred_Loc : out Node_Acc;
                   Location : out Node_Acc) is

      Current : Node_Acc;
      Previous : Node_Acc;
   begin
      Current := List.Next;
      Previous := null;
      loop
         exit when Current = null;

         Previous := Current;
         Current := Current.Next;
      end loop;
      Location := Current;
      Pred_Loc := Previous;
      Found := Current /= null;
   end Find;

   --  FIXME: Draw a graph of the list
   --  program stub. Haven't implimented Draw_Graph yet.
   --  still trying to get the other errors out.

   procedure Draw_Graph (Fname : String) is

   begin
      null;
   end Draw_Graph;

   --  Insert an element into the list

   procedure Insert (List : in out Node_Acc;
                     Item : in Element_Type) is
      Have_Duplicate : Boolean;
      Pred_Loc : Node_Acc;
      Location : Node_Acc;
   begin
      Find (List => List,
            Found => Have_Duplicate,
            Pred_Loc => Pred_Loc,
            Location => Location);
      if Have_Duplicate then
         raise Program_Error;
      elsif Pred_Loc = null then
         List.Next := New_Node (Node'(Info => Item, Next =>
List.Next));
      else
         Pred_Loc.Next := New_Node (Node'(Info => Item, Next =>
Location));
      end if;
   end Insert;

   --  Retrieve an element from the list

   procedure Retrieve (List : in Node_Acc;
                       Element : out Element_Type) is
      Found : Boolean;
      Pred_Loc : Node_Acc;
      Location : Node_Acc;
   begin
      Find (List => List,

            Found => Found,
            Pred_Loc => Pred_Loc,
            Location => Location);
      if not Found then
         Put_Line ("Cannot be found");
      else
         Element := Location.Info;
      end if;
   end Retrieve;
 
   --  this function checks if the list is empty
 
   function Empty (List :  Node_Acc) return Boolean is
   begin
      return List.Next = null;
   end Empty;
 
   --  this function checks the length of the list
 
   function Length (List : in Node_Acc) return Natural is
      Location : Node_Acc;
      Count : Natural;
   begin
      Count := 0;
      Location := List.Next;
      loop
         exit when Location = null;
         Count := Count + 1;
         Location := Location.Next;
      end loop;
      return Count;
   end Length;
 
   --  FIXME: this procedure removes a node
 
   procedure Delete (X : in out Node_Acc) is
   begin
      X.Next := Free;
      Free := X;
      X := null;
   end Delete;
 
end List;

Request for Answer Clarification by loeric18-ga on 20 Dec 2002 09:36 PST
Hi, Maniac
thank you for your rapid work. It is very helpful for me so far. But I
tried to compile it, it showed " main.adb  2:50 : warning: no entities
of "integer_text_io" are referenced " ..so can I remove it?

Clarification of Answer by maniac-ga on 20 Dec 2002 09:45 PST
Hello loeric18,

Re: Integer_Text_IO
Yes. I have found the warnings from GNAT to be quite helpful in
eliminating a lot of odd code. As a suggestion to clean up all that
kind of code is to use
  -gnatWaH
which enables all warnings except for "hiding" warnings (the same name
used in more than one package).

I made a change to Find to add the Value parameter, but as I mentioned
before, I want feedback before sending you an update. In particular,
 Is it your intent to "Insert" at the beginning if the entry is "not
found"?
 Do you want to store data at the head of the list?
Answers to the other questions would help as well.

  --Maniac

Request for Answer Clarification by loeric18-ga on 20 Dec 2002 10:05 PST
HI, Maniac
    Actually, I am ashamed to say I don't even know very much about
how to answer your question to help me...so my feedback is "you could
decide yourself to finish the work", but please choose the easy simple
way which look like made by a rookie. And also please follow the
instruction of the project to finish the code...sorry, that's only
feedback I could give you....Could I just learned Ada 2 weeks..... :(
BTW, after I compiled the version you gave me, can it run for an
output? or just can be compiled?...

Request for Answer Clarification by loeric18-ga on 20 Dec 2002 12:18 PST
Hi,Maniac
   I just finished the meeting with my instructor. He postponeed the
deadline to Jan 6th. So we can do this without rush.
   About the input and output, please apply the example "
http://www.cs.fit.edu/~ryan/ada/programs/io/copy-adb.html " to the
main.adb program.  you can decide which way to make the whole project
run correct according to the instruction of the project. Please help
me make the program done.
Eric

Clarification of Answer by maniac-ga on 20 Dec 2002 14:45 PST
Hello loeric18,

Glad for the extension, but I am not sure what is meant by the last
clarification. Is the output supposed to be line numbered or is this
supposed to be an example of how to input the data from the file? The
input method I used is a similar (use Get_Line) and use the length so
you may be OK already. You should probably read up on Find_Token in
the Ada Reference Manual - it is part of Ada.Strings so you can answer
questions about it. It is a handy tool.

Let me provide a copy of what I have right now. It appears to work
with the sample data posted on the web site and matches the format as
specified. The list stuff works OK - I am not sure how much polish you
want applied. The next few paragraphs describe what is done and how it
is done.
Main program:

The two lists are now called "South_Of" and "List_Of_Cities". The
first is just the name of a city, the second has an addition
"Is_South_Of" field that points to the list of cities south of this
one. An equals function is defined for both, Unbounded_String."=" for
the first and the one shown for the A_City type to compare just the
names of the city (and not the links).

The procedure Search_South_Of is recursive - it calls itself whenver
it finds a city and the name does not match the one it is looking for.
This is how the "transitive search" is done (e.g. A->B, and B->C, then
A->C). It runs pretty fast on my machine, no noticeable delay from
entry of the question to printing the answer. If there was one thing
you might want to change is to add functions to "go to next list item"
in the List package and use it here to replace the
  South_Head := South_Head.Next;
statement.

The variables in the main program include
 Big_Line - a string array long enough to fit the sample input.
 Max_Big_Line, Last_Character, First, Last - indexes into Big_Line
 Alpha_Set - a "set of characters"; the letters "A" through "Z" and
"a" through "z". This is used to recognize the city names.
 Head - the head of the "List_Of_Cities" list
 Pred_Loc - a dummy value, set but never read
 Found - a boolean for a function return

The first loop loads the list of cities and the nested south of lists.
Read a line, use "Find_Token" to get the first word, insert into the
city list, use "Find_Token" again for the second word, insert that
into the city list, and then add the south of list item to the first
city. Repeats until a line w/ a single character is read.

The second loop does the same with reading the line and building the
two city names. It has five nested if cases
 - first name not present, print the "unknown" message
 - second name not present, ditto
 - 2 is south of 1 according to Search_South_Of, say 2 is south of 1
 - 1 is south of 2 according to Search_South_Of, say 2 is north of 1
 - print the unknown message
and that's it for the main program.

List specification

Added the equals function to the generic declaration, otherwise pretty
much the same.

List body

Added the Value parameter to Find and made appropriate fixes. Works
really good.

Draw_Graph is still a stub, I used gvd to figure out the structures
for debugging so never needed it. You might just remove it.

Insert is modified to return "Where" the item was inserted and will
return "Location" if you attempt to insert the same value more than
once into a list.

I don't think I ever ran Retrieve, Empty, Length, nor Delete. I did
fix the null access type stuff so it should work OK, but otherwise
they are what you provided.

Give it a good beating and let me know how it works for you. If
something still is not clear, don't hesitate to ask more as a
clarification. I probably can't code up more until Monday but a
general question will be answered promptly.

Good luck.
  --Maniac

----   source code follows ----


Main program

with List; -- with our generic pavkage
with Ada.Strings;
use Ada.Strings;
with Ada.Strings.Unbounded;
use Ada.Strings.Unbounded;
with Ada.Strings.Fixed;
use Ada.Strings.Fixed;
with Ada.Strings.Maps; -- for character set type
use Ada.Strings.Maps;
with Text_IO;
use Text_IO;

procedure main is

   --  South of relationship
   package South_Of is new List (Unbounded_String,
                                 "=");

   type A_City is record
      Name : Unbounded_String;
      Is_South_Of : South_Of.Node_Acc;
   end record;

   --  Equivalence function used to compare if two
   --  cities in "A_City" match (ignore the link)

   function "=" (Left, Right : A_City) return Boolean;

   function "=" (Left, Right : A_City) return Boolean is
   begin
      return Left.Name = Right.Name;
   end "=";

   --  The list of cities (list of lists)
   package List_Of_Cities is new List (A_City, "=");

   --  Recursive function to do the transitive
   --  search for a city "south of" another

   procedure Search_South_Of (City1 : in List_Of_Cities.Node_Acc;
                              City2_Name : in Unbounded_String;
                              Found : out Boolean);

   City1_Name, City2_Name : Unbounded_String;
   City1, City2 : List_Of_Cities.Node_Acc;
   Max_Big_Line : constant Natural := 500;
   Big_Line : String (1 .. Max_Big_Line);
   Last_Character : Natural; --  Last character of Big_Line
   First, Last : Natural; --  Indicies into Big_Line
   Alpha_Set : constant Character_Set :=
     To_Set (Character_Ranges'((Low => 'A', High => 'Z'),
                               (Low => 'a', High => 'z')));
   Head : List_Of_Cities.Node_Acc := null;
   City_South : South_Of.Node_Acc;
   Pred_Loc : List_Of_Cities.Node_Acc;  --  dummy value for find
   Found : Boolean; -- did we find the city

   procedure Search_South_Of (City1 : in List_Of_Cities.Node_Acc;
                              City2_Name : in Unbounded_String;
                              Found : out Boolean) is

      use type South_Of.Node_Acc;
      South_Head : South_Of.Node_Acc := City1.Info.Is_South_Of;
      Cityx : List_Of_Cities.Node_Acc;
      Xfound : Boolean;
      Xpred : List_Of_Cities.Node_Acc;

   begin
      Found := False;
      loop
         exit when South_Head = null;
         if South_Head.Info = City2_Name then
            Found := True;
            exit;
         else
            List_Of_Cities.Find (Head, A_City'(South_Head.Info, null),
Xfound,
                                 Xpred, Cityx);
            Search_South_Of (Cityx, City2_Name, Xfound);
            if Xfound then
               Found := True;
               exit;
            else
               South_Head := South_Head.Next;
            end if;
         end if;
      end loop;

   end Search_South_Of;

begin

   loop --  build the lists
      Text_IO.Get_Line (Big_Line, Last_Character);
      exit when Last_Character = 1;
      --  Extract the first city name (assume correct input)
      Find_Token (Big_Line (1 .. Last_Character), Alpha_Set,
                  Inside, First, Last);
      City1_Name := To_Unbounded_String (Big_Line (First .. Last));
      List_Of_Cities.Insert (Head, A_City'(City1_Name, null), City1);
      --  Repeat with the second city name
      Find_Token (Big_Line (Last + 1 .. Last_Character), Alpha_Set,
                  Inside, First, Last);
      City2_Name := To_Unbounded_String (Big_Line (First .. Last));
      List_Of_Cities.Insert (Head, A_City'(City2_Name, null), City2);
      --  Both cities now in the "list of cities, create a "south of"
      --  relationship between them
      South_Of.Insert (City1.Info.Is_South_Of, City2_Name,
City_South);
   end loop;

   --  at this point, we have our "list of lists"
   --  Head points to a list of cities
   --  Some of the Cities have "Is_South_Of" lists which point
   --  to cities that are know to be north of them

   null; -- debug point

   loop
      --  get the next pair of names
      Text_IO.Get_Line (Big_Line, Last_Character);
      exit when Last_Character = 1;
      --  Extract the first city name (assume correct input)
      Find_Token (Big_Line (1 .. Last_Character), Alpha_Set,
                  Inside, First, Last);
      City1_Name := To_Unbounded_String (Big_Line (First .. Last));
      --  Repeat with the second city name
      Find_Token (Big_Line (Last + 1 .. Last_Character), Alpha_Set,
                  Inside, First, Last);
      City2_Name := To_Unbounded_String (Big_Line (First .. Last));
      List_Of_Cities.Find (Head, A_City'(City1_Name, null), Found,
                          Pred_Loc, City1);
      --  first case, first name not found - can't say
      --  anything about where it is
      if (not Found) then
         Text_IO.Put_Line ("The relative position of " &
                             To_String (City1_Name) & " and " &
                             To_String (City2_Name) & " is unknown.");
      else
         --  second case, same situation, same message
         List_Of_Cities.Find (Head, A_City'(City2_Name, null), Found,
                             Pred_Loc, City2);
         if (not Found) then
            Text_IO.Put_Line ("The relative position of " &
                                To_String (City1_Name) & " and " &
                                To_String (City2_Name) & " is
unknown.");
         else
            --  third case, 2 is south of 1
            Search_South_Of (City1, City2_Name, Found);
            if (Found) then
               Text_IO.Put_Line (To_String (City2_Name) &
                                  " is north of " &
                                  To_String (City1_Name) & ".");
            else
               --  fourth case, 2 is north of 1
               Search_South_Of (City2, City1_Name, Found);
               if (Found) then
                  Text_IO.Put_Line (To_String (City2_Name) &
                                      " is south of " &
                                      To_String (City1_Name) & ".");
               else
                  --  last case, still can't tell
                  Text_IO.Put_Line ("The relative position of " &
                                To_String (City1_Name) & " and " &
                                      To_String (City2_Name) & " is
unknown.");
               end if;
            end if;
         end if;
      end if;
   end loop;
end main;

list.ads

generic

   --  Element_Type is the data to be stored into the linked list
   type Element_Type is private;
   with function "=" (Left, Right : Element_Type) return Boolean;

package List is

   type Node; -- is private;
   type Node_Acc is access Node;
 
   --  Node is a simple linked list element with two parts
   --  X.Next is the link to the next element of the list
   --  X.Info is the data to be stored
   type Node is
      record
         Next : Node_Acc;
         Info : Element_Type;
      end record;
 
   --  Create (or reuse) a new node with initial value as provided
 
   function New_Node (Initial_Value : in Node) return Node_Acc;
 
   --  Find an element in the list
 
   procedure Find (List : in Node_Acc;
                   Value : in Element_Type;
                   Found : out Boolean;
                   Pred_Loc : out Node_Acc;
                   Location : out Node_Acc);
 
   --  Draw a graph of the current list
 
   procedure Draw_Graph (Fname : String);
 
 
   --  Insert an element into the list
 
   procedure Insert (List : in out Node_Acc;
                     Item : in Element_Type;
                     Where : out Node_Acc);
 
   --  Retrieve an element from the list that matches the value
provided
 
   procedure Retrieve (List : in Node_Acc;
                       Element : out Element_Type);
 
   --  Return true if the list is empty
 
   function Empty (List : Node_Acc) return Boolean;
 
   --  Return the length of the list
 
   function Length (List : in Node_Acc) return Natural;
 
   --  Delete an element from the list
   --  Deleted element retained in the free list for reuse
 
   procedure Delete (X : in out Node_Acc);
 
 
end List;

list.adb

package body List is

   use type Element_Type;
   --  Free list, initially empty
   Free : Node_Acc := null;

   --  Pull an item from the free list or create a new one
   --  if none are available

   function New_Node (Initial_Value : in Node) return Node_Acc is

      Result : Node_Acc;

   begin
      if Free = null then
         Result := new Node;
      else
         Result := Free;
         Free := Free.Next;
      end if;
      Result.all := Initial_Value;
      return Result;
   end New_Node;


   --  Find an element in the list

   procedure Find (List : in Node_Acc;
                   Value : in Element_Type;
                   Found : out Boolean;
                   Pred_Loc : out Node_Acc;
                   Location : out Node_Acc) is

      Current : Node_Acc;
      Previous : Node_Acc := null;
   begin
      Current := List;
      loop
         exit when Current = null;
         exit when Value = Current.Info;
         Previous := Current;
         Current := Current.Next;
      end loop;
      Location := Current;
      Pred_Loc := Previous;
      Found := Current /= null;
   end Find;

   --  FIXME: Draw a graph of the list
   --  program stub. Haven't implimented Draw_Graph yet.
   --  still trying to get the other errors out.

   procedure Draw_Graph (Fname : String) is

   begin
      null;
   end Draw_Graph;

   --  Insert an element into the list

   procedure Insert (List : in out Node_Acc;
                     Item : in Element_Type;
                     Where : out Node_Acc) is
      Have_Duplicate : Boolean;
      Pred_Loc : Node_Acc;
      Location : Node_Acc;
   begin
      Find (List => List,
            Value => Item,
            Found => Have_Duplicate,
            Pred_Loc => Pred_Loc,
            Location => Location);
      if Have_Duplicate then
         Where := Location;
      elsif Pred_Loc = null then
         List := New_Node (Node'(Info => Item, Next => List));
         Where := List;
      else
         Pred_Loc.Next := New_Node (Node'(Info => Item, Next =>
Location));
         Where := Pred_Loc.Next;
      end if;
   end Insert;

   --  Retrieve an element from the list
 
   procedure Retrieve (List : in Node_Acc;
                       Element : out Element_Type) is
      Found : Boolean;
      Pred_Loc : Node_Acc;
      Location : Node_Acc;
   begin
      Find (List => List,
            Value => Element,
            Found => Found,
            Pred_Loc => Pred_Loc,
            Location => Location);
      if not Found then
         null;
      else
         Element := Location.Info;
      end if;
   end Retrieve;
 
   --  this function checks if the list is empty
 
   function Empty (List :  Node_Acc) return Boolean is
   begin
      return List = null;
   end Empty;
 
   --  this function checks the length of the list
 
   function Length (List : in Node_Acc) return Natural is
      Location : Node_Acc;
      Count : Natural;
   begin
      Count := 0;
      Location := List;
      loop
         exit when Location = null;
         Count := Count + 1;
         Location := Location.Next;
      end loop;
      return Count;
   end Length;
 
   --  FIXME: this procedure removes a node
 
   procedure Delete (X : in out Node_Acc) is
   begin
      X.Next := Free;
      Free := X;
      X := null;
   end Delete;
 
 
end List;

Request for Answer Clarification by loeric18-ga on 21 Dec 2002 09:23 PST
Hi, Maniac
  First of all, I have to appreciate to your awsome job. But I am
going to San  Francisco for about one week, so after I come back I'll
test the program you gave me, and rate the answer. I think I am sure I
will pay some more for your excellemnt work. About the example
copy.adb is supposed to be an example of how to input the data from
the file asked by my instructor. Later

Eric

Clarification of Answer by maniac-ga on 21 Dec 2002 09:27 PST
Hello Loeric18,

OK. Have a good trip and hear from you again later.
  --Maniac

Request for Answer Clarification by loeric18-ga on 05 Jan 2003 18:39 PST
Hi, Maniac
   I jsut tried to compile those file. Compilation is ok, but I can't
find the list.exe to execute and run the file, is there anything
wrong?? thx

Eric

Request for Answer Clarification by loeric18-ga on 05 Jan 2003 18:58 PST
WOW.......I tried again, and it said "main.exe" missing, but I checked
the folder, these was a main.exe there, so I just ran it ,and it
worked perfect!!!!!!  Thank you very much!!

Eric

Request for Answer Clarification by loeric18-ga on 05 Jan 2003 19:15 PST
Hi, Maniac
   Could you modify little bit to make the program read all the
relations of the cities first, and then a "#", after "#" are all the
questions, then a "#" again, then all the answers. for example:
   Melbourne    DaytonaBeach
DaytonaBeach Jacksonville
Orlando   Jacksonville
#
Melbourne Jacksonville
Tampa Melbourne
Jacksonville Orlando
Orlando DaytonaBeach
#

the output should be 
Melbourne is south of Jacksonville.
The relative position of Tampa and Melbourne is unknown.
Jacksonville is north of Orlando.
The relative position of Orlando and DaytonaBeach is unknown.

thx!!! I think it would be the last request!!plz

Eric

Clarification of Answer by maniac-ga on 06 Jan 2003 14:04 PST
Hello loeric18,

Thank you for the kind comments (and tip!).

About the clarification request - that is a straightforward change.

In list.adb, lines 150-152 should read...
  Text_Io.Put_Line(To_String(City1_Name) &
  " is sorth of " &
  To_String(City2_Name) & ".");
[third case - change the order of City1_Name and City2_Name, replace
"north" with "south"]

and similarly on lines 157-159, make the same kind of change (to
reverse City1_Name and City2_Name, and replace "south" with "north").

The line numbers may be off by a little in your copy - adjust if
needed. Check the comments for case 3 and 4 as well (I noticed they
were identical - oops :-() and fix them to match the code.

I tested with your input and get the "correct" output.

  --Maniac
loeric18-ga rated this answer:5 out of 5 stars and gave an additional tip of: $20.00
Nice job,excellent answered, thx a lot!!!

Comments  
There are no comments at this time.

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy