2015-03-10 4 views
1

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

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

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, но я ничего не понимаю.

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

Спасибо!

ответ

3

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

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

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

:- [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 ; 
...