42aabce1bb
git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1973 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
278 lines
6.1 KiB
Plaintext
278 lines
6.1 KiB
Plaintext
|
|
:- category(chopstick).
|
|
|
|
:- info([
|
|
version is 2.0,
|
|
author is 'Paulo Moura',
|
|
date is 2007/3/19,
|
|
comment is 'Dining philosophers problem: chopstick representation.']).
|
|
|
|
:- public(pick_up/0).
|
|
:- mode(pick_up, zero_or_one).
|
|
:- info(pick_up/0, [
|
|
comment is 'A Philosopher picks up the chopstick.']).
|
|
|
|
:- public(put_down/0).
|
|
:- mode(put_down, zero_or_one).
|
|
:- info(put_down/0, [
|
|
comment is 'A Philosopher puts down the chopstick.']).
|
|
|
|
% chopstick actions (picking up and putting down) are synchronized using a notification
|
|
% such that a chopstick can only be handled by a single philosopher at a time:
|
|
|
|
pick_up :-
|
|
threaded_wait(available).
|
|
|
|
put_down :-
|
|
threaded_notify(available).
|
|
|
|
:- end_category.
|
|
|
|
|
|
:- object(cs1,
|
|
imports(chopstick)).
|
|
|
|
:- threaded.
|
|
:- initialization(threaded_notify(available)).
|
|
|
|
:- end_object.
|
|
|
|
|
|
:- object(cs2,
|
|
imports(chopstick)).
|
|
|
|
:- threaded.
|
|
:- initialization(threaded_notify(available)).
|
|
|
|
:- end_object.
|
|
|
|
|
|
:- object(cs3,
|
|
imports(chopstick)).
|
|
|
|
:- threaded.
|
|
:- initialization(threaded_notify(available)).
|
|
|
|
:- end_object.
|
|
|
|
|
|
:- object(cs4,
|
|
imports(chopstick)).
|
|
|
|
:- threaded.
|
|
:- initialization(threaded_notify(available)).
|
|
|
|
:- end_object.
|
|
|
|
|
|
:- object(cs5,
|
|
imports(chopstick)).
|
|
|
|
:- threaded.
|
|
:- initialization(threaded_notify(available)).
|
|
|
|
:- end_object.
|
|
|
|
|
|
:- category(philosopher).
|
|
|
|
:- info([
|
|
version is 2.0,
|
|
author is 'Paulo Moura',
|
|
date is 2007/1/3,
|
|
comment is 'Dining philosophers problem: philosopher representation.']).
|
|
|
|
:- public(left_chopstick/1).
|
|
:- mode(left_chopstick(?object_identifier), zero_or_one).
|
|
:- info(left_chopstick/1, [
|
|
comment is 'Chopstick at the left of a philosopher.',
|
|
argnames is ['Chopstick']]).
|
|
|
|
:- public(right_chopstick/1).
|
|
:- mode(right_chopstick(?object_identifier), zero_or_one).
|
|
:- info(right_chopstick/1, [
|
|
comment is 'Chopstick at the right of a philosopher.',
|
|
argnames is ['Chopstick']]).
|
|
|
|
:- public(run/2).
|
|
:- mode(run(+integer, +integer), one).
|
|
:- info(run/2, [
|
|
comment is 'Runs Count number of thinking/eating cycles, with each activity taking MaxTime (in seconds).',
|
|
argnames is ['Count', 'MaxTime']]).
|
|
|
|
:- private(message/1).
|
|
:- synchronized(message/1).
|
|
:- mode(message(+list), one).
|
|
:- info(message/1, [
|
|
comment is 'Writes all the terms on a list as an atomic operation.',
|
|
argnames is ['Atoms']]).
|
|
|
|
:- uses(random, [random/3]).
|
|
|
|
run(0, _) :-
|
|
this(Philosopher),
|
|
message([Philosopher, ' terminated.']).
|
|
|
|
run(Count, MaxTime) :-
|
|
Count > 0,
|
|
think(MaxTime),
|
|
eat(MaxTime),
|
|
Count2 is Count - 1,
|
|
run(Count2, MaxTime).
|
|
|
|
think(MaxTime):-
|
|
this(Philosopher),
|
|
random(1, MaxTime, ThinkTime),
|
|
message(['Philosopher ', Philosopher, ' thinking for ', ThinkTime, ' seconds.']),
|
|
thread_sleep(ThinkTime).
|
|
|
|
eat(MaxTime):-
|
|
this(Philosopher),
|
|
random(1, MaxTime, EatTime),
|
|
::left_chopstick(LeftStick),
|
|
::right_chopstick(RightStick),
|
|
LeftStick::pick_up,
|
|
RightStick::pick_up,
|
|
message(['Philosopher ', Philosopher, ' eating for ', EatTime, ' seconds with chopsticks ', LeftStick, ' and ', RightStick, '.']),
|
|
thread_sleep(EatTime),
|
|
::LeftStick::put_down,
|
|
::RightStick::put_down.
|
|
|
|
% writing a message needs to be synchronized as it's accomplished
|
|
% using a combination of individual write/1 and nl/0 calls:
|
|
message([]) :-
|
|
nl,
|
|
flush_output.
|
|
message([Atom| Atoms]) :-
|
|
write(Atom),
|
|
message(Atoms).
|
|
|
|
:- end_category.
|
|
|
|
|
|
:- object(p1,
|
|
imports(philosopher)).
|
|
|
|
left_chopstick(cs1).
|
|
right_chopstick(cs2).
|
|
|
|
:- end_object.
|
|
|
|
|
|
:- object(p2,
|
|
imports(philosopher)).
|
|
|
|
left_chopstick(cs2).
|
|
right_chopstick(cs3).
|
|
|
|
:- end_object.
|
|
|
|
|
|
:- object(p3,
|
|
imports(philosopher)).
|
|
|
|
left_chopstick(cs3).
|
|
right_chopstick(cs4).
|
|
|
|
:- end_object.
|
|
|
|
|
|
:- object(p4,
|
|
imports(philosopher)).
|
|
|
|
left_chopstick(cs4).
|
|
right_chopstick(cs5).
|
|
|
|
:- end_object.
|
|
|
|
|
|
:- object(p5,
|
|
imports(philosopher)).
|
|
|
|
left_chopstick(cs1). % change order so that the chopsticks are picked
|
|
right_chopstick(cs5). % in different order from the other philosophers
|
|
|
|
:- end_object.
|
|
|
|
|
|
:- object(philosopher(_Philosopher, _LeftChopstick, _RightShopstick)).
|
|
|
|
:- info([
|
|
version is 2.0,
|
|
author is 'Paulo Moura',
|
|
date is 2007/1/3,
|
|
comment is 'Dining philosophers problem: philosopher representation.']).
|
|
|
|
:- public(left_chopstick/1).
|
|
:- mode(left_chopstick(?object_identifier), zero_or_one).
|
|
:- info(left_chopstick/1, [
|
|
comment is 'Chopstick at the left of a philosopher.',
|
|
argnames is ['Chopstick']]).
|
|
|
|
:- public(right_chopstick/1).
|
|
:- mode(right_chopstick(?object_identifier), zero_or_one).
|
|
:- info(right_chopstick/1, [
|
|
comment is 'Chopstick at the right of a philosopher.',
|
|
argnames is ['Chopstick']]).
|
|
|
|
:- public(run/2).
|
|
:- mode(run(+integer, +integer), one).
|
|
:- info(run/2, [
|
|
comment is 'Runs Count number of thinking/eating cycles, with each activity taking MaxTime (in seconds).',
|
|
argnames is ['Count', 'MaxTime']]).
|
|
|
|
:- private(message/1).
|
|
:- synchronized(message/1).
|
|
:- mode(message(+list), one).
|
|
:- info(message/1, [
|
|
comment is 'Writes all the terms on a list as an atomic operation.',
|
|
argnames is ['Atoms']]).
|
|
|
|
:- uses(random, [random/3]).
|
|
|
|
left_chopstick(LeftStick) :-
|
|
parameter(2, LeftStick).
|
|
|
|
rigth_chopstick(RightStick) :-
|
|
parameter(3, RightStick).
|
|
|
|
run(0, _) :-
|
|
parameter(1, Philosopher),
|
|
message([Philosopher, ' terminated.']).
|
|
|
|
run(Count, MaxTime) :-
|
|
Count > 0,
|
|
think(MaxTime),
|
|
eat(MaxTime),
|
|
Count2 is Count - 1,
|
|
run(Count2, MaxTime).
|
|
|
|
think(MaxTime):-
|
|
random(1, MaxTime, ThinkTime),
|
|
parameter(1, Philosopher),
|
|
message(['Philosopher ', Philosopher, ' thinking for ', ThinkTime, ' seconds.']),
|
|
thread_sleep(ThinkTime).
|
|
|
|
eat(MaxTime):-
|
|
random(1, MaxTime, EatTime),
|
|
parameter(2, LeftStick),
|
|
parameter(3, RightStick),
|
|
LeftStick::pick_up,
|
|
RightStick::pick_up,
|
|
parameter(1, Philosopher),
|
|
message(['Philosopher ', Philosopher, ' eating for ', EatTime, ' seconds with chopsticks ', LeftStick, ' and ', RightStick, '.']),
|
|
thread_sleep(EatTime),
|
|
::LeftStick::put_down,
|
|
::RightStick::put_down.
|
|
|
|
% writing a message needs to be synchronized as it's accomplished
|
|
% using a combination of individual write/1 and nl/0 calls:
|
|
message([]) :-
|
|
nl,
|
|
flush_output.
|
|
message([Atom| Atoms]) :-
|
|
write(Atom),
|
|
message(Atoms).
|
|
|
|
:- end_object.
|