2015-04-14 5 views
1

Учитывая следующий код:clpfd - ограничение верхней связь домена, как максимум списка элементов

solve(G,L) :- 
    G = [A0,B0,C0,D0], 
    L = [A1,B1,C1,D1,A2,B2,C2,D2,A3,B3,C3,D3,A4,B4,C4,D4], 
    G ins 0..4, 
    L ins 0..max(G). 

Я хочу тяготы L не содержит значение, которые выше, чем максимальное значение, содержащееся в G , но при использовании этого синтаксиса я получаю «ошибку домена». Есть ли другой способ выразить это?

+0

Имеет ли 'G' длину в четыре раза? – repeat

+0

Да, максимальное значение в G равно 4 и фиксировано. –

ответ

2

По существу, вы были на правильном пути. Но L ins 0..max(G) не работает, потому что границы, которые вы переходите на ins/2, должны быть целыми числами или inf или sup.

SWI-Prolog clpfd manual page поддерживает в конечной области арифметических выражений max, поэтому мы первое государство, которое MaxG это максимум A0, B0, C0 и D0. Затем укажем, что MaxG больше или равно каждому элементу в списке L.

Собираем все вместе:

:- use_module(library(clpfd)). 

gte_than(X,Y) :- 
    X #>= Y. 

solve(G,L) :- 
    G = [A0,B0,C0,D0], 
    L = [A1,B1,C1,D1,A2,B2,C2,D2,A3,B3,C3,D3,A4,B4,C4,D4], 
    G ins 0..4, 
    L ins 0..sup, 
    MaxG #= max(max(A0,B0),max(C0,D0)), 
    maplist(gte_than(MaxG),L). 

Вот некоторые вопросы:

?- solve([0,1,2,1], [0,1,2,1,1,2,1,2,1,0,1,2,1,1,1,2]). 
true. 

?- solve([0,1,2,1], [0,3,2,1,1,2,1,2,1,0,1,2,1,1,1,2]). 
false. 

?- solve([0,3,2,1], [0,3,2,1,1,2,1,2,1,0,1,2,1,1,1,2]). 
true. 

?- solve([0,3,2,1], [0,3,2,1,1,2,4,4,1,0,1,2,1,1,1,2]). 
false. 

?- solve([4,3,2,1], [0,3,2,1,1,2,4,4,1,0,1,2,1,1,1,2]). 
true. 

Примечание стороны: SICStus Пролог имеет специализированный arithmetic constraint имени maximum/2 мы могли бы использовать здесь, но это ограничение пока недоступно в clpfd с SWI-Prolog.

+0

Я забыл указать, что я использую SWI-Prolog. Это все еще применяется? –

+1

+1! Если в вашей системе нет 'maximum/2', я предлагаю следующее определение' list_max/2': Вспомогательный предикат: 'max_ (L, Max0, Max): - Max # = max (L, Max0) .' и главный предикат: 'list_max ([L | Ls], Max): - foldl (max_, Ls, L, Max) .'. Это дает вам 'list_max/2', связывая список выражений CLP (FD) с максимальным значением в каждой системе, которая поддерживает' max/2'. – mat

+0

Спасибо, решение работает! Я просто получаю это предупреждение: 'Предупреждение: c: /.../ strata.pro:10: Тест всегда прав: var (MaxG)' и мне было интересно, о чем это? –

 Смежные вопросы

  • Нет связанных вопросов^_^