Code Comments
Programming Forum and web based access to our favorite programming groups.It's nearly 3 years since the last time I posted an fyi to this list, so long that we've changed the name of the website! We have SWI-Prolog and YAP installed, the problem with Prolog on the benchmarks game has always been finding competent Prolog programmers willing to spend a little time writing such uninteresting ill-suited programs. Here are the programs contributed for SWI-Prolog http://shootout.alioth.debian.org/g...lang2=swiprolog I've transliterated just one of those to check that YAP was working http://shootout.alioth.debian.org/g...ng2 =yap If anyone is interested in contributing Prolog programs then the FAQ provides plenty of information: http://shootout.alioth.debian.org/gp4sandbox/faq.php
Post Follow-up to this messageOn Mar 30, 12:53 am, Isaac Gouy <igo...@yahoo.com> wrote: > It's nearly 3 years since the last time I posted an fyi to this list, > so long that we've changed the name of the website! > > We have SWI-Prolog and YAP installed, the problem with Prolog on the > benchmarks game has always been finding competent Prolog programmers > willing to spend a little time writing such uninteresting ill-suited > programs. > > Here are the programs contributed for SWI-Prolog > > http://shootout.alioth.debian.org/g...p?test=all&l... > > I've transliterated just one of those to check that YAP was working > > http://shootout.alioth.debian.org/g...p?test=all&l... > > If anyone is interested in contributing Prolog programs then the FAQ > provides plenty of information: > > http://shootout.alioth.debian.org/gp4sandbox/faq.php I have spent a little time on nbody.pl for SWI-Prolog. It's somewhat faster and more idiomatic than the original. I bet there are gurus here who can push it a lot further. % ---------------------------------------------------------------------- % The Computer Language Shootout % http://shootout.alioth.debian.org/ % % Assumes execution using the following command-line usage: % % pl -q -g main -t halt -s SOURCENAME -- USERARG1 ... < in > out % % Contributed by Anthony Borla % Improved by Tom Schrijvers % ---------------------------------------------------------------------- main :- cmdlNumArg(1, N), make_bodies(Bodies), offset_momentum(Bodies), energy(Bodies, EnergyStart), advance(Bodies, N, 0.01), energy(Bodies, EnergyAfter), format('~9f~N~9f~N', [EnergyStart, EnergyAfter]), drop_bodies(Bodies). % ------------------------------- % offset_momentum(Bodies) :- offset(Bodies,0.0,0.0,0.0,PX,PY,PZ), solar_mass(SOLAR_MASS), getvar(sun, body(X, Y, Z, _, _, _, Mass)), VX1 is -(PX / SOLAR_MASS), VY1 is -(PY / SOLAR_MASS), VZ1 is -(PZ / SOLAR_MASS), setvar(sun, body(X, Y, Z, VX1, VY1, VZ1, Mass)). offset([],PX,PY,PZ,PX,PY,PZ). offset([Body|Bodies],PX,PY,PZ,NPX,NPY,NP Z) :- getvar(Body, body(_, _, _, VX, VY, VZ, Mass)), PX1 is PX + VX * Mass, PY1 is PY + VY * Mass, PZ1 is PZ + VZ * Mass, offset(Bodies,PX1,PY1,PZ1,NPX,NPY,NPZ). % ------------------------------- % energy(Bodies, Energy) :- energy(Bodies,0.0,Energy). energy([],C,C). energy([Body|Bodies],C,NC) :- getvar(Body, body(X, Y, Z, VX, VY, VZ, Mass)), C1 is C + 0.5 * Mass * (VX * VX + VY * VY + VZ * VZ), energy_dist(Bodies,X,Y,Z,Mass,C1,C2), energy(Bodies,C2,NC). energy_dist([],_,_,_,_,C,C). energy_dist([Body|Bodies],X,Y,Z,Mass,C,N C) :- getvar(Body, body(XT, YT, ZT, _, _, _, MassT)), DX is X - XT, DY is Y - YT, DZ is Z - ZT, DISTANCE is sqrt(DX * DX + DY * DY + DZ * DZ), C1 is C - (Mass * MassT) / DISTANCE, energy_dist(Bodies,X,Y,Z,Mass,C1,NC). % ------------------------------- % advance(Bodies, Repetitions, DT) :- between(1,Repetitions,Counter), forall(head_and_tail(E, T, Bodies), (forall(member(ET, T), (getvar(E, body(X, Y, Z, VX, VY, VZ, Mass)), getvar(ET, body(XT, YT, ZT, VXT, VYT, VZT, MassT)), DX is X - XT, DY is Y - YT, DZ is Z - ZT, DISTANCE is sqrt(DX * DX + DY * DY + DZ * DZ), Mag is DT / (DISTANCE * DISTANCE * DISTANCE), VX1 is VX - DX * MassT * Mag, VY1 is VY - DY * MassT * Mag, VZ1 is VZ - DZ * MassT * Mag, VXT1 is VXT + DX * Mass * Mag, VYT1 is VYT + DY * Mass * Mag, VZT1 is VZT + DZ * Mass * Mag, setvar(E, body(X, Y, Z, VX1, VY1, VZ1, Mass)), setvar(ET, body(XT, YT, ZT, VXT1, VYT1, VZT1, MassT)))) ) ), forall(member(E, Bodies), (getvar(E, body(X, Y, Z, VX, VY, VZ, Mass)), X1 is X + DT * VX, Y1 is Y + DT * VY, Z1 is Z + DT * VZ, setvar(E, body(X1, Y1, Z1, VX, VY, VZ, Mass)))), Counter >= Repetitions. % ------------------------------- % make_bodies(Bodies) :- forall(planet(Key,Values), setvar(Key,Values)), findall(Body, planet(Body,_), Bodies). solar_mass(3.9478417604357432000e+01). planet(sun, body(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, SOLAR_MASS)) :- solar_mass(SOLAR_MASS). planet(jupiter, body(4.84143144246472090e+00, -1.16032004402742839e +00, -1.03622044471123109e-01, 6.06326392995832020e-01, 2.811986844916260200e+00, -2.5218361659887636e-02, 3.7693674870389486e-02)). planet(saturn, body(8.34336671824457987e+00, 4.12479856412430479e+00, -4.03523417114321381e-01, -1.010774346178792400e+00, 1.825662371230411900e+00, 8.415761376584154e-03, 1.1286326131968767e-02)). planet(uranus, body(1.28943695621391310e+01, -1.51111514016986312e+01, -2.23307578892655734e-01, 1.082791006441535600e+00, 8.68713018169607890e-01, -1.0832637401363636e-02, 1.723724057059711e-03)). planet(neptune, body(1.53796971148509165e+01, -2.59193146099879641e +01, 1.79258772950371181e-01, 9.79090732243897980e-01, 5.94698998647676060e-01, -3.4755955504078104e-02, 2.033686869924631e-03)). % ------------- % drop_bodies(Bodies) :- forall(member(E, Bodies), dropvar(E)). % ------------------------------- % getvar(Id, Value) :- nb_getval(Id, Value). setvar(Id, Value) :- nb_setval(Id, Value). dropvar(Id) :- nb_delete(Id). % ------------- % head_and_tail(X, T, [X|T]). head_and_tail(X, T1, [_|T]) :- head_and_tail(X, T1, T). % ------------------------------- % argument_value(N, Arg) :- current_prolog_flag(argv, Cmdline), append(_, [--|UserArgs], Cmdline), Nth is N - 1, nth0(Nth, UserArgs, Arg). cmdlNumArg(Nth, N) :- argument_value(Nth, Arg), catch(atom_number(Arg, N), _, fail) ; halt(1).
Post Follow-up to this messageOn 2008-03-31, tomenannemie@gmail.com <tomenannemie@gmail.com> wrote: > On Mar 30, 12:53 am, Isaac Gouy <igo...@yahoo.com> wrote: > % Assumes execution using the following command-line usage: > % > % pl -q -g main -t halt -s SOURCENAME -- USERARG1 ... < in > out > % > % Contributed by Anthony Borla > % Improved by Tom Schrijvers Hi Tom, I speed is of any value, don't forget to add -O, especially if there is this much arithmetic. Using library(apply_macros) may also help a bit. Cheers --- Jan
Post Follow-up to this messageOn Mar 31, 6:49 am, Jan Wielemaker <j...@nospam.ct.xs4all.nl> wrote: > On 2008-03-31, tomenanne...@gmail.com <tomenanne...@gmail.com> wrote: > > > Hi Tom, > > I speed is of any value, don't forget to add -O, especially if there > is this much arithmetic. Using library(apply_macros) may also help > a bit. You can see the args that were used to run the program, at the bottom of the page below the program listing: http://shootout.alioth.debian.org/g...d=0 #log
Post Follow-up to this messagetomenannemie@gmail.com writes: > I have spent a little time on nbody.pl for SWI-Prolog. I did mandelbrot.pl; a few simple changes made it 10-20% faster in SWI: % ---------------------------------------------------------------------- % The Great Computer Language Shootout % http://shootout.alioth.debian.org/ % % Assumes execution using the following command-line usage: % % pl -q -g main -t halt -s SOURCENAME -- USERARG1 ... < in > out % % Contributed by Anthony Borla % ---------------------------------------------------------------------- main :- argument_value(1, Height), nb_setval(byteout, 0), nb_setval(bitnumber, 0), format('P4~N~d ~d~N',[Height, Height]), Limit is Height - 1, ignore((between(0, Limit, Y), between(0, Limit, X), point(X, Y, Height, Height), fail)), halt. point(X, Y, Height, Width) :- nb_getval(byteout, Out0), ( mandel(Height, Width, Y, X, 50) -> Out1 is Out0 << 1 + 1 ; Out1 is Out0 << 1 ), nb_getval(bitnumber, Bit0), succ(Bit0, Bit1), nb_setval(bitnumber, Bit1), ( Bit1 =:= 8 -> output(Out1) ; Width - 1 =:= X -> Out2 is Out1 * (1 << (8 - Width mod 8)), output(Out2) ; nb_setval(byteout, Out1) ). mandel(Height, Width, Y, X, Repetitions) :- Cr is ( X << 1 / Width - 1.5), Ci is ( Y << 1 / Height - 1.0), mandel_(Repetitions, Cr, Ci, 0.0, 0.0). mandel_(0, _, _, _, _) :- !. mandel_(N, Cr, Ci, Zr, Zi) :- Zr1 is Zr*Zr - Zi*Zi + Cr, Zi1 is 2 * Zr * Zi + Ci, Zr1*Zr1 + Zi1*Zi1 =< 4, succ(N1, N), mandel_(N1, Cr, Ci, Zr1, Zi1). output(Byte) :- put_byte(Byte), nb_setval(bitnumber, 0), nb_setval(byteout, 0). argument_value(Nth, N) :- ( current_prolog_flag(argv, Cmdline), append(_, [--|UserArgs], Cmdline), nth1(Nth, UserArgs, Arg), catch(atom_number(Arg, N), _, fail) -> true ; halt(1) ).
Post Follow-up to this message> I have spent a little time on nbody.pl for SWI-Prolog. It's somewhat > faster > and more idiomatic than the original. I bet there are gurus here who > can push it > a lot further. My friendly neighborhood Prolog guru has just made my program twice as fast, and eliminated the remaining nasty destructive updates. Apart from the command ling argument handling, this code also runs in Yap. %---------------------------------------------------------------------- % The Computer Language Shootout % http://shootout.alioth.debian.org/ % % Assumes execution using the following command-line usage: % % pl -q -g main -t halt -s SOURCENAME -- USERARG1 ... < in > out % % Contributed by Anthony Borla % Improved by Tom Schrijvers % Improved by Bart Demoen % ---------------------------------------------------------------------- main :- cmdlNumArg(1, N), main(N). main(N) :- make_bodies(Bodies), offset_momentum(Bodies,NewBodies), energy(NewBodies, EnergyStart), advance(NewBodies, N, 0.01, FinalBodies), energy(FinalBodies, EnergyAfter), % format('~9f~N~9f~N', [EnergyStart, EnergyAfter]), write([EnergyStart, EnergyAfter]), nl. % ------------------------------- % offset_momentum(Bodies,NewBs) :- offset(Bodies,0.0,0.0,0.0,PX,PY,PZ), solar_mass(SOLAR_MASS), planet(sun, body(X, Y, Z, _, _, _, Mass)), VX1 is -(PX / SOLAR_MASS), VY1 is -(PY / SOLAR_MASS), VZ1 is -(PZ / SOLAR_MASS), [body(X, Y, Z, VX1, VY1, VZ1, Mass)|Bodies] = NewBs. offset([],PX,PY,PZ,PX,PY,PZ). offset([Body|Bodies],PX,PY,PZ,NPX,NPY,NP Z) :- Body = body(_, _, _, VX, VY, VZ, Mass), PX1 is PX + VX * Mass, PY1 is PY + VY * Mass, PZ1 is PZ + VZ * Mass, offset(Bodies,PX1,PY1,PZ1,NPX,NPY,NPZ). % ------------------------------- % energy(Bodies, Energy) :- energy(Bodies,0.0,Energy). energy([],C,C). energy([Body|Bodies],C,NC) :- Body = body(X, Y, Z, VX, VY, VZ, Mass), C1 is C + 0.5 * Mass * (VX * VX + VY * VY + VZ * VZ), energy_dist(Bodies,X,Y,Z,Mass,C1,C2), energy(Bodies,C2,NC). energy_dist([],_,_,_,_,C,C). energy_dist([Body|Bodies],X,Y,Z,Mass,C,N C) :- Body = body(XT, YT, ZT, _, _, _, MassT), DX is X - XT, DY is Y - YT, DZ is Z - ZT, DISTANCE is sqrt(DX * DX + DY * DY + DZ * DZ), C1 is C - (Mass * MassT) / DISTANCE, energy_dist(Bodies,X,Y,Z,Mass,C1,NC). % ------------------------------- % advance(Bodies, Repetitions, DT, FinalBodies) :- (Repetitions == 0 -> FinalBodies = Bodies ; treatallpairs(Bodies,DT,Bodies1), updateeach(Bodies1,DT,Bodies2), Repetitions1 is Repetitions - 1, advance(Bodies2, Repetitions1, DT, FinalBodies) ). treatallpairs(BodiesIn,DT,BodiesOut) :- BodiesIn = [B|Bs], (Bs == [] -> BodiesOut = BodiesIn ; BodiesIn = [B|Bs], treatallpairs1(Bs,B,DT,NewB,NewBs), BodiesOut = [NewB|RestOut], treatallpairs(NewBs,DT,RestOut) ). treatallpairs1([],B,_,B,[]). treatallpairs1([ET|RET],E,DT,NewB,NewBs) :- E = body(X, Y, Z, VX, VY, VZ, Mass), ET = body(XT, YT, ZT, VXT, VYT, VZT, MassT), DX is X - XT, DY is Y - YT, DZ is Z - ZT, DISTANCE is sqrt(DX * DX + DY * DY + DZ * DZ), Mag is DT / (DISTANCE * DISTANCE * DISTANCE), VX1 is VX - DX * MassT * Mag, VY1 is VY - DY * MassT * Mag, VZ1 is VZ - DZ * MassT * Mag, VXT1 is VXT + DX * Mass * Mag, VYT1 is VYT + DY * Mass * Mag, VZT1 is VZT + DZ * Mass * Mag, NewE = body(X, Y, Z, VX1, VY1, VZ1, Mass), NewET = body(XT, YT, ZT, VXT1, VYT1, VZT1, MassT), NewBs = [NewET|RestNewBs], treatallpairs1(RET,NewE,DT,NewB,RestNewB s). updateeach([],_,[]). updateeach([body(X, Y, Z, VX, VY, VZ, Mass)|R],DT, [body(X1, Y1, Z1, VX, VY, VZ, Mass)|S]) :- X1 is X + DT * VX, Y1 is Y + DT * VY, Z1 is Z + DT * VZ, updateeach(R,DT,S). % ------------------------------- % make_bodies(Bodies) :- findall(V, (planet(Body,V), Body \== sun), Bodies). solar_mass(3.9478417604357432000e+01). planet(sun, body(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, SOLAR_MASS)) :- solar_mass(SOLAR_MASS). planet(jupiter, body(4.84143144246472090e+00, -1.16032004402742839e +00, -1.03622044471123109e-01, 6.06326392995832020e-01, 2.811986844916260200e+00, -2.5218361659887636e-02, 3.7693674870389486e-02)). planet(saturn, body(8.34336671824457987e+00, 4.12479856412430479e+00, -4.03523417114321381e-01, -1.010774346178792400e+00, 1.825662371230411900e+00, 8.415761376584154e-03, 1.1286326131968767e-02)). planet(uranus, body(1.28943695621391310e+01, -1.51111514016986312e+01, -2.23307578892655734e-01, 1.082791006441535600e+00, 8.68713018169607890e-01, -1.0832637401363636e-02, 1.723724057059711e-03)). planet(neptune, body(1.53796971148509165e+01, -2.59193146099879641e +01, 1.79258772950371181e-01, 9.79090732243897980e-01, 5.94698998647676060e-01, -3.4755955504078104e-02, 2.033686869924631e-03)). % ------------------------------- % argument_value(N, Arg) :- current_prolog_flag(argv, Cmdline), append(_, [--|UserArgs], Cmdline), Nth is N - 1, nth0(Nth, UserArgs, Arg). cmdlNumArg(Nth, N) :- argument_value(Nth, Arg), catch(atom_number(Arg, N), _, fail) ; halt(1).
Post Follow-up to this message"Isaac Gouy" <igouy2@yahoo.com> wrote in message news:b71129dd-7652-461f-89cb-aa0f56d57b51@e10g2000prf.googlegroups.com... > It's nearly 3 years since the last time I posted an fyi to this list, > so long that we've changed the name of the website! > > We have SWI-Prolog and YAP installed, the problem with Prolog on the > benchmarks game has always been finding competent Prolog programmers > willing to spend a little time writing such uninteresting ill-suited > programs. > > Here are the programs contributed for SWI-Prolog > > http://shootout.alioth.debian.org/g... /> =swiprolog I made changes to part of the programs to make them run with B-Prolog (the programs are available at www.probp.com/download/shootout.zip). I needed to change x:y to (x:y) because the operator ':' is defined in B-Prolog with a different precedence, and change X**Y to integer(X**Y) because X**Y returns float in B-Prolog even when the arguments are integers (same as in C). In addition, B-Prolog's built-ins instead are used for global variables and fetching command line arguments. Some of the programs do not run because big integers are used. One suggestion: In order not to make Prolog look terribly slow compared with other languages, you should give performance data on the fastest Prolog systems including Sicstus and Yap. B-Prolog is one of the fastest, but is not so fast in floats which are intensively used in the benchmakrs. Here is the screen shot from a run of the programs: c:\shootout>bp -g main binarytrees.out -- 6 stretch tree of depth 7 check: -1 128 trees of depth 4 check: -128 32 trees of depth 6 check: -32 long lived tree of depth 6 check: -1 c:\shootout>bp -g main fannkuch.out -- 4 [1,2,3,4] [2,1,3,4] [3,1,2,4] [1,3,2,4] [2,3,1,4] [3,2,1,4] [4,1,2,3] [1,4,2,3] [2,4,1,3] [4,2,1,3] [1,2,4,3] [2,1,4,3] [3,4,1,2] [4,3,1,2] [1,3,4,2] [3,1,4,2] [4,1,3,2] [1,4,3,2] [2,3,4,1] [3,2,4,1] [4,2,3,1] [2,4,3,1] [3,4,2,1] [4,3,2,1] Pfannkuchen(4) = 4 c:\shootout>bp -g main fasta.out -- 5 >ONE Homo sapiens alu GGCCGGGCGC >TWO IUB ambiguity codes ctaaDaaaagtacgN >THREE Homo sapiens frequency aaaataagaataaactaaaaataat c:\shootout>bp -g main nbody.out -- 5 -0.169075164 -0.169074105 c:\shootout>bp -g main nsieve.out -- 6 Primes up to 640000 52074 Primes up to 320000 27608 Primes up to 160000 14683 c:\shootout>bp -g main partialsums.out -- 4 2.407407407 (2/3)^k 2.784457050 k^-0.5 0.800000000 1/k(k+1) 3.450514093 Flint Hills 4.221679429 Cookson Hills 2.083333333 Harmonic 1.423611111 Riemann Zeta 0.583333333 Alternating Harmonic 0.723809524 Gregory c:\shootout>bp -g main pidigits.out -- 3 314 :3 c:\shootout>bp -g main recursive.out -- 4 Ack(3,4): 125 Fib(31.0): 2178309.0 Tak(9,6,3): 6 Fib(3): 3 Tak(3.0,2.0,1.0): 2.0 c:\shootout>bp -g main spectralnorm.out -- 5 main(5) 1.261206139 Cheers, Neng-Fa
Post Follow-up to this messageOn Apr 1, 9:08 am, "Neng-Fa Zhou" <nz...@acm.org> wrote: > "Isaac Gouy" <igo...@yahoo.com> wrote in message -snip- > One suggestion: In order not to make Prolog look terribly slow compared wi th > other languages, you should give performance data on the fastest Prolog > systems including Sicstus and Yap. B-Prolog is one of the fastest, but is > not so fast in floats which are intensively used in the benchmakrs. As I said, I have YAP installed but I don't have programs for YAP. The SWI-Prolog programs were written by a novice (transliterating them to B-Prolog won't fix them). To make Prolog look better we need better programs, and better programs that are tested on YAP as-well as SWI-Prolog.
Post Follow-up to this messageOn 2008-04-01, Isaac Gouy <igouy2@yahoo.com> wrote: > On Apr 1, 9:08 am, "Neng-Fa Zhou" <nz...@acm.org> wrote: > -snip- > > As I said, I have YAP installed but I don't have programs for YAP. > > The SWI-Prolog programs were written by a novice (transliterating them > to B-Prolog won't fix them). > > To make Prolog look better we need better programs, and better > programs that are tested on YAP as-well as SWI-Prolog. Its pretty unlikely you'll win anything using Prolog if speed is the criterium. Using dynamic typing and safe bignum arithmetic is enough to loose. Only YAP's hotspot compilation may get you somewhere on these tight loops with a lot of arithmetic. Prolog's strength is in problems that are nicely handled through search and backtracking. Other languages will have to implement similar mechanisms and doing this properly is not a very easy task. Development time and robustness may come to mind too. How many languages can do a `retry' in the debugger? Number chrunching isn't. Though I know of at least one person using GMP through SWI-Prolog because it programs so easily and on many problems the GMP library takes most of the time anyway. Cheers --- Jan
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.