![]() | ![]() | ![]() | Adding Dimensions | ![]() |
A central concept in GBBopen is dimensionality. Dimensional abstraction of space instances, unit instances, and proximity-based retrieval patterns is used to provide a semantically meaningful separation of blackboard-repository storage mechanisms from system and application code. This separation provides flexibility in developing and evolving complex blackboard applications and allows GBBopen to change storage and search strategies and optimizations dynamically.
Each space instance can be created as a conceptual hyper-dimensional volume. Unit instances occupy multidimensional extent based on their attributes. The location of a unit instance within the space instance is determined by the intersection of the space instance's dimensionality and the unit instance's dimension values.
GBBopen supports three types of dimensions:
In this exercise, we will redefine the locationx and y, that represent Euclidean
positions on a two-dimensional plane. Then we will create a two-dimensional
known-worldlocationknown-world
tutorial-example.lisp
(in-package :gbbopen-user)
(define-unit-class location ()
(x y))
:gbbopen-userlocation unit class
Edit your tutorial-example.lisplocation
(define-unit-class location ()
(x y)
(:dimensional-values
(x :point x)
(y :point y)))
In this tutorial, we will highlight code additions and changes using a
black font.
The :dimensional-valueslocationx
and y, and that the value of each dimension will be a single numeric
value obtained from the slots x and y, respectively.
Because we chose to use the same name for each dimension and its associated
slot value, our :dimensional-values
(define-unit-class location ()
(x-slot y-slot)
(:dimensional-values
(x :point x-slot)
(y :point y-slot)))
which clarifies the semantics of the :dimensional-values
We could compile and load the entire tutorial-example.lispC-c
C-cC-c C-xlocation
location unit instance
Let's test our new location
gbbopen-user> (defparameter ui (make-instance 'location :x 40 :y 60)) ui gbbopen-user>and display its description:
gbbopen-user> (describe-instance ui)
Location #<location 1>
Instance name: 1
Space instances: None
Dimensional values:
x: 40
y: 60
Non-link slots:
x: 40
y: 60
Link slots: None
gbbopen-user>
Note the dimensional values for the x and y dimensions.
known-world space instance
Create the known-world
gbbopen-user> (defparameter si (make-space-instance '(known-world))) si gbbopen-user>
Now, add the location
gbbopen-user> (add-instance-to-space-instance ui si)
Warning: In add-instance-to-space-instance: #<location 1>
does not share any dimensions with space instance
#<standard-space-instance (known-world)>.
#<location 1>
gbbopen-user>
GBBopen has warned us that our locationknown-worldknown-world
gbbopen-user> (describe-blackboard-repository)
Space Instance Contents
-------------- --------
known-world 1 instance (1 location)
Unit Class Instances
---------- ---------
location 1
standard-space-instance 1
---------
2 instances
gbbopen-user>
but we cannot perform dimension-based retrieval of our locationknown-worldknown-world
Let's delete the known-worldx and y dimensions:
gbbopen-user> (delete-space-instance si)
#<deleted-unit-instance standard-space-instance (known-world)>
gbbopen-user> (setf si (make-space-instance '(known-world)
:dimensions '((x :ordered) (y :ordered))))
#<standard-space-instance (known-world)>
gbbopen-user>
We have specified x and y as ordered dimensions, making the
known-worldVerify the dimensionality of the known-world
gbbopen-user> (describe-space-instance si)
Standard-space-instance #<standard-space-instance (known-world)>
Allowed unit classes: t
Dimensions:
(x :ordered)
(y :ordered)
gbbopen-user>
location unit instance to the new
known-world
Add the locationknown-world
gbbopen-user> (add-instance-to-space-instance ui si) #<location 1> gbbopen-user>The dimension warning is gone.
location to the known-world
automatically
Up to this point, we have used locationknown-world:initial-space-instances
Add the following :initial-space-instanceslocationtutorial-example.lisp
(define-unit-class location ()
(x y)
(:dimensional-values
(x :point x)
(y :point y))
(:initial-space-instances (known-world)))
Compile and load the new location
location unit instances
Let's test our new location
gbbopen-user> (make-instance 'location :x 70 :y 30) #<location 2> gbbopen-user>and confirm that the new
locationknown-world
gbbopen-user> :dsbb
Space Instance Contents
-------------- --------
known-world 2 instances (2 location)
Unit Class Instances
---------- ---------
location 2
standard-space-instance 1
---------
3 instances
gbbopen-user>
Here we used GBBopen's :dsbb REPL command, which is equivalent to
evaluating (describe-blackboard-repository)Now, let's populate the known-world
gbbopen-user> (make-instance 'location :x 20 :y 20) #<location 3> gbbopen-user> (make-instance 'location :x 25 :y 25) #<location 4> gbbopen-user> (make-instance 'location :x 20 :y 30) #<location 5> gbbopen-user>and verify that they are all on the
known-world
gbbopen-user> :dsbb
Space Instance Contents
-------------- --------
known-world 5 instances (5 location)
Unit Class Instances
---------- ---------
location 5
standard-space-instance 1
---------
6 instances
gbbopen-user>
We have seen how we can use locationknown-world
gbbopen-user> (find-instances 'location '(known-world) :all) (#<location 5> #<location 4> #<location 3> #<location 2> #<location 1>) gbbopen-user>
Now that we have added x and y dimensions to
locationknown-worldlocation
gbbopen-user> (find-instances 'location '(known-world)
'(and (= x 20) (= y 20)))
(#<location 3>)
gbbopen-user>
We can use location
gbbopen-user> (find-instances 'location '(known-world)
'(and (= x 20) (= y 20)))
(#<location 3>)
gbbopen-user> (describe-instance (first *))
Location #<location 3>
Instance name: 3
Space instances: ((known-world))
Dimensional values:
x: 20
y: 20
Non-link slots:
x: 20
y: 20
Link slots: None
gbbopen-user>
Note that we used Common Lisp's REPL * variable that is always set to
the value returned by evaluating the last REPL expression (in this case, the
result of location unit instances
It would be convenient if we could easily see the coordinates of
locationprint-objectlocation
Add the following locationtutorial-example.lisp
(define-unit-class location ()
(x y)
(:dimensional-values
(x :point x)
(y :point y))
(:initial-space-instances (known-world)))
(defmethod print-instance-slots ((location location) stream)
(call-next-method)
(when (and (slot-boundp location 'x)
(slot-boundp location 'y))
(format stream " (~s ~s)"
(x-of location)
(y-of location))))
The method first performs a (call-next-method)locationx and y slots are bound and, if so,
writes the locationx and
y, formatted together.)
Now, compile and load the
gbbopen-user> (find-instances 'location '(known-world)
'(= (x y) (20 20)))
(#<location 3 (20 20)>)
gbbopen-user>
Note that this time we used a two-dimensional (x,y) retrieval
pattern rather than the conjunction of two one-dimensional patterns that we
used previously. The two patterns are equivalent, but often a
higher-dimensional pattern may be more convenient than a conjunction. Also
note that we can see immediately that we retrieved the desired
location
Let's try some additional dimensional retrievals. First, find all
locationx position of 20:
gbbopen-user> (find-instances 'location '(known-world)
'(= x 20))
(#<location 5 (20 30)> #<location 3 (20 20)>)
gbbopen-user>
Find all locationx and y
coordinates are less than or equal to 25:
gbbopen-user> (find-instances 'location '(known-world)
'(<= (x y) (25 25)))
(#<location 4 (25 25)> #<location 3 (20 20)>)
gbbopen-user>
Find all locationx coordinates are
between 0 and 40 (inclusive) and whose y coordinates are between 60 and
100 (inclusive):
gbbopen-user> (find-instances 'location '(known-world)
'(within (x y) ((0 40) (60 100))))
(#<location 1 (40 60)>)
gbbopen-user>
Find all location
gbbopen-user> (find-instances 'location '(known-world)
'(not (within (x y) ((0 40) (60 100)))))
(#<location 5 (20 30)> #<location 4 (25 25)> #<location 3 (20 20)>
#<location 2 (70 30)>)
gbbopen-user>
Recall that we assigned location1 to the global variable
ui:
gbbopen-user> ui #<location 1 (40 60)> gbbopen-user>and we can retrieve it by its
x and y coordinates:
gbbopen-user> (find-instances 'location '(known-world)
'(= (x y) (40 60)))
(#<location 1 (40 60)>)
gbbopen-user>
Let's change its x position to 80 and try retrieving it again:
gbbopen-user> (setf (x-of ui) 80)
80
gbbopen-user> (find-instances 'location '(known-world)
'(= (x y) (40 60)))
nil
gbbopen-user>
It has moved on the known-worldlocation1 unit instance is now at (80, 60):
gbbopen-user> (find-instances 'location '(known-world)
'(= (x y) (80 60)))
(#<location 1 (80 60)>)
gbbopen-user>
Also note that the textual representation of location1
shows the new x slot value.
The GBBopen Project
![]() | ![]() | ![]() | Adding Dimensions | ![]() |