write a prolog program to print out a square of n x n given character '*' on the screen.
EXAMPLE
?- square(5,5,'*').
*****
*****
*****
*****
*****
write a prolog program to print out a square of n x n given character '*' on the screen.
EXAMPLE
?- square(5,5,'*').
*****
*****
*****
*****
*****
You are talking about squares, no need to pass the width twice.
:- set_prolog_flag(double_quotes, chars).
seq([]) -->
[].
seq([X|Xs]) -->
[X],
seq(Xs).
lines([]) -->
[].
lines([Line|Lines]) -->
seq(Line),
"\n",
lines(Lines).
n_square_with(N, Sq, Ch) :-
length(Line, N),
length(Lines, N),
maplist(=(Ch), Line),
maplist(=(Line), Lines),
phrase(lines(Lines), Sq).
?- n_square_with(N, *, Sq).
N = 0, Sq = []
; N = 1, Sq = "*\n"
; N = 2, Sq = "**\n**\n"
; N = 3, Sq = "***\n***\n***\n"
; N = 4, Sq = "****\n****\n****\n****\n"
; ... .
This predicate n_square_with/3 is true for a size N, some character Ch and a text representing a square of that size. But that is not all you need. Now, you need to do something, you need to print this with format("~s",[Sq]). It is always a good idea to keep that part separated from the pure relations.
do_print_square(N, With) :-
n_square_with(N, With, Sq),
format("~s",[Sq]).
?- do_print_square(5,*).
*****
*****
*****
*****
*****
true.
The obvious solution is a nested loop:
forall(between(1, N, _),
( forall(between(1, N, _),
format("*")),
format("~n")
))
But the answer by false is better for some goodness measure you could come up with.
The format specification ~*c can be used to repeatedly output a given character.
square(N) :-
forall(between(1, N, _),
format('~*c\n', [N, 0'*])).
Example:
?- square(3).
***
***
***
true.
Assuming that this exercise is to teach you something about recursion, you can simply say (in pure ISO Prolog:
square(N,C) :- rectangle(N,N,C) .
rectangle(H,W,C) :- H > 0 , W > 0, lines(H,W,C).
lines(H,W,C) :- H > 0, line(W,C), H1 is H-1, lines(H1,W,C).
lines(0,_,_) .
line(W,C) :- W > 0 , write(C), W1 is W-1, line(W1,C).
line(0,_) :- nl.
Alternatively, using a "failure-driven loop":
square(H,W,C) :- ( between(1,H,_), line(W,C), fail ; true ).
line(W,C) :- ( between(1,W,_), write(C) ; nl ).