Я бы смоделировал это с помощью термина и подпрограммы хранения, примерно так:
% this is a start state
start(storage(empty, empty, empty, empty)).
Это дает вам 4 места для хранения. Теперь вам нужно правило для вставки в них.
store(BoxSize, storage(empty, S2, S3, S4), storage(BoxSize, S2, S3, S4)).
store(BoxSize, storage(S1, empty, S3, S4), storage(S1, BoxSize, S3, S4)).
store(BoxSize, storage(S1, S2, empty, S4), storage(S1, S2, BoxSize, S4)).
store(BoxSize, storage(S1, S2, S3, empty), storage(S1, S2, S3, BoxSize)).
Это определяет store/3
, который принимает новый блок (представленный его размером) и вашу структуру из 4 областей памяти, и помещает этот блок в следующую пустую корзину в ваших областях памяти.
Теперь вы можете легко подсчитать, сколько места вы используете:
total(storage(S1, S2, S3, S4), Total) :-
findall(N, (member(N, [S1, S2, S3, S4]), number(N)), Sizes),
sumlist(Sizes, Total).
Соблазнительно написать Total is S1+S2+S3+S4
, но это не удастся, если какой-либо контейнер пуст.
Вот как вы используете то, что мы построили здесь:
?- start(Store), store(40, Store, NewStore),
store(50, NewStore, NewerStore), total(NewerStore, Total).
Store = storage(empty, empty, empty, empty),
NewStore = storage(40, empty, empty, empty),
NewerStore = storage(40, 50, empty, empty),
Total = 90 ;
Store = storage(empty, empty, empty, empty),
NewStore = storage(40, empty, empty, empty),
NewerStore = storage(40, empty, 50, empty),
Total = 90 ;
Как вы видите, мы можем добавлять вещи в магазин, и это дает нам альтернативные решения, перемещая корзины в разные слоты. Нанизывать состояние вокруг вручную не очень весело; вы, вероятно, записали бы это как свертку или использовали бы phrase/3
для обработки состояния, чтобы вам не нужно было создавать промежуточные состояния.
Я не совсем уверен, что вы пытаетесь сделать в отношении вашего списка из пяти пунктов. Поэтому вам, вероятно, придется взять его отсюда, чтобы выяснить, как вы хотите вставить их и удовлетворить свои ограничения. Я предполагаю, что вы хотите что-то сделать с select/3
, где вы положите их в мусорные ведра, получите размер и забудете обо всем, что осталось.