编写序言 star/1 程序

Writing a prolog star/1 program

我的任务是编写一个程序,给定一个包含 N 个整数的列表作为参数,打印 N 行,每一行 有 X 个星号,其中 X 在列表中的一个元素中。我得到了这个例子:

   ?-printstars([4,3,4,2]). 
    ****
    ***
    ****
    **

制作它的尝试并不顺利。

foreach([]).
foreach([N|R]) :- stars(N), foreach(R).

解决方案只产生了:

?- stars(4).
ERROR: Unknown procedure: stars/1 (DWIM could not correct goal)

在这里使用递归是个好主意:

printstars([]).
printstars([0 | R]) :- nl, printstars(R), !.
printstars([A | B]) :- write("*"), K is A - 1, printstars([K | B]).

你猜对了一半。您只需要定义 stars/1.

foreach([]).
foreach([N|R]) :- stars(N), foreach(R).

stars(0) :- nl.
stars(N) :-
    N > 0,
    write("*"),
    N2 is N - 1,
    stars(N2).
?- foreach([2,3,2,1]).
**
***
**
*
true 

由于打印是副作用,如果使用 forall/2 会更干净,如下所示:

print_stars(L) :-
    forall(member(X, L), stars(X)).

stars(X) :-
    forall(between(1, X, _), write(*)),
    nl.

此外,在 SWI-Prolog 中,您可以使用以下格式说明符来打印 N 星的序列:

format("~`*t~*+", [N]).

有了这个你可以摆脱第二个循环:

print_stars(L) :-
    forall(member(X, L), format("~`*t~*+~n", [X]).