----------------------------------------------- | | | Wiltshire | Berkshire | Surrey | Kent | | | | Hampshire | Sussex | ________________________________________ In the following Prolog definitions, there are three predicates - border, adjacent, and affordable: The predicate border is a fact, expressing that there is a border between Sussex and Kent, Sussex and Surrey, etc. The predicates adjacent and affordable are rules, expressed with the symbol :- X is adjacent to Y if there exists a border between X and Y. A journey is affordable from X to Y if X is adjacent to some country Z and country Z is adjacent to Y. NOTE: In Prolog, variables begin with an uppercase letter, such as X and Y. non-variables begin with a lowercase letter, such as sussex and kent. border(sussex,kent). border(sussex,surrey). border(surrey,kent). border(hampshire,sussex). border(hampshire,surrey). border(hampshire,berkshire). border(berkshire,surrey). border(wiltshire,hampshire). border(wiltshire,berkshire). adjacent(X,Y) :- border(X,Y). adjacent(X,Y) :- border(Y,X). affordable(X,Y) :- adjacent(X,Z), adjacent(Z,Y).
Assignment, Part 1:
?- consult(journey). This assumes the program file is 'journey.pl'
?-affordable(wiltshire,sussex). ?-affordable(wiltshire,kent). ?-affordable(hampshire,hampshire). ?-affordable(X,kent). ?-affordable(sussex,X). ?-affordable(X,Y).
a ------> b -----> c | \ ^ | \ | | ---> f <--- | ^ | V / | e --------------- | | | V | d <---- g --------> h ---The following Prolog facts represent the directed graph above.
The predicate path is used to define a search method for this graph.
This definition for path is an example of a recursive definition in Prolog.
As in any language, the recursive definition is split into two basic parts, a non-recursive base case
and a recursive portion that must lead eventually to the base case in order to stop the recursion.
path(X,X). is a fact stating that there is a path from any node X to itself.
This is the base case or stopping condition for the recursive definition.
path(X,Y) :- a(X,Z), path(Z,Y). is a rule meaning that there exists
a path from node X to node Y if there exists a directed path from X to another
node Z, and there is a path from node Z to the goal node Y.
This is the recursive portion of the definition. If the base case, path(X,X), is never reached, an 'infinite' loop occurs.
a(g,h). a(g,d). a(e,d). a(h,f). a(e,f). a(a,e). a(a,b). a(b,f). a(b,c). a(f,c). path(X,X). path(X,Y) :- a(X,Z), path(Z,Y).Assignment Part 2:
?-path(f,f). ?-path(a,c). ?-path(g,e). ?-path(g,X). ?-path(X,h).
Here's an example list with 4 elements: [john,george,paul,ringo]
Accessing a list is accomplished by separating the list into the head of the list - the first element,
and the tail of the list - the rest of the list after the first element.
Note that, in general, the tail of a list is always a list.
The Prolog notation: [X|T] separates a list into the head, X, and tail, T.
Remember that X and T are variable names; you can use any word beginning with a capital letter.
For example, you could use [First | Rest] to split the list. In this case, First represents
the first element and Rest represents the rest of the list after the first element.
See the definition of member below. The first portion, member(X,[X|T]) is the non-recursive base case.
This states: X is a member of the list having X as the first element.
The recursive portion of the definition is member(X,[H|T]) :- member(X,T).
This reads as follows: if the first case is not 'satisfied', if X is not the first element of the list,
then X is a member of the list [H|T] if X is a member of T.
In other words, X is a member of a list if
1. it is not the first element and
2. it is a member of the Rest of the list.
Prolog has something called an anonymous variable, represented by an underscore '_'.
This is a variable that you don't care about, so you don't need to name.
Anonymous variables are used when a variable appears only once in a definition and do not co-refer with any other variable in the definition.
Using the anonymous variable, member can be defined alternatively as:
member(X,[X|_]). member(X,[_|T]) :- member(X,T).Here's a definition using variables throughout:
member(X,[X|T]). member(X,[H|T]) :- member(X,T).
Assignment Part 3:
What do the following goals do (what is the first answer if any,
and then what are
the subsequent answers if any on backtracking?
Implementing backtracking: after the Prolog system responds to your query,
use a semicolon to find moreanswers, if any.
Press return if you don't want any more answers. Prolog is using a built in
bactracking system to generate multiple answers. The semicolon in Prolog means "or".
Find the responses of the following queries (after you have loaded the program with consult(member)
(assuming you have named the file member.pl
?-member(john,[paul,john]). ?-member(X,[paul,john]). ?-member(joe,[marx,darwin,freud]). ?-member(foo,X).
Add this definition to your file, and 'consult' again.
mystery(X,A,B) :- member(X,A), member(X,B).
Assignment part 4:
What do the following goals do?
?-mystery(a,[b,c,a],[p,a,l]). ?-mystery(b,[b,l,u,e],[y,e,l,l,o,w]). ?-mystery(X,[r,a,p,i,d],[a,c,t,i,o,n]). ?-mystery(X,[w,a,l,n,u,t],[c,h,e,r,r,y]).