Path: utzoo!utgpu!news-server.csri.toronto.edu!clyde.concordia.ca!uunet!munnari.oz.au!goanna!ok From: ok@goanna.cs.rmit.OZ.AU (Richard A. O'Keefe) Newsgroups: comp.lang.prolog Subject: Re: London Underground central area map in Prolog (LONG: 137 lines) Message-ID: <3155@goanna.cs.rmit.OZ.AU> Date: 5 May 90 03:25:35 GMT References: <2371@skye.ed.ac.uk> Organization: Comp Sci, RMIT, Melbourne, Australia Lines: 63 In article <2371@skye.ed.ac.uk>, ken@aiai.ed.ac.uk (Ken Johnson) writes: > THIS IS an interesting data set if you want to give your students a > ``real'' programming problem. Ken Johnson is one of my favourite people, and it's nice to have good examples to play with, _BUT_ The tuples in his data base have the form > % station(Name, X_coord, Y_coord, Lines) > % X_coord and Y_coord are centimetres from the bottom left hand > % corner of the London Underground map and have little > % geographical significance. > % Lines is a list of London Underground lines that pass through > % the Station. The first thing that hits a Codd fan in the eye is that this relation is not in 1st Normal Form: the Lines attribute is not atomic with respect to likely applications (e.g. if one wants to know whether two stations are on the same line, and if so which). But that was actually the second thing that hit me. The first thing that _really_ hit was "I can't use this". I have often travelled on the London underground, and the two questions I have been vitally concerned with are (1) how many stops before I get off? (2) where should I change? Basically, the kind of information you need for this is "how are the stations connected". It seems to me that a better structure for this data base would be station(StationName, X, Y). -- StationName is the name of a station at (X,Y) on the map. line(FromStation, ToStation, LineName) -- you can get from FromStation to ToStation in one step -- by travelling along the line called LineName Then one could define station_line(Station, Line) :- line(Station, _, Line). station_line(Station, Line) :- line(_, Station, Line). kj_station(Station, X, Y, Lines) :- station(Station, X, Y), setof(Line, station_line(Station,Line), Lines). A richer data base for the London underground would also include the fares, or rather the zoning structure underlying the fares. I've forgotten how that would go for London. In Melbourne the fare structure for the Met would go something like station_zone(Station, /* -> */ Zone /* 1, 2, or 3 */). zone_card(FromZone, ToZone, CardType). -- you can travel from FromZone to ToZone if you hold a -- current card of type CardType (e.g. '2/1 weekly') -- This is symmetric in FromZone, ToZone card_price(CardType, /* -> */ Price).