/* Elevator benchmark in Picat. From https://swi-prolog.discourse.group/t/vm-code-refactor-thoughts/3845/54 This model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ % import v3_utils. % import util. % import cp. main => go. /* Picat: elevator: 1.766s. elevator1: 1.081s elevator2: 0.954s elevator3: 1.758s elevator4: 1.105s SWI-Prolog version 8.3.22: ?- time((between(1,10000,_), elevator(10000,_), fail; true)). % 100,030,002 inferences, 3.002 CPU in 3.002 seconds (100% CPU, 33318585 Lips) true. B-Prolog: CPU time 36.158 seconds. ! GProlog: Don't work! Trealla: > 5minutes YAP: 0.754 CPU in 0.754 seconds (100% CPU) BinProlog, #12.01: > 4min? SICStus: don't have time/1 or between/3 ?- [elevator2]. ?- ensure_loaded(library(between)). ?- call_time((between(1,10000,_), elevator(10000,_), fail; true),Time). Time = 230 ? ECLiPSe CLP: [eclipse 12]: use_module(util). [eclipse 13]: between(1,10000,_), elevator(10000,_), fail; true. Yes (1.44s cpu) [eclipse 14]: between(1,10000,_), elevator(10000,_), fail; true. Yes (1.41s cpu) SICStus is the fastest so far: 0.230s! */ % elevator/2 go ?=> time((between(1,10000,_), elevator(10000,_), fail; true)), nl. go => true. % elevator1/2 go1 ?=> time((between(1,10000,_), elevator1(10000,_), fail; true)), nl. go1 => true. % elevator2/2 go2 ?=> time((between(1,10000,_), elevator2(10000,_), fail; true)), nl. go2 => true. % elevator3/1 go3 ?=> time((between(1,10000,_), _=elevator3(10000), fail; true)), nl. go3 => true. % elevator4/1 go4 ?=> time((between(1,10000,_), _=elevator4(10000), fail; true)), nl. go4 => true. % From % https://swi-prolog.discourse.group/t/vm-code-refactor-thoughts/3845/54 % elevator/2 elevator(N,M) :- elevator(N, 0, M). elevator(0, N, N) :- !. elevator(N, X, Y) :- M is N-1, H is X+1, elevator(M, H, Y). % elevator1/2 % Without is/2 assignements elevator1(N,M) :- elevator1(N, 0, M). elevator1(0, N, N) :- !. elevator1(N, X, Y) :- elevator1(N-1, X+1, Y). % elevator2/2. % Picat style: Slightly faster elevator2(N,M) => elevator2(N, 0, M). elevator2(0, N1, N2) => N1 = N2. elevator2(N, X, Y) => elevator2(N-1, X+1, Y). % elevator3/1 % Functional version % (inspired by Jan Burse's recursive Java code ) elevator3(N) = elevator3(N,0). elevator3(N,M) = Res => if N == 0 then Res = M else Res = elevator3(N-1,M+1) end. % elevator4/1: same as elevator3/1-2 without if/1 elevator4(N) = elevator4(N,0). elevator4(0,M) = M => true. elevator4(N,M) = elevator4(N-1,M+1) => true.