Logtalk 2.29.1 files.

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1744 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
pmoura
2006-12-28 13:03:34 +00:00
parent 7316eb490c
commit d79dd807e6
301 changed files with 6700 additions and 998 deletions

View File

@@ -1,6 +1,6 @@
=================================================================
Logtalk - Object oriented extension to Prolog
Release 2.28.2
Release 2.29.1
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
=================================================================
@@ -9,5 +9,5 @@ Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
This folder contains some examples of multi-threading programming.
Multi-threading programming is only supported on some Prolog compilers.
Currently this includes SWI-Prolog and YAP. Moreover, multi-threading
is turned off by default. In order to run the examples, you will need
may be turned off by default. In order to run the examples, you may need
to first turn on multi-threading support on the Prolog config files.

View File

@@ -1,6 +1,6 @@
=================================================================
Logtalk - Object oriented extension to Prolog
Release 2.28.2
Release 2.29.1
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
=================================================================

View File

@@ -1,18 +1,12 @@
=================================================================
Logtalk - Object oriented extension to Prolog
Release 2.28.2
Release 2.29.1
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
=================================================================
% start by loading the "event_handlersp" protocol:
| ?- logtalk_load(library(event_handlersp)).
...
% now you are ready for loading the example:
% load the example:
| ?- logtalk_load(birthdays(loader)).
...

View File

@@ -1,11 +1,11 @@
:- object(agent,
implements(event_handlersp)).
implements(monitoring)).
:- info([
version is 1.0,
author is 'Peter Robinson and Paulo Moura',
date is 2006/04/09,
version is 1.2,
author is 'Paulo Moura and Peter Robinson',
date is 2006/12/27,
comment is 'Simple multi-threading example with agents and their birthdays.']).
:- threaded.
@@ -57,34 +57,42 @@
comment is 'New friend, watch out for his/her birthday.',
argnames is ['Name']]).
% new agents are created as threaded objects:
new(Name, Age, Gender) :-
this(This),
create_object(Name, [extends(This)], [threaded], [age(Age), gender(Gender)]).
% ask a friend's age using an asynchronous message:
ask_age(Friend, Age) :-
threaded_call(Friend::age(Age)),
threaded_exit(Friend::age(Age)).
% getting older:
birthday :-
::retract(age(Old)),
New is Old + 1,
::assertz(age(New)).
% when someone congratulate us for our birthday, acknowledge it,
% and offer her/him a slice of the birthday cake:
happy_birthday(From) :-
self(Self),
write('Happy birthday from '), write(From), write('!'), nl,
write('Thanks! Here, have a slice of cake, '), write(From), write('.'), nl,
threaded_call(From::cake_slice(Self), [noreply]).
threaded_ignore(From::cake_slice(Self)).
% be nice, give thanks for the cake offer:
cake_slice(From) :-
write('Thanks for the cake '), write(From), write('!'), nl.
% whatch out for our new friend anniversary:
new_friend(Friend) :-
self(Self),
define_events(after, Friend, birthday, _, Self).
% congratule a friend for his/her birthday:
after(Friend, birthday, _) :-
self(Self),
threaded_call(Friend::happy_birthday(Self), [noreply]).
threaded_ignore(Friend::happy_birthday(Self)).
:- end_object.

View File

@@ -1,6 +1,6 @@
=================================================================
Logtalk - Object oriented extension to Prolog
Release 2.28.2
Release 2.29.1
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
=================================================================

View File

@@ -1,6 +1,6 @@
=================================================================
Logtalk - Object oriented extension to Prolog
Release 2.28.2
Release 2.29.1
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
=================================================================

View File

