recursive Prolog predicate?

后端 未结 2 414
迷失自我
迷失自我 2021-01-20 22:29

i am currently working on a project and i want to implement helper predicate in Prolog

break_down(N, L)

which works as follows



        
相关标签:
2条回答
  • 2021-01-20 22:45

    Here's a straight-forward recursive implementation using plain integer arithmetic and backtracking:

    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
    

    Sample query:

    ?- 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.
    
    0 讨论(0)
  • 2021-01-20 23:09

    Here's an implementation based on clpfd.

    :- use_module(library(clpfd)).
    

    As the predicate break_downFD/2 is non-recursive, the code is both readable and simple:

    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
    

    Sample query using SWI-Prolog:

    ?- 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.
    
    0 讨论(0)
提交回复
热议问题