Plus some notes on what you have learned.
. . . . . . . . . ( end of section Introduction) <<Contents | Index>>
go.You can edit f in the program to change the function from squaring to cubing:
f(X,Y):- Y is X*X*X.Then exit the editor and see if the binary search will find cube roots. How about fourth roots?
Problems: I just typed it in and haven't checked it for errors.
Write simple Prolog queries that will detect some of the possible errors that I might have made:
Can you fix the data base?
X=1;X=2;X=3....and so we can solve simple word problems by writing searches: What digit has a square of 9?
member(X,[1,2,3,4,5,6,7,8,9,0]), X*X =:= 9.
What digit has a square of 3?
member(X,[1,2,3,4,5,6,7,8,9,0]), X^2 =:= 3.
How about looking for a solution of an equation:
member(X,[1,2,3,4,5,6,7,8,9,0]), X^2-11*X+28=:=0.
But the following fails.... why?
member(X,[1,2,3,4,5,6,7,8,9,0]), X^2-11*X+28=0.
You can also search for two digits:
member(X,[1,2,3,4,5,6,7,8,9,0]),member(Y,[1,2,3,4,5,6,7,8,9,0]), X^2+Y^2 =:= 10 *X+1.What two digit numbers does this find?
Explore other simple arithmetic puzzles based on the digits.
% s(N,SN) - given a positive non zero integer number N, SN=1+2+...+N
s(1,1).
s(N,SN ) :- N > 1, N1 is N-1, s(N1, SN1), SN is SN1 + N.
s(N, _ ) :- N < 1, print('Error in s1'), nl, fail.
Can you write a predicate that adds up a different series: sum of squares, for example?
Download it, and consult it, and then
go(More).Be ready for a long delay....
Of course there is a better algorithm. If you study what the program does you'll notice that it spends a lot of time generating digits and rejecting them here:
row(X,Y,Z):-d(X),d(Y), X=\=Y, d(Z),X=\=Z, Y=\=Z, X+Y+Z=:=15.Here it keeps trying different Zs until it finds one (if any) that fits the last calculation. It would be faster to calculate a single Z instead of using trial-an-error:
row(X,Y,Z):-d(X),d(Y), X=\=Y, Z is 15-X-Y, X=\=Z, Y=\=Z.Similarly, once the first two rows have been found in a 3><3 magic square it is easy to calculate the bottom row. Here [ magic3.plg ] is the improved program. Is it faster? Does it produce the same squares?
Write a file 'cones.plg' that defines all my favorite scoop(Flavor).
scoop(chocolate).
scoop(vanilla).
scoop(strawberry).Compile, run and test it with:
scoop(Top).(and don't forget to tap ';' to ask for each cone in turn.)
Then try two scoops of ice-cream.
scoop(Top),scoop(Bottom).(and don't forget to tap ';' to ask for each cone in turn.) Now try the following simple Prolog loop....
scoop(Top),write(Top),nl,fail.Notice how we put fail at the end of the loop, because it forces Prolog to go back and find the next alternative, and in the above, the scoop provides a choice point with 3 alternatives. 'fail' take Prolog back to the last choice point to look for another alternative... and if there are none it backtracks to the next previous choice point.
We can use the same technique with two scoops... to generate all combinations:
scoop(Top),scoop(Bottom),write(Top+Bottom),nl,fail.Also notice that we can use + in the output.... because Prolog will write X+Y without evaluating it!
Edit your 'cones.plg' file so that it defines a predicate cone(Top, Middle, Bottom) that chooses a Top, Middle and Bottom Scoop.
cone(Top, Middle, Botttom):-scoop(Top), scoop(Middle). scoop(Bottom).Compile and run. Test it like this:
cone(Top,Middle,Bottom),
write(Top+Middle+Bottom),nl,fail.
Prolog has some high-level commands for handling list, sets, and "bags". (A bag can have elements that occur several times). The bagof(Term, Condition, Bag) predicate is built into our Prolog and assembles a list in Bag of all Terms that fit the Condition. Load your 'cones.plg' into Prolog and try the following:
bagof(X, scoop(X), Scoops).
bagof(X+Y, (scoop(X), scoop(Y)), Scoops).You can count the number of cones easily by using the length(List, Length) predicate:
bagof(A+B+C, cone(A,B,C), Cones), length(Cones, Number_cones).You can add a definition of count to your cones.plg program:
count(N):-bagof(A+B+C, cone(A,B,C), Cones), length(Cones, N).
Modify the program to count the cones must have three different flavors.
How about 4 scoops?
. . . . . . . . . ( end of section Combinatorics) <<Contents | Index>>
Can you see how it records some information on 3 students?
Notice the clever use of Prolog operators to encode grades:
cs320=a: A grade of A in CS320
cs320+b: A grade of B+ in CS320
cs320-c: A grade of C- in CS320(This may not be a good idea... but it shows you that in Prolog you can make expressions mean anything you want).
load_students.
list_students.
save_students.
admit(Student_number, Student_name).
dismiss(Student_number, Student_name).Notice it also needs you to have download [ students.plg ] first.
Run the ar.plg program, load the students, list them, add a new student with number 9999 and name 'Joe Coyote', list the result, and save the students. Quit Prolog and look at the result.
Study how the program is written. Notice the unfriendly user interface. Notice how simple the resulting code is. This is just a prototype to check out the algorithms and data structures, not a finished program.
consult('ar.plg').
load_students.to get the data online.
Add student with number 9999 and name 'Joe Coyote'. Hint. [ Admissions and Records ] above.
Give him the grade of a in cs125.
grade(9999, cs125=a).List the student records. Give Joe a grade of B+ in cs201 (cs201+b), and list the result.
Give Joe a grade of A- in CS320, and check the result...
If this works, study the code and then try some other experiments. Can you improve it?
. . . . . . . . . ( end of section A Prototype Student Data Base) <<Contents | Index>>
function(square(X),X*X).You can then see how '=', 'is', and 'es' differ:
Y = square(3).
Y is square(3).
Y es square(3).You can add a new function to the definitions by asserting it:
assert(function( cube(X), X*X*X)).or like this:
assert((function( abs(X), X) :- X>=0))).
assert((function( abs(X), Y) :- X<0, Y is -X))).
Experiment with adding new functions.
n/das a fraction with numerator n and denominator d. This shows how the ADT(class) of rational numbers is declared and can be used.
When you look at the code, notice that 'ram' is essentially a function that converts the names of variables into values. So the code must make sure that there is never more than one value for any variable.
The file also needs you to download [ functions.plg ] so that the 'let' command will work.
It uses two special Prolog functors 'assert' and 'retract' to store and retrieve values in a array called ram.
Here is a set of tests.
set(x,1)
print_ram.
set(x,3)
print_ram.
set(y,2)
print_ram.
let(z,x+y).
print_ram.
Can you add more featrues of an imperative language?
Load the bad solution and investigate why and how it fails, using trace to help. What are the problems?
Later I produced [ lotto93.plg ] that seems to have the problem licked by using a smarter idea and a way to express a 'for loop' in Prolog.
Can you model another paradox in Prolog?
qsort(Given_list, Variable_result).
Can you program a merge or selection sort?
help(sort).
help(setof).or trying out [ setof.plg ]
. . . . . . . . . ( end of section More sample Programs) <<Contents | Index>>
element(Name, _, Number1), element(Name, _, Number2), Number1=\=Number2.
. . . . . . . . . ( end of section CS620 Prolog Examples) <<Contents | Index>>