You are on page 1of 5

Anupam Garg (garga) CMPS203; 04/2006 Assignment 3.

Prolog

Exercises 12.1 - 12.12, 12.17, 12.18. -------------------12.1: A standard method for analyzing logical statements is the truth table: Assigning truth values to elementary statements allows us to determine the truth value of a compound statement, and statements with the same truth tables are logically equivalent. Thus the statement "p and not p" is equivalent to "false" by the following truth table: p false true not p true false p and not p false false false false false

Use truth tables to show that p->q is equivalent to (not p) or q (remember that p->q is false only if p is true and q is false). p true true false false not p false false true true q true false true false not q false true false true p->q true false true true (not p) or q true false true true

-------------------12.2: A tautology is a statement that is always true, no matter what the truth values of its components. Use a truth table to show that false->p is a tautology for any statement p. false false false p true false false->p true true

-------------------12.3: A refutation system is a logical system that proves a statement by assuming it is false and then deriving a contradiction. Show that Horn clause logic with resolution is a refutation system. (Hint: The empty clause is assumed to be false, so a goal <-a is equivalent to a->false. Show that this is equivalent to not(a).) a true false false false false a->false false true not a false true

-------------------12.4: Write the following statements in the first-order predicate calculus: If it is raining or snowing, then there is precipitation. If it is feezing and there is precipitation, then it is snowing. If it is not freezing and there is precipitation, then it is raining. It is snowing.

precipitation ==> raining or snowing. snowing ==> freezing and precipitation. raining ==> not freezing and precipitation. snowing. -------------------12.5: Write the statements in Exercise 12.4 as Prolog clauses, in the order given. What answer does Prolog give when the query "Is it freezing?" The query "Is it raining?" Why? Can you rearrange the clauses so that Prolog can give better answers? :- dynamic precipitation/0, raining/0, snowing/0, freezing/0. precipitation :- raining. precipitation :- snowing. snowing :- freezing, precipitation. raining :- \+ freezing, precipitation. snowing. returns: freezing. no. raining. out of stack. First, prolog answers that it is raining because when we make the query "raining", prolog matches the body with :- "\+ freezing, precipitation". Prolog does not have the inference rules necessary to determine that it is freezing (inferring from the fact that it is snowing). So, "\+ freezing" will yield true, and precipitation will get expanded to raining. This places prolog into an infinite loop (left associative resolution). In order to prevent this, we can rearrange the statements as such: :- dynamic precipitation/0, raining/0, snowing/0, freezing/0. precipitation :- snowing. precipitation :- raining. snowing :- freezing, precipitation. snowing. raining :- \+ freezing, precipitation. returns: freezing. no. raining. yes. These answers are still not correct however. The way to get the answers correct is to either assert the fact that it is snowing, or to give a rule for determining if it is freezing. We could introduce the rule: freezing :- snowing. If it is snowing, it is freezing. Adding this statement to the list, would allow for the correct answers. Likewise, adding: assert(freezing). would yield the correct answers as well. This is because prolog does not have the necessary inference tools to derive that it is freezing from the fact that it is snowing. :- dynamic precipitation/0, raining/0, snowing/0, freezing/0. precipitation :- snowing. precipitation :- raining.

