2016-04-04 7 views
1

Я пытаюсь решить следующую задачу, используя логические ограничения:Решения головоломки с Прологом, кидает ошибку «Аргументы не достаточно инстанцированы»

Пакера должен поставить 5 ящиков на длинный грузовик. В 5 ящиках содержатся цыплята, ячмень, лисицы, яд крысы и пшеница. Ящики нуждаются в для размещения в длинной линии без каких-либо зазоров между ними, чтобы:

• цыплята отделены от лисиц;

• Яд крысы не рядом с ячменем;

• Яд крысы находится не рядом с пшеницей.

Узнайте, как могут различные способы размещения этих ящиков в соответствии с этими ограничениями на упаковку.

Это то, что я до сих пор:

:- use_module(library(clpfd)). 

position(Crates) :- 
    Crates = [Chicken, Barley, Foxes, RatPoison, Wheat], 
    Regions ins 1..5, 
    Chicken #\= Foxes, 
    RatPoison #\= Barley, 
    RatPoison #\= Wheat, 
    labeling([], Regions). 

Он бросает ошибку «Аргументы не достаточно инстанцирован», когда я пытаюсь запустить его.

Я очень новичок в Prolog, поэтому любая помощь будет оценена по достоинству.

+2

Попробуйте '[Регионы] ins 1..5' и' labeling ([], [Regions]). 'Прочитайте документацию CLPFD относительно' ins' и 'labeling'. – lurker

ответ

2

Во-первых, вы ограничиваете Regions до 1..5 и не нанесете на него ярлык. Но вы хотите знать возможные позиции для 5 ящиков. Поэтому ограничьте и назовите Crates. Обратите внимание, что Regions является свободной переменной, когда вы ограничиваете ее значениями от 1 до 5, а длина списка Regions не ограничена вообще, поэтому ошибка при попытке маркировать ее. В этой версии в последнем задании положения предиката/1 список Crates уже ограничен фиксированной длиной (= 5) и значениями от 1 до 5 при маркировке.

Затем вы хотите, чтобы цыпленок и лисицы не были в одном ящике: Chicken #\= Foxes. Но в соответствии с описанием задачи они все равно находятся в разных ящиках. Вы скорее хотите, чтобы они не были в соседних ящиках. То же самое относится к рационам/ячменю и рационам/пшенице. Также нет двух ящиков в одном месте: вы можете использовать для этого библиотеку all_distinct/1 form (clpfd). Сведя все это вместе, вы получите что-то вроде:

:- use_module(library(clpfd)). 

position(Crates) :- 
    Crates = [Chicken, Barley, Foxes, RatPoison, Wheat], 
    Crates ins 1..5, 
    all_distinct(Crates), 
    not_adjacent(Chicken,Foxes), 
    not_adjacent(RatPoison,Barley), 
    not_adjacent(RatPoison,Wheat), 
    labeling([], Crates). 

not_adjacent(X,Y) :- 
    X #\= Y+1, 
    Y #\= X+1. 

Теперь попробуйте запросить позиции/1:

?- position(Crates). 
Crates = [1,2,4,5,3] ? ; 
Crates = [1,3,4,5,2] ? ; 
Crates = [1,4,3,2,5] ? 
... 

Если вы не хотите, чтобы пройти через все решения в интерактивном режиме вы можете использовать FindAll/3 и длина/2, чтобы показать все решения и посчитать их:

?- findall(Crates,position(Crates),L),length(L,X). 
L = [[1,2,4,5,3],[1,3,4,5,2],[1,4,3,2,5],[1,5,3,2,4],[2,1,4,3,5],[2,1,4,5,3],[2,3,4,1,5],[2,3,4,5,1],[2,3,5,1,4],[2,4,5,1,3],[2,5,4,1,3],[2,5,4,3,1],[3,1,5,4,2],[3,2,5,4,1],[3,4,1,2,5],[3,5,1,2,4],[4,1,2,3,5],[4,1,2,5,3],[4,2,1,5,3],[4,3,1,5,2],[4,3,2,1,5],[4,3,2,5,1],[4,5,2,1,3],[4,5,2,3,1],[5,1,3,4,2],[5,2,3,4,1],[5,3,2,1,4],[5,4,2,1,3]], 
X = 28 
+0

Большое вам спасибо, это очень полезно! – AgarAgar

1

Моя модель дает отличный результат WRT @tas answer.Может быть, я не совсем понимаю фразу

куры отделены от лисиц

, что я перевожу как

abs(Chicken - Foxes) #> 2 

Во всяком случае, полная модель

position(Crates) :- 
    Crates = [Chicken, Barley, Foxes, RatPoison, Wheat], 
    all_different(Crates), 
    Crates ins 1..5, 
    abs(Chicken - Foxes) #> 2, 
    abs(RatPoison - Barley) #> 1, 
    abs(RatPoison - Wheat) #> 1, 
    label(Crates). 

?- aggregate(count,Cs^position(Cs),N). 
N = 8. 
+2

Если цыпленок находится в ящике 3, а лисицы находятся в ящике 1 (например, [3,4,1,2,5]), они четко разделены, поскольку ящики «расположены в длинной линии», но «abs (курица - Foxes) #> 2' fail as 3-1 = 2. С 'abs (Chicken-Foxes) #> 1 ваша версия дает тот же результат, что и мой ;-) – tas

+0

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

+0

Я чувствую, что постановка проблемы несколько вводит в заблуждение, особенно когда речь идет о «лисицах» и «цыплятах» ... ИМО есть ровно одна лиса и ровно одна лиса. – repeat