I’m using: SWI-Prolog version SWI-Prolog (threaded, 64 bits, version 9.2.2)
Hi,
I have this code:
create_p0( AMOUNT, VALUE) :- A is AMOUNT - 1, between( 0, A, VALUE).
p1e6( VALUE) :- A is floor( 1e6), create_p0( A, VALUE).
p1e5( VALUE) :- A is floor( 1e5), create_p0( A, VALUE).
p1e4( VALUE) :- A is floor( 1e4), create_p0( A, VALUE).
:- discontiguous benchmarks/1.
benchmarks( TERM) :- TERM = forall( p1e6(_), true).
p001( V1, V2) :- p1e6( VALUE), V1 is VALUE + 11, V2 is ( VALUE +3) * 7.
benchmarks( TERM) :- TERM = forall( p001(_,_), true).
:- table p001_tabled/2.
p001_tabled( V1, V2) :- p001( V1, V2).
benchmarks( TERM) :- TERM = forall( p001_tabled(_,_), true).
% benchmarks( TERM) :- TERM = forall( ( p001_tabled(V,_), p001_tabled(V,_)), true).
% benchmarks( TERM) :- TERM = forall( ( p1e6(V), p001_tabled(V,_)), true).
p002( V1, V2) :- p1e5( VALUE), V1 is VALUE + 11, V2 is ( VALUE +3) * 7.
benchmarks( TERM) :- TERM = forall( p002(_,_), true).
:- table p002_tabled/2.
p002_tabled( V1, V2) :- p002( V1, V2).
benchmarks( TERM) :- TERM = forall( p002_tabled(_,_), true).
% benchmarks( TERM) :- TERM = forall( ( p1e5(V), p002_tabled(V,_)), true).
p003( V1, V2) :- p1e4( VALUE), V1 is VALUE + 11, V2 is ( VALUE +3) * 7.
benchmarks( TERM) :- TERM = forall( p003(_,_), true).
:- table p003_tabled/2.
p003_tabled( V1, V2) :- p003( V1, V2).
benchmarks( TERM) :- TERM = forall( ( p003_tabled( V1, V2), p003_tabled( V1, V2)), true).
benchmarks( TERM) :- TERM = forall( ( p1e4(V), p003_tabled(V,_)), true).
benchmarks( TERM) :- TERM = forall( ( p1e4(V), p003_tabled(_,V)), true).
p004( V1, V2, V3) :- p1e4( VALUE), V1 is VALUE + 11, V2 is ( VALUE +3) * 7, V3 is ( VALUE + 5) * 4.
benchmarks( TERM) :- TERM = forall( ( p004( _, _, _)), true).
:- table p004_tabled/3.
p004_tabled( V1, V2, V3) :- p004( V1, V2, V3).
benchmarks( TERM) :- TERM = forall( ( p004_tabled( V1, V2, V3), p004_tabled( V1, V2, V3)), true).
benchmarks( TERM) :- TERM = forall( ( p004_tabled( V1, V2, _), p004_tabled( V1, V2, _)), true).
benchmarks( TERM) :- TERM = forall( ( p004_tabled( V1, _, _), p004_tabled( V1, _, _)), true).
benchmarks( TERM) :- TERM = forall( ( p004_tabled( V1, _, V3), p004_tabled( V1, _, V3)), true).
benchmarks( TERM) :- TERM = forall( ( p004_tabled( _, V2, V3), p004_tabled( _, V2, V3)), true).
benchmarks( TERM) :- TERM = forall( ( p004_tabled( V1, _, _), p004_tabled( V1, _, _)), true).
benchmarks( TERM) :- TERM = forall( ( p004_tabled( _, V2, _), p004_tabled( _, V2, _)), true).
benchmarks( TERM) :- TERM = forall( ( p004_tabled( _, _, V3), p004_tabled( _, _, V3)), true).
benchmarks( TERM) :- TERM = findall( ( V1, V2, V3), p004_tabled( V1, V2, V3), _) .
benchmarks( TERM) :- TERM = ( findall( ( V1, V2, V3), p004_tabled( V1, V2, V3), L), msort( L, _) ) .
%%%%%%%%%%%%%%%%%%%
writeln_numbervars( X) :- copy_term( X, Y), numbervars( Y), writeln( Y).
write_numbervars( X) :- copy_term( X, Y), numbervars( Y), write( Y).
bench_001 :- true
, PART1 = ( benchmarks( BENCHMARK), write_numbervars( BENCHMARK), write( ' '))
, PART2 = ( call_time( BENCHMARK, TIMES) -> writeln( TIMES) ; writeln( fail))
, forall( ( PART1, PART2), true)
.
And the results are:
(ins)?- bench_001.
forall(p1e6(A),true) time{cpu:0.152036984,inferences:2000003,wall:0.15209054946899414}
forall(p001(A,B),true) time{cpu:0.37155494199999994,inferences:4000002,wall:0.3717055320739746}
forall(p001_tabled(A,B),true) time{cpu:1.070959616,inferences:6000043,wall:1.071279764175415}
forall(p002(A,B),true) time{cpu:0.0372204009999999,inferences:400002,wall:0.03724193572998047}
forall(p002_tabled(A,B),true) time{cpu:0.10757483500000009,inferences:600033,wall:0.10759520530700684}
forall(p003(A,B),true) time{cpu:0.0036793770000000947,inferences:40002,wall:0.0036787986755371094}
forall((p003_tabled(A,B),p003_tabled(A,B)),true) time{cpu:6.241080409,inferences:100440033,wall:6.243399381637573}
forall((p1e4(A),p003_tabled(A,B)),true) time{cpu:12.305494142999999,inferences:200399968,wall:12.306515455245972}
forall((p1e4(A),p003_tabled(B,A)),true) time{cpu:25.277419118999997,inferences:300372854,wall:25.28428339958191}
forall(p004(A,B,C),true) time{cpu:0.004904959000000986,inferences:50002,wall:0.004904985427856445}
forall((p004_tabled(A,B,C),p004_tabled(A,B,C)),true) time{cpu:6.275805583,inferences:100460033,wall:6.277759790420532}
forall((p004_tabled(A,B,C),p004_tabled(A,B,D)),true) time{cpu:12.543872714999992,inferences:200410002,wall:12.547720909118652}
forall((p004_tabled(A,B,C),p004_tabled(A,D,E)),true) time{cpu:12.556584845000003,inferences:200410002,wall:12.56180191040039}
forall((p004_tabled(A,B,C),p004_tabled(A,D,C)),true) time{cpu:12.502370339999999,inferences:200410002,wall:12.504623651504517}
forall((p004_tabled(A,B,C),p004_tabled(D,B,C)),true) time{cpu:25.38937169399999,inferences:300400002,wall:25.3902587890625}
forall((p004_tabled(A,B,C),p004_tabled(A,D,E)),true) time{cpu:0.010050477000007163,inferences:70002,wall:0.010048151016235352}
forall((p004_tabled(A,B,C),p004_tabled(D,B,E)),true) time{cpu:25.19731204700001,inferences:300400002,wall:25.198315858840942}
forall((p004_tabled(A,B,C),p004_tabled(D,E,C)),true) time{cpu:38.133921052999995,inferences:400390002,wall:38.13900637626648}
findall((A,B,C),p004_tabled(A,B,C),D) time{cpu:0.0030484610000200973,inferences:20009,wall:0.003048419952392578}
findall((A,B,C),p004_tabled(A,B,C),D),msort(D,E) time{cpu:0.007130032999981495,inferences:20011,wall:0.00712895393371582}
true.
(ins)?- bench_001.
forall(p1e6(A),true) time{cpu:0.13977522500002237,inferences:2000001,wall:0.1397719383239746}
forall(p001(A,B),true) time{cpu:0.3678001289999884,inferences:4000002,wall:0.3677978515625}
forall(p001_tabled(A,B),true) time{cpu:0.1485414710000157,inferences:2000002,wall:0.14855289459228516}
forall(p002(A,B),true) time{cpu:0.03665447100001984,inferences:400002,wall:0.0366518497467041}
forall(p002_tabled(A,B),true) time{cpu:0.014550981000013508,inferences:200002,wall:0.014548540115356445}
forall(p003(A,B),true) time{cpu:0.004127347999997255,inferences:40002,wall:0.004127025604248047}
forall((p003_tabled(A,B),p003_tabled(A,B)),true) time{cpu:0.010568749000015032,inferences:70002,wall:0.010565757751464844}
forall((p1e4(A),p003_tabled(A,B)),true) time{cpu:0.010088303999992831,inferences:69990,wall:0.010085821151733398}
forall((p1e4(A),p003_tabled(B,A)),true) time{cpu:0.005279084000022749,inferences:61428,wall:0.005278110504150391}
forall(p004(A,B,C),true) time{cpu:0.005105455999995456,inferences:50002,wall:0.005105495452880859}
forall((p004_tabled(A,B,C),p004_tabled(A,B,C)),true) time{cpu:0.010921296000020675,inferences:70002,wall:0.01091766357421875}
forall((p004_tabled(A,B,C),p004_tabled(A,B,D)),true) time{cpu:0.010430209999981344,inferences:70002,wall:0.01042628288269043}
forall((p004_tabled(A,B,C),p004_tabled(A,D,E)),true) time{cpu:0.010878321000006963,inferences:70002,wall:0.010875225067138672}
forall((p004_tabled(A,B,C),p004_tabled(A,D,C)),true) time{cpu:0.01028998099999967,inferences:70002,wall:0.01029515266418457}
forall((p004_tabled(A,B,C),p004_tabled(D,B,C)),true) time{cpu:0.010308952000002591,inferences:70002,wall:0.010305643081665039}
forall((p004_tabled(A,B,C),p004_tabled(A,D,E)),true) time{cpu:0.009980528999989247,inferences:70002,wall:0.009977579116821289}
forall((p004_tabled(A,B,C),p004_tabled(D,B,E)),true) time{cpu:0.00969715099998325,inferences:70002,wall:0.009694099426269531}
forall((p004_tabled(A,B,C),p004_tabled(D,E,C)),true) time{cpu:0.007976431000003004,inferences:70002,wall:0.007982492446899414}
findall((A,B,C),p004_tabled(A,B,C),D) time{cpu:0.0027242280000052688,inferences:20009,wall:0.00272369384765625}
findall((A,B,C),p004_tabled(A,B,C),D),msort(D,E) time{cpu:0.007332769999976563,inferences:20010,wall:0.0073320865631103516}
true.
Look out for the 6 - 38 seconds lasting calculations.
The second run is impressive fast but the first run has some issues.
I assume this behaviour cannot be changed because every single access to the tabled predicates leads to a partial creation of an index. But can I explicitly index contents of the tabled predicates? That would be great.
Thanks in advance.