I have the following facts and rules:
flight(sea,msp).
flight(msp,jfk).
route(A,B) :- flight(A,B).
route(B,A) :- flight(A,B).
route(A,C) :- flight(A,B) , flight(B,C).
when query for route(sea,jfk)
I get a result true
but what I wish to get is the explination:
sea-->msp-->jfk
this way I can tell not only that it's true but also how it's true.
The true is a prompt to allow you to find out if this is so - i.e. that the query can be proven in more than one way. Type a semicolon if you want Prolog to go ahead and look for a different proof. Press "return" if you are happy with a single proof.
The concept of logical negation in Prolog is problematical, in the sense that the only method that Prolog can use to tell if a proposition is false is to try to prove it (from the facts and rules that it has been told about), and then if this attempt fails, it concludes that the proposition is false.
The notation [X|Y] refers to a list whose first element is X and whose tail is Y.
As EMS and Chac explained this number denotes number of arguments. The reason why you will find this number in documentation is because predicates with same name and different arity (number of arguments) are different predicates.
So you want to get from A
to B
, but not only that, you also want to know the list of stations of your itinerary.
Be sure to carefully look at the following two related questions and the answers proposed to the question:
The meta-predicates presented in above links allow you to delegate the handling of recursion to a solid, tested, reusable component. More time to focus on other parts of the problem solving!
You keep track of what nodes in your graph that you've already visited. You need to do this anyway, as you need to detect cycles in your graph lest you fall into the rabbit hole of infinite recursion.
And in Prolog, we use helper methods that carry state around as 1 or more extra arguments. A frequently used convention is to have a "public" predicate — say route/3
that invokes a "private" worker predicate having the same name with a higher arity, say route/4
. Something like this ought to do you:
route( A , B , R ) :- % find a route R from A to B
route(A,B,[],R) % - by invoking a worker, seeding its list of visited nodes with the empty list
. % Easy!
route(B,B,V,R) :- % we've arrived at the destination (B) when the origination node is the same as the destination node.
reverse([B|V],R) % - just reverse the list of visited nodes to get the routing.
. %
route(A,B,V,R) :- % otherwise...
flight(A,T) , % - if there's an edge out of the current node (A) ,
\+ member(T,V) , % - to an as-yet unvisited node...
route(T,B,[A|V],R) % - go visit that node, marking the current node as visited.
. % Easy!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With