Introduction to Lisp for ACS 340
Total Page:16
File Type:pdf, Size:1020Kb
Prolog Introduction, Part Two
Remember that we’re learning by doing. Start up prolog and do all of the exercises in this handout. All files for Prolog practice will be located in ~mecalif/public/itk340/prolog_examples.
Some Practice Start by looking at the file family.pl (in the prolog_examples directory). It defines parent relationships, male and female properties, and some rules for family relationships.
Start sicstus and type in each query below in bold. The plain text is simply comments intended to enhance understanding.
| ?- consult('~mecalif/public/itk340/prolog_examples/family.pl'). ignore the warnings. I’ll explain them later. % For the queries below, write the response prolog gives you
| ?- parent(bob, pat).
| ?- parent(liz, pat).
| ?- parent(tom, ben).
| ?- parent(X, liz). % after the response here, just hit return
| ?- parent(bob, X). % try typing a semi-colon and enter after the first response
| ?- parent(X,Y). % try getting all possible results for this query % The following are conjunctive queries
| ?- parent(Y, jim), parent(X, Y). % X is the grandparent of jim
| ?- parent(tom, X), parent(X, Y). % The Ys will be Tom’s grandchildren
| ?- offspring(liz,tom).
| ?- mother(X, bob).
| ?- grandparent(tom, X).
| ?- sister(X, ann).
| ?- hasachild(X). % Note that we’ve used a rule to create a property
Try It Out Try writing the following predicates: happy/1: happy(X) should be true if X has a child
grandchild/2: define a grandchild relation using the parent relation—your definition should be similar to the definition for grandparent/2 aunt/2: define an aunt relation in terms of parent and sister (don’t worry about aunts by marriage—only by blood)
Write your predicates in a file, consult the file (along with the family.pl file) and try them out. You may need to add some additional facts to try them out much.
Recursion Take a look at the ancestor predicate in family.pl. This is a fairly standard example of a recursive predicate in Prolog.
Type a query using the ancestor predicate that will tell you who Pam’s descendants are.
Try writing your own descendants relation, also recursive, using only the parent relation. Data Objects Prolog has several different types of data objects: constants, variables, and structures. Like Lisp, Prolog has two kinds of constants: atoms and numbers.
Atoms: 1) Strings of letters, digits and the underscore character starting with a lowercase letter Examples: anna nil x25 x_25AB x_ miss_Jones 2) Strings of special characters (be careful here, since many have a pre-defined meaning (like ‘:-’) 3) Strings of characters enclosed in single quotes (which allows us to have atoms that being with capital letters or include blanks, etc.): ‘Tom’ ‘South_America’ ‘Sarah Jones’
Numbers:
Numbers come in two flavors, integer and real, and follow fairly typical rules. Real numbers are seldom used in Prolog, primarily because Prolog is seldom used for number- crunching.
Variables:
As we have discussed, variables in Prolog begin with either a capital letter or an underscore character. The single underscore character is a special variable called an anonymous variable. It should be used when a variable appears only once in a clause. When the anonymous variable appears more than once, each occurrence denotes a different variable. The scope of a variable in Prolog is always one clause.
Remember that variables in Prolog are logic variables, not memory locations. Once the variable is bound (given a value), that value cannot be changed (unless the current proof fails and you backtrack over the variable binding).
Structures:
Structures are used much like the structures of C, to combine smaller items into a single object. However, in Prolog we don’t have to define a structure type; we just use the objects. Example: date(17, january, 2000)
The date is called the functor, and 17, january, and 2000 are arguments. We can use structures in Prolog to naturally represent many kinds of data. As you might expect we can embed structures as deeply as we like. Variables can be unified with entire structure or with components of structures.
Matching or unification:
One of the important computational mechanisms of Prolog is unification, or matching of terms. Two terms match if they are identical or a substitution exists that will make them be identical.
Try it out.
| ?- date(D, M, 2000) = date(D1, january, Y1).
| ?- date(D, M, 2000) = date(D1, january, Y1), date(D, M, 2000) = date(17, M, Y).
Let’s look at the power of matching. Consider that we have a structure point, which has two arguments, each numbers. The suppose we have a structure line_seg, which has two arguments, both points. So line_seg represents a line segment in two-dimensional space.
Suppose we want to be able to recognize vertical and horizontal line segments. We can write unary predicates that are true of vertical or horizontal line segments.
% vertical(Seg) % a line segment is vertical if its x-coordinates are the same. vertical(seg(point(X,Y), point(X, Y1))).
% horizontal(Seg) % a line segment is horizontal if its y-coordinates are the same. horizontal(seg(point(X, Y), point(X1, Y))). Consult the handout4.pl file and try these out:
| ?- vertical(seg(point(1, 1), point(1, 2))).
| ?- vertical(seg(point(1, 1), point(2, Y))).
| ?- horizontal(seg(point(1, 1), point(2, Y))).
| ?- vertical(seg(point(2, 3), P)).
| ?- vertical(S), horizontal(S).
Think about how these might relate to things like location in the Wumpus World.