Logtalk 2.30.7 files.

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1973 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
pmoura
2007-11-06 01:50:09 +00:00
parent 6c3aee8c63
commit 42aabce1bb
320 changed files with 2252 additions and 1289 deletions

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================
@@ -8,8 +8,14 @@ Copyright (c) 1998-2007 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 (make sure that you use the
multi-threading versions of these Prolog compilers!). Moreover,
multi-threading 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.
Currently this includes SWI-Prolog, YAP, and XSB CVS (make sure that you
use the multi-threading versions of these Prolog compilers!). Moreover,
multi-threading 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.
Some of the examples try to benchmark single-threaded and multi-threaded
solutions. Depending on the Prolog compiler, the operating-system, and the
computer used, you may need to adjust the size of the problem data in order
to find the threshold where multi-threading solutions begin to outperform
the single-threaded solutions.

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================

View File

@@ -1,4 +1,4 @@
:- initialization((
logtalk_load(library(random_loader), [reload(skip)]),
logtalk_load(library(random_loader), [reload(skip)]), % allow for static binding
logtalk_load(blackboard))).

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================
@@ -14,25 +14,55 @@ Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
% start the producer and the consumer, each one running in its own thread:
| ?- threaded_ignore(producer::run(10)), threaded_ignore(consumer::run(10)).
| ?- threaded_ignore(producer(2)::run(25)), threaded_ignore(consumer(5)::run(25)).
producer wrote item 0
consumer read item 0
producer wrote item 1
consumer read item 1
producer wrote item 2
consumer read item 2
producer wrote item 3
consumer read item 3
producer wrote item 4
consumer read item 4
producer wrote item 5
consumer read item 5
producer wrote item 6
consumer read item 6
producer wrote item 7
consumer read item 7
producer wrote item 8
consumer read item 8
producer wrote item 9
consumer read item 9
produced item 0 (1/7 items in the buffer)
consumed item 0 (0/7 items in the buffer)
produced item 1 (1/7 items in the buffer)
produced item 2 (2/7 items in the buffer)
produced item 3 (3/7 items in the buffer)
produced item 4 (4/7 items in the buffer)
consumed item 1 (3/7 items in the buffer)
produced item 5 (4/7 items in the buffer)
produced item 6 (5/7 items in the buffer)
produced item 7 (6/7 items in the buffer)
consumed item 2 (5/7 items in the buffer)
produced item 8 (6/7 items in the buffer)
consumed item 3 (5/7 items in the buffer)
produced item 9 (6/7 items in the buffer)
consumed item 4 (5/7 items in the buffer)
produced item 10 (6/7 items in the buffer)
consumed item 5 (5/7 items in the buffer)
produced item 11 (6/7 items in the buffer)
produced item 12 (7/7 items in the buffer)
consumed item 6 (6/7 items in the buffer)
produced item 13 (7/7 items in the buffer)
consumed item 7 (6/7 items in the buffer)
produced item 14 (7/7 items in the buffer)
consumed item 8 (6/7 items in the buffer)
produced item 15 (7/7 items in the buffer)
consumed item 9 (6/7 items in the buffer)
produced item 16 (7/7 items in the buffer)
consumed item 10 (6/7 items in the buffer)
produced item 17 (7/7 items in the buffer)
consumed item 11 (6/7 items in the buffer)
produced item 18 (7/7 items in the buffer)
consumed item 12 (6/7 items in the buffer)
produced item 19 (7/7 items in the buffer)
consumed item 13 (6/7 items in the buffer)
produced item 20 (7/7 items in the buffer)
consumed item 14 (6/7 items in the buffer)
produced item 21 (7/7 items in the buffer)
consumed item 15 (6/7 items in the buffer)
produced item 22 (7/7 items in the buffer)
consumed item 16 (6/7 items in the buffer)
produced item 23 (7/7 items in the buffer)
consumed item 17 (6/7 items in the buffer)
produced item 24 (7/7 items in the buffer)
consumed item 18 (6/7 items in the buffer)
consumed item 19 (5/7 items in the buffer)
consumed item 20 (4/7 items in the buffer)
consumed item 21 (3/7 items in the buffer)
consumed item 22 (2/7 items in the buffer)
consumed item 23 (1/7 items in the buffer)
consumed item 24 (0/7 items in the buffer)

View File

