2016-04-07 5 views
2

Привет, надеюсь, кто-то может мне помочь. Мне было просто интересно, был ли мой код ниже достаточным для создания матрицы из 12 x 12 и, предполагая, что «constrain (M)» вызывает все правильные ограничения, которые определены в правилах ниже, обозначая каждую из строк? На данный момент это не удается, и я отслеживал свои ограничения, поэтому я знаю, что все они работают, но не знали, было ли это потому, что я называю их за пределами основного предиката?Порядок выполнения операций Prolog CLP?

matrix(M) :- 
M = [R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12], 
R1 = [A,B,C,D,E,F,G,H,I,J,K,L], 
R2 = [A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2], 
R3 = [A3,B3,C3,D3,E3,F3,G3,H3,I3,J3,K3,L3], 
R4 = [A4,B4,C4,D4,E4,F4,G4,H4,I4,J4,K4,L4], 
R5 = [A5,B5,C5,D5,E5,F5,G5,H5,I5,J5,K5,L5], 
R6 = [A6,B6,C6,D6,E6,F6,G6,H6,I6,J6,K6,L6], 
R7 = [A7,B7,C7,D7,E7,F7,G7,H7,I7,J7,K7,L7], 
R8 = [A8,B8,C8,D8,E8,F8,G8,H8,I8,J8,K8,L8], 
R9 = [A9,B9,C9,D9,E9,F9,G9,H9,I9,J9,K9,L9], 
R10 = [A10,B10,C10,D10,E10,F10,G10,H10,I10,J10,K10,L10], 
R11 = [A11,B11,C11,D11,E11,F11,G11,H11,I11,J11,K11,L11], 
R12 = [A12,B12,C12,D12,E12,F12,G12,H12,I12,J12,K12,L12], 

constrain(M), 

labeling([],R1), 
labeling([],R2), 
labeling([],R3), 
labeling([],R4), 
labeling([],R5), 
labeling([],R6), 
labeling([],R7), 
labeling([],R8), 
labeling([],R9), 
labeling([],R10), 
labeling([],R11), 
labeling([],R12). 

ответ

3

Вы должны всегда отдельные ограничение размещения от фактического поиска (labeling/2).

Причина ясна: часто бывает чрезвычайно дорого искать конкретные решения. С другой стороны, проводка ограничений часто происходит очень быстро.

Если, как и в вашем случае, две части нечисто смешаны, вы не можете легко сказать, какая часть несет ответственность за непредвиденные проблемы, такие как инертение.

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

Ошибка, которая вызывает непредвиденный сбой, скорее всего, содержится в одном из правил, которые вы не размещали здесь. Вы можете узнать, какие правила связаны с провалом, систематически заменяя цели, в которых они вызывают, true. Таким образом, нет необходимости в трассировке: вы можете отлаживать программы CLP (FD) декларативно таким образом.

EDIT: Здесь представлена ​​дополнительная информация о разделении ограничений на проводку и поиск конкретных решений. Как введены в GUPU, мы будем использовать понятие сердечника относительно, которая обладает следующими свойствами:

  1. По соглашению, его имя заканчивается подчеркивания_.
  2. Также по соглашению, его последним аргументом является список переменных, которые должны быть помечены.
  3. Это Должности Ограничения CLP (FD). Это также называется (ограничение) моделирование часть или (ограничение) модель.
  4. Это неlabeling/2.

Часть поиска обычно выполняется label/1 или labeling/2.

Предположим, у вас есть предикат, где смешались эти два аспекта, например, в текущем случае:

 
matrix(M) :- 
     constraints_hold(M), 
     ... relate M to variables Vs ... 
     labeling(Strategy, Vs). 

Очевидно, что по причинам, изложенным выше, вызов labeling/2 является частью мы хотим Вытащите из этого предиката. Конечно, как вы заметили, мы все равно хотим каким-то образом получить доступ к переменным , которые должны быть помечены.

Мы делаем это следующим образом:

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

  • По соглашению, мы отражаем дополнительный аргумент, добавляя в подчеркивание   (_) к имени предиката.

Таким образом, мы получаем следующее соотношение: ядро ​​

 
matrix_(M, Vs) :- 
     constraints_hold(M), 
     ... relate M to variables Vs ... 

только недостающую часть (которую вы еще не сделали, но вы должны были сделать в любом случае), является (в данном случае: матрица ) и конечные переменные домена. Это та часть, которую я оставляю вам как простое упражнение. Подсказка: append/2.

После того, как вы сделали все это, вы можете решить всю задачу путем объединения основного отношения и labeling/2 в одном запросе или предикате:

?- matrix_(M, Vs), labeling(Strategy, Vs). 

Следует отметить, что это разделение между основной связью и поиском:

  • позволяет очень легко попробовать различные стратегии маркировки без перекомпиляции вашей программы.
  • позволяет определить важные процедурные свойства основного отношения без поиска конкретных решений.

Используйте введение и объяснение этого важного разделения в качестве индикатора при оценке качества любого текста относительно ограничений CLP (FD).

+0

Спасибо. Я понимаю, что отделять их лучше, но я не уверен, как отделить маркировку от домена. Меня только учили, что переменные, ограничения и маркировка идут в одном предикате, и хотя я понимаю, как работают матрицы/ограничения, это первый раз, когда я сталкивался с маркировкой, и я не очень хорошо разбираюсь в инструкциях библиотеки! – eponini

+0

Я добавил дополнительную информацию о том, как отделить эти аспекты. Я надеюсь, что это помогает! – mat

+0

Я никогда не сталкивался с термином «основное отношение» - это ваша собственная терминология или она исходит из литературы? Обычно я называю это * (ограничение) *. – jschimpf