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
production.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
/* -------------------------------------------------------------------
7
production.h
8
9
Fields in a production:
10
11
name: points to the name of the production (a symbol)
12
13
documentation: points to a string (a memory_block_for_string) giving
14
user-provided documentation about the production, or NIL if the
15
user didn't give any documentation for it.
16
17
reference_count: (see below)
18
19
firing_count: the number of times this production has ever fired
20
since it was created. (Note that this is not reset by an init-soar.)
21
22
next, prev: used for a doubly-linked list of productions of the same
23
type (see below). The list header is all_productions_of_type[].
24
25
type: the type of the production: USER_PRODUCTION_TYPE,
26
DEFAULT_PRODUCTION_TYPE, CHUNK_PRODUCTION_TYPE, or
27
JUSTIFICATION_PRODUCTION_TYPE.
28
29
declared_support: indicates whether the production was declared
30
:o-support or :i-support. This field is either UNDECLARED_SUPPORT,
31
DECLARED_O_SUPPORT, or DECLARED_I_SUPPORT.
32
33
trace_firings: TRUE iff a (pwatch) has been set on this production.
34
35
p_node: If the production is currently in the Rete, this points to
36
the corresponding p_node in the Rete. If the production is not in
37
the Rete, this field is NIL.
38
39
action_list: singly-linked list of the RHS actions of the production.
40
41
rhs_unbound_variables: A (consed) list of variables used on the RHS
42
that aren't bound on the LHS, in the order of their indices (for
43
rhs_values). For chunks, this is NIL, since we discard chunk
44
variable names.
45
46
instantiations: header for a doubly-linked list of the instantiations
47
of this production that are currently in the match set (i.e.,
48
Rete-supported).
49
50
OPERAND_which_assert_list: (need comment info from REW or RCHONG)
51
52
Reference counts on productions:
53
+1 if it's in production memory (i.e., hasn't been excised)
54
+1 for each existing instantiation pointing to it
55
We deallocate a production if its reference_count goes to 0.
56
------------------------------------------------------------------- */
57
58
#ifndef PRODUCTION_H
59
#define PRODUCTION_H
60
61
#ifdef __cplusplus
62
//extern "C"
63
//{
64
#endif
65
66
#define UNDECLARED_SUPPORT 0
67
#define DECLARED_O_SUPPORT 1
68
#define DECLARED_I_SUPPORT 2
69
70
/* RCHONG: begin 10.11 */
71
72
#define PE_PRODS 0
73
#define IE_PRODS 1
74
#define NO_SAVED_PRODS -1
75
76
/* RCHONG: end 10.11 */
77
78
struct
not_struct
;
79
80
typedef
char
Bool
;
81
typedef
char
*
test
;
82
typedef
char
*
rhs_value
;
83
typedef
unsigned
char
byte
;
84
typedef
uint64_t
tc_number
;
85
typedef
struct
action_struct
action
;
86
typedef
struct
condition_struct
condition
;
87
typedef
struct
cons_struct
cons
;
88
typedef
struct
agent_struct
agent
;
89
typedef
cons
list
;
90
typedef
union
symbol_union
Symbol
;
91
92
#include <map>
93
#include <set>
94
95
typedef
std::map< Symbol*, Symbol* >
rl_symbol_map
;
96
typedef
std::set< rl_symbol_map >
rl_symbol_map_set
;
97
98
typedef
struct
production_struct
{
99
Symbol
*
name
;
100
char
*
documentation
;
/* pointer to memory block, or NIL */
101
char
*
filename
;
/* name of source file, or NIL. kjh CUSP(b11) */
102
uint64_t
reference_count
;
103
uint64_t
firing_count
;
/* how many times it's fired */
104
struct
production_struct
*
next
, *
prev
;
/* used for dll */
105
byte
type
;
106
byte
declared_support
;
107
Bool
trace_firings
;
/* used by pwatch */
108
struct
rete_node_struct
*
p_node
;
/* NIL if it's not in the rete */
109
action
*
action_list
;
/* RHS actions */
110
::list
*
rhs_unbound_variables
;
/* RHS vars not bound on LHS */
111
struct
instantiation_struct
*
instantiations
;
/* dll of inst's in MS */
112
int
OPERAND_which_assert_list
;
/* RCHONG: 10.11 */
113
byte
interrupt
;
/* SW: 7.31.03 */
114
bool
already_fired
;
/* RPM test workaround for bug #139 */
115
116
bool
rl_rule
;
/* if true, is a Soar-RL rule */
117
double
rl_update_count
;
/* number of (potentially fractional) updates to this rule */
118
unsigned
int
rl_ref_count
;
/* number of states referencing this rule in prev_op_rl_rules list */
119
120
// Per-input memory parameters for delta bar delta algorithm
121
double
rl_delta_bar_delta_beta
;
122
double
rl_delta_bar_delta_h
;
123
124
double
rl_ecr
;
// expected current reward (discounted reward)
125
double
rl_efr
;
// expected future reward (discounted next state)
126
127
condition
*
rl_template_conds
;
128
rl_symbol_map_set
*
rl_template_instantiations
;
129
}
production
;
130
131
/* ========================================================================
132
133
Various utility routines for manipulating productions and parts thereof.
134
Also includes the reorderer and compile-time o-support calculations.
135
136
Init_production_utilities() should be called before anything else here.
137
======================================================================== */
138
139
/* This structure is used to break ties in favor of non-multi-attributes */
140
typedef
struct
multi_attributes_struct
{
141
Symbol
*
symbol
;
142
int64_t
value
;
143
struct
multi_attributes_struct
*
next
;
144
}
multi_attribute
;
145
146
extern
void
init_production_utilities
(
agent
* thisAgent);
147
148
/* ------------------------------------------ */
149
/* Utilities for symbols and lists of symbols */
150
/* ------------------------------------------ */
151
152
/* --- Looks at a symbol, returns appropriate first letter for a dummy
153
variable or identifier to follow it. Returns '*' if none found. --- */
154
extern
char
first_letter_from_symbol
(
Symbol
*sym);
155
156
/* --- Takes a list of symbols and returns a copy of the same list,
157
incrementing the reference count on each symbol in the list. --- */
158
extern ::list
*
copy_symbol_list_adding_references
(
agent
* thisAgent, ::
list
*sym_list);
159
160
/* --- Frees a list of symbols, decrementing their reference counts. --- */
161
extern
void
deallocate_symbol_list_removing_references
(
agent
* thisAgent, ::
list
*sym_list);
162
163
/* ------------------- */
164
/* Utilities for tests */
165
/* ------------------- */
166
167
extern
void
add_all_variables_in_action
(
agent
* thisAgent,
action
*a,
tc_number
tc,
168
::
list
**var_list);
169
extern
void
add_bound_variables_in_test
(
agent
* thisAgent,
test
t,
tc_number
tc,
170
::
list
**var_list);
171
extern
void
add_bound_variables_in_condition
(
agent
* thisAgent,
condition
*c,
tc_number
tc,
172
::
list
**var_list);
173
extern
void
unmark_variables_and_free_list
(
agent
* thisAgent, ::
list
*var_list);
174
175
/* --- Takes a test and returns a new copy of it. --- */
176
extern
test
copy_test
(
agent
* thisAgent,
test
t);
177
178
/* --- Same as copy_test(), only it doesn't include goal or impasse tests
179
in the new copy. The caller should initialize the two flags to FALSE
180
before calling this routine; it sets them to TRUE if it finds a goal
181
or impasse test. --- */
182
extern
test
copy_test_removing_goal_impasse_tests
183
(
agent
* thisAgent,
test
t,
Bool
*removed_goal,
Bool
*removed_impasse);
184
185
/* --- Deallocates a test. --- */
186
extern
void
deallocate_test
(
agent
* thisAgent,
test
t);
187
188
/* --- Destructively modifies the first test (t) by adding the second
189
one (add_me) to it (usually as a new conjunct). The first test
190
need not be a conjunctive test. --- */
191
extern
void
add_new_test_to_test
(
agent
* thisAgent,
test
*t,
test
add_me);
192
193
/* --- Same as above, only has no effect if the second test is already
194
included in the first one. --- */
195
extern
void
add_new_test_to_test_if_not_already_there
(
agent
* thisAgent,
test
*t,
test
add_me,
bool
neg);
196
197
/* --- Returns TRUE iff the two tests are identical.
198
If neg is true, ignores order of members in conjunctive tests
199
and assumes variables are all equal. --- */
200
extern
Bool
tests_are_equal
(
test
t1,
test
t2,
bool
neg);
201
202
/* --- Returns a hash value for the given test. --- */
203
extern
uint32_t
hash_test
(
agent
* thisAgent,
test
t);
204
205
/* --- Returns TRUE iff the test contains an equality test for the given
206
symbol. If sym==NIL, returns TRUE iff the test contains any equality
207
test. --- */
208
extern
Bool
test_includes_equality_test_for_symbol
(
test
t,
Symbol
*sym);
209
210
/* --- Looks for goal or impasse tests (as directed by the two flag
211
parameters) in the given test, and returns TRUE if one is found. --- */
212
extern
Bool
test_includes_goal_or_impasse_id_test
(
test
t,
213
Bool
look_for_goal,
214
Bool
look_for_impasse);
215
216
/* --- Looks through a test, and returns a new copy of the first equality
217
test it finds. Signals an error if there is no equality test in the
218
given test. --- */
219
extern
test
copy_of_equality_test_found_in_test
(
agent
* thisAgent,
test
t);
220
221
/* --- Looks through a test, returns appropriate first letter for a dummy
222
variable to follow it. Returns '*' if none found. --- */
223
extern
char
first_letter_from_test
(
test
t);
224
225
/* ------------------------ */
226
/* Utilities for conditions */
227
/* ------------------------ */
228
229
/* --- Deallocates a condition list (including any NCC's and tests in it). */
230
extern
void
deallocate_condition_list
(
agent
* thisAgent,
condition
*cond_list);
231
232
/* --- Returns a new copy of the given condition. --- */
233
extern
condition
*
copy_condition
(
agent
* thisAgent,
condition
*cond);
234
235
/* --- Copies the given condition list, returning pointers to the
236
top-most and bottom-most conditions in the new copy. --- */
237
extern
void
copy_condition_list
(
agent
* thisAgent,
condition
*top_cond,
condition
**dest_top,
238
condition
**dest_bottom);
239
240
/* --- Returns TRUE iff the two conditions are identical. --- */
241
extern
Bool
conditions_are_equal
(
condition
*c1,
condition
*c2);
242
243
/* --- Returns a hash value for the given condition. --- */
244
extern
uint32_t
hash_condition
(
agent
* thisAgent,
condition
*cond);
245
246
/* ------------------------------------ */
247
/* Utilities for actions and RHS values */
248
/* ------------------------------------ */
249
250
/* --- Deallocates the given rhs_value. --- */
251
extern
void
deallocate_rhs_value
(
agent
* thisAgent,
rhs_value
rv);
252
253
/* --- Returns a new copy of the given rhs_value. --- */
254
extern
rhs_value
copy_rhs_value
(
agent
* thisAgent,
rhs_value
rv);
255
256
/* --- Deallocates the given action (singly-linked) list. --- */
257
extern
void
deallocate_action_list
(
agent
* thisAgent,
action
*actions);
258
259
/* --- Looks through an rhs_value, returns appropriate first letter for a
260
dummy variable to follow it. Returns '*' if none found. --- */
261
extern
char
first_letter_from_rhs_value
(
rhs_value
rv);
262
263
/* ------------------ */
264
/* Utilities for nots */
265
/* ------------------ */
266
267
/* --- Deallocates the given (singly-linked) list of Nots. --- */
268
extern
void
deallocate_list_of_nots
(
agent
* thisAgent,
not_struct
*nots);
269
270
/* --------------------------------------------------------------------
271
Transitive Closure Utilities
272
Marking, Unmarking, and Collecting Symbols
273
274
Get_new_tc_number() is called from lots of places. Any time we need
275
to mark a set of identifiers and/or variables, we get a new tc_number
276
by calling this routine, then proceed to mark various ids or vars
277
by setting the sym->id.tc_num or sym->var.tc_num fields.
278
279
Sometimes in addition to marking symbols using their tc_num fields,
280
we also want to build up a list of the symbols we've marked. So,
281
the routines here take an "id_list" or "var_list" argument. This
282
argument should be NIL if no such list is desired. If non-NIL, it
283
should point to the header of the linked list being built.
284
285
Transitive Closure Calculations for Conditions and Actions
286
287
Usage:
288
1. Set my_tc = get_new_tc_number() to start a new TC
289
2. (optional) If you want linked lists of symbols in the TC, initialize
290
id_list=NIL and var_list=NIL.
291
If you're not using id_list and/or var_list, give NIL for "&id_list"
292
and/or "&var_list" in the function calls below.
293
3. (optional) setup any id's or var's that you want to include in the
294
initial TC, by calling
295
add_symbol_to_tc (sym, my_tc, &id_list, &var_list)
296
(If not using id_list or var_list, you can just mark
297
sym->{id,var}.tc_num = my_tc instead.)
298
4. To do the work you want, use any of the following any number of times:
299
add_cond_to_tc (cond, my_tc, &id_list, &var_list);
300
add_action_to_tc (cond, my_tc, &id_list, &var_list);
301
result = cond_is_in_tc (cond, my_tc);
302
result = action_is_in_tc (action, my_tc);
303
5. When finished, free the cons cells in id_list and var_list (but
304
don't call symbol_remove_ref() on the symbols in them).
305
306
Warning: actions must not contain reteloc's or rhs unbound variables here.
307
-------------------------------------------------------------------- */
308
309
tc_number
get_new_tc_number
(
agent
* thisAgent);
310
311
extern
void
add_symbol_to_tc
(
agent
* thisAgent,
Symbol
*sym,
tc_number
tc,
312
::
list
**id_list, ::
list
**var_list);
313
extern
void
add_cond_to_tc
(
agent
* thisAgent,
condition
*c,
tc_number
tc,
314
::
list
**id_list, ::
list
**var_list);
315
extern
void
add_action_to_tc
(
agent
* thisAgent,
action
*a,
tc_number
tc,
316
::
list
**id_list, ::
list
**var_list);
317
extern
Bool
cond_is_in_tc
(
agent
* thisAgent,
condition
*cond,
tc_number
tc);
318
extern
Bool
action_is_in_tc
(
action
*a,
tc_number
tc);
319
320
/* --------------------------------------------------------------------
321
Variable Generator
322
323
These routines are used for generating new variables. The variables
324
aren't necessarily "completely" new--they might occur in some existing
325
production. But we usually need to make sure the new variables don't
326
overlap with those already used in a *certain* production--for instance,
327
when variablizing a chunk, we don't want to introduce a new variable that
328
conincides with the name of a variable already in an NCC in the chunk.
329
330
To use these routines, first call reset_variable_generator(), giving
331
it lists of conditions and actions whose variables should not be
332
used. Then call generate_new_variable() any number of times; each
333
time, you give it a string to use as the prefix for the new variable's
334
name. The prefix string should not include the opening "<".
335
-------------------------------------------------------------------- */
336
337
extern
void
reset_variable_generator
(
agent
* thisAgent,
338
condition
*conds_with_vars_to_avoid,
339
action
*actions_with_vars_to_avoid);
340
extern
Symbol
*
generate_new_variable
(
agent
* thisAgent,
const
char
*prefix);
341
342
/* -------------------------------------------------------------------
343
Production Management
344
345
For each type of production, we maintain a doubly-linked list of
346
all productions of that type. The headers of these dll's are
347
stored in the array all_productions_of_type[]. Another array,
348
num_productions_of_type[], keeps counts of how many productions
349
there are of each type.
350
351
Production_add_ref() and production_remove_ref() are macros for
352
incrementing and decrementing the reference count on a production.
353
Production_remove_ref() also deallocates the production if the
354
count goes to 0.
355
356
Make_production() does reordering, compile-time o-support calc's,
357
and builds and returns a production structure for a new production.
358
It does not enter the production into the Rete net, however.
359
The "type" argument should be one of USER_PRODUCTION_TYPE, etc.
360
The flag "reorder_nccs" tells whether to recursively reorder
361
the subconditions of NCC's--this is not necessary for newly
362
built chunks, as their NCC's are copies of other NCC's in SP's that
363
have already been reordered. If any error occurs, make_production()
364
returns NIL.
365
366
Deallocate_production() and excise_production() do just what they
367
say. Normally deallocate_production() should be invoked only via
368
the production_remove_ref() macro.
369
------------------------------------------------------------------- */
370
371
extern
production
*
make_production
(
agent
* thisAgent,
372
byte
type,
373
Symbol
*name,
374
condition
**lhs_top,
375
condition
**lhs_bottom,
376
action
**rhs_top,
377
Bool
reorder_nccs);
378
extern
void
deallocate_production
(
agent
* thisAgent,
production
*prod);
379
extern
void
excise_production
(
agent
* thisAgent,
production
*prod,
Bool
print_sharp_sign);
380
extern
void
excise_all_productions_of_type
(
agent
* thisAgent,
381
byte
type,
382
Bool
print_sharp_sign);
383
extern
void
excise_all_productions
(
agent
* thisAgent,
384
Bool
print_sharp_sign);
385
386
extern
Bool
canonical_cond_greater
(
condition
*c1,
condition
*c2);
387
388
#ifdef USE_MACROS
389
390
#define production_add_ref(p) { (p)->reference_count++; }
391
#define production_remove_ref(thisAgent, p) { \
392
(p)->reference_count--; \
393
if ((p)->reference_count == 0) \
394
deallocate_production(thisAgent, p); }
395
396
#else
397
398
inline
void
production_add_ref
(
production
* p)
399
{
400
(p)->reference_count++;
401
}
402
403
inline
void
production_remove_ref
(
agent
* thisAgent,
production
* p)
404
{
405
(p)->reference_count--;
406
if
((p)->reference_count == 0)
407
deallocate_production
(thisAgent, p);
408
}
409
410
#endif
/* USE_MACROS */
411
412
#ifdef __cplusplus
413
//}
414
#endif
415
416
#endif
Generated on Mon Aug 6 2012 17:21:02 for Soar Kernel by
1.8.1.2