Add ch04, start working on ch05.
This commit is contained in:
		
							parent
							
								
									50dbc5f0c0
								
							
						
					
					
						commit
						5f9633349c
					
				| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
## Some basic syntax
 | 
					## Chapter 1: Some basic syntax
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
property(name).
 | 
					property(name).
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
## Unification
 | 
					## Chapter 2: Unification
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Two terms unify if they are
 | 
					Two terms unify if they are
 | 
				
			||||||
1. The same term
 | 
					1. The same term
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
## Recursion
 | 
					## Chapter 3: Recursion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Recursive definitions require that the recursive function isn't the first
 | 
					Recursive definitions require that the recursive function isn't the first
 | 
				
			||||||
clause, ex:
 | 
					clause, ex:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,60 @@
 | 
				
			||||||
 | 
					%% Exercises from chapter 4
 | 
				
			||||||
 | 
					%%
 | 
				
			||||||
 | 
					%% Exercise 4.3 Write a predicate second(X,List) which checks whether X is the
 | 
				
			||||||
 | 
					%% second element of List .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					second(X, [_, X|_]).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% Exercise 4.4 Write a predicate swap12(List1,List2) which checks whether
 | 
				
			||||||
 | 
					%% List1 is identical to List2 , except that the first two elements are
 | 
				
			||||||
 | 
					%% exchanged.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					swap12([X,Y|T], [Y,X|T]).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% Exercise  4.5 Suppose we are given a knowledge base with the following
 | 
				
			||||||
 | 
					%% facts:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tran(eins,one).
 | 
				
			||||||
 | 
					tran(zwei,two).
 | 
				
			||||||
 | 
					tran(drei,three).
 | 
				
			||||||
 | 
					tran(vier,four).
 | 
				
			||||||
 | 
					tran(fuenf,five).
 | 
				
			||||||
 | 
					tran(sechs,six).
 | 
				
			||||||
 | 
					tran(sieben,seven).
 | 
				
			||||||
 | 
					tran(acht,eight).
 | 
				
			||||||
 | 
					tran(neun,nine).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% Write a predicate listtran(G,E) which translates a list of German number
 | 
				
			||||||
 | 
					%% words to the corresponding list of English number words. For example:
 | 
				
			||||||
 | 
					%%     listtran([eins,neun,zwei],X).
 | 
				
			||||||
 | 
					%% should give:
 | 
				
			||||||
 | 
					%%     X  =  [one,nine,two].
 | 
				
			||||||
 | 
					%% Your program should also work in the other direction. For example, if you give it the query
 | 
				
			||||||
 | 
					%%     listtran(X,[one,seven,six,two]).
 | 
				
			||||||
 | 
					%% it should return:
 | 
				
			||||||
 | 
					%%     X  =  [eins,sieben,sechs,zwei].
 | 
				
			||||||
 | 
					%% (Hint: to answer this question, first ask yourself “How do I translate the
 | 
				
			||||||
 | 
					%% empty list of number words?”. That’s the base case. For non-empty lists, first
 | 
				
			||||||
 | 
					%% translate the head of the list, then use recursion to translate the tail.)
 | 
				
			||||||
 | 
					listtran([], []).
 | 
				
			||||||
 | 
					listtran([X|TX], [Y|TY]) :-
 | 
				
			||||||
 | 
						tran(X, Y),
 | 
				
			||||||
 | 
						listtran(TX, TY).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% Exercise 4.6 Write a predicate twice(In,Out) whose left argument is a list,
 | 
				
			||||||
 | 
					%% and whose right argument is a list consisting of every element in the left
 | 
				
			||||||
 | 
					%% list written twice. For example, the query
 | 
				
			||||||
 | 
					%%     twice([a,4,buggle],X).
 | 
				
			||||||
 | 
					%% should return
 | 
				
			||||||
 | 
					%%     X  =  [a,a,4,4,buggle,buggle]).
 | 
				
			||||||
 | 
					%% And the query
 | 
				
			||||||
 | 
					%%     twice([1,2,1,1],X).
 | 
				
			||||||
 | 
					%% should return
 | 
				
			||||||
 | 
					%%     X  =  [1,1,2,2,1,1,1,1].
 | 
				
			||||||
 | 
					%% (Hint: to answer this question, first ask yourself “What should happen when
 | 
				
			||||||
 | 
					%% the first argument is the empty list?”. That’s the base case. For non-empty
 | 
				
			||||||
 | 
					%% lists, think about what you should do with the head, and use recursion to
 | 
				
			||||||
 | 
					%% handle the tail.)
 | 
				
			||||||
 | 
					twice([], []).
 | 
				
			||||||
 | 
					twice([X|T1], [X,X|T2]) :-
 | 
				
			||||||
 | 
						twice(T1, T2).
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					member(X, [X|_]).
 | 
				
			||||||
 | 
					member(X, [_|T]) :- member(X, T).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					memberr(X, X).
 | 
				
			||||||
 | 
					memberr(X, [X|_]).
 | 
				
			||||||
 | 
					memberr(X, [[H|T1]|T2]) :-
 | 
				
			||||||
 | 
						memberr(X, H);
 | 
				
			||||||
 | 
						memberr(X, T1);
 | 
				
			||||||
 | 
						memberr(X, T2).
 | 
				
			||||||
 | 
					memberr(X, [_|T]) :- member(X, T).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sameLen([], []).
 | 
				
			||||||
 | 
					sameLen([_|TA], [_|TB]) :- sameLen(TA, TB).
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,30 @@
 | 
				
			||||||
 | 
					## Chapter 4: Lists
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Lists are enclosed in square brackets, and are finite sequences of elements.
 | 
				
			||||||
 | 
					Elements can be anything: `[mia, robber(yolanda), X, 2, mia]` or `[mia,
 | 
				
			||||||
 | 
					[vincent, jules], [butch, girlfriend(butch)]]` --- a list can contain other
 | 
				
			||||||
 | 
					lists.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Prolog lists use the standard head/tail vocabulary, and the decomposition operator is `|`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					[Head|Tail] = [mia,  [vincent,  jules],  [butch,  girlfriend(butch)]]
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note that the empty list behaves as one would think.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					 ?-  [X|Y]  =  [].
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					   no 
 | 
				
			||||||
 | 
					````
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Arguments can be chained, such as `[X, Y | Z]`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### The `member` function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					member(X, [X|_]).
 | 
				
			||||||
 | 
					member(X, [_|T]) :- member(X, T).
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,39 @@
 | 
				
			||||||
 | 
					%% 1. Write a 3-place predicate combine1 which takes three lists as arguments
 | 
				
			||||||
 | 
					%% and combines the elements of the first two lists into the third as follows:
 | 
				
			||||||
 | 
					%%
 | 
				
			||||||
 | 
					%%    ?-  combine1([a,b,c],[1,2,3],X).
 | 
				
			||||||
 | 
					%%    
 | 
				
			||||||
 | 
					%%    X  =  [a,1,b,2,c,3]
 | 
				
			||||||
 | 
					%%    
 | 
				
			||||||
 | 
					%%    ?-  combine1([f,b,yip,yup],[glu,gla,gli,glo],Result).
 | 
				
			||||||
 | 
					%%    
 | 
				
			||||||
 | 
					%%    Result  =  [f,glu,b,gla,yip,gli,yup,glo]
 | 
				
			||||||
 | 
					combine1([], [], []).
 | 
				
			||||||
 | 
					combine1([X|TX], [Y|TY], [X,Y|TXY]) :- combine1(TX, TY, TXY).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% Now write a 3-place predicate combine2 which takes three lists as arguments
 | 
				
			||||||
 | 
					%% and combines the elements of the first two lists into the third as follows:
 | 
				
			||||||
 | 
					%%
 | 
				
			||||||
 | 
					%%   ?-  combine2([a,b,c],[1,2,3],X).
 | 
				
			||||||
 | 
					%%   
 | 
				
			||||||
 | 
					%%   X  =  [[a,1],[b,2],[c,3]]
 | 
				
			||||||
 | 
					%%   
 | 
				
			||||||
 | 
					%%   ?-  combine2([f,b,yip,yup],[glu,gla,gli,glo],Result).
 | 
				
			||||||
 | 
					%%   
 | 
				
			||||||
 | 
					%%   Result  =  [[f,glu],[b,gla],[yip,gli],[yup,glo]]
 | 
				
			||||||
 | 
					combine2([], [], []).
 | 
				
			||||||
 | 
					combine2([X|TX], [Y|TY], [[X, Y]|TXY]) :- combine2(TX, TY, TXY).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% Finally, write a 3-place predicate combine3 which takes three lists as
 | 
				
			||||||
 | 
					%% arguments and combines the elements of the first two lists into the third
 | 
				
			||||||
 | 
					%% as follows:
 | 
				
			||||||
 | 
					%%
 | 
				
			||||||
 | 
					%%   ?-  combine3([a,b,c],[1,2,3],X).
 | 
				
			||||||
 | 
					%%   
 | 
				
			||||||
 | 
					%%   X  =  [j(a,1),j(b,2),j(c,3)]
 | 
				
			||||||
 | 
					%%   
 | 
				
			||||||
 | 
					%%   ?-  combine3([f,b,yip,yup],[glu,gla,gli,glo],R).
 | 
				
			||||||
 | 
					%%   
 | 
				
			||||||
 | 
					%%   R  =  [j(f,glu),j(b,gla),j(yip,gli),j(yup,glo)] 
 | 
				
			||||||
 | 
					combine3([], [], []).
 | 
				
			||||||
 | 
					combine3([X|TX], [Y|TY], [j(X,Y)|TXY]) :- combine3(TX, TY, TXY).
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					len([], 0).
 | 
				
			||||||
 | 
					len([_|T], N) :-
 | 
				
			||||||
 | 
						len(T, X),
 | 
				
			||||||
 | 
						N is X+1.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					alen_([], A, A).
 | 
				
			||||||
 | 
					alen_([_|H], A, L) :-
 | 
				
			||||||
 | 
						A2 is A+1,
 | 
				
			||||||
 | 
						alen_(H, A2, L).
 | 
				
			||||||
 | 
					alen(X, L) :- alen_(X, 0, L).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					max([], N, N).
 | 
				
			||||||
 | 
					max([H|T], N, M) :-
 | 
				
			||||||
 | 
						H > N,
 | 
				
			||||||
 | 
						max(T, H, M).
 | 
				
			||||||
 | 
					max([H|T], N, M) :-
 | 
				
			||||||
 | 
						H =< N,
 | 
				
			||||||
 | 
						max(T, N, M).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					max([H|T], N) :-
 | 
				
			||||||
 | 
						max(T, H, N).
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,24 @@
 | 
				
			||||||
 | 
					%% Exercise 5.2
 | 
				
			||||||
 | 
					%% 
 | 
				
			||||||
 | 
					%% 1. Define a 2-place predicate increment that holds only when its second
 | 
				
			||||||
 | 
					%% argument is an integer one larger than its first argument. For example,
 | 
				
			||||||
 | 
					%% increment(4,5) should hold, but increment(4,6) should not.
 | 
				
			||||||
 | 
					increment(A, B) :- B is A+1.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% 2. Define a 3-place predicate sum that holds only when its third argument is
 | 
				
			||||||
 | 
					%% the sum of the first two arguments. For example, sum(4,5,9) should hold, but
 | 
				
			||||||
 | 
					%% sum(4,6,12) should not.
 | 
				
			||||||
 | 
					sum(X, Y, Z) :- Z is X+Y.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% Exercise  5.3
 | 
				
			||||||
 | 
					%%
 | 
				
			||||||
 | 
					%% Write a predicate addone/2 whose first argument is a list of integers, and
 | 
				
			||||||
 | 
					%% whose second argument is the list of integers obtained by adding 1 to each
 | 
				
			||||||
 | 
					%% integer in the first list. For example, the query
 | 
				
			||||||
 | 
					%%     ?-  addone([1,2,7,2],X).
 | 
				
			||||||
 | 
					%% should give
 | 
				
			||||||
 | 
					%%     X  =  [2,3,8,3].
 | 
				
			||||||
 | 
					addone([], []).
 | 
				
			||||||
 | 
					addone([X|TX], [Y|TY]) :-
 | 
				
			||||||
 | 
						Y is X+1,
 | 
				
			||||||
 | 
						addone(TX, TY).
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,74 @@
 | 
				
			||||||
 | 
					## Chapter 5: Arithmetic in Prolog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Prolog provides basic arithmetic operators.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Ex.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					  ?-  8  is  6+2.
 | 
				
			||||||
 | 
					   yes
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					   ?-  12  is  6*2.
 | 
				
			||||||
 | 
					   yes
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					   ?-  -2  is  6-8.
 | 
				
			||||||
 | 
					   yes
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					   ?-  3  is  6/2.
 | 
				
			||||||
 | 
					   yes
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					   ?-  1  is  mod(7,2).
 | 
				
			||||||
 | 
					   yes 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   ?- X is 12/4.
 | 
				
			||||||
 | 
					   X = 3.
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The operators don't actually do arithmetic:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					?- X = 2 + 3.
 | 
				
			||||||
 | 
					X = 2+3.
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The default is just to do unification; `is` must be used. The arithmetic
 | 
				
			||||||
 | 
					expression must be on the RHS. This part of Prolog is a black box that
 | 
				
			||||||
 | 
					handles this, and isn't part of the normal KB and unification parts.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Arithmetic and lists
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A recursive list length calculator:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					len([], 0).
 | 
				
			||||||
 | 
					len([_|T], N) :-
 | 
				
			||||||
 | 
						len(T, X),
 | 
				
			||||||
 | 
						N is X+1.
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A tail-recursive length calculator:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					alen_([], A, A).
 | 
				
			||||||
 | 
					alen_([_|H], A, L) :-
 | 
				
			||||||
 | 
						A2 is A+1,
 | 
				
			||||||
 | 
						alen_(H, A2, L).
 | 
				
			||||||
 | 
					alen(X, L) :- alen_(X, 0, L).
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Standard notes about tail recursion efficiency apply here.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Comparing integers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* *x < y* → `X < Y.`
 | 
				
			||||||
 | 
					* *x ≤ y* → `X =< Y.`
 | 
				
			||||||
 | 
					* *x = y* → `X =:= Y.`
 | 
				
			||||||
 | 
					* *x ≠ y* → `X =\= Y.`
 | 
				
			||||||
 | 
					* *x ≥ y* → `X >= Y`
 | 
				
			||||||
 | 
					* *x > y* → `X > Y`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note the difference between `=` and `=:=`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Let's write a `max` function:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,54 @@
 | 
				
			||||||
 | 
					%% Chapter 5 practical session
 | 
				
			||||||
 | 
					%%
 | 
				
			||||||
 | 
					%% The purpose of Practical Session 5 is to help you get familiar with Prolog’s
 | 
				
			||||||
 | 
					%% arithmetic capabilities, and to give you some further practice in list
 | 
				
			||||||
 | 
					%% manipulation. To this end, we suggest the following programming exercises:
 | 
				
			||||||
 | 
					%% 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% 1. In the text we discussed the 3-place predicate accMax which returned the
 | 
				
			||||||
 | 
					%% maximum of a list of integers. By changing the code slightly, turn this into
 | 
				
			||||||
 | 
					%% a 3-place predicate accMin which returns the minimum of a list of integers.
 | 
				
			||||||
 | 
					min([], N, N).
 | 
				
			||||||
 | 
					min([H|T], N, M) :-
 | 
				
			||||||
 | 
						H < N,
 | 
				
			||||||
 | 
						min(T, H, M).
 | 
				
			||||||
 | 
					min([H|T], N, M) :-
 | 
				
			||||||
 | 
						H >= N,
 | 
				
			||||||
 | 
						min(T, N, M).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					min([H|T], N) :-
 | 
				
			||||||
 | 
						min(T, H, N).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% 2. In mathematics, an n-dimensional vector is a list of numbers of length n.
 | 
				
			||||||
 | 
					%% For example, [2,5,12] is a 3-dimensional vector, and [45,27,3,-4,6] is a
 | 
				
			||||||
 | 
					%% 5-dimensional vector. One of the basic operations on vectors is scalar
 | 
				
			||||||
 | 
					%% multiplication . In this operation, every element of a vector is multiplied
 | 
				
			||||||
 | 
					%% by some number. For example, if we scalar multiply the 3-dimensional vector
 | 
				
			||||||
 | 
					%% [2,7,4] by 3 the result is the 3-dimensional vector [6,21,12] .
 | 
				
			||||||
 | 
					%% 
 | 
				
			||||||
 | 
					%% Write a 3-place predicate scalarMult whose first argument is an integer,
 | 
				
			||||||
 | 
					%% whose second argument is a list of integers, and whose third argument is the
 | 
				
			||||||
 | 
					%% result of scalar multiplying the second argument by the first. For example,
 | 
				
			||||||
 | 
					%% the query
 | 
				
			||||||
 | 
					%%    ?-  scalarMult(3,[2,7,4],Result).
 | 
				
			||||||
 | 
					%% should yield
 | 
				
			||||||
 | 
					%%    Result  =  [6,21,12]
 | 
				
			||||||
 | 
					scalarMult(_, [], []).
 | 
				
			||||||
 | 
					scalarMult(K, [H|T], R) :-
 | 
				
			||||||
 | 
						V is K * H, 
 | 
				
			||||||
 | 
						scalarMult(K, T, [R|V]).
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% 3. Another fundamental operation on vectors is the dot product. This
 | 
				
			||||||
 | 
					%% operation combines two vectors of the same dimension and yields a
 | 
				
			||||||
 | 
					%% number as a result. The operation is carried out as follows: the
 | 
				
			||||||
 | 
					%% corresponding elements of the two vectors are multiplied, and the
 | 
				
			||||||
 | 
					%% results added. For example, the dot product of [2,5,6] and [3,4,1] is
 | 
				
			||||||
 | 
					%% 6+20+6 , that is, 32 . Write a 3-place predicate dot whose first
 | 
				
			||||||
 | 
					%% argument is a list of integers, whose second argument is a list of
 | 
				
			||||||
 | 
					%% integers of the same length as the first, and whose third argument is
 | 
				
			||||||
 | 
					%% the dot product of the first argument with the second. For example,
 | 
				
			||||||
 | 
					%% the query
 | 
				
			||||||
 | 
					%%    ?-  dot([2,5,6],[3,4,1],Result).
 | 
				
			||||||
 | 
					%% should yield
 | 
				
			||||||
 | 
					%%    Result  =  32
 | 
				
			||||||
		Loading…
	
		Reference in New Issue