@@ -2,9 +2,9 @@
:- protocol(find_rootp).
:- info([
version is 1.0,
date is 2006/4/21,
author is 'Paulo Nunes',
version is 1.1,
author is 'Paulo Moura and Paulo Nunes',
date is 2006/11/26,
comment is 'Default protocol for root find algorithms.']).
:- public(find_root/5).
@@ -25,9 +25,9 @@
:- protocol(functionp).
:- info([
version is 1.0,
date is 2006/4/21,
author is 'Paulo Nunes',
version is 1.1,
author is 'Paulo Moura and Paulo Nunes',
date is 2006/11/26,
comment is 'Default protocol for real functions of a single real variable.']).
:- public(eval/2).
@@ -93,9 +93,9 @@
implements(find_rootp)).
:- info([
version is 1.0,
date is 2006/4/21,
author is 'Paulo Nunes',
version is 1.1,
author is 'Paulo Moura and Paulo Nunes',
date is 2006/11/26,
comment is 'Multi-threading interface to root finding algorithms.']).
:- threaded.
@@ -104,7 +104,7 @@
find_root(Function, A, B, Error, Zero, _).
find_root(Function, A, B, Error, Zero, Algorithm) :-
threaded_call(
threaded_race(
( try_method(bisection, Function, A, B, Error, Zero)
; try_method(newton, Function, A, B, Error, Zero)
; try_method(muller, Function, A, B, Error, Zero)
@@ -121,9 +121,9 @@
implements(find_rootp)).
:- info([
version is 1.0,
date is 2006/4/21,
author is 'Paulo Nunes',
version is 1.1,
author is 'Paulo Moura and Paulo Nunes',
date is 2006/11/26,
comment is 'Bisection algorithm.']).
find_root(Function, A, B, Error, Zero) :-
@@ -163,9 +163,9 @@
implements(find_rootp)).
:- info([
version is 1.0,
date is 2006/4/21,
author is 'Paulo Nunes',
version is 1.1,
author is 'Paulo Moura and Paulo Nunes',
date is 2006/11/26,
comment is 'Newton algorithm.']).
find_root(Function, Xa, Xb, Deviation, Zero) :-
@@ -203,9 +203,9 @@
implements(find_rootp)).
:- info([
version is 1.0,
date is 2006/4/21,
author is 'Paulo Nunes',
version is 1.1,
author is 'Paulo Moura and Paulo Nunes',
date is 2006/11/26,
comment is 'Muller algorithm.']).
find_root(Function, Xa, Xb, Deviation, Zero) :-

View File

@@ -1,6 +1,6 @@
=================================================================
Logtalk - Object oriented extension to Prolog
Release 2.28.2
Release 2.29.1
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
=================================================================

View File

@@ -1,6 +1,6 @@
=================================================================
Logtalk - Object oriented extension to Prolog
Release 2.28.2
Release 2.29.1
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
=================================================================
@@ -27,3 +27,18 @@ X = 1 ;
X = 2 ;
X = 3 ;
no
% make a threaded call by commiting to the first solution found:
| ?- threaded_once(lists::member(X, [1,2,3])).
X = _G189
yes
% retrieve through backtracking the goal solution:
| ?- threaded_exit(lists::member(X, [1,2,3])).
X = 1 ;
no

View File

@@ -0,0 +1,12 @@
=================================================================
Logtalk - Object oriented extension to Prolog
Release 2.29.1
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
=================================================================
To load this example and for sample queries, please see the SCRIPT file.
This folder contains a Logtalk implementation of the classical "dining
philosophers" multi-threading problem.

View File

