2015-02-12 8 views
-1

У меня есть 3 Ограничения для списка:Пролог ограничение

  1. списка Ins 1..9
  2. all_different (список)
  3. списков в списке -> я получаю некоторые списки из списка , каждый список из списка должен выполнять ограничение без разрыва. например:

    List1 = [1,3,2,4];
    List2 = [3,2,1];
    List3 = [5,7,6]
    НЕПРАВИЛЬНО: песни4 = [1,4,3]

1 Вопрос: У вас есть идея, чтобы установить ограничение 3? Я бы сортировал списки и проверял: Element1 = Element2 + 1?

В конце концов я хочу использовать маркировку ([далее], список)

2 Вопрос: Я получаю решение с маркировкой, если я установить contraint 3, как моя идея?

+5

[MCVE] (http://stackoverflow.com/help/mcve), пожалуйста. Придерживайтесь программ, ваши слова трудно понять. – false

+0

Я буду редактировать свой вопрос завтра. сначала я должен закончить свой башелортез. Пойди за плохой вопрос. – Hans

+0

Все ли списки в списке являются списком только одного элемента? Если да, то непонятно, почему они являются списками. – lurker

ответ

2

Я думаю, что это по линии того, что вы ищете ...

:- use_module(library(clpfd)). 

foo(L) :- 
    Len in 1..9, % lists of length 1 through 9 
    length(L, Len), 
    L ins 1..9, 
    label(L), 
    msort(L, LS), 
    series(LS). 

series([_]). 
series([X,Y|T]) :- Y #= X + 1, series([Y|T]). 

Поскольку вы уже сдерживая список к определенному поведению серии, с указанием all_different было бы излишним.

Другой подход может быть:

foo(L) :- 
    [Fst,Lst] ins 1..9, 
    Fst #=< Lst, 
    Len #= Lst - Fst + 1, 
    length(L, Len), 
    label([Fst,Lst]), 
    L ins Fst..Lst, 
    all_different(L), 
    label(L). 

Эти предикаты генерировать все возможные списки, отвечающие критериям, и должны добиться успеха, если и только если данный список соответствует критериям.

+1

Что касается первого фрагмента: есть «in/2' и' indomain/1' для отдельных конечных переменных домена. И: Замена '=: =' на '# =' сделает 'series/2' более общим. – mat

+0

@mat да спасибо. Я не привык использовать SWI. Я исправлю. Первоначально я имел '# =', но не думал, что это имеет значение, поскольку переменные уже были созданы или помечены. Но я согласен с вашим комментарием. – lurker

+1

с 'indomain/1', я имею в виду, что вы можете заменить' label ([Len]) 'на' indomain (Len) 'в обоих фрагментах. – mat

2

Это может быть и то, что вы ищете. Без сортировки, просто использование maximum и minimum:

:- use_module(library(clpfd)). 

listl(LSize, List) :- 
    length(List, LSize), 
    domain(List, 1, 9), 

    maximum(MaxL, List), 
    minimum(MinL, List), 

    all_different(List), 
    LSize #= MaxL - MinL + 1, 

    labeling([], List). 

С небольшой тест:

| ?- listl(4, L). 
L = [1,2,3,4] ? ; 
L = [1,2,4,3] ? ; 
L = [1,3,2,4] ? ; 
L = [1,3,4,2] ? 
yes 
| ?- 

Отказ от ответственности: Вопрос трудно было понять.