Logtalk 2.28.2 files.
git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1713 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
13
Logtalk/examples/threads/NOTES.txt
Normal file
13
Logtalk/examples/threads/NOTES.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
=================================================================
|
||||
Logtalk - Object oriented extension to Prolog
|
||||
Release 2.28.2
|
||||
|
||||
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
|
||||
to first turn on multi-threading support on the Prolog config files.
|
19
Logtalk/examples/threads/atomic/NOTES.txt
Normal file
19
Logtalk/examples/threads/atomic/NOTES.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
=================================================================
|
||||
Logtalk - Object oriented extension to Prolog
|
||||
Release 2.28.2
|
||||
|
||||
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 "atomic" option on threaded_call/2 calls to cope with methods
|
||||
that have side-effects.
|
||||
|
||||
The object defined in the example source file, "atomic.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 "atomic" option. This
|
||||
predicate uses a counter that you might need to adjust, depending on your
|
||||
Prolog compiler and computer performance.
|
71
Logtalk/examples/threads/atomic/SCRIPT.txt
Normal file
71
Logtalk/examples/threads/atomic/SCRIPT.txt
Normal file
@@ -0,0 +1,71 @@
|
||||
=================================================================
|
||||
Logtalk - Object oriented extension to Prolog
|
||||
Release 2.28.2
|
||||
|
||||
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
|
||||
=================================================================
|
||||
|
||||
|
||||
% start by loading the loading the example:
|
||||
|
||||
| ?- logtalk_load(atomic(loader)).
|
||||
...
|
||||
|
||||
|
||||
% send three asynchronous messages whose corresponding methods perform output operations:
|
||||
|
||||
| ?- threaded_call(nasty1::io(alpha), [noreply]), threaded_call(nasty1::io(digit), [noreply]), threaded_call(nasty1::io(alpha), [noreply]).
|
||||
|
||||
a0ab1bc2c3ddefef45gg6hh7ii8jkjk9
|
||||
llmmnnopopqqrrsstztzyyxxwwuv
|
||||
uv
|
||||
|
||||
Yes
|
||||
|
||||
|
||||
% the same three asynchronous messages but making them atomic for the receiver object:
|
||||
|
||||
| ?- threaded_call(nasty1::io(alpha), [atomic, noreply]), threaded_call(nasty1::io(digit), [atomic, noreply]), threaded_call(nasty1::io(alpha), [atomic, noreply]).
|
||||
|
||||
abcdefghijklmnopqrstzyxwuv
|
||||
0123456789
|
||||
abcdefghijklmnopqrstzyxwuv
|
||||
|
||||
Yes
|
||||
|
||||
|
||||
% send three asynchronous messages whose corresponding methods perform database updates
|
||||
% (this may or may not work, most likely will throw an exception):
|
||||
|
||||
| ?- threaded_call(nasty1::update_db(_), [noreply]), threaded_call(nasty1::update_db(_), [noreply]), threaded_call(nasty1::update_db(_), [noreply]).
|
||||
|
||||
No
|
||||
|
||||
|
||||
% the same three asynchronous messages but making them atomic for the receiver object
|
||||
% (this should always work):
|
||||
|
||||
| ?- threaded_call(nasty1::update_db(_), [atomic, noreply]), threaded_call(nasty1::update_db(_), [atomic, noreply]), threaded_call(nasty1::update_db(_), [atomic, noreply]).
|
||||
|
||||
Yes
|
||||
|
||||
|
||||
% a better solution is to declare predicates that need to be thread syncronized as "atomic",
|
||||
% as exemplified in object "nasty2":
|
||||
|
||||
| ?- nasty2::(io(alpha), io(digit), io(alpha)).
|
||||
|
||||
abcdefghijklmnopqrstzyxwuv
|
||||
0123456789
|
||||
abcdefghijklmnopqrstzyxwuv
|
||||
|
||||
Yes
|
||||
|
||||
|
||||
| ?- nasty2::(update_db(X), update_db(Y), update_db(Z)).
|
||||
|
||||
X = 1
|
||||
Y = 2
|
||||
Z = 3
|
||||
|
||||
Yes
|
121
Logtalk/examples/threads/atomic/atomic.lgt
Normal file
121
Logtalk/examples/threads/atomic/atomic.lgt
Normal file
@@ -0,0 +1,121 @@
|
||||
|
||||
:- object(nasty1).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
author is 'Paulo Moura',
|
||||
date is 2006/04/14,
|
||||
comment is 'Simple example for using the "atomic" option for multi-threading calls 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.0,
|
||||
author is 'Paulo Moura',
|
||||
date is 2006/04/14,
|
||||
comment is 'Simple example for using the "atomic" option for multi-threading calls with side-effects.']).
|
||||
|
||||
:- threaded.
|
||||
|
||||
:- public(update_db/1).
|
||||
:- atomic(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).
|
||||
:- atomic(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.
|
13
Logtalk/examples/threads/atomic/loader.lgt
Normal file
13
Logtalk/examples/threads/atomic/loader.lgt
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
:- initialization(
|
||||
logtalk_load(
|
||||
atomic)).
|
||||
|
||||
/*
|
||||
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(
|
||||
atomic, [xmlsref(standalone)])).
|
||||
*/
|
12
Logtalk/examples/threads/birthdays/NOTES.txt
Normal file
12
Logtalk/examples/threads/birthdays/NOTES.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
=================================================================
|
||||
Logtalk - Object oriented extension to Prolog
|
||||
Release 2.28.2
|
||||
|
||||
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 agents and
|
||||
their birthdays.
|
52
Logtalk/examples/threads/birthdays/SCRIPT.txt
Normal file
52
Logtalk/examples/threads/birthdays/SCRIPT.txt
Normal file
@@ -0,0 +1,52 @@
|
||||
=================================================================
|
||||
Logtalk - Object oriented extension to Prolog
|
||||
Release 2.28.2
|
||||
|
||||
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:
|
||||
|
||||
| ?- logtalk_load(birthdays(loader)).
|
||||
...
|
||||
|
||||
|
||||
% create two new agents, Paul and Nathalie:
|
||||
|
||||
| ?- agent::(new(paul, 40, male), new(nathalie, 32, female)).
|
||||
|
||||
Yes
|
||||
|
||||
|
||||
% make them friends:
|
||||
|
||||
| ?- paul::new_friend(nathalie).
|
||||
|
||||
Yes
|
||||
|
||||
|
||||
% it's birthday for Nathalie:
|
||||
|
||||
| ?- nathalie::birthday.
|
||||
|
||||
Happy birthday from paul!
|
||||
Thanks! Here, have a slice of cake, paul.
|
||||
Thanks for the cake nathalie!
|
||||
|
||||
Yes
|
||||
|
||||
|
||||
% tell Paul to ask Nathalie her age:
|
||||
|
||||
| ?- paul::ask_age(nathalie, Age).
|
||||
|
||||
Age = 33
|
||||
|
||||
Yes
|
90
Logtalk/examples/threads/birthdays/birthdays.lgt
Normal file
90
Logtalk/examples/threads/birthdays/birthdays.lgt
Normal file
@@ -0,0 +1,90 @@
|
||||
|
||||
:- object(agent,
|
||||
implements(event_handlersp)).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
author is 'Peter Robinson and Paulo Moura',
|
||||
date is 2006/04/09,
|
||||
comment is 'Simple multi-threading example with agents and their birthdays.']).
|
||||
|
||||
:- threaded.
|
||||
|
||||
:- public(new/3).
|
||||
:- mode(new(+atom, +integer, +atom), one).
|
||||
:- info(new/3, [
|
||||
comment is 'Creates a new agent given its name, age, and gender.',
|
||||
argnames is ['Name', 'Age', 'Gender']]).
|
||||
|
||||
:- public(age/1).
|
||||
:- dynamic(age/1).
|
||||
:- mode(age(?integer), zero_or_one).
|
||||
:- info(age/1, [
|
||||
comment is 'Agent age.']).
|
||||
|
||||
:- public(ask_age/2).
|
||||
:- mode(ask_age(+atom, ?integer), zero_or_one).
|
||||
:- info(ask_age/2, [
|
||||
comment is 'Ask a friend his/her age.',
|
||||
argnames is ['Name', 'Age']]).
|
||||
|
||||
:- public(gender/1).
|
||||
:- dynamic(gender/1).
|
||||
:- mode(gender(?integer), zero_or_one).
|
||||
:- info(gender/1, [
|
||||
comment is 'Agent gender.']).
|
||||
|
||||
:- public(birthday/0).
|
||||
:- mode(birthday, one).
|
||||
:- info(birthday/0, [
|
||||
comment is 'Increments an agent age, an unfortunate side-effect of its birthday.']).
|
||||
|
||||
:- public(happy_birthday/1).
|
||||
:- mode(happy_birthday(+object_identifier), one).
|
||||
:- info(happy_birthday/1, [
|
||||
comment is 'Happy birthday message from a friend.',
|
||||
argnames is ['From']]).
|
||||
|
||||
:- public(cake_slice/1).
|
||||
:- mode(cake_slice(+object_identifier), one).
|
||||
:- info(cake_slice/1, [
|
||||
comment is 'Offer a slice of birthday cake to a friend.',
|
||||
argnames is ['From']]).
|
||||
|
||||
:- public(new_friend/1).
|
||||
:- mode(new_friend(+object_identifier), one).
|
||||
:- info(new_friend/1, [
|
||||
comment is 'New friend, watch out for his/her birthday.',
|
||||
argnames is ['Name']]).
|
||||
|
||||
new(Name, Age, Gender) :-
|
||||
this(This),
|
||||
create_object(Name, [extends(This)], [threaded], [age(Age), gender(Gender)]).
|
||||
|
||||
ask_age(Friend, Age) :-
|
||||
threaded_call(Friend::age(Age)),
|
||||
threaded_exit(Friend::age(Age)).
|
||||
|
||||
birthday :-
|
||||
::retract(age(Old)),
|
||||
New is Old + 1,
|
||||
::assertz(age(New)).
|
||||
|
||||
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]).
|
||||
|
||||
cake_slice(From) :-
|
||||
write('Thanks for the cake '), write(From), write('!'), nl.
|
||||
|
||||
new_friend(Friend) :-
|
||||
self(Self),
|
||||
define_events(after, Friend, birthday, _, Self).
|
||||
|
||||
after(Friend, birthday, _) :-
|
||||
self(Self),
|
||||
threaded_call(Friend::happy_birthday(Self), [noreply]).
|
||||
|
||||
:- end_object.
|
13
Logtalk/examples/threads/birthdays/loader.lgt
Normal file
13
Logtalk/examples/threads/birthdays/loader.lgt
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
:- initialization(
|
||||
logtalk_load(
|
||||
[birthdays], [events(on)])).
|
||||
|
||||
/*
|
||||
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(
|
||||
[birthdays], [events(on), xmlsref(standalone)])).
|
||||
*/
|
14
Logtalk/examples/threads/functions/NOTES.txt
Normal file
14
Logtalk/examples/threads/functions/NOTES.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
=================================================================
|
||||
Logtalk - Object oriented extension to Prolog
|
||||
Release 2.28.2
|
||||
|
||||
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 how
|
||||
to create threads for competing goals, which one performing the same
|
||||
task using diferent methods. The first goal to complete leads to the
|
||||
immediate termination of the threads running the remaining goals.
|
65
Logtalk/examples/threads/functions/SCRIPT.txt
Normal file
65
Logtalk/examples/threads/functions/SCRIPT.txt
Normal file
@@ -0,0 +1,65 @@
|
||||
=================================================================
|
||||
Logtalk - Object oriented extension to Prolog
|
||||
Release 2.28.2
|
||||
|
||||
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
|
||||
=================================================================
|
||||
|
||||
|
||||
% start by loading the loading the example:
|
||||
|
||||
| ?- logtalk_load(functions(loader)).
|
||||
...
|
||||
|
||||
|
||||
% find the roots of some functions using each one of provided methods:
|
||||
|
||||
| ?- bisection::find_root(f1, 1.0, 2.3, 1e-15, Zero).
|
||||
|
||||
Zero = 2.0
|
||||
yes
|
||||
|
||||
| ?- newton::find_root(f1, 1.0, 2.3, 1e-15, Zero).
|
||||
|
||||
Zero = 2.0
|
||||
yes
|
||||
| ?- muller::find_root(f1, 1.0, 2.3, 1e-15, Zero).
|
||||
|
||||
Zero = 2.0
|
||||
yes
|
||||
|
||||
| ?- bisection::find_root(f2, 1.0, 1.3, 1e-15, Zero).
|
||||
|
||||
Zero = 1.25809265664599
|
||||
yes
|
||||
|
||||
| ?- newton::find_root(f2, 1.0, 1.3, 1e-15, Zero).
|
||||
|
||||
Zero = 1.25809265664599
|
||||
yes
|
||||
|
||||
| ?- muller::find_root(f2, 1.0, 1.3, 1e-15, Zero).
|
||||
|
||||
Zero = 1.25809265664599
|
||||
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).
|
||||
|
||||
Zero = 2.0
|
||||
Method = bisection
|
||||
yes
|
||||
|
||||
| ?- function_root::find_root(f2, 1.0, 1.3, 1e-15, Zero, Method).
|
||||
|
||||
Zero = 1.25809265664599
|
||||
Method = newton
|
||||
yes
|
||||
|
||||
| ?- function_root::find_root(f3, 0.0, 3.0, 1e-15, Zero, Method).
|
||||
|
||||
Zero = 1.4142135623731
|
||||
Method = newton
|
||||
yes
|
268
Logtalk/examples/threads/functions/functions.lgt
Normal file
268
Logtalk/examples/threads/functions/functions.lgt
Normal file
@@ -0,0 +1,268 @@
|
||||
|
||||
:- protocol(find_rootp).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
date is 2006/4/21,
|
||||
author is 'Paulo Nunes',
|
||||
comment is 'Default protocol for root find algorithms.']).
|
||||
|
||||
:- public(find_root/5).
|
||||
:- mode(find_root(+object_identifier, +float, +float, +float, -float), one).
|
||||
:- info(find_root/5, [
|
||||
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([
|
||||
version is 1.0,
|
||||
date is 2006/4/21,
|
||||
author is 'Paulo Nunes',
|
||||
comment is 'Default protocol for real functions of a single real variable.']).
|
||||
|
||||
:- public(eval/2).
|
||||
:- mode(eval(+float, -float), one).
|
||||
:- info(eval/2, [
|
||||
comment is 'Calculate 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.',
|
||||
argnames is ['X', 'DFx']]).
|
||||
|
||||
:- end_protocol.
|
||||
|
||||
|
||||
:- object(f1,
|
||||
implements(functionp)).
|
||||
|
||||
% x^2 - 4
|
||||
% 2.0
|
||||
|
||||
eval(X, Y) :-
|
||||
Y is X * X - 4.
|
||||
evald(X, Y) :-
|
||||
Y is 2 * X.
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(f2,
|
||||
implements(functionp)).
|
||||
|
||||
% x^7 + 9x^5 - 13x - 17
|
||||
% 1.29999999999945448
|
||||
|
||||
eval(X, Y) :-
|
||||
Y is X**7 + 9*X**5 - 13*X - 17.
|
||||
|
||||
evald(X, Y) :-
|
||||
Y is 7*X**6 + 45*X**4 - 13.
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(f3,
|
||||
implements(functionp)).
|
||||
|
||||
% (x - sqrt(2))^7
|
||||
% 1.41421356237309537
|
||||
|
||||
eval(X, Y) :-
|
||||
Y is (X - sqrt(2.0))**8.
|
||||
|
||||
evald(X, Y) :-
|
||||
Y is 8*(X - sqrt(2.0))**7.
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(function_root,
|
||||
implements(find_rootp)).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
date is 2006/4/21,
|
||||
author is 'Paulo Nunes',
|
||||
comment is 'Multi-threading interface to root finding algorithms.']).
|
||||
|
||||
:- threaded.
|
||||
|
||||
find_root(Function, A, B, Error, Zero) :-
|
||||
find_root(Function, A, B, Error, Zero, _).
|
||||
|
||||
find_root(Function, A, B, Error, Zero, Algorithm) :-
|
||||
threaded_call(
|
||||
( 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).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(bisection,
|
||||
implements(find_rootp)).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
date is 2006/4/21,
|
||||
author is 'Paulo Nunes',
|
||||
comment is 'Bisection algorithm.']).
|
||||
|
||||
find_root(Function, A, B, Error, Zero) :-
|
||||
Function::eval(A, Fa),
|
||||
Function::eval(B, Fb),
|
||||
( Fa > 0.0, Fb < 0.0 ->
|
||||
true
|
||||
; Fa < 0.0, Fb > 0.0
|
||||
),
|
||||
X0 is (A + B) / 2,
|
||||
Function::eval(X0, F0),
|
||||
bisection(Function, A, B, X0, F0, Error, Zero).
|
||||
|
||||
bisection(_, _, _, Xn1, 0.0, _, Xn1) :-
|
||||
!.
|
||||
|
||||
bisection(_, Xn1, Xn, _, _, Error, Xn1) :-
|
||||
abs(Xn1 - Xn) < Error,
|
||||
!.
|
||||
|
||||
bisection(Function, An, Bn, _, _, Error, Zero) :-
|
||||
Xn1 is (An + Bn) / 2,
|
||||
Function::eval(Xn1, Fn1),
|
||||
Function::eval(An, FAn),
|
||||
( Fn1*FAn < 0.0 ->
|
||||
An1 is An,
|
||||
Bn1 is Xn1
|
||||
; An1 is Xn1,
|
||||
Bn1 is Bn
|
||||
),
|
||||
bisection(Function, An1, Bn1, Xn1, Fn1, Error, Zero).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(newton,
|
||||
implements(find_rootp)).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
date is 2006/4/21,
|
||||
author is 'Paulo Nunes',
|
||||
comment is 'Newton algorithm.']).
|
||||
|
||||
find_root(Function, Xa, Xb, Deviation, Zero) :-
|
||||
X0 is (Xa + Xb) / 2,
|
||||
newton(Function, X0, 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,
|
||||
!.
|
||||
|
||||
% 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).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(muller,
|
||||
implements(find_rootp)).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
date is 2006/4/21,
|
||||
author is 'Paulo Nunes',
|
||||
comment is 'Muller algorithm.']).
|
||||
|
||||
find_root(Function, Xa, Xb, Deviation, Zero) :-
|
||||
Xc is (Xa + Xb) / 2,
|
||||
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),
|
||||
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),
|
||||
( Rn < 0.0 ->
|
||||
muller(Function, _, _, complex, Deviation, _, _, _, _, _, _, Zero),
|
||||
!, fail
|
||||
; V is sqrt(Rn)
|
||||
),
|
||||
( Bn > 0.0 ->
|
||||
Dn is (Bn + V)
|
||||
; Dn is (Bn - V)
|
||||
),
|
||||
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.
|
13
Logtalk/examples/threads/functions/loader.lgt
Normal file
13
Logtalk/examples/threads/functions/loader.lgt
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
:- initialization(
|
||||
logtalk_load(
|
||||
functions)).
|
||||
|
||||
/*
|
||||
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(
|
||||
functions, [xmlsref(standalone)])).
|
||||
*/
|
15
Logtalk/examples/threads/nondet/NOTES.txt
Normal file
15
Logtalk/examples/threads/nondet/NOTES.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
=================================================================
|
||||
Logtalk - Object oriented extension to Prolog
|
||||
Release 2.28.2
|
||||
|
||||
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
|
||||
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.
|
29
Logtalk/examples/threads/nondet/SCRIPT.txt
Normal file
29
Logtalk/examples/threads/nondet/SCRIPT.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
=================================================================
|
||||
Logtalk - Object oriented extension to Prolog
|
||||
Release 2.28.2
|
||||
|
||||
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
|
||||
=================================================================
|
||||
|
||||
|
||||
% start by loading the loading the example:
|
||||
|
||||
| ?- logtalk_load(nondet(loader)).
|
||||
...
|
||||
|
||||
|
||||
% make a threaded call with a non-deterministic goal:
|
||||
|
||||
| ?- threaded_call(lists::member(X, [1,2,3])).
|
||||
|
||||
X = _G189
|
||||
yes
|
||||
|
||||
% retrieve through backtracking all solutions for the non-deterministic goal:
|
||||
|
||||
| ?- threaded_exit(lists::member(X, [1,2,3])).
|
||||
|
||||
X = 1 ;
|
||||
X = 2 ;
|
||||
X = 3 ;
|
||||
no
|
13
Logtalk/examples/threads/nondet/loader.lgt
Normal file
13
Logtalk/examples/threads/nondet/loader.lgt
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
:- initialization(
|
||||
logtalk_load(
|
||||
nondet)).
|
||||
|
||||
/*
|
||||
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(
|
||||
nondet, [xmlsref(standalone)])).
|
||||
*/
|
12
Logtalk/examples/threads/nondet/nondet.lgt
Normal file
12
Logtalk/examples/threads/nondet/nondet.lgt
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
:- object(lists).
|
||||
|
||||
:- threaded.
|
||||
|
||||
:- public(member/2).
|
||||
|
||||
member(H, [H| _]).
|
||||
member(H, [_| T]) :-
|
||||
member(H, T).
|
||||
|
||||
:- end_object.
|
15
Logtalk/examples/threads/primes/NOTES.txt
Normal file
15
Logtalk/examples/threads/primes/NOTES.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
=================================================================
|
||||
Logtalk - Object oriented extension to Prolog
|
||||
Release 2.28.2
|
||||
|
||||
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
|
||||
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.
|
31
Logtalk/examples/threads/primes/SCRIPT.txt
Normal file
31
Logtalk/examples/threads/primes/SCRIPT.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
=================================================================
|
||||
Logtalk - Object oriented extension to Prolog
|
||||
Release 2.28.2
|
||||
|
||||
Copyright (c) 1998-2006 Paulo Moura. All Rights Reserved.
|
||||
=================================================================
|
||||
|
||||
|
||||
% start by loading the loading the example:
|
||||
|
||||
| ?- logtalk_load(primes(loader)).
|
||||
...
|
||||
|
||||
|
||||
% calculate the prime numbers in a given interval using a single thread:
|
||||
|
||||
| ?- primes::st_prime_numbers(1, 200000, Primes).
|
||||
|
||||
Primes = [199999, 199967, 199961, 199933, 199931, 199921, 199909, 199889, 199877|...]
|
||||
|
||||
Yes
|
||||
|
||||
|
||||
% calculate the prime numbers in a given interval by splitting the interval
|
||||
% in two sub-intervals and using a thread pere interval:
|
||||
|
||||
| ?- primes::mt_prime_numbers(1, 200000, Primes).
|
||||
|
||||
Primes = [199999, 199967, 199961, 199933, 199931, 199921, 199909, 199889, 199877|...]
|
||||
|
||||
Yes
|
13
Logtalk/examples/threads/primes/loader.lgt
Normal file
13
Logtalk/examples/threads/primes/loader.lgt
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
:- initialization(
|
||||
logtalk_load(
|
||||
primes)).
|
||||
|
||||
/*
|
||||
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(
|
||||
primes, [xmlsref(standalone)])).
|
||||
*/
|
62
Logtalk/examples/threads/primes/primes.lgt
Normal file
62
Logtalk/examples/threads/primes/primes.lgt
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
:- object(primes).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
author is 'Paulo Moura',
|
||||
date is 2006/04/14,
|
||||
comment is 'Simple example for comparing single and multi-threading calculation of prime numbers.']).
|
||||
|
||||
:- threaded.
|
||||
|
||||
:- public(st_prime_numbers/3).
|
||||
:- mode(st_prime_numbers(+integer, +integer, -list), one).
|
||||
:- info(st_prime_numbers/3, [
|
||||
comment is 'Returns all prime numbers in the given interval using a single calculation thread.',
|
||||
argnames is ['Inf', 'Sup', 'Primes']]).
|
||||
|
||||
:- public(mt_prime_numbers/3).
|
||||
:- mode(mt_prime_numbers(+integer, +integer, -list), one).
|
||||
:- info(mt_prime_numbers/3, [
|
||||
comment is 'Returns all prime numbers in the given interval using two calculation threads.',
|
||||
argnames is ['Inf', 'Sup', 'Primes']]).
|
||||
|
||||
st_prime_numbers(N, M, Primes) :-
|
||||
M > N,
|
||||
prime_numbers(N, M, [], Primes).
|
||||
|
||||
mt_prime_numbers(N, M, Primes) :-
|
||||
M > N,
|
||||
N1 is N + (M - N) // 2,
|
||||
N2 is N1 + 1,
|
||||
threaded_call(prime_numbers(N, N1, [], Acc)),
|
||||
threaded_call(prime_numbers(N2, M, Acc, Primes)),
|
||||
threaded_exit(prime_numbers(N, N1, [], Acc)),
|
||||
threaded_exit(prime_numbers(N2, M, Acc, Primes)).
|
||||
|
||||
prime_numbers(N, M, Primes, Primes) :-
|
||||
N > M,
|
||||
!.
|
||||
prime_numbers(N, M, Acc, Primes) :-
|
||||
( is_prime(N) ->
|
||||
Acc2 = [N| Acc]
|
||||
; Acc2 = Acc),
|
||||
N2 is N + 1,
|
||||
prime_numbers(N2, M, Acc2, Primes).
|
||||
|
||||
is_prime(2) :- !.
|
||||
is_prime(Prime):-
|
||||
Prime > 2,
|
||||
Prime mod 2 =:= 1,
|
||||
Sqrt is sqrt(Prime),
|
||||
is_prime(3, Sqrt, Prime).
|
||||
|
||||
is_prime(N, Sqrt, Prime):-
|
||||
( N > Sqrt ->
|
||||
true
|
||||
; Prime mod N > 0,
|
||||
N2 is N + 2,
|
||||
is_prime(N2, Sqrt, Prime)
|
||||
).
|
||||
|
||||
:- end_object.
|
Reference in New Issue
Block a user