为解谜程序prolog生成矩阵



我编写了一个prolog程序来解决和显示类似数独的谜题的解决方案。起初,如果网格是例如4x4:,我会使用这样的东西

main:-
     Matrix = [[_,_,_,_],[_,_,_,_],[_,_,_,_],[_,_,_,_]],
     solve_puzzle(Matrix),
     display_matrix(Matrix).

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

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).

然后我可以做:

main:-
    Rows = 4, Columns = 4,
    generate_matrix(Columns,Rows,Matrix),
    solve_puzzle(Matrix),
    display_matrix(Matrix).

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

length/2maplist/2的组合在这里运行良好:

length_list(N, List) :- length(List, N).
generate_matrix(Cols, Rows, Matrix) :-
    length_list(Rows, Matrix),
    maplist(length_list(Cols), Matrix).

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

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

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

我使用SWI-Prolog的time/1进行了一些快速计时检查,上面的方法看起来明显更快。

最新更新