ITEC 360: Program 1


Program due by: 11:59:59 p.m. Monday, March 02, 2020

Example submit command: submit itec360-01 README.txt topo.adb etc.adb


Last modified:

Updates:

  1. 2020 Feb 22 04:14:36 PM: Added acyclic command, assignment checker, due date
  2. 2020 Feb 21 04:33:16 PM: Corrected error in sample input
  3. 2020 Feb 17 02:48:13 PM: Fixed duplicate children on print. Added print and help commands to sample input.
  4. 2020 Feb 16 09:57:30 PM: Changed the specifications to have 2 input streams: the graph is in a file and the commands come from standard input.
  5. 2020 Feb 16 09:57:30 PM: Made several minor changes, including changing the commands a little. and loosening the no-scripting-language requirement, a bit

You can see an example of this program at assignment checker (which uses gnoga to integrate the GUI, web server, and problem solution). On-campus or VPN session required. [Note that the URL has changed.]

Overview: This assignment involves implementing a directed graph data structure and using that structure for implementing depth-first, breadth-first, topological sorts and checking a topological sort.

Sample Run: If the input file prereqs.txt is as follows:

7
120 0
220 1 120
122 1 120
324 1 220
320 1 220
360 4 320 324 122 171
360 3 320 324 122 171 
420 1 122
And if the input file commands.txt is as follows:
count
acyclic
breadth 120
depth 120
topological
check 120 122 220 320 324 171 360 420 
check 120 122 220 320 324 360 171 420 
print
help
quit
The following sample run reads standard input from a file
>./topo prereqs.txt <  commands.txt
Node count: 8
Acyclic: Yes
Breadth-first search from 120:
  120,   122,   220,   360,   420,   320,   324,   171
Depth-first search from 120:
  120,   122,   360,   420,   220,   320,   324,   171
Topological search:
  171,   120,   220,   324,   320,   122,   420,   360
Valid topological sort: Yes:
  120,   122,   220,   320,   324,   171,   360,   420
Valid topological sort: No:
  120,   122,   220,   320,   324,   360,   171,   420
Graph: 
   Node:   120:
       Parents:  
       Children:   122,   220
   Node:   220:
       Parents:    120
       Children:   320,   324
   Node:   122:
       Parents:    120
       Children:   360,   420
   Node:   324:
       Parents:    220
       Children:   360
   Node:   320:
       Parents:    220
       Children:   360
   Node:   360:
       Parents:    122,   171,   320,   324
       Children: 
   Node:   171:
       Parents:  
       Children:   360
   Node:   420:
       Parents:    122
       Children: 
Possible commands:
   [A]CYCLIC
   [D]EPTH Node
   [B]READTH Node
   [CH]ECK Node+
   [C]OUNT
   [T]OPOLOGICAL
   [P]RINT
   [H]ELP
   [Q]UIT

Acyclic: The command "Acyclic" should indicate whether or not the graph is acyclic.

An attempted topological sort of a non-acyclic (ie cyclic) graph should simply report that the graph is cyclic. A check of a cyclic graph should simply report that the graph is cyclic. See the assignment checker's second data set.

Personally, I found it easier to implement the function is_cyclic rather than is_acyclic (to reduce the need for negations). A graph has a topological sort iff it is acyclic. A graph is cyclic iff a DFS finds a back edge. How do you know if an edge is a back edge? Well, a few years ago you were precollege, now you are progressing through college, and soon (for some of you, about 11 weeks!) you will be done with college. (In case you didn't notice, that was a hint!)

Language and Platform: In general you should use a traditional, non-scripting language, but if you really want to use a scripting language, then I will consider that. So if you want to use a language other than Ada, C++, or Java then you should discuss your choice with me first. I will test your program on rucs, and so you should verify that it works correctly there. (Although if you want to use something exotic that's not on rucs, then I will at least consider that possibility.)

Submit a file called README.txt (case sensitive) that briefly describes the following:

  1. The commands on rucs that will compile and run your program
  2. Any other commands that you implemented
  3. Whether each command works correctly, and if it does not work correctly, what kind of error to expect

Program Name, Program Execution, and Comments: You may name your program anything that you like. Give the commands needed for compiling and running in both the comments of your main routine and in the README.txt file that you submit along with your program.

No specific commenting style is required, except that your name should be in all files. You should of course make good use of white space, and your comments should help the reader by describing the purpose of routines and sections of your code and by explaining any non-obvious and/or interesting design and implementation decisions.

Input: Your program will have two input streams:

  1. A file whose name is given as the first command line argument. This file will define the graph nodes and edges.
  2. Standard input will contain a sequence of commands to process.
The first line of the graph file will be a positive integer n and each of the following n lines of the input contain nodes and their parents (ie prereqs). For a given node, the parents themselves will be preceded by a natural number that is the number of parents of that node. DO NOT code the graph file name into your program!

In standard input will be a sequence of commands (case insensitive):

  1. count - report the number of nodes in the graph (can be different from n)
  2. acyclic - report whether or not the graph is acyclic
  3. depth k - perform and print a depth-first search starting from k
  4. breadth k - perform and print a breadth-first search starting from k
  5. topological - perform and print a topological search [acyclic graph only]
  6. check {list of count nodes} - print the list and whether or not it is a valid topological sort [acyclic graph only]
  7. print - print the graph
  8. help - give a list of available commands
  9. quit - quit processing and exit program
You can implement other commands if you like. You should mention any extra commands in your README.txt file. Your program may handle input that is spread across multiple lines, but it should work with the input format shown (ie line-by-line and left justified). You can assume that your input is valid - no error checking required (although it doesn't hurt if you have some). If one of command words is a reserved word in your implementation language, then you can use a different word, as long as the change is documented (ie in your README.txt file).

Output: Output from your program will be in response to the commands that are read from standard input. The output for each command, and the output's format, should be similar to that of the sample run.

Graph Data Type: You are to implement a graph abstract data type similar to this one: graphs.ads. You do not have to implement exactly these routines, but they should provide you with a good starting point (and they are adequate for implementing the searches and check routines).

Program Submission: Use a submit command on rucs similar to the one above. Submit all of your source code files and your README.txt file. You may also submit your data files if you like.