240 likes | 393 Views
4. Using Structures: Example Programs. Contents. Retrieving structured information from a database Doing data abstraction Simulating a non-deterministic automaton Travel planning The eight queens problem. Retrieving Structured Information from a DB.
E N D
Contents • Retrieving structured information from a database • Doing data abstraction • Simulating a non-deterministic automaton • Travel planning • The eight queens problem
Retrieving Structured Information from a DB • This exercise develops the skill of representing and manipulating structured data objects. • It also illustrates Prolog as a natural database query language. • A database can be represented in Prolog as a set of facts.
Retrieving Structured Information from a DB • A database about families: family( person(tom,fox,date(7,may,1950),works(bbc,15200)), person(ann,fox,date(9,may,1951),unemployed), [person(pat,fox,date(5,may,1973),unemployed), person(jim,fox,date(5,may,1973),unemployed)]). • We can refer to all Armstrong families by: family(person(_,armstrong,_,_),_,_) • Refer to all families with three children: family(_,_,[_,_,_])
Retrieving Structured Information from a DB • To find all married women that have at least three children: ?-family(_,person(Name,Surname,_,_), [_,_,_|_]).
Retrieving Structured Information from a DB • Provide a set of procedures that can serve as a utility to make the intersection with the database more comfortable. husband(X):- family(X,_,_). wife(X):- family(_,X,_). child(X):- family(_,_,Children), member(X,Children). exist(X):- husband(X); wife(X); child(X). dateofbirth( person(_,_,Date,_),Date)). salary( person(_,_,_Works(_,S),S)). salary( person(_,_,_,unemployed),0).
Retrieving Structured Information from a DB Find the names of all the people in the DB: ?-exists(person(Name,Surname,_,_)). Find all children born in 1981: ?-child(X),dateofbirth(X,date(_,_,1981)). Find all employed wives: ?-wife(person(Name,Surname,_,works(_,_))). Find the names of unemployed people who were born before 1963: ?-exists(person,N,S,date(_,_,Y),unemployed)), Y<1963. Find people born before 1950 whose salary is less than 8000: ?-exists(P),dateofbirth(P,date(_,_,Year)), Year<1950,salary(P,S),S<8000.
Retrieving Structured Information from a DB • Total income of a family: total([],0). total([Person|List],Sum):- salary(Person,S0, total(List,Rest), Sum is S+Rest.
Simulating an NDA b final(s3). trans(s1,a,a1). trans(s1,a,s2). trans(s1,b,s1). trans(s2,b,s3). trans(s3,b,s4). silent(s2,s4). silent(s3,s1). a s1 s2 null a b null s4 s3 b
Simulating an NDA ?-accepts(s1,[a,a,a,b]). yes ?-accepts(S,[a,b]). S=s1; S=s3. ?-accepts(s1,[X1,X2,X3]). X1=a X2=a X3=b; X1=b X2=a X3=b; no ?-String=[_,_,_], accepts(s1,String). String=[a,a,b]; String=[b,a,b]; no accepts(State,[]):- final(State). accepts(State,[X|Rest]):- trans(State,X,State1), accepts(State1,Rest). accepts(State,String):- silent(State,State1), accepts(State1,String).
Travel Planning • Develop an advisor program that will be able to answer useful questions, such as: • What days of the week is there a direct flight from London to Ljubljana? • How can I get from Ljubljana to Edinburgh on Thursday? • I have to visit Milan, Ljubljana and Zurich, starting from London on Tuesday and returning to London on Friday. In what sequence should I visit these cities so that I have no more than one flight each day of the tour?
Travel Planning • The program will be centered around a DB holding the flight information. timetable(Place1,Place2,List_of_flight) where List_of_flight is of the form: Departure_time/Arrival_time/Flight_number/List_of_days timetable(london,edinburgh, [9:40/10:50/ba4733/alldays, 17:40/20:50/ba4833/[mo,tu,we,th,fr,su]]).
Travel Planning • To find exact routes between two given cities on a given day of the week. route(Place1,Place2,Day,Route) Here Route is a sequence of flight satisfying the following criteria: • the start point of the route is Place1; • the end of the route is Place2; • all the flights are one the same day of the week Day; • all the flight in Route are in the timetable relation; • there is enough time for transfer between flights.
Travel Planning • The route is represented as a list of structured objects of the form: From-to:Flight_Number:departure_time • Some auxiliary predicates: • flight(Place1,Place2,Day,Flight_num,Dep_time,Arr_time) • deptime(Route,Time) • transfer(time1,Time2) There is at least 40 minutes between Time1 and Time2.
Travel Planning • The problem of finding a route is similar to the simulation of the NDA • States of NDA cities • Transition between two states a flight between two cities • transition timetable • Finding a path finding a route.
Travel Planning • Defining the route relation: • Direct flight route(Place1,Place2,Day,[Place1-Place2:Fnum:Dep]):- flight(Place,Place2,Day,Fnum,Dep,Arr). • Indirect flight route(P1,P2,Day,[P1-P3:Fnum1:Dep1|Route]):- route(P3,P2,Day,Route), flight(P1,P3,Fnum1,Dep1,Arr1), deptime(Route,Dep2), transfer(Arr1,Dep2). See Fig. 4.5, pp 111-112 for the complete program.
Travel Planning • Some example questions: • What days of the week is tehre a direct flight from London to Ljubljana? ?-flight(london,ljubljana,Day,_,_,_). Day=fr; day=su; no • How can I get from Ljubljana to Edinburgh on Thursday? ?-route(ljubljana,edinburgh,th,R). R=[ljubljana-zurich:yu322:11:30, zurich-london:sr806:16:10, london-edinburgh:ba4822:18:40]
The Eight Queens Problem:Program 1 • The problem here is to place eight queens on the empty chessboard in such a way that no queen attacks any other queen. 8 7 6 5 4 3 2 1 1 8 2 3 4 5 6 7
The Eight Queens Problem: Program 1 • The problem is to find such as list [X1/Y1,X2/Y2,X3/Y3,X4/Y4,X5/Y5,X6/Y6,X7/Y7,X8/Y8] • To make the search task easier, we fix the X-coordinates: [1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8]
The Eight Queens Problem: Program 1 • Case 1: The list of the queen is empty: the empty list id certainly a solution because there is no attack. Case 2: The list of queen is non-empty: it looks like [X/Y|Others]. Then • There must be no attack between the queens in the list Others; i.e., Others must be a solution. • X and Y must be integers between 1 and 8. • A queen at square X/Y must not attack any of the queens in the list Others.
The Eight Queens Problem: Program 1 solution([]). solution([X/Y|Others]):- solution(Others), member(Y,[1,2,3,4,5,6,7,8]), noattack(X/Y,Others). noattack(_,[]). noattack(X/Y,[X1/Y1|Others]):- Y=\=Y1,Y1-Y=\=X1-X,Y1-Y=\=X-X1, noattack(X/Y,Others). template([1/Y1,2/Y2,3/Y3,4/Y4,5/Y5, 6/Y6,7/Y7,8/Y8]). ?-template(S),solution(S).
The Eight Queens Problem: Program 2 • X-coordinates can be omitted, retaining only Y-coordinates: [Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8]. • To prevent the horizontal attack, no two queens can be in the same row. • Each solution is therefore represented by a permutation of the list: [1,2,3,4,5,6,7,8]. • Such a permutation, S, is a solution if all queens are safe.
The Eight Queens Problem: Program 2 solution(S):- permutation([1,2,3,4,5,6,7,8],S), safe(S). safe([]). safe([Queen|Others]):- sate(Others), noattack(Queen,Others,1). noattack(_,[],_). noattack(Y,[Y1|Ylist],Xdist):- Y1-Y=\=Xdist,Y-Y1=\=Xdist, Dist1 is Xdist+1, noattack(Y,Ylist,Disy1).
The Eight Queens Problem: Program 2 Others Queen Xdist=1 Xdist=3