1

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?

false
  • 10,264
  • 13
  • 101
  • 209
whd
  • 1,819
  • 1
  • 21
  • 52

2 Answers2

2

Alternatively you could use DCG as mentionned by @false in this great answer:

seq([])     --> [].
seq([E|Es]) --> [E], seq(Es).

divide(List, Length, Result) :-
    length(Result, Length),
    phrase((seq(_), seq(Result), seq(_)), List).
Community
  • 1
  • 1
m09
  • 7,490
  • 3
  • 31
  • 58
1

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...

CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • it does work for me 4 ?- length(X,3),sublist([1,2,3,4,5],X). X = [1, 2, 3] ; X = [1, 2, 4] ; X = [1, 2, 5] ;... – whd Mar 24 '12 at 20:33
  • try with sublist([],[]). sublist([X|T], [X|TS]) :- sublist(T, TS). sublist([_|T], X) :- sublist(T, X). – whd Mar 24 '12 at 20:35
  • Yes it is because i'm working on long lists and i'm not interested with all sublist just with all 4-length lists allocated from my List – whd Mar 24 '12 at 20:39