Ashish Kumar
Ashish Kumar

Reputation: 23

Writing onto a file in Prolog

Hi I have the following code:

show_result(Squares,MaxRow,MaxCol) :-
    show_result(Squares,MaxRow,MaxCol,1), nl.

show_result(_,MaxRow,_,Row) :- Row > MaxRow, !.
show_result(Squares,MaxRow,MaxCol,Row) :- 
    show_result(Squares,MaxRow,MaxCol,Row,1), nl,
    Row1 is Row+1, show_result(Squares,MaxRow,MaxCol,Row1).

show_result(_,_,MaxCol,_,Col) :- Col > MaxCol, !. 
show_result(Squares,MaxRow,MaxCol,Row,Col) :- 
    (memberchk(sq(Row,Col,X),Squares), !, write(X); write('#')),
    Col1 is Col+1, show_result(Squares,MaxRow,MaxCol,Row,Col1).  

When I run the code it shows the correct output on the screen.

But I want to write it to a file for which I have modified the code in this way:

show_result(Squares,MaxRow,MaxCol,SolutionFile) :-
   show_result(Squares,MaxRow,MaxCol,1,SolutionFile),
   open(SolutionFile,write,Stream),
   nl(Stream), close(Stream).

show_result(_,MaxRow,_,Row,SolutionFile) :- Row > MaxRow, !.
show_result(Squares,MaxRow,MaxCol,Row,SolutionFile) :- 
   show_result(Squares,MaxRow,MaxCol,Row,1,SolutionFile),
   open(SolutionFile,write,Stream),nl(Stream), close(Stream),
   Row1 is Row+1,
   show_result(Squares,MaxRow,MaxCol,Row1,SolutionFile).

show_result(_,_,MaxCol,_,Col,SolutionFile) :- Col > MaxCol, !. 
show_result(Squares,MaxRow,MaxCol,Row,Col,SolutionFile) :- 
   (  memberchk(sq(Row,Col,X),Squares),
      !,
      open(SolutionFile,write,Stream), write(Stream,X), close(Stream)
   ;  open(SolutionFile,write,Stream), write(Stream,'#'), close(Stream)
   ),
   Col1 is Col+1,
   show_result(Squares,MaxRow,MaxCol,Row,Col1,SolutionFile).  

This returns 'true' but doesn't write anything to the file. What do I need to change to get the output written to the file?

Upvotes: 2

Views: 74

Answers (2)

false
false

Reputation: 10102

Use your original program and:

..., once_to_file(show_result(Squares,MaxRow,MaxCol)), ...

once_to_file(Goal, File) :-
   open(File, write, S),
   with_output_to(S,once(Goal)),
   close(S).

This can be further improved using setup_call_cleanup/3.

But seriously, it would be much better for you to "write" the information into a list via a . In this manner you would have a clean, program for this part too.

Upvotes: 1

CapelliC
CapelliC

Reputation: 60004

although this seems overly inefficient, you could try to change the open/3 mode, from write to append.

Much better would be to pass around the file descriptor, instead of SolutionFile. So I would suggest

show_result(Squares,MaxRow,MaxCol,SolutionFile) :-
   open(SolutionFile,write,Stream),
   show_result(Squares,MaxRow,MaxCol,1,Stream),
   nl(Stream), close(Stream).

and remove all other open/3 from those predicates, writing instead into SolutionFile:

how_result(_,MaxRow,_,Row,SolutionFile) :- Row > MaxRow, !.
show_result(Squares,MaxRow,MaxCol,Row,SolutionFile) :- 
   show_result(Squares,MaxRow,MaxCol,Row,1,SolutionFile),
   nl(SolutionFile),
   Row1 is Row+1,
   show_result(Squares,MaxRow,MaxCol,Row1,SolutionFile).

show_result(_,_,MaxCol,_,Col,SolutionFile) :- Col > MaxCol, !. 
show_result(Squares,MaxRow,MaxCol,Row,Col,SolutionFile) :- 
   (  memberchk(sq(Row,Col,X),Squares),
      !,
      write(SolutionFile,X)
   ;  write(SolutionFile,'#')
   ),
   Col1 is Col+1,
   show_result(Squares,MaxRow,MaxCol,Row,Col1,SolutionFile).  

note: untested code.

Since you mention that the output is already correct, an alternative, available in SWI-Prolog, would be to keep the origincal program unchanged, and call it using with_output_to.

Another alternative, use old fashioned IO, prefixing execution with tell/1, and resume after execution with told/0. But this IO modality is deprecated, since it leads to several difficulties...

Upvotes: 0

Related Questions