Reputation: 23
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
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 dcg. In this manner you would have a clean, program for this part too.
Upvotes: 1
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