@@ -2,21 +2,19 @@
:- object(buffer(_MaxCapacity)).
:- info([
version is 2.0,
version is 2.1,
author is 'Paulo Moura',
date is 2007/6/20,
date is 2007/9/16,
comment is 'Producer-consumer problem with a bounded buffer.']).
:- threaded.
:- public(put/1).
:- dynamic(put/1).
:- mode(put(?integer), one).
:- info(put/1, [
comment is 'Put an item in the buffer.']).
:- public(get/1).
:- dynamic(get/1).
:- mode(get(?integer), one).
:- info(get/1, [
comment is 'Get an item from the buffer.']).
@@ -29,6 +27,26 @@
size_(0).
:- 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.
put(Item) :-
parameter(1, MaxCapacity),
size_(N),
@@ -55,24 +73,6 @@
)
).
:- synchronized([put_item/1, get_item/1]).
put_item(Item) :-
assertz(item_(Item)),
retract(size_(N)),
N2 is N + 1,
assertz(size_(N2)),
sender(Sender),
writeq(Sender), write(' stored item '), write(Item), nl.
get_item(Item) :-
retract(item_(Item)),
retract(size_(N)),
N2 is N - 1,
assertz(size_(N2)),
sender(Sender),
writeq(Sender), write(' consumed item '), write(Item), nl.
:- end_object.

View File

@@ -1,4 +1,4 @@
:- initialization((
logtalk_load(library(random_loader), [reload(skip)]),
logtalk_load(library(random_loader), [reload(skip)]), % allow for static binding
logtalk_load(buffer))).

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================
@@ -14,31 +14,31 @@ Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
% find the roots of some functions using each one of provided methods:
| ?- bisection::find_root(f1, 1.0, 2.3, 1e-15, Zero).
| ?- bisection::find_root(f1, 1.0, 2.3, 1.0e-15, Zero).
Zero = 2.0
yes
| ?- newton::find_root(f1, 1.0, 2.3, 1e-15, Zero).
| ?- newton::find_root(f1, 1.0, 2.3, 1.0e-15, Zero).
Zero = 2.0
yes
| ?- muller::find_root(f1, 1.0, 2.3, 1e-15, Zero).
| ?- muller::find_root(f1, 1.0, 2.3, 1.0e-15, Zero).
Zero = 2.0
yes
| ?- bisection::find_root(f2, 1.0, 1.3, 1e-15, Zero).
| ?- bisection::find_root(f2, 1.0, 1.3, 1.0e-15, Zero).
Zero = 1.25809265664599
yes
| ?- newton::find_root(f2, 1.0, 1.3, 1e-15, Zero).
| ?- newton::find_root(f2, 1.0, 1.3, 1.0e-15, Zero).
Zero = 1.25809265664599
yes
| ?- muller::find_root(f2, 1.0, 1.3, 1e-15, Zero).
| ?- muller::find_root(f2, 1.0, 1.3, 1.0e-15, Zero).
Zero = 1.25809265664599
yes
@@ -46,20 +46,26 @@ yes
% find the roots of some functions running all methods at once using multi-threading:
| ?- function_root::find_root(f1, 1.0, 2.3, 1e-15, Zero, Method).
| ?- function_root::find_root(f1, 1.0, 2.3, 1.0e-15, Zero, Method).
Zero = 2.0
Method = bisection
yes
| ?- function_root::find_root(f2, 1.0, 1.3, 1e-15, Zero, Method).
| ?- function_root::find_root(f2, 1.0, 1.3, 1.0e-15, Zero, Method).
Zero = 1.25809265664599
Method = newton
yes
| ?- function_root::find_root(f3, 0.0, 3.0, 1e-15, Zero, Method).
| ?- function_root::find_root(f3, 0.0, 3.0, 1.0e-15, Zero, Method).
Zero = 1.4142135623731
Method = newton
yes
| ?- function_root::find_root(f4, -1.0, 2.0, 1.0e-15, Zero, Method).
Zero = -8.88178419700125e-16
Method = bisection
yes

View File