@@ -0,0 +1,114 @@
=================================================================
Logtalk - Object oriented extension to Prolog
Release 2.29.1
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
=================================================================
% start by loading the necessary library support files:
| ?- logtalk_load(library(random_loader)).
...
% now you are ready for loading the example:
| ?- logtalk_load(philosophers(loader)).
...
% five meals for each philosopher, each one spending a maximum of five seconds of continuous thinking or eating:
| ?- threaded_ignore(p1::run(5, 5)), threaded_ignore(p2::run(5, 5)), threaded_ignore(p3::run(5, 5)), threaded_ignore(p4::run(5, 5)), threaded_ignore(p5::run(5, 5)).
Yes
Philosopher p3 thinking for 1 seconds.
Philosopher p1 thinking for 2 seconds.
Philosopher p2 thinking for 3 seconds.
Philosopher p4 thinking for 4 seconds.
Philosopher p5 thinking for 3 seconds.
Philosopher p3 eating for 2 seconds with chopsticks cs3 and cs2.
Philosopher p1 eating for 3 seconds with chopsticks cs5 and cs1.
Philosopher p2 thinking for 3 seconds.
Philosopher p3 thinking for 2 seconds.
Philosopher p5 thinking for 1 seconds.
Philosopher p4 eating for 1 seconds with chopsticks cs4 and cs3.
Philosopher p5 thinking for 1 seconds.
Philosopher p1 thinking for 3 seconds.
Philosopher p4 thinking for 1 seconds.
Philosopher p3 eating for 2 seconds with chopsticks cs3 and cs2.
Philosopher p5 eating for 2 seconds with chopsticks cs5 and cs4.
Philosopher p2 thinking for 3 seconds.
Philosopher p4 thinking for 2 seconds.
Philosopher p3 thinking for 2 seconds.
Philosopher p5 thinking for 1 seconds.
Philosopher p1 eating for 3 seconds with chopsticks cs5 and cs1.
Philosopher p4 eating for 4 seconds with chopsticks cs4 and cs3.
Philosopher p5 thinking for 1 seconds.
Philosopher p2 thinking for 1 seconds.
Philosopher p3 thinking for 4 seconds.
Philosopher p5 thinking for 2 seconds.
Philosopher p2 thinking for 4 seconds.
Philosopher p1 thinking for 1 seconds.
Philosopher p5 thinking for 1 seconds.
Philosopher p4 thinking for 4 seconds.
Philosopher p1 eating for 1 seconds with chopsticks cs5 and cs1.
Philosopher p5 thinking for 3 seconds.
Philosopher p3 eating for 2 seconds with chopsticks cs3 and cs2.
Philosopher p1 thinking for 3 seconds.
Philosopher p2 thinking for 4 seconds.
Philosopher p3 thinking for 3 seconds.
Philosopher p5 eating for 4 seconds with chopsticks cs5 and cs4.
Philosopher p4 thinking for 3 seconds.
Philosopher p1 thinking for 4 seconds.
Philosopher p2 eating for 1 seconds with chopsticks cs1 and cs2.
Philosopher p3 thinking for 3 seconds.
Philosopher p4 thinking for 3 seconds.
Philosopher p2 thinking for 1 seconds.
Philosopher p5 thinking for 2 seconds.
Philosopher p2 eating for 3 seconds with chopsticks cs1 and cs2.
Philosopher p1 thinking for 4 seconds.
Philosopher p3 thinking for 3 seconds.
Philosopher p5 eating for 2 seconds with chopsticks cs5 and cs4.
Philosopher p4 thinking for 1 seconds.
Philosopher p4 thinking for 4 seconds.
Philosopher p2 thinking for 1 seconds.
Philosopher p5 thinking for 4 seconds.
Philosopher p1 eating for 4 seconds with chopsticks cs5 and cs1.
Philosopher p2 thinking for 2 seconds.
Philosopher p3 eating for 2 seconds with chopsticks cs3 and cs2.
Philosopher p2 thinking for 3 seconds.
Philosopher p3 thinking for 1 seconds.
Philosopher p4 eating for 1 seconds with chopsticks cs4 and cs3.
Philosopher p5 thinking for 1 seconds.
Philosopher p3 thinking for 4 seconds.
Philosopher p4 thinking for 4 seconds.
Philosopher p1 thinking for 2 seconds.
Philosopher p5 eating for 2 seconds with chopsticks cs5 and cs4.
Philosopher p2 eating for 2 seconds with chopsticks cs1 and cs2.
Philosopher p1 thinking for 3 seconds.
Philosopher p5 thinking for 4 seconds.
Philosopher p2 thinking for 2 seconds.
Philosopher p3 eating for 4 seconds with chopsticks cs3 and cs2.
Philosopher p4 thinking for 2 seconds.
Philosopher p1 eating for 3 seconds with chopsticks cs5 and cs1.
Philosopher p2 thinking for 1 seconds.
Philosopher p4 thinking for 3 seconds.
Philosopher p2 thinking for 1 seconds.
Philosopher p5 thinking for 3 seconds.
p3 terminated.
Philosopher p2 thinking for 3 seconds.
p1 terminated.
Philosopher p4 eating for 3 seconds with chopsticks cs4 and cs3.
Philosopher p5 thinking for 4 seconds.
Philosopher p2 eating for 4 seconds with chopsticks cs1 and cs2.
Philosopher p4 thinking for 4 seconds.
Philosopher p5 eating for 1 seconds with chopsticks cs5 and cs4.
Philosopher p2 thinking for 1 seconds.
p5 terminated.
Philosopher p2 eating for 4 seconds with chopsticks cs1 and cs2.
Philosopher p4 eating for 3 seconds with chopsticks cs4 and cs3.
p4 terminated.
p2 terminated.

