Soar Kernel
9.3.2 08-06-12
Main Page
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
src
gdatastructs.h
Go to the documentation of this file.
1
/*************************************************************************
2
* PLEASE SEE THE FILE "license.txt" (INCLUDED WITH THIS SOFTWARE PACKAGE)
3
* FOR LICENSE AND COPYRIGHT INFORMATION.
4
*************************************************************************/
5
6
/* gdatastructs.h */
7
8
/* ========================================================================= */
9
/* */
10
/* Global Data Structures */
11
/* */
12
/* ========================================================================= */
13
14
#ifndef GDATASTRUCTS_H
15
#define GDATASTRUCTS_H
16
17
#include "
symtab.h
"
/* needed for definition of symbol_union */
18
#include "
kernel.h
"
/* needed for definition of NIL */
19
#include "
soar_module.h
"
/* needed for definition of memory pool allocator */
20
21
#include <set>
22
23
#ifdef __cplusplus
24
//extern "C"
25
//{
26
#endif
27
28
typedef
char
Bool
;
29
typedef
unsigned
char
byte
;
30
typedef
uint64_t
tc_number
;
31
typedef
signed
short
goal_stack_level
;
32
typedef
struct
complex_test_struct
complex_test
;
33
typedef
struct
cons_struct
cons
;
34
typedef
struct
dl_cons_struct
dl_cons
;
35
typedef
struct
wme_struct
wme
;
36
typedef
union
symbol_union
Symbol
;
37
typedef
cons
list
;
38
39
#ifdef USE_MEM_POOL_ALLOCATORS
40
template
<
class
T>
41
class
SoarMemoryPoolAllocator;
42
43
typedef
std::set< wme*, std::less< wme* >,
soar_module::soar_memory_pool_allocator< wme* >
>
wma_pooled_wme_set
;
44
typedef
std::map< Symbol*, uint64_t, std::less< Symbol* >,
soar_module::soar_memory_pool_allocator< std::pair< Symbol*, uint64_t >
> >
wma_sym_reference_map
;
45
#else
46
typedef
std::set< wme* >
wma_pooled_wme_set
;
47
typedef
std::map< Symbol*, uint64_t >
wma_sym_reference_map
;
48
#endif
49
50
/* REW: begin 09.15.96 */
51
52
/* ------------------------------------------------------------------------
53
Goal Dependency Set
54
55
The Goal Dependency Set is a data strcuture used in Operand2 to maintain
56
the integrity of a subgoal with respect to changes in supergoal WMEs.
57
Whenever a WME in the goal's dependency set changes, the goal is immediately
58
removed. The routines for maintaining the GDS and determining if a goal
59
should be retracted are in decide.c
60
61
Fields in a goal dependency set:
62
63
goal: points to the goal for which this dependency set was created.
64
The goal also has a pointer back to the GDS.
65
66
wmes_in_gds: A DLL of WMEs in the goal dependency set
67
68
The GDS is created only when necessary; that is, when an o-suppported WME
69
is created in some subgoal and that subgoal has no GDS already. The
70
instantiations that led to the creation of the o-supported WME are
71
examined; any supergoal WMEs in these instantiations are added to the
72
wmes_in_gds DLL. The GDS for each goal is examined for every WM change;
73
if a WME changes that is on a GDS, the goal that the GDS points to is
74
immediately removed.
75
76
When a goal is removed, the GDS is not immediately removed. Instead,
77
whenever a WME is removed (or when it is added to another GDS), we check
78
to also make certain that its GDS has other WMEs on the wmes_in_gds DLL.
79
If not, then we remove the GDS then. This delay avoids having to scan
80
over all the WMEs in the GDS in addition to removing the goal (i.e., the
81
maintenance cost is amortized over a number of WM phases).
82
83
*/
84
85
typedef
struct
gds_struct
{
86
Symbol
*
goal
;
/* pointer to the goal for the dependency set */
87
wme
*
wmes_in_gds
;
/* pointer to the dll of WMEs in GDS of goal */
88
}
goal_dependency_set
;
89
/* REW: end 09.15.96 */
90
91
/* ------------------------------------------------------------------------
92
Preferences
93
94
Fields in a preference:
95
96
type: indicates the type of the preference. This is one of the
97
types defined below: ACCEPTABLE_PREFERENCE_TYPE, etc.
98
99
o_supported: TRUE iff the preference has o-support
100
101
in_tm: TRUE iff the preference is currently in temporary memory
102
103
on_goal_list: TRUE iff the preference is on the list of preferences
104
supported by its match goal (see all_of_goal_next below)
105
106
reference_count: (see below)
107
108
id, attr, value, referent: points to the symbols. Referent is only
109
used for binary preferences.
110
111
slot: points to the slot this preference is for. (NIL if the
112
preference is not in TM.)
113
114
next, prev: used for a doubly-linked list of preferences of the
115
same type in that particular slot
116
117
all_of_slot_next, all_of_slot_prev: used for a doubly-linked list
118
of all preferences (of any type) in that particular slot
119
120
all_of_goal_next, all_of_goal_prev: used for a doubly-linked list
121
of all preferences supported by this particular match goal.
122
This is needed in order to remove all o-support from a particular
123
goal when that goal is removed from the context stack.
124
125
next_clone, prev_clone: used for a doubly-linked list of all "clones"
126
of this preference. When a result is returned from a subgoal and a
127
chunk is built, we get two copies of the "same" preference, one from
128
the subgoal's production firing, and one from the chunk instantiation.
129
If results are returned more than one level, or the same result is
130
returned simultaneously by multiple production firings, we can get
131
lots of copies of the "same" preference. These clone preferences
132
are kept on a list so that we can find the right one to backtrace
133
through, given a wme supported by "all the clones."
134
135
inst: points to the instantiation that generated this preference
136
137
inst_next, inst_prev: used for a doubly-linked list of all
138
existing preferences that were generated by that instantiation
139
140
next_candidate: used by the decider for lists of candidate values
141
for a certain slot
142
143
next_result: used by the chunker for a list of result preferences
144
145
Reference counts on preferences:
146
+1 if the preference is currently in TM
147
+1 for each instantiation condition that points to it (bt.trace)
148
+1 if it supports an installed context WME
149
150
We deallocate a preference if:
151
(1) reference_count==0 and all its clones have reference_count==0
152
(hence it couldn't possibly be needed anymore)
153
or (2) its match goal is removed from the context stack
154
(hence there's no way we'll ever want to BT through it)
155
------------------------------------------------------------------------ */
156
157
/* WARNING: preference types must be numbered 0..(NUM_PREFERENCE_TYPES-1),
158
because the slot structure contains an array using these indices. */
159
160
#define ACCEPTABLE_PREFERENCE_TYPE 0
161
#define REQUIRE_PREFERENCE_TYPE 1
162
#define REJECT_PREFERENCE_TYPE 2
163
#define PROHIBIT_PREFERENCE_TYPE 3
164
#define RECONSIDER_PREFERENCE_TYPE 4
165
#define UNARY_INDIFFERENT_PREFERENCE_TYPE 5
166
#define UNARY_PARALLEL_PREFERENCE_TYPE 6
167
#define BEST_PREFERENCE_TYPE 7
168
#define WORST_PREFERENCE_TYPE 8
169
#define BINARY_INDIFFERENT_PREFERENCE_TYPE 9
170
#define BINARY_PARALLEL_PREFERENCE_TYPE 10
171
#define BETTER_PREFERENCE_TYPE 11
172
#define WORSE_PREFERENCE_TYPE 12
173
#define NUMERIC_INDIFFERENT_PREFERENCE_TYPE 13
174
#define NUM_PREFERENCE_TYPES 14
175
176
#ifdef USE_MACROS
177
178
#define preference_is_unary(p) ((p)<9)
179
#define preference_is_binary(p) ((p)>8)
180
181
#else
182
183
inline
Bool
preference_is_unary
(
byte
p)
184
{
185
return
(p < 9);
186
}
187
188
inline
Bool
preference_is_binary
(
byte
p)
189
{
190
return
(p > 8);
191
}
192
193
#endif
/* USE_MACROS */
194
195
#ifdef __cplusplus
196
//extern "C" {
197
#endif
198
199
extern
const
char
*
preference_name
[
NUM_PREFERENCE_TYPES
];
200
201
#ifdef __cplusplus
202
//}
203
#endif
204
205
typedef
struct
preference_struct
{
206
byte
type
;
/* acceptable, better, etc. */
207
Bool
o_supported
;
/* is the preference o-supported? */
208
Bool
in_tm
;
/* is this currently in TM? */
209
Bool
on_goal_list
;
/* is this pref on the list for its match goal */
210
uint64_t
reference_count
;
211
Symbol
*
id
;
212
Symbol
*
attr
;
213
Symbol
*
value
;
214
Symbol
*
referent
;
215
struct
slot_struct
*
slot
;
216
217
/* dll of pref's of same type in same slot */
218
struct
preference_struct
*
next
, *
prev
;
219
220
/* dll of all pref's in same slot */
221
struct
preference_struct
*
all_of_slot_next
, *
all_of_slot_prev
;
222
223
/* dll of all pref's from the same match goal */
224
struct
preference_struct
*
all_of_goal_next
, *
all_of_goal_prev
;
225
226
/* dll (without header) of cloned preferences (created when chunking) */
227
struct
preference_struct
*
next_clone
, *
prev_clone
;
228
229
struct
instantiation_struct
*
inst
;
230
struct
preference_struct
*
inst_next
, *
inst_prev
;
231
struct
preference_struct
*
next_candidate
;
232
struct
preference_struct
*
next_result
;
233
234
unsigned
int
total_preferences_for_candidate
;
235
double
numeric_value
;
236
bool
rl_contribution
;
237
238
wma_pooled_wme_set
*
wma_o_set
;
239
240
}
preference
;
241
242
/* Decl'd in prefmem.cpp and needed in decide.cpp */
243
extern
Bool
remove_preference_from_clones
(
agent
* thisAgent,
preference
*pref);
244
245
/* ------------------------------------------------------------------------
246
247
Impasse Types
248
249
------------------------------------------------------------------------ */
250
251
#define NONE_IMPASSE_TYPE 0
/* no impasse */
252
#define CONSTRAINT_FAILURE_IMPASSE_TYPE 1
253
#define CONFLICT_IMPASSE_TYPE 2
254
#define TIE_IMPASSE_TYPE 3
255
#define NO_CHANGE_IMPASSE_TYPE 4
256
257
/* ------------------------------------------------------------------------
258
Slots
259
260
Fields in a slot:
261
262
next, prev: used for a doubly-linked list of all slots for a certain
263
identifier.
264
265
id, attr: identifier and attribute of the slot
266
267
wmes: header of a doubly-linked list of all wmes in the slot
268
269
acceptable_preference_wmes: header of doubly-linked list of all
270
acceptable preference wmes in the slot. (This is only used for
271
context slots.)
272
273
all_preferences: header of a doubly-linked list of all preferences
274
currently in the slot
275
276
preferences[NUM_PREFERENCE_TYPES]: array of headers of doubly-linked
277
lists, one for each possible type of preference. These store
278
all the preferences, sorted into lists according to their types.
279
Within each list, the preferences are sorted according to their
280
match goal, with the pref. supported by the highest goal at the
281
head of the list.
282
283
impasse_id: points to the identifier of the attribute impasse object
284
for this slot. (NIL if the slot isn't impassed.)
285
286
isa_context_slot: TRUE iff this is a context slot
287
288
impasse_type: indicates the type of the impasse for this slot. This
289
is one of NONE_IMPASSE_TYPE, CONSTRAINT_FAILURE_IMPASSE_TYPE, etc.
290
291
marked_for_possible_removal: TRUE iff this slot is on the list of
292
slots that might be deallocated at the end of the current top-level
293
phase.
294
295
changed: indicates whether the preferences for this slot have changed.
296
For non-context slots, this is either NIL or a pointer to the
297
corresponding dl_cons in changed_slots (see decide.c); for context
298
slots, it's just a zero/nonzero flag.
299
300
acceptable_preference_changed: for context slots only; this is zero
301
if no acceptable or require preference in this slot has changed;
302
if one has changed, it points to a dl_cons.
303
------------------------------------------------------------------------ */
304
305
typedef
struct
slot_struct
{
306
struct
slot_struct
*
next
, *
prev
;
/* dll of slots for this id */
307
Symbol
*
id
;
/* id, attr of the slot */
308
Symbol
*
attr
;
309
wme
*
wmes
;
/* dll of wmes in the slot */
310
wme
*
acceptable_preference_wmes
;
/* dll of acceptable pref. wmes */
311
preference
*
all_preferences
;
/* dll of all pref's in the slot */
312
preference
*
preferences
[
NUM_PREFERENCE_TYPES
];
/* dlls for each type */
313
Symbol
*
impasse_id
;
/* NIL if slot is not impassed */
314
Bool
isa_context_slot
;
315
byte
impasse_type
;
316
Bool
marked_for_possible_removal
;
317
dl_cons
*
changed
;
/* for non-context slots: points to the corresponding
318
dl_cons in changed_slots; for context slots: just
319
zero/nonzero flag indicating slot changed */
320
dl_cons
*
acceptable_preference_changed
;
/* for context slots: either zero,
321
or points to dl_cons if the slot
322
has changed + or ! pref's */
323
324
wma_sym_reference_map
*
wma_val_references
;
325
326
}
slot
;
327
328
/* -------------------------------------------------------------------
329
Tests
330
331
Tests in conditions can be blank (null) tests, tests for equality
332
with a variable or constant, or more complicated tests (such as
333
not-equal tests, conjunctive tests, etc.). We use some bit twiddling
334
here to minimize space. We use just a pointer to represent any kind
335
of test. For blank tests, this is the NIL pointer. For equality tests,
336
it points to the symbol referent of the test. For other kinds of tests,
337
bit 0 of the pointer is set to 1, and the pointer (minus 1) points to
338
a complex_test structure. (A field in the complex_test structure
339
further indicates the type of the test.)
340
------------------------------------------------------------------- */
341
342
typedef
char
*
test
;
343
344
#ifdef USE_MACROS
345
346
#define test_is_blank_test(t) ((t)==NIL)
347
#define test_is_complex_test(t) (((uint64_t)(t)) & 1)
348
#define test_is_blank_or_equality_test(t) (! test_is_complex_test(t))
349
350
#define make_blank_test() ((test)NIL)
351
#define make_equality_test(sym) ((sym)->common.reference_count++, (test)(sym)) // what's this???
352
#define make_equality_test_without_adding_reference(sym) ((test)(sym))
353
#define make_blank_or_equality_test(sym_or_nil) \
354
((sym_or_nil) ? make_equality_test(sym_or_nil) : make_blank_test() )
355
#define make_test_from_complex_test(ct) ((test) (((char *)(ct))+1))
356
357
#define referent_of_equality_test(t) ((Symbol *) (t))
358
#define complex_test_from_test(t) ((complex_test *) (((char *)(t))-1))
359
360
#else
361
362
inline
Bool
test_is_blank_test
(
test
t)
363
{
364
return
(t ==
NIL
);
365
}
366
369
//#ifdef _MSC_VER
370
//#pragma warning (disable : 4311)
371
//#endif
372
373
inline
Bool
test_is_complex_test
(
test
t)
374
{
375
return
(
char
)(
376
reinterpret_cast<
uint64_t
>
(t)
377
& 1);
378
}
379
380
#ifdef _MSC_VER
381
#pragma warning (default : 4311)
382
#endif
383
384
inline
Bool
test_is_blank_or_equality_test
(
test
t)
385
{
386
return
(!
test_is_complex_test
(t));
387
}
388
389
inline
test
make_blank_test
()
390
{
391
return
static_cast<
test
>
(
NIL
);
392
}
393
394
inline
test
make_equality_test
(
Symbol
* sym)
// is this equivalent to the macro above??
395
{
396
(sym)->
common
.reference_count++;
397
#ifdef DEBUG_SYMBOL_REFCOUNTS
398
char
buf[64];
399
OutputDebugString(
symbol_to_string
(0, (sym),
FALSE
, buf, 64));
400
OutputDebugString(
":+ "
);
401
OutputDebugString(_itoa((sym)->
common
.reference_count, buf, 10));
402
OutputDebugString(
"\n"
);
403
#endif // DEBUG_SYMBOL_REFCOUNTS
404
return
reinterpret_cast<
test
>
(sym);
405
}
406
407
inline
test
make_equality_test_without_adding_reference
(
Symbol
* sym)
408
{
409
return
reinterpret_cast<
test
>
(sym);
410
}
411
412
inline
test
make_blank_or_equality_test
(
Symbol
* sym_or_nil)
413
{
414
return
((sym_or_nil) ? (
make_equality_test
(sym_or_nil)) :
make_blank_test
());
415
}
416
417
inline
char
*
make_test_from_complex_test
(
complex_test
* ct)
418
{
419
return
reinterpret_cast<
test
>
(ct) + 1;
420
}
421
422
inline
Symbol
*
referent_of_equality_test
(
test
t)
423
{
424
return
reinterpret_cast<
Symbol
*
>
(t);
425
}
426
427
inline
complex_test
*
complex_test_from_test
(
test
t)
428
{
429
return
reinterpret_cast<
complex_test
*
>
(t - 1);
430
}
431
432
#endif
/* USE_MACROS */
433
434
typedef
struct
complex_test_struct
{
435
byte
type
;
/* see definitions below */
436
union
test_info_union
{
437
Symbol
*
referent
;
/* for relational tests */
438
::list
*
disjunction_list
;
/* for disjunction tests */
439
::list
*
conjunct_list
;
/* for conjunctive tests */
440
}
data
;
441
}
complex_test
;
442
443
/* types of the complex_test's */
444
/* WARNING -- none of these can be 254 or 255 -- see rete.cpp */
445
//#define NOT_EQUAL_TEST 1 /* various relational tests */
446
//#define LESS_TEST 2
447
//#define GREATER_TEST 3
448
//#define LESS_OR_EQUAL_TEST 4
449
//#define GREATER_OR_EQUAL_TEST 5
450
//#define SAME_TYPE_TEST 6
451
//#define DISJUNCTION_TEST 7 /* item must be one of a list of constants */
452
//#define CONJUNCTIVE_TEST 8 /* item must pass each of a list of tests */
453
//#define GOAL_ID_TEST 9 /* item must be a goal identifier */
454
//#define IMPASSE_ID_TEST 10 /* item must be an impasse identifier */
455
enum
ComplexTextTypes
{
456
NOT_EQUAL_TEST
= 1,
/* various relational tests */
457
LESS_TEST
= 2,
458
GREATER_TEST
= 3,
459
LESS_OR_EQUAL_TEST
= 4,
460
GREATER_OR_EQUAL_TEST
= 5,
461
SAME_TYPE_TEST
= 6,
462
DISJUNCTION_TEST
= 7,
/* item must be one of a list of constants */
463
CONJUNCTIVE_TEST
= 8,
/* item must pass each of a list of tests */
464
GOAL_ID_TEST
= 9,
/* item must be a goal identifier */
465
IMPASSE_ID_TEST
= 10
/* item must be an impasse identifier */
466
};
467
468
#define NUM_TEST_TYPES 10
469
470
//
471
// Symbol types.
472
//
473
#define VARIABLE_SYMBOL_TYPE 0
474
#define IDENTIFIER_SYMBOL_TYPE 1
475
#define SYM_CONSTANT_SYMBOL_TYPE 2
476
#define INT_CONSTANT_SYMBOL_TYPE 3
477
#define FLOAT_CONSTANT_SYMBOL_TYPE 4
478
#define NUM_SYMBOL_TYPES 5
479
#define NUM_PRODUCTION_TYPES 5
480
481
482
/* -------------------------------------------------------------------
483
Conditions
484
485
Conditions are used for two things: (1) to represent the LHS of newly
486
entered productions (new SP's or chunks); and (2) to represent the
487
instantiated LHS in production instantiations.
488
489
Fields in a condition:
490
491
type: indicates the type of condition: either POSITIVE_CONDITION,
492
NEGATIVE_CONDITION, or CONJUNCTIVE_NEGATION_CONDITION.
493
494
already_in_tc: (reserved for use by the cond_is_in_tc() stuff in
495
production.c)
496
497
next, prev: used for a doubly-linked list of all conditions on the
498
LHS, or all subconditions of an NCC.
499
500
data.tests.id_test, data.tests.attr_test, data.tests.value_test:
501
for positive and negative conditions, these are the three wme
502
field tests for the condition.
503
504
test_for_acceptable_preference: for positive and negative conditions,
505
this is TRUE iff the condition tests for acceptable preference wmes.
506
507
data.ncc.top, data.ncc.bottom: for NCC's, these point to the top and
508
bottom of the subconditions likned list.
509
510
bt: for top-level positive conditions in production instantiations,
511
this structure gives information for that will be used in backtracing.
512
513
reorder: (reserved for use by the reorderer)
514
------------------------------------------------------------------- */
515
516
/* --- types of conditions --- */
517
#define POSITIVE_CONDITION 0
518
#define NEGATIVE_CONDITION 1
519
#define CONJUNCTIVE_NEGATION_CONDITION 2
520
521
/* --- info on conditions used for backtracing (and by the rete) --- */
522
typedef
struct
bt_info_struct
{
523
wme
*
wme_
;
/* the actual wme that was matched */
524
goal_stack_level
level
;
/* level (at firing time) of the id of the wme */
525
preference
*
trace
;
/* preference for BT, or NIL */
526
527
/* mvp 5-17-94 */
528
::list
*
prohibits
;
/* list of prohibit prefs to backtrace through */
529
}
bt_info
;
530
531
/* --- info on conditions used only by the reorderer --- */
532
typedef
struct
reorder_info_struct
{
533
::list
*
vars_requiring_bindings
;
/* used only during reordering */
534
struct
condition_struct
*
next_min_cost
;
/* used only during reordering */
535
}
reorder_info
;
536
537
/* --- info on positive and negative conditions only --- */
538
typedef
struct
three_field_tests_struct
{
539
test
id_test
;
540
test
attr_test
;
541
test
value_test
;
542
}
three_field_tests
;
543
544
/* --- info on negated conjunctive conditions only --- */
545
typedef
struct
ncc_info_struct
{
546
struct
condition_struct
*
top
;
547
struct
condition_struct
*
bottom
;
548
}
ncc_info
;
549
550
/* --- finally, the structure of a condition --- */
551
typedef
struct
condition_struct
{
552
byte
type
;
553
Bool
already_in_tc
;
/* used only by cond_is_in_tc stuff */
554
Bool
test_for_acceptable_preference
;
/* for pos, neg cond's only */
555
struct
condition_struct
*
next
, *
prev
;
556
union
condition_main_data_union
{
557
three_field_tests
tests
;
/* for pos, neg cond's only */
558
ncc_info
ncc
;
/* for ncc's only */
559
}
data
;
560
bt_info
bt
;
/* for top-level positive cond's: used for BT and by the rete */
561
reorder_info
reorder
;
/* used only during reordering */
562
}
condition
;
563
564
#ifdef __cplusplus
565
//}
566
#endif
567
568
#endif
Generated on Mon Aug 6 2012 17:21:02 for Soar Kernel by
1.8.1.2