CLP в Прологе с последовательными суммами в списке

Пример моей проблемы с CLP (это небольшая часть более крупной проблемы, в которой используется библиотека clpfd):

Для списка длиной 5 факт el_sum(Pos,N,Sum) указывает, что N последовательных элементов, начиная с позиции Pos (индекс от 1), имеют сумму, равную Sum. Итак, если у нас есть

el_sum(1,3,4).
el_sum(2,2,3).
el_sum(4,2,5).

Тогда [1,2,1,4,1] будет работать для этого примера, поскольку 1 + 2 + 1 = 4, 2 + 1 = 3, 4 + 1 = 5.

Я борюсь с тем, как даже начать использовать el_sum's для поиска решений со списком ввода [X1,X2,X3,X4,X5]. Я думаю, мне стоит использовать findall, но я ничего не добился.

(Моя настоящая проблема намного больше, чем эта, поэтому я ищу решение, которое работает не только для трех фактов и небольшого списка).

Спасибо!


person mmgro27    schedule 10.03.2015    source источник


Ответы (2)


Здесь вы смешиваете монотонный мир ограничений с некоторой немонотонной количественной оценкой. Не пытайтесь смешать их слишком тесно. Вместо этого сначала преобразуйте эти факты, скажем, в список терминов.

el_sums(Gs) :-
   G = el_sum(_,_,_),
   findall(G, G, Gs).

И только тогда начните с части ограничения, которая теперь останется монотонной. Так:

?- el_sums(Gs), length(L5,5), maplist(l5_(L5), Gs).

l5_(L5, el_sum(P, N, S)) :-
   length([_|Pre], P),
   length(Cs, N),
   phrase((seq(Pre),seq(Cs),seq(_)), L5),
   list_sum(Cs,S).

seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).
person false    schedule 10.03.2015

Не уверен, что это поможет, я не понимаю вашего рабочего процесса ... откуда вообще взялся список? Так или иначе

:- [library(clpfd)].

el_sum(Pos,N,Sum) :-
    length(L, 5),
    L ins 0..100,
    el_sum(Pos,N,Sum,L),
    label(L), writeln(L).

el_sum(P,N,Sum,L) :-
    N #> 0,
    M #= N-1,
    Q #= P+1,
    el_sum(Q,M,Sum1,L),
    element(N,L,T),
    Sum #= Sum1 + T.
el_sum(_P,0,0,_L).

дает

?- el_sum(1,2,3).
[0,3,0,0,0]
true ;
[0,3,0,0,1]
true ;
...
person CapelliC    schedule 11.03.2015