| 
									
										
										
										
											2007-02-19 19:05:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-24 13:27:35 +00:00
										 |  |  | :- object(buffer(_MaxCapacity)). | 
					
						
							| 
									
										
										
										
											2007-02-19 19:05:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-24 13:27:35 +00:00
										 |  |  | 	:- info([ | 
					
						
							| 
									
										
										
										
											2007-11-06 01:50:09 +00:00
										 |  |  | 		version is 2.1, | 
					
						
							| 
									
										
										
										
											2007-06-24 13:27:35 +00:00
										 |  |  | 		author is 'Paulo Moura', | 
					
						
							| 
									
										
										
										
											2007-11-06 01:50:09 +00:00
										 |  |  | 		date is 2007/9/16, | 
					
						
							| 
									
										
										
										
											2007-06-24 13:27:35 +00:00
										 |  |  | 		comment is 'Producer-consumer problem with a bounded buffer.']). | 
					
						
							| 
									
										
										
										
											2007-02-19 19:05:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-24 13:27:35 +00:00
										 |  |  | 	:- threaded. | 
					
						
							| 
									
										
										
										
											2007-02-19 19:05:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-24 13:27:35 +00:00
										 |  |  | 	:- public(put/1). | 
					
						
							|  |  |  | 	:- mode(put(?integer), one). | 
					
						
							|  |  |  | 	:- info(put/1, [ | 
					
						
							|  |  |  | 		comment is 'Put an item in the buffer.']). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	:- public(get/1). | 
					
						
							|  |  |  | 	:- mode(get(?integer), one). | 
					
						
							|  |  |  | 	:- info(get/1, [ | 
					
						
							|  |  |  | 		comment is 'Get an item from the buffer.']). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	:- private(item_/1). | 
					
						
							|  |  |  | 	:- dynamic(item_/1). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	:- private(size_/1). | 
					
						
							|  |  |  | 	:- dynamic(size_/1). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	size_(0). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-06 01:50:09 +00:00
										 |  |  | 	:- synchronized([put_item/1, get_item/1]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	put_item(Item) :- | 
					
						
							|  |  |  | 		parameter(1, MaxCapacity), | 
					
						
							|  |  |  | 		assertz(item_(Item)), | 
					
						
							|  |  |  | 		retract(size_(N)), | 
					
						
							|  |  |  | 		N2 is N + 1, | 
					
						
							|  |  |  | 		assertz(size_(N2)), | 
					
						
							|  |  |  | 		write(' produced item '), write(Item), | 
					
						
							|  |  |  | 		write(' ('), write(N2), write('/'), write(MaxCapacity), write(' items in the buffer'), write(')'), nl. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	get_item(Item) :- | 
					
						
							|  |  |  | 		parameter(1, MaxCapacity), | 
					
						
							|  |  |  | 		retract(item_(Item)), | 
					
						
							|  |  |  | 		retract(size_(N)), | 
					
						
							|  |  |  | 		N2 is N - 1, | 
					
						
							|  |  |  | 		assertz(size_(N2)), | 
					
						
							|  |  |  | 		write(' consumed item '), write(Item), | 
					
						
							|  |  |  | 		write(' ('), write(N2), write('/'), write(MaxCapacity), write(' items in the buffer'), write(')'), nl. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-24 13:27:35 +00:00
										 |  |  | 	put(Item) :- | 
					
						
							|  |  |  | 		parameter(1, MaxCapacity), | 
					
						
							|  |  |  | 		size_(N), | 
					
						
							|  |  |  | 		(	N =:= MaxCapacity ->		% if the maximum buffer capacity have been | 
					
						
							|  |  |  | 			threaded_wait(vacancy),		% reached, wait until an item is consumed | 
					
						
							|  |  |  | 			put(Item)					% be sure to consume all "vacancy" notifications before proceeding | 
					
						
							|  |  |  | 		;	put_item(Item), | 
					
						
							|  |  |  | 			(	N =:= 0 -> | 
					
						
							|  |  |  | 				threaded_notify(not_empty) | 
					
						
							|  |  |  | 			;	true | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 		). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	get(Item) :- | 
					
						
							|  |  |  | 		parameter(1, MaxCapacity), | 
					
						
							|  |  |  | 		size_(N), | 
					
						
							|  |  |  | 		(	N =:= 0 ->					% if the buffer is empty, wait | 
					
						
							|  |  |  | 			threaded_wait(not_empty),	% until an item is produced | 
					
						
							|  |  |  | 			get(Item)					% be sure to consume all "not_empty" notifications before proceeding | 
					
						
							|  |  |  | 		;	get_item(Item), | 
					
						
							|  |  |  | 			(	N =:= MaxCapacity -> | 
					
						
							|  |  |  | 				threaded_notify(vacancy) | 
					
						
							|  |  |  | 			;	true | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 		). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-02-19 19:05:42 +00:00
										 |  |  | :- end_object. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-24 13:27:35 +00:00
										 |  |  | :- object(producer(_MaxTime)). | 
					
						
							| 
									
										
										
										
											2007-02-19 19:05:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	:- public(run/1). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	run(N) :- | 
					
						
							|  |  |  | 		run(0, N). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	run(N, N) :- !. | 
					
						
							|  |  |  | 	run(M, N) :- | 
					
						
							|  |  |  | 		M < N, | 
					
						
							| 
									
										
										
										
											2007-06-24 13:27:35 +00:00
										 |  |  | 		parameter(1, MaxTime), | 
					
						
							|  |  |  | 		random::random(1, MaxTime, Random),	% simulate a variable amount of  | 
					
						
							|  |  |  | 		thread_sleep(Random),				% time to produce a new item | 
					
						
							|  |  |  | 		buffer(7)::put(M), | 
					
						
							| 
									
										
										
										
											2007-02-19 19:05:42 +00:00
										 |  |  | 		M2 is M + 1, | 
					
						
							|  |  |  | 		run(M2, N). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :- end_object. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-24 13:27:35 +00:00
										 |  |  | :- object(consumer(_MaxTime)). | 
					
						
							| 
									
										
										
										
											2007-02-19 19:05:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	:- public(run/1). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	run(N) :- | 
					
						
							|  |  |  | 		run(0, N). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	run(N, N) :- !. | 
					
						
							|  |  |  | 	run(M, N) :- | 
					
						
							|  |  |  | 		M < N, | 
					
						
							| 
									
										
										
										
											2007-06-24 13:27:35 +00:00
										 |  |  | 		parameter(1, MaxTime), | 
					
						
							|  |  |  | 		random::random(1, MaxTime, Random),	% simulate a variable amount of  | 
					
						
							|  |  |  | 		thread_sleep(Random),				% time to produce a new item | 
					
						
							|  |  |  | 		buffer(7)::get(_Item), | 
					
						
							| 
									
										
										
										
											2007-02-19 19:05:42 +00:00
										 |  |  | 		M2 is M + 1, | 
					
						
							|  |  |  | 		run(M2, N). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :- end_object. |