как я могу нарисовать звездообразный треугольник, используя рекурсивный в prolog?

#prolog

#пролог

Вопрос:

этот код используется для рисования треугольника, пожалуйста, кто-нибудь может объяснить, как это работает

 predicates
star(integer).
count(integer,integer).
clauses
star(1):-write('*'),!.
star(X):-X<=0,!.
star(X):-count(1,X),Z=x-1,nl,star(Z),!.
count(X,Y):-X<=Y,write('*'),X1=X 1,count(X1,Y),!.
count(X<Y):-X>Y,!.
 

этот код рисует 5 звезд,
4,3,2,1, как я делаю, чтобы начать с 1,2,3,4,5

Комментарии:

1. с другим прологом, ?- N=5,forall(between(1,N,R),(forall(between(1,R,_),write(*)),nl)).

2. Синтаксические ошибки: <= следует заменить на =< поскольку <= имеет другое значение в prolog. x-1 должно быть X-1 . Назначение выполняется с is помощью not = , так, например, X1=X 1 должно быть X1 is X 1 .

3. @mbratch: я думаю, что это синтаксис, используемый Win-Prolog

4. @CapelliC ах, хорошо. Я не знаком с Win-Prolog. OP пометил это как SWI. Это означает, что ваш альтернативный 1-liner — хорошая альтернатива.

Ответ №1:

CapelliC получает похвалу за решение, но я лишь слегка изменю его для ясности и попытаюсь добавить некоторые пояснения:

 % Print a triangle of 1 to N stars
star(N) :- star(1, N).   % (I modified this slightly to accept N parameter)

% Print rows of NStars stars up to MaxStars stars
star(NStars , MaxStars ) :- 
    NStars =< MaxStars ,         % Print this row if NStars <= MaxStars
    row_of_stars(NStars),        % Print NStars for this row
    NStars1 is NStars 1,         % Increment the star count
    star(NStars1, MaxStars ).    % recursively print NStar1 to MaxStars triangle
star(NStars, MaxStars) :-
    NStars > MaxStars .          % Done when exceed MaxStars

% Print NumStars stars
row_of_stars(NumStars) :-
    row_of_stars(1, NumStars).   % Print NumStars starting with star number 1
row_of_stars(N, MaxStars) :-
    N =< MaxStars,               % This case is if star number doesn't exceed max
    write('*'),                  % Print a star
    N1 is N 1,                   % Increment the star count
    print_a_star(N1, MaxStars).  % Print the next star in the row
row_of_stars(N, MaxStars) :-
    N > MaxStars, nl.            % Done when exceed MaxStars
 

Эта проблема была решена с использованием двух основных предикатов: star и row_of_stars (ранее, count ). star Предикат управляет проблемой на уровне «треугольника». То есть он фокусируется на строках: сколько строк нужно напечатать и сколько звездочек должна получить каждая строка при печати. Другой предикат row_of_stars (или ранее count ) фокусируется на одном ряду из заданного количества звезд. Он просто печатает количество звезд, которое ему указано для печати. Поскольку проблема требует повторения или итерации по строкам, а также количества звездочек в строке, проблема упрощается путем разделения решения на эти две области.

Комментарии:

1. @CapelliC хаха, нет проблем. 🙂

Ответ №2:

Вы должны обойти верхний предел:

 star :- star(0, 5).

star(C, X) :- C < X, count(0, C), C1 is C 1, star(C1, X).
star(C, X) :- C >= X.

count(X, Y) :- X =< Y, write('*'), X1 is X 1, count(X1,Y).
count(X, Y) :- X > Y, nl.
 

Измените обратные операторы, чтобы они соответствовали вашему prolog (т. Е. is become = , >= become => и т. Д.).
Обратите внимание, что сокращения не являются обязательными… Используйте с осторожностью.

 ?- star.
*
**
***
****
*****
 

Комментарии:

1. КапеллиК, пожалуйста, можешь объяснить, как работают счетчик и звезда, пожалуйста

2. Сейчас я немного ленив 🙂 Подробное объяснение требует гораздо больше усилий, чем написание такого простого кода. Что там вы не можете понять?

3. о, ^ _^ большое спасибо… Я не могу понять, почему мы используем star и count вместе

4. Возможно, код мог бы быть проще, но я предпочел сохранить вашу структуру. В любом случае, я думаю, что ограничение цикла в вашем коде неявно равно 0, тогда, как я уже сказал, необходимость его обойти…