简体   繁体   中英

Accessing a list in Prolog outside of its predicate

I'm a Prolog newbie working on an assignment that's been giving me tremendous trouble. I have to write a program that solves an n by n puzzle; the solution's predicate has two parameters, game(Size, SolList) where Size is the size of the board and SolList is the solution of the puzzle in the form of a list. Here is the code provided by the professor to generate the board:

generate_board(N, Board) :-
  generate_board(N, N, Board), !.

generate_board(0, _, []).
generate_board(1, Columns, [LastRow]) :-
  row(Columns, LastRow).
generate_board(Rows, Columns, [R1|RestOfBoard]) :-
  row(Columns, R1),
  NewRows is Rows - 1,
  generate_board(NewRows, Columns, RestOfBoard).

Solving the puzzle requires "clicking" certain squares on the board. What I want to do is generate a list of the squares - for example, when Size = 5, the list would have a length of 25 and go from 0 to 24 - in (if it's possible) the generate_board/2 predicate. I then want Prolog to remember that list and when using a different predicate to solve the puzzle and present solutions, to register the "clicks" on the necessary elements of my list and output it in the console. I don't know of a way to work around the local nature of lists in Prolog, and so I'm at a loss how to jump this hurdle.

If you can't just pass the list around as has been suggested in the comments, a good way to "remember" it would be by asserting and retracting it.

So for instance:

setup_board :-
   generate_board(5, L),
   assert(board(L)).

do_something :-
   retract(board(L)),
   process_board(L, L1),
   assert(board(L1)).

You do have to be careful with this, though. If process_board(L, L1) fails, your board will have been retracted, but no new board will have been asserted.

You can fix this this by using the Prolog "if -> then":

do_something :- 
   retract(board(L)),
   (process_board(L, L1) -> assert(board(L1)) ; assert(board(L))).

In other words, if process_board(L, L1) succeeds, assert the new board, otherwise reassert the old board.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM