diff --git a/lpn/ch03/connected.pl b/lpn/ch03/connected.pl new file mode 100644 index 0000000..7b425cc --- /dev/null +++ b/lpn/ch03/connected.pl @@ -0,0 +1,60 @@ +%% Imagine that the following knowledge base describes a maze. The +%% facts determine which points are connected, that is, from which +%% points you can get to which other points in one step. Furthermore, +%% imagine that all paths are one-way streets, so that you can only +%% walk them in one direction. So, you can get from point 1 to point +%% 2, but not the other way round. +connected(1,2). +connected(3,4). +connected(5,6). +connected(7,8). +connected(9,10). +connected(12,13). +connected(13,14). +connected(15,16). +connected(17,18). +connected(19,20). +connected(4,1). +connected(6,3). +connected(4,7). +connected(6,11). +connected(14,9). +connected(11,15). +connected(16,12). +connected(14,17). +connected(16,19). + + +%% Write a predicate path/2 that tells you from which points in the +%% maze you can get to which other points when chaining together +%% connections given in the above knowledge base. Can you get from +%% point 5 to point 10? Which other point can you get to when starting +%% at point 1? And which points can be reached from point 13? + +path(X, Y) :- connected(X, Y). +path(X, Y) :- connected(X, Z), + path(Z, Y). + +%% Questions: +%% 1. Can you get from point 5 to point 10? Yes: +%% +%% ?- path(5, 10). +%% true . +%% +%% 2. Which other point can you get when starting at point 1? You can't +%% get to any other points: +%% +%% ?- path(1, P). +%% P = 2 ; +%% false. +%% +%% 3. Which points can be reached from point 13? Points 9, 10, 14, 17, +%% 18. +%% +%% ?- path(13, P). +%% P = 14 ; +%% P = 9 ; +%% P = 17 ; +%% P = 10 ; +%% P = 18 ; +%% false. diff --git a/lpn/ch03/travel.pl b/lpn/ch03/travel.pl index 01dd410..dda6630 100644 --- a/lpn/ch03/travel.pl +++ b/lpn/ch03/travel.pl @@ -11,3 +11,49 @@ directTrain(nancy,metz). travelFromTo(X, Y) :- directTrain(X, Y). travelFromTo(X, Y) :- directTrain(X, Z), travelFromTo(Z, Y). + +%% New version from practical exercises. +%% We are given the following knowledge base of travel information: +byCar(auckland,hamilton). +byCar(hamilton,raglan). +byCar(valmont,saarbruecken). +byCar(valmont,metz). + +byTrain(metz,frankfurt). +byTrain(saarbruecken,frankfurt). +byTrain(metz,paris). +byTrain(saarbruecken,paris). + +byPlane(frankfurt,bangkok). +byPlane(frankfurt,singapore). +byPlane(paris,losAngeles). +byPlane(bangkok,auckland). +byPlane(singapore,auckland). +byPlane(losAngeles,auckland). + +%% Write a predicate travel/2 which determines whether it is possible +%% to travel from one place to another by chaining together car, +%% train, and plane journeys. For example, your program should answer +%% yes to the query travel(valmont,raglan). + +%% The base case is a direct route via car, train or plane. +travelDirect(X, Y) :- byCar(X, Y). +travelDirect(X, Y) :- byTrain(X, Y). +travelDirect(X, Y) :- byPlane(X, Y). +travel(X, Y) :- travelDirect(X, Y). + +%% The recursive case chains these together. +travel(X, Y) :- travel(X, Z), + travel(Z, Y). + +%% So, by using travel/2 to query the above database, you can find out +%% that it is possible to go from Valmont to Raglan. If you are +%% planning such a voyage, that’s already something useful to know, +%% but you would probably prefer to have the precise route from +%% Valmont to Raglan. Write a predicate travel/3 which tells you which +%% route to take when travelling from one place to another. For +%% example, the program should respond +%% X = go(valmont,metz, +%% go(metz,paris, +%% go(paris,losAngeles))) +%% to the query travel(valmont,losAngeles,X).