序言。如何根据动态谓词打印矩阵?

时间:2015-04-27 12:59:56

标签: prolog

我有下一个矩阵:

map(1,[[2,0,0,0,0,0,0,0,0,0],
   [3,2,0,0,2,2,0,0,0,0],
   [0,2,0,0,2,0,0,0,0,0],
   [0,0,0,0,0,0,0,0,0,0],
   [0,0,2,0,0,0,1,0,0,0],
   [0,2,2,0,0,0,0,0,0,0],
   [0,0,0,0,0,0,0,1,1,0],
   [0,0,0,0,0,0,0,0,0,0],
   [0,0,0,0,0,0,0,0,0,0],
   [0,0,0,0,0,0,0,0,0,0]]).

和动态谓词:

:- dynamic visited/2.

和这个"功能"打印矩阵:

printEncoded(M) :-
maplist(\X^(maplist(\Y^(Y = 0
                        -> write(' ~ ')
                        ;
           write(' # ')),
                   X),
           nl),
       M).

我想根据visited / 2谓词打印矩阵,条件如下:          
            - 如果访问(X,Y)为真,则打印("矩阵元素的值")
- 如果访问(X,Y)为假,则打印("〜")。

我怎么能这样做? 在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

visited是动态的这一事实在这里完全无关紧要。 我完全可以强调你希望使用maplist(这会以某种方式感觉更“pythonic”),但在这种情况下你需要行和列索引。 如果您使用\X^...\Y^...,则只能获得行/元素,而不能获取其索引。如果您需要if-T-then-A-else-B之类的内容,则可以在Prolog中轻松地将其表达为(T,A;B)。这是一个粗略的草图,显式写出所有必要的递归(使用swipl运行):

:- initialization(main).
:- dynamic(visited).

matrix([
  [2,0,0,0,0,0,0,0,0,0],
  [3,2,0,0,2,2,0,0,0,0],
  [0,2,0,0,2,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,2,0,0,0,1,0,0,0],
  [0,2,2,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,1,1,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0]
]).

visited(0, 0).
visited(1, 0).
visited(1, 1).
visited(4, 6).
visited(5, 6).

printMatrix(M) :- printRows(M, 0).
printRows([], _).
printRows([H|T], R) :- 
  printRow(H, R, 0), 
  Rpp is R + 1, 
  printRows(T, Rpp).
printRow([], _, _) :- nl.
printRow([H|T], R, C) :- 
  (visited(R,C), write(H); write("~")),
  write(" "),
  Cpp is C + 1, 
  printRow(T, R, Cpp).

main :- matrix(M), printMatrix(M), halt.

这是输出:

2 ~ ~ ~ ~ ~ ~ ~ ~ ~ 
3 2 ~ ~ ~ ~ ~ ~ ~ ~ 
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 
~ ~ ~ ~ ~ ~ 1 ~ ~ ~ 
~ ~ ~ ~ ~ ~ 0 ~ ~ ~ 
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 
~ ~ ~ ~ ~ ~ ~ ~ ~ ~

关于dynamic(visited)的评论:一个人是否真的应该以这种方式保持某个全球状态的轨道是值得怀疑的。这完全污染了全局数据库,从而使代码不能用作较大程序的组件。