snowing. snowing :- freezing, precipitation. raining :- \+ freezing, precipitation. freezing :- snowing. returns: freezing. yes. raining. no. -------------------12.6: Write the following mathematical definition of the greatest common divisor of two numbers in first-order predicate calculus: the gcd of u and v is that number x such that x divides both u and v, and, given any other number y such that y divides u and v, then y divides x. INCOMPLETE:: -------------------12.7: Translate the definition of the gcd in Exercise 12.6 into Prolog. Compare its efficiency to Euclid's gcd algorithm as given in Figure 12.1. INCOMPLETE:: -------------------12.8: Write the following statement as Prolog clauses: Mammals have four legs and no arms, or two arms and two legs. :- dynamic mammal/1, legs/2, arms/2. mammal(X) :- legs(X,4), arms(X,0). mammal(X) :- legs(X,2), arms(X,2). assert(mammal(horse)). assert(legs(horse,4)). assert(arms(horse,0)). -------------------12.9: Add the statement that a horse is a mammal and that a horse has no arms to the clauses of Exercise 12.8. Can Prolog derive that a horse has four legs? Explain. :- dynamic mammal/1, legs/2, arms/2. mammal(X) :- legs(X,4), arms(X,0). mammal(X) :- legs(X,2), arms(X,2). mammal(horse). arms(horse,0). No, prolog cannot derive that a horse has four legs. This is because there are no rules for prolog to use to determine legs. Prolog will not use inference rules to determine that if a horse is a mammal and it has 0 arms, then it must have 4 legs. It seems this can only be done by explicitly creating rules for the queries we would like: i.e.

:- dynamic mammal/1, legs/2, arms/2. mammal(horse). mammal(X) :- legs(X,4), arms(X,0). mammal(X) :- legs(X,2), arms(X,2). arms(horse,0). legs(X,4) :- mammal(X), arms(X,0). legs(X,2) :- mammal(X), arms(X,2). -------------------12.10: Write Prolog clauses to express the following relationships, given the parent relationship: grandparent, sibling, cousin. grandparent(A,C) :- parent(A,X), parent(X,C). sibling(A,B) :- parent(X,A), parent(X,B), not(A = B). cousin(A,B) :- parent(X,A), parent(Y,B), sibling(X,Y), not(A = B). -------------------12.11: Write a Prolog program to find the last item in a list. lastelem([HEAD | []], HEAD). lastelem([HEAD | TAIL], X) :- lastelem(TAIL, X). -------------------12.12: Write a Prolog program in find the maximum and minimum of a list of numbers. findmaxmin([HEAD | []], HEAD, HEAD). findmaxmin([HEAD | TAIL], MAX, MIN) :- findmaxmin(TAIL, MAX, MIN), HEAD @< MAX, HEAD @> MIN. findmaxmin([MIN | TAIL], MAX, MIN) :- findmaxmin(TAIL, MAX, NEWMIN), NEWMIN @>= MIN, MAX @>= NEWMIN. findmaxmin([MAX | TAIL], MAX, MIN) :- findmaxmin(TAIL, NEWMAX, MIN), NEWMAX @>= MIN, MAX @>= NEWMAX. -------------------12.17: In Prolog it is possible to think of certain clauses as representing tail recursion, in which the final term of a clause is a recursive reference, and a cut is written just before the final term. For example, the gcd clause gcd(U,V,W) :- not(V=0), R is U mod V, !, gcd(V,R,W). can be viewed as being tail-recursive. Explain why this is so. A cut acts by pruning the branches of the search tree produced by a prolog program. The cut instructs prolog to not backtrack for a clause. Putting the cut directly before the last recursive call is like tail recursion because the cut eliminates all backtracking information. Without backtracking, the calling frame is equivalent to being removed from the call stack -- because it is no longer necessary -- allowing the call to return to the caller's caller (tail recursion). -------------------12.18: Write a Prolog program to print all Pythagorean triples (x, y, z) such that 1 <= x < y <= z <= 100. ((x, y, z) is a Pythagorean triple if x * x + y * y = z * z.)

isInt(0). isInt(X) :- isInt(Y), X is Y+1. minus(X,X,0). minus(X,Y,Z) :- X @> 0, TEMP1 is X-1, minus(TEMP1, Y, TEMP2), Z is TEMP2+1. generateTriple(X,Y,Z) :- isInt(TEMP1), minus(TEMP1, X, TEMP2), X @> 0, minus(TEMP2, Y, Z), Y @> 0, Z @> 0, isInRange(X,Y,Z,1,10). isInRange(X,Y,Z,LOW,HIGH) :- LOW @=< X, X @< Y, Y @=< Z, Z @=< HIGH. pythagTriple(X,Y,Z) :- generateTriple(X,Y,Z), X*X + Y*Y =:= Z*Z.