View File

@@ -0,0 +1,13 @@
:- initialization(
logtalk_load(
philosophers)).
/*
If you intend to use the FOP XSL:FO processor for generating PDF documenting
files, comment the directive above and uncomment the directive below
:- initialization(
logtalk_load(
philosophers, [xmlsref(standalone)])).
*/

View File

@@ -0,0 +1,235 @@
:- category(chopstick).
:- info([
version is 1.1,
author is 'Paulo Moura',
date is 2006/12/2,
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.']).
:- private(available/0).
:- dynamic(available/0).
:- mode(available, zero_or_one).
:- info(available/0, [
comment is 'Chopstick state (either available or in use).']).
% chopstick actions (picking up and putting down) are synchronized using the same mutext
% such that a chopstick can only be handled by a single philosopher at a time:
:- synchronized([pick_up/0, put_down/0]).
pick_up :-
::available,
::retract(available).
put_down :-
\+ ::available,
::asserta(available).
:- end_category.
:- object(cs1,
imports(chopstick)).
:- dynamic(available/0).
available.
:- end_object.
:- object(cs2,
imports(chopstick)).
:- dynamic(available/0).
available.
:- end_object.
:- object(cs3,
imports(chopstick)).
:- dynamic(available/0).
available.
:- end_object.
:- object(cs4,
imports(chopstick)).
:- dynamic(available/0).
available.
:- end_object.
:- object(cs5,
imports(chopstick)).
:- dynamic(available/0).
available.
:- end_object.
:- category(philosopher).
:- info([
version is 1.0,
author is 'Paulo Moura',
date is 2006/12/2,
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']]).
:- private(random/2).
:- synchronized(random/2).
:- mode(random(+integer, -integer), one).
:- info(random/2, [
comment is 'Ensures synchronized access to the random number generator.',
argnames is ['Limit', 'Random']]).
run(0, _) :-
this(Philosopher),
message([Philosopher, ' terminated.']).
run(Count, MaxTime) :-
think(MaxTime),
( eat(MaxTime) ->
Count2 is Count - 1,
run(Count2, MaxTime)
; run(Count, MaxTime)
).
think(MaxTime):-
this(Philosopher),
random(MaxTime, ThinkTime),
message(['Philosopher ', Philosopher, ' thinking for ', ThinkTime, ' seconds.']),
sleep(ThinkTime).
% deadlock while a philosopher is trying to eat is prevented by putting
% down the first chopstick when picking up the second one fails:
eat(MaxTime):-
this(Philosopher),
random(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, '.']),
sleep(EatTime),
::LeftStick::put_down,
::RightStick::put_down
; ::LeftStick::put_down,
fail
).
% as the "random" library object is not multi-threading aware, we must use a
% synchronized wrap up predicate (random/2) to call the random number generator:
random(Limit, Value) :-
random::random(1, Limit, Value).
% 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)).
:- threaded.
left_chopstick(cs5).
right_chopstick(cs1).
:- end_object.
:- object(p2,
imports(philosopher)).
:- threaded.
left_chopstick(cs1).
right_chopstick(cs2).
:- end_object.
:- object(p3,
imports(philosopher)).
:- threaded.
left_chopstick(cs3).
right_chopstick(cs2).
:- end_object.
:- object(p4,
imports(philosopher)).
:- threaded.
left_chopstick(cs4).
right_chopstick(cs3).
:- end_object.
:- object(p5,
imports(philosopher)).
:- threaded.
left_chopstick(cs5).
right_chopstick(cs4).
:- end_object.

