/* A table is created sequentially, then after the table is completed, threads read from the table concurrently N times Tabling is perturbed by making some dummy threads that execute and then join between the time the table is created and when it adds its first answer. This may help to flesh out global variables. */ :- import for/3 from basics. :- thread_shared num_is/1. :- dynamic num_is/1. :- assert((concurr_initialize(tableread(N,_)):- retractall(num_is(_)), assert(num_is(N)), (tableread_table(_),fail;true))). :- thread_shared tableread_table/1. :- table tableread_table/1. % This isn't good tabling style, but does make a good test. tableread_table(X):- test_thread_number(Threads), num_is(N), make_duplicate_goals(Threads,spin(N),List), exec_goals(List,Ids), join_list(Ids), for(X,1,N). spin(N):- num_is(N), for(_X,1,N), fail. spin(_). tableread(N,Str):- for(_X,1,N), tableread_table(_), fail. tableread(_,Str):- tableread_table(X), writeln(Str,X), fail. tableread(_,_).