为难题求解器序言程序生成矩阵

mmg*_*o27 2 matrix prolog

我写了一个序言程序来解决和显示数独之类的难题的解决方案。首先,如果网格为例如4x4,我会使用类似的方法:

main:-
     Matrix = [[_,_,_,_],[_,_,_,_],[_,_,_,_],[_,_,_,_]],
     solve_puzzle(Matrix),
     display_matrix(Matrix).
Run Code Online (Sandbox Code Playgroud)

但是我希望能够设置矩阵的大小,所以我写了这样的代码:

generate_list(N, [ ]) :-
    N =< 0, !.
generate_list(N, [_ | T]) :-
    N > 0,
    N2 is N - 1,
    generate_list(N2, T).

generate_matrix(_, N, []) :-
    N =< 0, !.
generate_matrix(M, N, [R|T]) :-
    generate_list(M,R),
    N2 is N - 1,
    generate_matrix(M, N2, T).
Run Code Online (Sandbox Code Playgroud)

然后我可以做:

main:-
    Rows = 4, Columns = 4,
    generate_matrix(Columns,Rows,Matrix),
    solve_puzzle(Matrix),
    display_matrix(Matrix).
Run Code Online (Sandbox Code Playgroud)

但这似乎减慢了我的程序。有没有更好的方法来生成N x M矩阵?

lur*_*ker 5

的组合length/2maplist/2运作良好的位置:

length_list(N, List) :- length(List, N).

generate_matrix(Cols, Rows, Matrix) :-
    length_list(Rows, Matrix),
    maplist(length_list(Cols), Matrix).
Run Code Online (Sandbox Code Playgroud)

我定义length_list/2了将length参数放在第一位,以便在中使用它maplist/2

length/2是关系型的,因此当您length/2使用实例化的长度(例如N)进行调用时,但将list参数作为变量调用时,它将导致[_,_, ..., _]带有N元素。因此,第一个length_list创建的列表Matrix看起来像是[_, _, _, ..., _]length Rows。然后maplist/2,对于的每个元素(行RMatrix,下面的调用length_list(Cols, R)将代替length 生成每个_列表。[_, _, ..., _]Cols

maplist/2将调用第一个参数作为第二个参数的每个元素的谓词,即列表。因为我们给它length_list(Cols),它呼吁,对于每一个元素[_, _, ..., _]call(length_list(Cols), _),这相当于,call(length_list(Cols, _)),这将实例_[_, _, ..., _],长度为匿名变量列表Cols

我使用SWI Prolog进行了一些快速的时间检查time/1,上述方法似乎要快得多。