Saint Louis University |
Computer Science 362
|
Dept. of Math & Computer Science |
For this assignment, you are allowed to work with one other student if you wish (in fact, we suggest that you do so). If any student wishes to have a partner but has not been able to locate one, please let the instructor know so that we can match up partners.
Please make sure you adhere to the policies on academic integrity in this regard.
Topic: Prolog Programming
Related Reading: Ch. 5 and online notes
Due:
Friday, 4 October 2013, 11:59pm
Monday, 7 October 2013, 11:59pm
For this assignment, we will be working with a data set that consists of over 17000 daily airline flights in the United States and its territories (data courtesy of the Bureau of Transportation Statistics). Translated into Prolog, our data set consists of three atomic predicates:
time(H,M) is always expressed in 24-hour time, such that
All flight times are expressed in local time for the relevant airport (and without any use of daylight savings times).
The airport abbreviation is the standard 3-letter code, although lowercased as a Prolog atom (e.g. stl). The airport's GMT time is an integer that represents the difference in the number of hours between the airport's local time and Greenwich Mean Time. For example, St. Louis is at -6 GMT, which means that when it is 11:00am in Greenwich, it is 5:00am in St. Louis.
The airline names are only necessary for pretty printing.
We are providing three files. The first, database.pl, has all of the raw airline data. The second, travel.pl, is a Prolog script that you must complete. We have structured the file so that it includes embedded documentation for all predicates that you must implement. All of your source code must be placed within the travel.pl file and that is the only one that you should modify and submit.
A third file we are providing is unittest.pl, which is a script that automates all of the tests that are embedded within the documentation of travel.pl. It can be executed from the command line as:
swipl -s unittest.pl -g main -q
These files are available on turing at:
/Public/goldwasser/362/prolog/flightsor they may be downloaded from here (database.pl, travel.pl, unittest.pl).
You must implement each of the following predicates in Prolog.
/*---------------------------------------------------------------- | Predicate: minutes(time(H,M), N). | | N is the number of minutes from the start of the day until time(H,M). | | Preconditions: H and M must be bound | | Examples: | | ?- minutes(time(13,45), N). | N = 825. | | ?- minutes(time(0,0), N). | N = 0. +----------------------------------------------------------------*/
/*---------------------------------------------------------------- | Predicate: as_early(T1,T2). | | true if time T1 is at least as early in the day as T2. | (We assume that both are expressed in the same timezone). | | Preconditions: both T1 and T2 must be bound. | | Examples: | ?- as_early(time(5,30), time(8,45)). | true. | | ?- as_early(time(5,30), time(5,30)). | true. | | ?- as_early(time(23,58), time(0,05)). | false. +----------------------------------------------------------------*/
/*---------------------------------------------------------------- | Predicate: between(T1,T2,T3). | | true if time T2 is within the cyclical range [T1,T3]. | (We assume that all times are expressed in the same timezone). | | Preconditions: all of T1, T2, and T3 must be bound. | | Examples: | ?- between(time(5,30), time(7,13), time(8,45)). | true. | | ?- between(time(5,30), time(8,45), time(8,45)). | true. | | ?- between(time(5,30), time(5,30), time(8,45)). | true. | | ?- between(time(5,30), time(4,30), time(8,45)). | false. | | ?- between(time(5,30), time(11,30), time(8,45)). | false. | | ?- between(time(5,30), time(5,30), time(5,30)). | true. | | ?- between(time(5,30), time(5,29), time(5,30)). | false. | | ?- between(time(22,15), time(23,49), time(1,23)). | true. | | ?- between(time(22,15), time(1,15), time(1,23)). | true. | | ?- between(time(22,15), time(5,05), time(1,23)). | false. +----------------------------------------------------------------*/
/*---------------------------------------------------------------- | Predicate: elapsed(T1,T2,M). | | Elapsed time from T1 to T2 is M, where T1 and T2 are | time(H,M) expressions and M expresses the number of minutes elapsed | | Preconditions: both T1 and T2 must be bound. | | T1 and T2 are assumed to be expressed in the same time zone, and that | T2 is the next occurrence of that time of day following T1. That is, | the elapsed time should be in the range [0,1439], as it is strictly less than 24 hours. | | Examples: | ?- elapsed(time(5,30), time(8,45), M). | M = 195. | | ?- elapsed(time(23,58), time(0,05), M). | M = 7 +----------------------------------------------------------------*/
/*---------------------------------------------------------------- | Predicate: gmt(Airport, Local, Global) | | True if Global is the GMT time that is equal to the Local time expressed at Airport. | This should be applicable with either one of Local or Global being unbound. That is | | Preconditions: Airport and at least one of Local or Global must be bound. | | Examples: | ?- gmt(stl, time(11,30), G). | G = time(17,30). | | ?- gmt(stl, L, time(17,30)). | L = time(11,30). +----------------------------------------------------------------*/
/*---------------------------------------------------------------- | Predicate: flight_time(F, Origin, Destination, T) | | True if the segment of flight F from Origin to Destination has | an elapsed time of T minutes (taking into consideration the time zones | of the airports). | | Preconditions: F, Origin, and Destination must be bound | | Examples: | ?- flight_time(flight(aa,1040), stl, ord, T). | T = 75. | | ?- flight_time(flight(dl,2088), stl, slc, T). | T = 197. +----------------------------------------------------------------*/
/*---------------------------------------------------------------- | Predicate: flies(Airline, Airport). | | True if Airline has at least one flight into or out of Airport | | Examples: | ?- flies(as,stl). /* Alaskan Airlines */ | true. | | ?- flies(ha,stl). /* Hawaiian Airlines */ | false. | | ?- setof(A, flies(A,pvd), L). | L = [b6, dl, e9, ev, ua, us, wn, yv]. +----------------------------------------------------------------*/
/*---------------------------------------------------------------- | Predicate: nonstop(Origin, Destination). | | True if there exists a direct flight segment from Origin to Destination. | | Examples: | ?- nonstop(stl,den). /* Denver */ | true. | | ?- nonstop(stl,cos). /* Colorado Springs */ | false. +----------------------------------------------------------------*/
/*---------------------------------------------------------------- | Predicate: nonstop(Origin, Destination, Airline). | | True if Airline operates a direct flight segment from Origin to Destination. | | Examples: | ?- nonstop(stl,den,wn). /* Southwest Airlines */ | true. | | ?- nonstop(stl,den,aa). /* American Airlines */ | false. | | ?- setof(D, nonstop(stl,D,dl), L). /* Destinations from St. Louis on Delta */ | L = [atl, dtw, msp, slc]. +----------------------------------------------------------------*/
/*---------------------------------------------------------------- | Predicate: arrivals(Airport, Start, End, L). | | L is a list of all flights that arrive at Airport during the interval | starting at time Start and ending with time End (where it is possible | that the interval wraps around midnight). | | Preconditions: Airport, Start, and End must be bound | | Examples: | | ?- arrivals(stl, time(10,00), time(10,10), L). | L = [flight(e9, 3360), flight(e9, 4102), flight(wn, 4)]. | | ?- arrivals(stl, time(9,25), time(9,25), L). | L = [flight(wn, 2425), flight(wn, 340), flight(wn, 3482), flight(wn, 3861), flight(wn, 683), flight(wn, 749)]. | | ?- arrivals(lax, time(23,50), time(0,45), L). | L = [flight(aa, 1035), flight(aa, 2497), flight(b6, 677), flight(dl, 2363), flight(ua, 1445)] +----------------------------------------------------------------*/
/*---------------------------------------------------------------- | Predicate: wait(F1, Airport, F2, W) | | W is the wait time (in minutes) between the arrival of F1 at Airport | and the subsequent departure of F2. | | Preconditions: F1, Airport, and F2 must be bound. | | Examples: | | ?- wait(flight(wn,369), mdw, flight(wn,369), W). | W = 50 ; | | ?- wait(flight(wn,2766), mdw, flight(wn,2766), W). | W = 40 ; +----------------------------------------------------------------*/
/*---------------------------------------------------------------- | Predicate: connecting(F1, Airport, F2, MinGap, MaxGap) | | true if it is possible to arrive at Airport on F1 and depart on F2. | | To make a connection the gap between the arrival of F1 and subsequent | departure of F2 must be at least MinGap minutes, and at most MaxGap minutes. | | Preconditions: Airport, MinGap, MaxGap must be bound. | | Examples: | | ?- connecting(flight(wn,1359), stl, F, 20, 40). | F = flight(fl, 544) ; | F = flight(wn, 1281) ; | F = flight(wn, 1359) ; | F = flight(wn, 2319) ; | | ?- connecting(F, stl, flight(wn,1359), 20, 40). | F = flight(e9, 3360) ; | F = flight(e9, 4102) ; | F = flight(aa, 1266) ; | F = flight(wn, 1359) ; | F = flight(wn, 2319) ; | F = flight(wn, 4) ; | +----------------------------------------------------------------*/
/*---------------------------------------------------------------- | Predicate: connecting_airline(F1, Airport, F2, MinGap, MaxGap) | | Similar to connecting predicate, except that F1 and F2 must use same airline. | | Examples: | | ?- connecting_airine(flight(wn,1359), stl, F, 20, 40). | F = flight(wn, 1281) ; | F = flight(wn, 1359) ; | F = flight(wn, 2319) ; | | ?- connecting_airline(F, stl, flight(wn,1359), 20, 40). | F = flight(wn, 1359) ; | F = flight(wn, 2319) ; | F = flight(wn, 4) ; | +----------------------------------------------------------------*/
/*---------------------------------------------------------------- | Predicate: travel_time(Itinerary, T) | | True if the end-to-end travel time for the given itinerary is T. | | Examples: | | ?- travel_time([pwm, flight(b6, 609), jfk], T). | T = 83 . | | ?- travel_time([pwm, flight(b6, 609), jfk, flight(dl, 1394), pdx], T). | T = 520 . | | ?- travel_time([pwm, flight(ev, 4091), ewr, flight(wn, 369), mdw, flight(wn, 2766), pdx], T). | T = 594 . | | /* Travel from Pago Pago, American Somoa to St. Croix, U.S. Virgin Islands */ | ?- travel_time([ppg, flight(ha,466), hnl, flight(ua,106), lax, flight(dl,1406), dtw, flight(e9,3489), | phl, flight(aa,1007), mia, flight(aa,1165), stx], T). | T = 2280 . /* Note that this is more than 24 hours. */ | +----------------------------------------------------------------*/
/*---------------------------------------------------------------- | Predicate: pretty_print(Itinerary) | | Produces pretty output to describe itinerary, which is represented | as an odd-length alternating list of airport/flight/airport | progression, such as: | | [ppg, flight(ha,466), hnl, flight(ua,106), lax, flight(dl,1406), dtw, | flight(e9,3489), phl, flight(aa,1007), mia, flight(aa,1165), stx] | | The output for this example appears as: | | Depart from PPG at 23:20 on Hawaiian Airlines flight #466 arriving at HNL at 5:40 | Depart from HNL at 13:34 on United Airlines flight #106 arriving at LAX at 21:00 | Depart from LAX at 23:00 on Delta Airlines flight #1406 arriving at DTW at 6:26 | Depart from DTW at 8:10 on Pinnacle Airlines flight #3489 arriving at PHL at 10:04 | Depart from PHL at 12:35 on American Airlines flight #1007 arriving at MIA at 15:25 | Depart from MIA at 16:45 on American Airlines flight #1165 arriving at STX at 20:20 | Total travel time is 2280 minutes. | | Note: string atoms can be uppercased using the built-in predicate upcase_atom(Original,Upper). | +----------------------------------------------------------------*/
/*---------------------------------------------------------------- | Predicate: plan(Origin, Destination, MinConnect, MaxHops, MaxTime, Itinerary) | | Generate an itinerary going from Origin to Destination | (which never passes through any airport more than once) | subject to the following additional constraints. | | MinConnect represents the tightest connection allowed, expressed in minutes | (e.g., 30 means that there must be at least 30 minutes between one arrival and connecting departure) | | MaxHops represents the maximum number of segments that may be used | (e.g., 1 means that it must be a nonstop) | | MaxTime represents the maximum end-to-end travel time for a passenger that is allowed. | That is, in actual clock time, the length from the very first departure to the final arrival. | | Example: | | ?- plan(pwm, pdx, 30, 3, 600, I). /* From Portland, Maine to Portland, Oregon in 10 hours */ | I = [pwm, flight(b6, 609), jfk, flight(dl, 1394), pdx] ; | I = [pwm, flight(ev, 6046), iad, flight(ua, 1671), pdx] ; | I = [pwm, flight(ev, 6046), iad, flight(ua, 72), den, flight(ua, 745), pdx] ; | I = [pwm, flight(ev, 4091), ewr, flight(wn, 369), mdw, flight(wn, 2766), pdx]. | | (although order of results may vary) +----------------------------------------------------------------*/
Submit your travel.pl file electronically via the course website (details on the submission process).
I will offer two forms of extra credit. First, to assist in testing, I have embedded some sample results within the documentation for each function (based upon my own implementation). I hope that those are correct results. I will award 1 point of extra credit for any mistake that is found in those examples, awarded to the first person to provide me with convincing evidence of the error.
Up to 5 points of extra credit can be earned by implmenting the following additional predicate, which is a version of plan that uses two additional parameters to define an earliest and latest acceptable departure from the origin airport. (e.g., "I want to travel from STL to ORD, departing sometime between 8:00 and 10:00").
/*---------------------------------------------------------------- | Predicate: plan(Origin, Destination, EarliestDeparture, LatestDeparture, | MinConnect, MaxHops, MaxTime, Itinerary) | | EarliestDeparture is a time specification that is the earliest time | of day the traveler is able to depart the origin. | | LatestDepaurture is a time specification that is the latest time of day the traveler | is able to depart the origin. | | MinConnect represents the tightest connection allowed, expressed in minutes | (e.g., 30 means that there must be at least 30 minutes between one arrival and connecting departure) | | MaxHops represents the maximum number of segments that may be used | (e.g., 1 means that it must be a nonstop) | | MaxTime represents the maximum end-to-end travel time for a passenger that is allowed. | That is, in actual clock time, the length from the very first departure to the final arrival. +----------------------------------------------------------------*/