@@ -13,15 +13,10 @@
comment is 'Find the root of a function in the interval [A, B] given a maximum aproximation error.',
argnames is ['Function', 'A', 'B', 'Error', 'Zero']]).
:- public(find_root/6).
:- mode(find_root(+object_identifier, +float, +float, +float, -float, -object_identifier), one).
:- info(find_root/6, [
comment is 'Find the root of a function in the interval [A, B] given a maximum aproximation error. Return the method used.',
argnames is ['Function', 'A', 'B', 'Error', 'Zero', 'Method']]).
:- end_protocol.
:- protocol(functionp).
:- info([
@@ -33,18 +28,19 @@
:- public(eval/2).
:- mode(eval(+float, -float), one).
:- info(eval/2, [
comment is 'Calculate the function value.',
comment is 'Calculates the function value.',
argnames is ['X', 'Fx']]).
:- public(evald/2).
:- mode(evald(+float, -float), one).
:- info(evald/2, [
comment is 'Calculate the value of the function derivative.',
comment is 'Calculates the value of the function derivative.',
argnames is ['X', 'DFx']]).
:- end_protocol.
:- object(f1,
implements(functionp)).
@@ -53,12 +49,14 @@
eval(X, Y) :-
Y is X * X - 4.
evald(X, Y) :-
Y is 2 * X.
:- end_object.
:- object(f2,
implements(functionp)).
@@ -74,6 +72,7 @@
:- end_object.
:- object(f3,
implements(functionp)).
@@ -89,41 +88,30 @@
:- end_object.
:- object(function_root,
implements(find_rootp)).
:- info([
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.']).
:- object(f4,
implements(functionp)).
:- threaded.
% x + x^2*sin(2.0/x)
% 0.0
eval(X, Y) :-
Y is X + (X**2)*sin(2.0/X).
find_root(Function, A, B, Error, Zero) :-
find_root(Function, A, B, Error, Zero, _).
find_root(Function, A, B, Error, Zero, Algorithm) :-
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)
)),
threaded_exit(try_method(Algorithm, Function, A, B, Error, Zero)).
try_method(Algorithm, Function, A, B, Error, Zero) :-
Algorithm::find_root(Function, A, B, Error, Zero).
evald(X, Y) :-
Y is 1 + 2*X*sin(2.0/X) - 2*cos(2.0/X).
:- end_object.
:- object(bisection,
implements(find_rootp)).
:- info([
version is 1.1,
version is 1.2,
author is 'Paulo Moura and Paulo Nunes',
date is 2006/11/26,
date is 2007/7/7,
comment is 'Bisection algorithm.']).
find_root(Function, A, B, Error, Zero) :-
@@ -133,19 +121,15 @@
true
; Fa < 0.0, Fb > 0.0
),
X0 is (A + B) / 2,
X0 is (A + B) / 2.0,
Function::eval(X0, F0),
bisection(Function, A, B, X0, F0, Error, Zero).
bisection(_, _, _, Xn1, 0.0, _, Xn1) :-
bisection(_, _, _, Xn, Fn, Error, Xn) :-
abs(Fn) < Error,
!.
bisection(_, Xn1, Xn, _, _, Error, Xn1) :-
abs(Xn1 - Xn) < Error,
!.
bisection(Function, An, Bn, _, _, Error, Zero) :-
Xn1 is (An + Bn) / 2,
Xn1 is (An + Bn) / 2.0,
Function::eval(Xn1, Fn1),
Function::eval(An, FAn),
( Fn1*FAn < 0.0 ->
@@ -159,42 +143,29 @@
:- end_object.
:- object(newton,
implements(find_rootp)).
:- info([
version is 1.1,
author is 'Paulo Moura and Paulo Nunes',
date is 2006/11/26,
version is 1.2,
author is 'Paul Crocker... No More Coffee',
date is 2007/07/06,
comment is 'Newton algorithm.']).
find_root(Function, Xa, Xb, Deviation, Zero) :-
X0 is (Xa + Xb) / 2,
newton(Function, X0, Deviation, Zero).
find_root(Function, Xa, Xb, Deviation, Zero) :-
Ac is (Xb - Xa) / 2,
newton(Function, Xa, Ac, Deviation, Zero).
newton(Function, X0, Deviation, Zero) :-
Xn1 is X0,
Function::eval(Xn1, Fn1),
Function::evald(Xn1, DFn1),
Ac is -(Fn1 / DFn1),
newton(Function, Xn1, Deviation, Fn1, Ac, Zero).
% test deviation
newton(_, Xn1, Deviation, _, Ac, Xn1) :-
abs(Ac) < Deviation,
newton(_, Zero, Ac, Deviation, Zero) :-
abs(Ac) < Deviation,
!.
% test solution
newton(_, Xn1, _, 0.0, _, Xn1) :-
!.
% calc
newton(Function, Xn, Deviation, _, Ac, Zero) :-
Xn1 is Xn + Ac,
Function::eval(Xn1, Fn1),
Function::evald(Xn1, DFn1),
Ac1 is (-(Fn1 / DFn1)),
newton(Function, Xn1, Deviation, Fn1, Ac1, Zero).
newton(Function, X0, Ac, Deviation, Zero):-
Xn1 is X0 + Ac,
Function::eval(Xn1, Fx),
Function::evald(Xn1, DFx),
Ac2 is -(Fx/DFx),
newton(Function, Xn1, Ac2, Deviation, Zero).
:- end_object.
@@ -203,66 +174,90 @@
implements(find_rootp)).
:- info([
version is 1.1,
version is 1.2,
author is 'Paulo Moura and Paulo Nunes',
date is 2006/11/26,
comment is 'Muller algorithm.']).
find_root(Function, Xa, Xb, Deviation, Zero) :-
Xc is (Xa + Xb) / 2,
Xc is (Xa + Xb) / 2.0,
muller(Function, Xa, Xc, Xb, Deviation, Zero).
muller(Function, Xa, Xb, Xc, Deviation, Zero) :-
Function::eval(Xa, Ya),
Function::eval(Xb, Yb),
Function::eval(Xc, Yc),
H1 is (Xb - Xa),
DDba is ((Yb - Ya) / H1),
Ac is (Deviation + 1),
H1 is Xb - Xa,
DDba is (Yb - Ya) / H1,
Ac is Deviation + 1.0,
muller(Function, Xa, Xb, Xc, Deviation, Ya, Yb, Yc, Ac, H1, DDba, Zero).
% complex
muller(_, _, _, complex, _, _, _, _, _, _, _, complex) :-
!.
% test deviation
muller(_, _, _, Xc, Deviation, _, _, _, Ac, _, _, Xc) :-
abs(Ac) < Deviation,
!.
% test solution
muller(_, _, _, Xc, _, _, _, 0.0, _, _, _, Xc) :-
!.
% calc
muller(Function, Xa, Xb, Xc, Deviation, _, Yb, Yc, _, _, DDba, Zero) :-
H2n is (Xc - Xb),
DDcbn is ((Yc - Yb) / H2n),
Cn is ((DDcbn - DDba) / (Xc - Xa)),
Bn is (DDcbn + H2n * Cn),
Rn is (Bn * Bn - 4.0 * Yc * Cn),
% complex
% write(Rn),
H2n is Xc - Xb,
DDcbn is (Yc - Yb) / H2n,
Cn is (DDcbn - DDba) / (Xc - Xa),
Bn is DDcbn + H2n * Cn,
Rn is Bn * Bn - 4.0 * Yc * Cn,
( Rn < 0.0 ->
muller(Function, _, _, complex, Deviation, _, _, _, _, _, _, Zero),
!, fail
fail
; V is sqrt(Rn)
),
( Bn > 0.0 ->
Dn is (Bn + V)
; Dn is (Bn - V)
Dn is Bn + V
; Dn is Bn - V
),
Acn is (-(2 * Yc / Dn)),
Acn is -(2 * Yc / Dn),
Xan is Xb,
Xbn is Xc,
Xcn is Xc + Acn,
Yan is Yb,
Ybn is Yc,
Function::eval(Xcn, Ycn),
H1n is H2n,
DDban is DDcbn,
muller(Function, Xan, Xbn, Xcn, Deviation, Yan, Ybn, Ycn, Acn, H1n, DDban, Zero).
:- end_object.
:- object(function_root,
implements(find_rootp)).
:- info([
version is 2.0,
author is 'Paulo Moura and Paulo Nunes',
date is 2007/07/05,
comment is 'Multi-threading interface to root finding algorithms.']).
:- threaded.
:- public(find_root/6).
:- mode(find_root(+object_identifier, +float, +float, +float, -float, -object_identifier), one).
:- info(find_root/6, [
comment is 'Finds the root of a function in the interval [A, B] given a maximum aproximation error. Returns the method used.',
argnames is ['Function', 'A', 'B', 'Error', 'Zero', 'Method']]).
find_root(Function, A, B, Error, Zero, Algorithm) :-
threaded((
(bisection::find_root(Function, A, B, Error, Zero), Algorithm = bisection)
; (newton::find_root(Function, A, B, Error, Zero), Algorithm = newton)
; (muller::find_root(Function, A, B, Error, Zero), Algorithm = muller)
)).
% an alternative, possibly better definition would be to make the methods simply fail in case of error:
%
% find_root(Function, A, B, Error, Zero, Algorithm) :-
% threaded((
% (catch(bisection::find_root(Function, A, B, Error, Zero), _, fail), Algorithm = bisection)
% ; (catch(newton::find_root(Function, A, B, Error, Zero), _, fail), Algorithm = newton)
% ; (catch(muller::find_root(Function, A, B, Error, Zero), _, fail), Algorithm = muller)
% )).
find_root(Function, A, B, Error, Zero) :-
find_root(Function, A, B, Error, Zero, _).
:- end_object.

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================
@@ -8,8 +8,5 @@ Copyright (c) 1998-2007 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
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.
This folder illustrates non-deterministic multi-threading calls and the
use of tags to distinguish between multi-threading calls.

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================
@@ -42,3 +42,63 @@ yes
X = 1 ;
no
% when two or more variant calls are made...
| ?- threaded_call(lists::member(X, [1,2,3])), threaded_call(lists::member(Y, [1,2,3])).
X = _G189 Y =_G190
yes
% ...the first threaded_exit/1 call will pick one of them:
| ?- threaded_exit(lists::member(X, [1,2,3])).
X = 1 ;
X = 2 ;
X = 3 ;
no
% ...and a second threaded_exit/1 call will pick the remaining one:
| ?- threaded_exit(lists::member(X, [1,2,3])).
X = 1 ;
X = 2 ;
X = 3 ;
no
% tags may be used to distinguish between threaded calls if needed:
| ?- threaded_call(lists::member(X, [1,2,3]), Tag).
Tag = 1
yes
| ?- threaded_call(lists::member(X, [1,2,3]), Tag).
Tag = 2
yes
| ?- threaded_exit(lists::member(X, [1,2,3]), 2).
X = 1 ;
X = 2 ;
X = 3 ;
no
% use a subsumed goal instead of a variant of the original goal:
| ?- threaded_call(lists::member(X, [1,2,3,2])).
X = _G189
yes
| ?- threaded_exit(lists::member(2, [1,2,3,2])).
More ;
More ;
no

