1
votes

I having a hard time understand what my predicate fly(....) is outputting. When I consult this file and ask the console(SWI-Prolog) flight(city1, city2, A, B) it prints out A=9 B=10. Which I was figuring is a single value for A and B alike. So I then wanted to use the output to finish what I was trying to accomplish; flight planner. But it seems that when I use the same question (flight(city1, city2, A, B)) in a predicate it returns a list. I did not realize this until I tried to write S and/or E. I am printing [1,2,3] in the code below because I was confused why when I only wrote S, and not anything after it, the output was just each value in the list not comma or space separated. So I decided to see how it would write a explicitly defined a list [1,2,3] and printed it.

The output I am receiving

8 ?- fly(city1, city4, 0, 24).
   14[1,2,3]9[1,2,3]
   false.

It seems like the line write(S), write([1,2,3]), is being called twice, why is this?

Also, why do I get a single value in the console for A and B but not in my predicate when it is called?

Code verbatim:

% I have no idea what I'm doing.
% Author: Skeeter

% Total of 5 cities
city(city1).
city(city2).
city(city3).
city(city4).
city(city5).

% List of flights
% flight( StartCity, EndCity, DepartureTime, ArrivalTime)
% city1 departures
flight( city1, city2, 09, 10).
flight( city1, city2, 10, 11).
flight( city1, city3, 12, 13).
flight( city1, city4, 14, 15).
flight( city1, city5, 16, 17).
% city2 departures
flight( city2, city1, 09, 10).
flight( city2, city1, 10, 11).
flight( city2, city3, 12, 13).
flight( city2, city4, 14, 15).
flight( city2, city5, 16, 17).
% city3 departures
flight( city3, city1, 09, 10).
flight( city3, city2, 10, 11).
flight( city3, city2, 12, 13).
flight( city3, city4, 14, 15).
flight( city3, city5, 16, 17).
% city4 departures
flight( city4, city1, 09, 10).
flight( city4, city2, 10, 11).
flight( city4, city3, 12, 13).
flight( city4, city3, 14, 15).
flight( city4, city5, 16, 17).
% city5 departures
flight( city5, city1, 09, 10).
flight( city5, city2, 10, 11).
flight( city5, city3, 12, 13).
flight( city5, city4, 14, 15).
flight( city5, city4, 16, 17).

% city1 arrivals
flight( city2, city1, 09, 10).
flight( city2, city1, 10, 11).
flight( city3, city1, 12, 13).
flight( city4, city1, 14, 15).
flight( city5, city1, 16, 17).
% city2 arrivals
flight( city1, city2, 09, 10).
flight( city1, city2, 10, 11).
flight( city3, city2, 12, 13).
flight( city4, city2, 14, 15).
flight( city5, city2, 16, 17).
% city3 arrivals
flight( city1, city3, 09, 10).
flight( city2, city3, 10, 11).
flight( city2, city3, 12, 13).
flight( city4, city3, 14, 15).
flight( city5, city3, 16, 17).
% city4 arrivals
flight( city1, city4, 09, 10).
flight( city2, city4, 10, 11).
flight( city3, city4, 12, 13).
flight( city3, city4, 14, 15).
flight( city5, city4, 16, 17).
% city5 arrivals
flight( city1, city5, 09, 10).
flight( city2, city5, 10, 11).
flight( city3, city5, 12, 13).
flight( city4, city5, 14, 15).
flight( city4, city5, 16, 17).

% is H1 later than X?
isLater(H1, [X|Y]) :-
H1 > X.


fly(CityFrom, CityTo, StartTime, EndTime) :-
flight(CityFrom, CityTo, S, E),
write(S), write([1,2,3]),
isLater(StartTime, S),
isLater(EndTime, E).
1
Why is the second argument to isLater a list?lurker
At one point I had figured S was a list, I didn't realize prolog backtracks as it does when it executes.user1311286
If you pass something that is not a list, it will mismatch, fail, and backtrack. In this case, you have only one isLater clause so it simply fails (there's nothing to backtrack to). You could allow list and non-list cases by adding clauses for each.lurker

1 Answers

1
votes

The program flow inside fly(city1, city2, A, B) goes like this:

  • Call flight(city1, city2, S, E). This comes back with S=9, E=10.
  • Call write(9).
  • Call isLater(A, 9). This fails, because 9 can't be unified with [X|Y], and triggers a backtrack.
  • Backtrack to flight(city1, city2, S, E). This time it returns with S=10, E=11.
  • Call write(10).
  • Again, isLater(A, 10) fails. It can't backtrack any more, since it's tried every alternative for flight(city1, city2, _, _), so at this point, fly fails.

Basically, the problem is that you're writing S before you've decided it's a valid solution, so you end up printing a bunch of non-solutions as well. You probably want to move it after your isLater checks. (The bigger issue here is that isLater is expecting a list, but you're giving it an integer...)

Note that typing flight(city1, city2, A, B). in the console will also return multiple values - after it shows you the first solution, just press ";" (instead of the enter key) to ask for the next one.