% Author: Piotr Holownia % How many times each philosopher needs to eat? number_of_meals(2). % What is the minimum and maximum amount of time for each meal in seconds? minimum_meal_time(3). maximum_meal_time(8). % What is the minimum and maximum amount of time for thinking in seconds? minimum_thinking_time(5). maximum_thinking_time(10). start :- mutex_create(fork1), mutex_create(fork2), mutex_create(fork3), mutex_create(fork4), mutex_create(fork5), number_of_meals(N), thread_create(philosopher(1,N,fork1,fork2),_,[]), thread_create(philosopher(2,N,fork2,fork3),_,[]), thread_create(philosopher(3,N,fork3,fork4),_,[]), thread_create(philosopher(4,N,fork4,fork5),_,[]), thread_create(philosopher(5,N,fork5,fork1),_,[]). philosopher(Number,0,_,_) :- write('The '), write(Number), writeln('. philosopher is NO MORE HUNGRY.'). philosopher(Number,Times,LeftFork,RightFork) :- mutex_lock(display), write('The '), write(Number), writeln('. philosopher is HUNGRY.'), mutex_unlock(display), try_lock_first(LeftFork,RightFork), mutex_lock(display), write('The '), write(Number), writeln('. philosopher has STARTED his meal.'), mutex_unlock(display), % Eating. minimum_meal_time(MinM), maximum_meal_time(MaxM), DiffM is MaxM - MinM, TM is random(DiffM) + MinM, sleep(TM), % Finished eating. mutex_lock(display), write('The '), write(Number), writeln('. philosopher has FINISHED his meal.'), mutex_unlock(display), mutex_unlock(LeftFork), mutex_unlock(RightFork), % Thinking. minimum_thinking_time(MinT), maximum_thinking_time(MaxT), DiffT is MaxT - MinT, TT is random(DiffT) + MinT, sleep(TT), % Finished thinking. NewTimes is Times - 1, philosopher(Number,NewTimes,LeftFork,RightFork). % At least one fork is available try_lock_first(Left,Right) :- mutex_trylock(Left), try_lock_second(Left,Right). % None fork is available. try_lock_first(Left,Right) :- sleep(0.2), try_lock_first(Left,Right). % Both forks are available. try_lock_second(_,Right) :- mutex_trylock(Right). % Only the left fork is available. try_lock_second(Left,Right) :- mutex_unlock(Left), sleep(0.2), try_lock_first(Left,Right).