I figured if you can travel from a place by car, train or plane, it should return true.
And that another condition would be that if you can travel from X to Y by car, train or plane, and then from Y to Z by by car, train or plane, it should also return true.
Unfortunately this does not work. What am I doing wrong?
Your travel predicate has a maximum length of 2 trips, so it cannot find the much longer journey of valmont to raglan. If you calculate how to get from valmont to raglan by hand, you will see the journey is : valmont->saarbruecken->frankfurt->singapore->auckland->hamiltion->raglan which is 6 trips.
Strangely you named the topic recursive travel, yet your travel definition is not recursive
When I think about traversing graphs I think of a start node O and then a series of connector with a node, -O. So a path would be O-O, or O-O-O-O, etc. In other words you start with O, then recursively add -O.
The recursive predicate above is O-O, when it should be -O
Here is the code I used to solve the problem.
The big change for this code is that it passes a state variable around to hold the path, e.g. Path0, Path1,Path. Since the real work is done by a predicate needing two variables to hold the state variables, and the query only needs one variable to return the path, the predicate with two variables is a helper predicate and the query predicate calls the helper predicate.
The other big change is that there needs to be a way to avoid adding a city to the path if you have already been to that city, i.e. \+ member((_,Y),Path0)
Many here do not speak English as a native language and so using such phrases/metaphors might cause them confusion. I myself use such phrases/metaphors often but when I do I find the definition that explains it so the others are not confused.
Sorry, it is not considered as a difficult word in my language (I am not a native English speaker either) so I did not think about that.
It is a cusine term and means put your vegetable in a sauce overnight. By extension, thinking/pondering a long time over an idea.
\+ is logical not. e.g.
if the predicate result is true then use not true, which is false.
if the predicate result is false then use not false, which is true.
member((_,Y),Path0). can be understood as follows.
Path0 will look like [(start, valmont), (car, saarbruecken), (train, frankfurt), (plane, bangkok)] which is a list.
Each item in the list will be (Mode, Location) and (_,Y) is a pattern to match against each item in the list. member/2 will do the matching of the pattern against each item in the list.
Y is the Location, e.g. valmont, most recently added to the end of the list, so member((_,Y),Path0) reads the predicate is true when the the Location in Y is the same as any Location in Path0. Which means that if the last location added matches any in the current path then the result is true. But \+ is not so, when the last location added already exist in the list is found, then the line \+ member((_,Y),Path0) will return false and the entire clause will fail.
The details can be seen by using trace/0 with protocol/1 as noted in the earlier post. Here I will just explain the details without showing the code or the trace.
The predicate travel_01_helper/4 is entered on the first line with the first three arguments bound, so [(Mode,Y)|Path0] is not fully bound but, Y and Path0 are bound because they were bound when the predicate was entered.
Next there are thee possibilities for the next statement because of the use of ;. When one of the three predicates, e.g. byCar(X,Y) succeeds/returns true, then the next predicate is called, e.g. Mode = car and via unification =/2, the unbound variable Mode is bound to the value.
In the example Mode = car, =/2 is used as an infix operator as opposed to a prefix operator.
Can you please elaborate (=explain more). Why would the whole close fail if we happened to already have traversed Valmont? Could we not have traversed Valmont by car to Amsterdam, and later in the list traversed Valmont again but by plane, to Hambourg?
Also, which English words am I supposed to explain? What is the rule of thumb?