Пролог. Разбить целое число в натуральном выражении

Моя задача: найти количество разбиений натурального числа в натуральном выражении. Например: N=5. Ответ 7, потому что 5: {1,1,1,1,1}, {2,1,1,1}, {2,2,1}, {3,1,1}, {3,2}, {4,1}, {5}

Я написал решение на JS:

function pcount(number, limit) { 
 if (limit === 0) {
  if (number === 0) {
   return 1;
  }
  return 0;
 }

 if (limit <= number) {
  return pcount(number, limit - 1) + pcount(number - limit, limit);
 }

 return pcount(number, number);
}

но сейчас я пытаюсь написать это, используя Пролог, но есть некоторые трудности с pcount(number, limit - 1) + pcount(number - limit, limit); заявление.

Вот мой код:

PREDICATES
    check(integer,integer,integer)
    check(integer,integer)
CLAUSES
    check(0,0,Result):-
        Result=1.
    check(_,0,Result):-
        Result=0.
    check(Number,Limit,Result):-
        Limit<=Number,!,
        NN=Limit-1,
        RR=Number-Limit,
        check(Number,NN,Result1),
        check(RR,Limit,Result2),
        Result=Result1+Result2.
    check(A,B):-
        check(A,B,X),
        write(X).

    %check(number, limit - 1) + check(number - limit, limit);

GOAL
    check(2,2).

но это не работает Ошибка в этом предикате: check(Number,Limit,Result), Как я могу объединить результаты двух вызовов предикатов: check(Number, Limit-1)+check(Number-Limit,Limit)?

1 ответ

Решение

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

check(0, 0, 1).
check(N, 0, 0) :-
    N > 0.                   % Added constraint N > 0
                             %    avoids overlap with first clause
check(Number, Limit, Result):-
    Limit > 0,               % Added constraint Limit > 0 avoids overlap
                             %    with first clause and negative values
    Limit <= Number, !,
    NN = Limit - 1,
    RR = Number - Limit,
    check(Number, NN, Result1),
    check(RR, Limit, Result2),
    Result = Result1 + Result2.
check(Number, Limit, Result) :-    % Case were Limit > Number as in your
    Limit > Number,                %    original non-Prolog code
    check(Number, Number, Result).

check(A, B):-
    check(A, B, X),
    write(X).
Другие вопросы по тегам