Container capacity and size of (items)?

Does the Dialog standard library implement container capacity and size of items? I have read through the documentation several times and can’t seem to find this function which is common with most development systems.

For example, putting a chair in a wallet should not be preventable.

If it is not implemented, I guess I will have to improvise.

Thank you.

2 Likes

No. It’s up to you to implement them. Here is an example container with limited capacity, both in number and type of items it can hold:

#player
(current player *)
(* is #in #livingroom)

#livingroom
(name *)     living room
(your *)
(room *)
(descr *)    It's your living room.

#bill
(name *)    single bill
(item *)
(* is #in #livingroom)

#snowglobe
(name *)    snow globe
(item *)
(* is #in #livingroom)

#creditcard
(name *)    credit card
(item *)
(* is #in #livingroom)

#driverslicense
(name *)    driver's license
(item *)
(* is #in #livingroom)

#wallet
(name *)    wallet
(your *)
(item *)
(container *)
(* has capacity 2)
(* is #in #livingroom)

(* has $N items)
	(collect $Obj)
		*($Obj is #in *)
	(into $List)
	(length of $List into $N)

(prevent [put $Obj #in *])
	~($Obj is one of [#bill #creditcard #driverslicense])
	(The $Obj) won't fit in (the *).

(prevent [put $ #in *])
	(* has $N items)
	(* has capacity $N)
	(The *) is full, you can't put anything else in (it *).

(*(item $) is handled)

Edit: Typo.

4 Likes

Not that important, but I think that instead of collecting objects into a list to count them, it should be more performant to accumulate numbers (untested):

($Container has $N items)
    (accumulate 1)
        *($ is #in $Container)
    (into $N)

You could also change the 1 into a variable and you could bind the bulk of the object, if each has a different size.

(I also changed the * into a $Container variable so that it works with any object and not only the wallet. The same can be done with the second (prevent $) rule.)

5 Likes

I agree that your solution would be more performant, also more elegant.

In addition, swapping the order of these two queries would be beneficial for performance, so that unlimited containers won’t count their contents unnecessarily:

(prevent [put $ #in $Container])
	($Container has capacity $N)
	($Container has $N items)
	(The $Container) is full, you can't put anything else in (it $Container).

Edit: Parameterized the context.

3 Likes

Sorry for the double post, but here is the implementation where objects have bulk size different than 1 as @Natrium729 has suggested:

#player
(current player *)
(* is #in #livingroom)

#livingroom
(name *)     living room
(your *)
(room *)
(descr *)    It's your living room.

#bill	%% no size rule for bill, hence it has the default size 1
(name *)    single bill
(item *)
(* is #in #livingroom)

#snowglobe
(name *)    snow globe
(item *)
(* is #in #livingroom)

#creditcard
(name *)    credit card
(item *)
(* has size 2)
(* is #in #livingroom)

#driverslicense
(name *)    driver's license
(item *)
(* has size 5)
(* is #in #livingroom)

#wallet
(name *)    wallet
(your *)
(item *)
(container *)
(* has capacity 7)
(* is #in #livingroom)

(prevent [put $Obj #in *])
	~($Obj is one of [#bill #creditcard #driverslicense])
	(The $Obj) won't fit in (the *).


%% General rules

($Container has $N items)
	(accumulate $Size)
		*($Obj is #in $Container)
		($Obj has size $Size)
	(into $N)

(prevent [put $Obj #in $Container])
	($Container has capacity $C)
	($Obj has size $Size)
	($Container has $N items)
	($N plus $Size into $Total)
	($Total > $C)
	There isn't enough space in (the $Container),
	you can't put (the $Obj) in (it $Container).

($ has size 1)	%%default bulk size of objects

(*(item $) is handled)

Edit: Ordered rules into context specific and general sections.
Edit 2: Fixed typo in the first Edit note :stuck_out_tongue_winking_eye:

3 Likes

Wow! The solution is more difficult than I expected. I am enjoying Dialog and this was something I wanted to do.

Thanks to both of you so much. I appreciate your help very much!

Jeff

2 Likes