View File

@@ -1,6 +1,6 @@
=================================================================
Logtalk - Object oriented extension to Prolog
Release 2.28.2
Release 2.29.1
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
=================================================================
@@ -9,7 +9,11 @@ Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
To load this example and for sample queries, please see the SCRIPT file.
This folder contains a simple multi-threading example with calculating
prime numbers on a given interval. Try to run the example in single and
prime numbers in a given interval. Try to run the example in single and
multi-processor (or multi-core) computers and compare the results. Most
Prolog compilers allows you to measure the time taken for proving a goal
using proprietary predicates.
Note that this example is meant to show how to use Logtalk multi-threading
predicates, not to illustrate the best solution for finding primes numbers
on a given interval.

View File

@@ -1,6 +1,6 @@
=================================================================
Logtalk - Object oriented extension to Prolog
Release 2.28.2
Release 2.29.1
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
=================================================================

View File

@@ -2,9 +2,9 @@
:- object(primes).
:- info([
version is 1.0,
version is 1.1,
author is 'Paulo Moura',
date is 2006/04/14,
date is 2006/11/26,
comment is 'Simple example for comparing single and multi-threading calculation of prime numbers.']).
:- threaded.

View File

@@ -0,0 +1,19 @@
=================================================================
Logtalk - Object oriented extension to Prolog
Release 2.29.1
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
=================================================================
To load this example and for sample queries, please see the SCRIPT file.
This folder contains a simple multi-threading example illustrating the
use of the "synchronized" predicate directive to cope with methods that
have side-effects.
The object defined in the example source file, "sync.lgt", defines a
predicate named waste_time/0 that is used to delay the execuion of goals
in order to better illustrate the semantics of the "synchronized" predicate
directive. This predicate uses a counter that you might need to adjust,
depending on your Prolog compiler and computer performance.

View File

@@ -0,0 +1,57 @@
=================================================================
Logtalk - Object oriented extension to Prolog
Release 2.29.1
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
=================================================================
% start by loading the loading the example:
| ?- logtalk_load(sync(loader)).
...
% send three asynchronous messages whose corresponding methods perform output operations:
| ?- threaded_ignore(nasty1::io(alpha)), threaded_ignore(nasty1::io(digit)), threaded_ignore(nasty1::io(alpha)).
a0ab1bc2c3ddefef45gg6hh7ii8jkjk9
llmmnnopopqqrrsstztzyyxxwwuv
uv
Yes
% send three asynchronous messages whose corresponding methods perform database updates
% (this may or may not work, most likely will throw an exception):
| ?- threaded_ignore(nasty1::update_db(_)), threaded_ignore(nasty1::update_db(_)), threaded_ignore(nasty1::update_db(_)).
No
% the best solution is to declare predicates that need to be thread synchronized as "synchronized",
% as exemplified in object "nasty2":
| ?- threaded_ignore(nasty2::io(alpha)), threaded_ignore(nasty2::io(digit)), threaded_ignore(nasty2::io(alpha)).
abcdefghijklmnopqrstzyxwuv
0123456789
abcdefghijklmnopqrstzyxwuv
Yes
| ?- threaded_call(nasty2::update_db(_)), threaded_call(nasty2::update_db(_)), threaded_call(nasty2::update_db(_)).
Yes
| ?- threaded_exit(nasty2::update_db(X)), threaded_exit(nasty2::update_db(Y)), threaded_exit(nasty2::update_db(Z)).
X = 1
Y = 2
Z = 3
Yes

View File

