2015-03-26 2 views
2

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

break_down(N, L)

, который работает следующим образом

?- break_down(1,L). 
L = [1] ; 
false. 
?- break_down(4,L). 
L = [1, 1, 1, 1] ; 
L = [1, 1, 2] ; 
L = [1, 3] ; 
L = [2, 2] ; 
L = [4] ; 
false. 

и так далее для любого натурального числа N.

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

break_down(1,[1]). 
break_down(N,L):- 
    N>0, 
    N1 is N-1, 
    break_down(N1,L1), 
    append(L1,[1],L). 

, который генерирует только первый выходной результат:

L = [1, 1, 1, 1] ; 

любое предложение, как отредактировать мой код, чтобы получить остальное?

+0

На основании постановки задачи, вам нужно добавлять некоторые номера куда-нибудь, но ваше решение не добавляет никаких чисел. Он только добавляет. – lurker

ответ

1

Вот прямолинейный рекурсивная реализация с помощью простого целочисленную арифметику и откаты:

break_down(N,L) :- 
    break_ref_down(N,1,L).  % reference item is initially 1 

break_ref_down(0,_,[]). 
break_ref_down(N,Z0,[Z|Zs]) :- 
    between(Z0,N,Z),    % multiple choices 
    N0 is N-Z, 
    break_ref_down(N0,Z,Zs).  % pass on current item as reference 

Пример запроса:

?- break_down(8,Zs). 
    Zs = [1,1,1,1,1,1,1,1] 
; Zs = [1,1,1,1,1,1,2] 
; Zs = [1,1,1,1,1,3] 
; Zs = [1,1,1,1,2,2] 
; Zs = [1,1,1,1,4] 
; Zs = [1,1,1,2,3] 
; Zs = [1,1,1,5] 
; Zs = [1,1,2,2,2] 
; Zs = [1,1,2,4] 
; Zs = [1,1,3,3] 
; Zs = [1,1,6] 
; Zs = [1,2,2,3] 
; Zs = [1,2,5] 
; Zs = [1,3,4] 
; Zs = [1,7] 
; Zs = [2,2,2,2] 
; Zs = [2,2,4] 
; Zs = [2,3,3] 
; Zs = [2,6] 
; Zs = [3,5] 
; Zs = [4,4] 
; Zs = [8] 
; false. 
1

Вот реализация на основе .

:- use_module(library(clpfd)). 

В предикате break_downFD/2 нерекурсивен, код для чтения и прост:

break_downFD(N,Zs) :- 
    length(Max,N),  % multiple choices 
    append(_,Zs,Max), 
    Zs ins 1..N, 
    sum(Zs,#=,N), 
    chain(Zs,#=<),  % enforce sequence is non-descending 
    labeling([],Zs).  % multiple choices, possibly 

Пример запрос с использованием SWI-Пролог:

?- break_downFD(6,Zs). 
    Zs = [1,1,1,1,1,1] 
; Zs = [1,1,1,1,2] 
; Zs = [1,1,1,3] 
; Zs = [1,1,2,2] 
; Zs = [1,1,4] 
; Zs = [1,2,3] 
; Zs = [2,2,2] 
; Zs = [1,5] 
; Zs = [2,4] 
; Zs = [3,3] 
; Zs = [6] 
; false. 
Смежные вопросы