View File

@@ -1,8 +1,6 @@
:- object(lists).
:- threaded.
:- public(member/2).
member(H, [H| _]).

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================
@@ -10,3 +10,13 @@ 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.
For more information, consult e.g. the following URL:
http://en.wikipedia.org/wiki/Dining_philosophers_problem
Two different implementations are provided, both using the same solution for
avoiding deadlock (which is having one philosopher picking its chopsticks
in a different order from the other philosophers; see the URL above for
details): one implementations uses a category and five philosopher objects
while the second implementation uses a parametric object.

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================
@@ -106,3 +106,7 @@ Philosopher p4 eating for 3 seconds with chopsticks cs4 and cs3.
p4 terminated.
p2 terminated.
% same problem as above but using a parametric object for representing the philosophers:
| ?- threaded_ignore(philosopher(p1,cs1,cs2)::run(5, 5)), threaded_ignore(philosopher(p2,cs2,cs3)::run(5, 5)), threaded_ignore(philosopher(p3,cs3,cs4)::run(5, 5)), threaded_ignore(philosopher(p4,cs4,cs5)::run(5, 5)), threaded_ignore(philosopher(p5,cs1,cs5)::run(5, 5)).

View File

@@ -1,4 +1,4 @@
:- initialization((
logtalk_load(library(random_loader), [reload(skip)]),
logtalk_load(library(random_loader), [reload(skip)]), % allow for static binding
logtalk_load(philosophers))).