@@ -0,0 +1,13 @@
:- initialization(
logtalk_load(
sync)).
/*
If you intend to use the FOP XSL:FO processor for generating PDF documenting
files, comment the directive above and uncomment the directive below
:- initialization(
logtalk_load(
sync, [xmlsref(standalone)])).
*/

View File

@@ -0,0 +1,121 @@
:- object(nasty1).
:- info([
version is 1.1,
author is 'Paulo Moura',
date is 2006/11/26,
comment is 'Simple example for illustrating the problems with lack of thread synchronization when calling methods with side-effects.']).
:- threaded.
:- public(update_db/1).
:- mode(update_db(-integer), one).
:- info(update_db/1, [
comment is 'Perform a database update with a long delay between retracting the old information and asserting the new one.',
argnames is ['New']]).
:- private(db/1).
:- dynamic(db/1).
:- public(io/1).
:- mode(io(+atom), one).
:- info(io/1, [
comment is 'Write some characters to the standard output stream with a long delay between each write operation.',
argnames is ['Chars']]).
db(0).
update_db(New) :-
retract(db(Old)),
waste_time,
New is Old + 1,
waste_time,
assertz(db(New)).
io(alpha) :-
write(a), waste_time, write(b), waste_time, write(c), waste_time, write(d), waste_time, write(e),
write(f), waste_time, write(g), waste_time, write(h), waste_time, write(i), waste_time, write(j),
write(k), waste_time, write(l), waste_time, write(m), waste_time, write(n), waste_time, write(o),
write(p), waste_time, write(q), waste_time, write(r), waste_time, write(s), waste_time, write(t),
write(z), waste_time, write(y), waste_time, write(x), waste_time, write(w), waste_time, write(u),
write(v), nl.
io(digit) :-
write(0), waste_time, write(1), waste_time, write(2), waste_time, write(3), waste_time, write(4),
write(5), waste_time, write(6), waste_time, write(7), waste_time, write(8), waste_time, write(9), nl.
waste_time :-
between(1, 10000, _),
fail.
waste_time.
between(Lower, _, Lower).
between(Lower, Upper, Integer) :-
Lower < Upper,
Next is Lower + 1,
between(Next, Upper, Integer).
:- end_object.
:- object(nasty2).
:- info([
version is 1.1,
author is 'Paulo Moura',
date is 2006/11/26,
comment is 'Simple example for using the "synchronized" predicate directive for multi-threading methods with side-effects.']).
:- threaded.
:- public(update_db/1).
:- synchronized(update_db/1).
:- mode(update_db(-integer), one).
:- info(update_db/1, [
comment is 'Perform a database update with a long delay between retracting the old information and asserting the new one.',
argnames is ['New']]).
:- private(db/1).
:- dynamic(db/1).
:- public(io/1).
:- synchronized(io/1).
:- mode(io(+atom), one).
:- info(io/1, [
comment is 'Write some characters to the standard output stream with a long delay between each write operation.',
argnames is ['Chars']]).
db(0).
update_db(New) :-
retract(db(Old)),
waste_time,
New is Old + 1,
waste_time,
assertz(db(New)).
io(alpha) :-
write(a), waste_time, write(b), waste_time, write(c), waste_time, write(d), waste_time, write(e),
write(f), waste_time, write(g), waste_time, write(h), waste_time, write(i), waste_time, write(j),
write(k), waste_time, write(l), waste_time, write(m), waste_time, write(n), waste_time, write(o),
write(p), waste_time, write(q), waste_time, write(r), waste_time, write(s), waste_time, write(t),
write(z), waste_time, write(y), waste_time, write(x), waste_time, write(w), waste_time, write(u),
write(v), nl.
io(digit) :-
write(0), waste_time, write(1), waste_time, write(2), waste_time, write(3), waste_time, write(4),
write(5), waste_time, write(6), waste_time, write(7), waste_time, write(8), waste_time, write(9), nl.
waste_time :-
between(1, 100000, _),
fail.
waste_time.
between(Lower, _, Lower).
between(Lower, Upper, Integer) :-
Lower < Upper,
Next is Lower + 1,
between(Next, Upper, Integer).
:- end_object.