Я использую функторы для получения массивов с произвольным доступом, используя arg/3 в SWI-Prolog. Что я делаю, так это загружаю значения из образца в функтор, который я создаю, и утверждаю массив для будущего использования.
После загрузки произвольный доступ действительно равен O (1), как я проверил, используя time/1. Проблема в том, что загрузка функтора из утверждения занимает много времени (время/1 предполагает, что оно линейно по размеру массива). Есть ли способ ускорить это до постоянного времени?
Минимальный код для воспроизведения:
:- dynamic
current_sample/1.
xrange(L,R,X):-
L < R,
( X = L;
X1 is L+1, xrange(X1,R,X)
).
arraybase_from_list__set_arg_from_list([], _, _).
arraybase_from_list__set_arg_from_list([Head|Tail], I, ResArray):-
I1 is I+1,
nb_setarg(I1, ResArray, Head),
arraybase_from_list__set_arg_from_list(Tail, I1, ResArray).
arraybase_from_list(List, ResArray):-
length(List, L),
functor(ResArray, custom_array_data, L),
arraybase_from_list__set_arg_from_list(List, 0, ResArray ).
test_array_create( N ):- % Creates a dummy array of squares of numbers fromo [0,N)
findall( X2, (xrange( 0,N,X), X2 is X*X), XList ),
arraybase_from_list( XList, Arr ),
assert( current_sample(Arr) ).
test_array_get(I,V):- % Unifies V with Ith element of Current sample
I0 is I+1,
current_sample(Arr), % Take turns timing this
arg( I0, Arr, V ). % And then timing this