Search code examples
prologdcg

Divide List to pieces of needed length


I was trying to write predicate divide(L,Len,Slist) which will be true when Slist can unify with a List of length Len allocated from List L. for example

divide([1,2,3,4,5,6,7],3,Slist).

Should give such answers

Slist=[1,2,3];
Slist=[2,3,4];
Slist=[3,4,5];
Slist=[4,5,6];
Slist=[5,6,7];

But i couldn't find a better way then length(X,Len), sublist(L,X). but it does work too slow. How should look divide predicate?


Solution

  • sublist/2 doesn't seems to work as expected:

    ?- [library(dialect/sicstus/lists)].
    % library(dialect/sicstus/lists) compiled into sicstus_lists 0,00 sec, 14 clauses
    true.
    
    ?- L=[1,2,3,4,5,6], length(T, 3),sublist(T,L).
    L = [1, 2, 3, 4, 5, 6],
    T = [1, 2, 3] ;
    L = [1, 2, 3, 4, 5, 6],
    T = [1, 2, 4] ;
    L = [1, 2, 3, 4, 5, 6],
    T = [1, 2, 5] ;
    ....
    

    You could use append/3 instead:

    ?- L=[1,2,3,4,5,6], length(T, 3), append(_, Q, L), append(T, _, Q).
    L = [1, 2, 3, 4, 5, 6],
    T = [1, 2, 3],
    Q = [1, 2, 3, 4, 5, 6] ;
    L = [1, 2, 3, 4, 5, 6],
    T = [2, 3, 4],
    Q = [2, 3, 4, 5, 6] ;
    L = [1, 2, 3, 4, 5, 6],
    T = [3, 4, 5],
    Q = [3, 4, 5, 6] ;
    L = [1, 2, 3, 4, 5, 6],
    T = Q, Q = [4, 5, 6] ;
    false.
    

    I don't think it's very fast, just essential...