Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 在prolog中断言和使用快速的大型数组_Arrays_Prolog_Swi Prolog_Prolog Directive Dynamic_Dcg - Fatal编程技术网

Arrays 在prolog中断言和使用快速的大型数组

Arrays 在prolog中断言和使用快速的大型数组,arrays,prolog,swi-prolog,prolog-directive-dynamic,dcg,Arrays,Prolog,Swi Prolog,Prolog Directive Dynamic,Dcg,我使用函子在SWI Prolog中使用arg/3获得随机访问数组。 我所做的是将样本中的值加载到我创建的functor中,并断言数组以备将来使用 一旦加载,随机访问确实是O(1),正如我使用time/1验证的那样。问题是从断言加载函子需要很多时间(time/1表示它在数组大小上是线性的)。 有什么方法可以加速到恒定时间吗 复制的最低代码: :- dynamic current_sample/1. xrange(L,R,X):- L < R, ( X = L;

我使用函子在SWI Prolog中使用arg/3获得随机访问数组。 我所做的是将样本中的值加载到我创建的functor中,并断言数组以备将来使用

一旦加载,随机访问确实是O(1),正如我使用time/1验证的那样。问题是从断言加载函子需要很多时间(time/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
:-动态
当前_样本/1。
X范围(L、R、X):-
L
在使用
当前样本/1
时,您会看到线性的开销,因为谓词的参数在调用谓词时是从数据库中复制的

有几种方法可以消除这种线性开销,将其转换为&Oscr;(1)

好办法 一个好方法是显式或隐式地携带整个数组,抛出所有需要访问它的谓词

您可以使用半文本表示法隐式地执行此操作(请参阅),或编写自己的自定义扩展规则。这与Haskell中的单子类似

考虑这样做!


更糟糕的方法 一种更糟糕、表面上更简单的方法是使用全局变量而不是全局数据库来存储术语

避免这种情况!

一些原因:

  • 它不是便携式的
  • 它引入了全局状态,使谓词难以读取和调试
  • 与简单地使用附加参数(隐式或显式)执行数组相比,它的效率要低得多
  • 它容易出错
  • 等等

谢谢。不幸的是,我的时间有点紧,所以我想在这里使用全局变量的简单解决方案。DCG是我很快就会学会的东西。感谢您抽出时间告诉我这一点!