View File

@@ -2,13 +2,11 @@
:- category(chopstick).
:- info([
version is 1.2,
version is 2.0,
author is 'Paulo Moura',
date is 2007/3/19,
comment is 'Dining philosophers problem: chopstick representation.']).
:- synchronized.
:- public(pick_up/0).
:- mode(pick_up, zero_or_one).
:- info(pick_up/0, [
@@ -19,22 +17,14 @@
:- 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 mutex
% 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 :-
::available,
::retract(available).
threaded_wait(available).
put_down :-
\+ ::available,
::asserta(available).
threaded_notify(available).
:- end_category.
@@ -42,9 +32,8 @@
:- object(cs1,
imports(chopstick)).
:- dynamic(available/0).
available.
:- threaded.
:- initialization(threaded_notify(available)).
:- end_object.
@@ -52,9 +41,8 @@
:- object(cs2,
imports(chopstick)).
:- dynamic(available/0).
available.
:- threaded.
:- initialization(threaded_notify(available)).
:- end_object.
@@ -62,9 +50,8 @@
:- object(cs3,
imports(chopstick)).
:- dynamic(available/0).
available.
:- threaded.
:- initialization(threaded_notify(available)).
:- end_object.
@@ -72,9 +59,8 @@
:- object(cs4,
imports(chopstick)).
:- dynamic(available/0).
available.
:- threaded.
:- initialization(threaded_notify(available)).
:- end_object.
@@ -82,9 +68,8 @@
:- object(cs5,
imports(chopstick)).
:- dynamic(available/0).
available.
:- threaded.
:- initialization(threaded_notify(available)).
:- end_object.
@@ -92,7 +77,7 @@
:- category(philosopher).
:- info([
version is 1.1,
version is 2.0,
author is 'Paulo Moura',
date is 2007/1/3,
comment is 'Dining philosophers problem: philosopher representation.']).
@@ -129,12 +114,11 @@
message([Philosopher, ' terminated.']).
run(Count, MaxTime) :-
Count > 0,
think(MaxTime),
( eat(MaxTime) ->
Count2 is Count - 1,
run(Count2, MaxTime)
; run(Count, MaxTime)
).
eat(MaxTime),
Count2 is Count - 1,
run(Count2, MaxTime).
think(MaxTime):-
this(Philosopher),
@@ -142,25 +126,20 @@
message(['Philosopher ', Philosopher, ' thinking for ', ThinkTime, ' seconds.']),
thread_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(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
; ::LeftStick::put_down,
fail
).
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:
% using a combination of individual write/1 and nl/0 calls:
message([]) :-
nl,
flush_output.
@@ -174,10 +153,8 @@
:- object(p1,
imports(philosopher)).
:- threaded.
left_chopstick(cs5).
right_chopstick(cs1).
left_chopstick(cs1).
right_chopstick(cs2).
:- end_object.
@@ -185,10 +162,8 @@
:- object(p2,
imports(philosopher)).
:- threaded.
left_chopstick(cs1).
right_chopstick(cs2).
left_chopstick(cs2).
right_chopstick(cs3).
:- end_object.
@@ -196,10 +171,8 @@
:- object(p3,
imports(philosopher)).
:- threaded.
left_chopstick(cs3).
right_chopstick(cs2).
right_chopstick(cs4).
:- end_object.
@@ -207,10 +180,8 @@
:- object(p4,
imports(philosopher)).
:- threaded.
left_chopstick(cs4).
right_chopstick(cs3).
right_chopstick(cs5).
:- end_object.
@@ -218,9 +189,89 @@
:- object(p5,
imports(philosopher)).
:- threaded.
left_chopstick(cs5).
right_chopstick(cs4).
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.

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================
@@ -17,3 +17,7 @@ a goal using proprietary predicates.
Note that this example is only meant to illustrate how to use Logtalk
multi-threading predicates, not to taken as the efficient solution for
finding primes numbers on a given interval (with or without threads).
You probably want to play with the list size in order to find out when the
list is big enough to make the use of multi-threading worth performance-wise
(i.e. to compensate the overhead of thread creation and management).

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================
@@ -10,7 +10,7 @@ To load this example and for sample queries, please see the SCRIPT file.
This folder contains a multi-threading implementation of the merge sort
algorithm. Depending on the size of the lists that are ordered, using
only one thread can be faster. The number of threads to use in sorting
only one thread can be faster. The number of threads to be use in sorting
is set using the msort/1 object parameter. You may need to adjust the
size of the memory areas used by your Prolog compiler, depending on the
size of the lists you want to sort.
@@ -30,3 +30,7 @@ other purpose, you may find the following paper a worthwhile reading:
year = "1993",
url = "citeseer.ist.psu.edu/apt93modular.html" }
You probably want to play with the list sizes in order to find out when the
lists to be sorted are big enough to make the use of multi-threading worth
performance-wise (i.e. to compensate the overhead of thread creation and
management).

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================

View File

@@ -1,4 +1,4 @@
:- initialization((
logtalk_load(library(random_loader), [reload(skip)]),
logtalk_load(library(random_loader), [reload(skip)]), % allow for static binding
logtalk_load([generator, qsort, msort]))).

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================

View File

@@ -1,6 +1,6 @@
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.2
Release 2.30.7
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
================================================================