void rl_add_goal_or_impasse_tests_to_conds( agent *my_agent, condition *all_conds )
{
	// mark each id as we add a test for it, so we don't add a test for the same id in two different places
	Symbol *id;
	test t;
	complex_test *ct;
	tc_number tc = get_new_tc_number( my_agent );

	for ( condition *cond = all_conds; cond != NIL; cond = cond->next )
	{
		if ( cond->type != POSITIVE_CONDITION )
			continue;

		id = referent_of_equality_test( cond->data.tests.id_test );

		if ( ( id->id.isa_goal || id->id.isa_impasse ) && ( id->id.tc_num != tc ) ) 
		{
			allocate_with_pool( my_agent, &my_agent->complex_test_pool, &ct );
			ct->type = static_cast<byte>( ( id->id.isa_goal )?( GOAL_ID_TEST ):( IMPASSE_ID_TEST ) );
			t = make_test_from_complex_test( ct );
			add_new_test_to_test( my_agent, &( cond->data.tests.id_test ), t );
			id->id.tc_num = tc;
		}
	}
}
Example #2
0
inline void wma_forgetting_add_to_p_queue( agent* my_agent, wma_decay_element* decay_el, wma_d_cycle new_cycle )
{
	if ( decay_el )
	{
		decay_el->forget_cycle = new_cycle;

		wma_forget_p_queue::iterator pq_p = my_agent->wma_forget_pq->find( new_cycle );
		if ( pq_p == my_agent->wma_forget_pq->end() )
		{
			wma_decay_set* newbie;
			allocate_with_pool( my_agent, &( my_agent->wma_decay_set_pool ), &newbie );
#ifdef USE_MEM_POOL_ALLOCATORS
			newbie = new (newbie) wma_decay_set( std::less< wma_decay_element* >(), soar_module::soar_memory_pool_allocator< wma_decay_element* >( my_agent ) );
#else
			newbie = new (newbie) wma_decay_set();
#endif
			newbie->insert( decay_el );

			my_agent->wma_forget_pq->insert( std::make_pair( new_cycle, newbie ) );
		}
		else
		{
			pq_p->second->insert( decay_el );
		}
	}
}
// creates an action for a template instantiation
action *rl_make_simple_action( agent *my_agent, Symbol *id_sym, Symbol *attr_sym, Symbol *val_sym, Symbol *ref_sym )
{
    action *rhs;
    Symbol *temp;

    allocate_with_pool( my_agent, &my_agent->action_pool, &rhs );
    rhs->next = NIL;
    rhs->type = MAKE_ACTION;

    // id
	temp = id_sym;
	symbol_add_ref( temp );
	variablize_symbol( my_agent, &temp );
	rhs->id = symbol_to_rhs_value( temp );

    // attribute
    temp = attr_sym;
	symbol_add_ref( temp );
	variablize_symbol( my_agent, &temp );
	rhs->attr = symbol_to_rhs_value( temp );

	// value
	temp = val_sym;
	symbol_add_ref( temp );
	variablize_symbol( my_agent, &temp );
	rhs->value = symbol_to_rhs_value( temp );

	// referent
	temp = ref_sym;
	symbol_add_ref( temp );
	variablize_symbol( my_agent, &temp );
	rhs->referent = symbol_to_rhs_value( temp );

    return rhs;
}
Example #4
0
void mark_slot_as_changed(agent* thisAgent, slot* s)
{
    dl_cons* dc;
    
    if (s->isa_context_slot)
    {
        if (thisAgent->highest_goal_whose_context_changed)
        {
            if (s->id->id->level <
                    thisAgent->highest_goal_whose_context_changed->id->level)
            {
                thisAgent->highest_goal_whose_context_changed = s->id;
            }
        }
        else
        {
            thisAgent->highest_goal_whose_context_changed = s->id;
        }
        s->changed = reinterpret_cast<dl_cons*>(s);   /* just make it nonzero */
    }
    else
    {
        if (! s->changed)
        {
            allocate_with_pool(thisAgent, &thisAgent->dl_cons_pool, &dc);
            dc->item = s;
            s->changed = dc;
            
            insert_at_head_of_dll(thisAgent->changed_slots, dc, next, prev);
        }
    }
}
Example #5
0
slot* make_slot(agent* thisAgent, Symbol* id, Symbol* attr)
{
    slot* s;
    int i;
    
    /* JC: Search for a slot first.  If it exists
    *  for the given symbol, then just return it
    */
    for (s = id->id->slots; s != NIL; s = s->next)
    {
        if (s->attr == attr)
        {
            return s;
        }
    }
    
    /* JC: need to create a new slot */
    allocate_with_pool(thisAgent, &thisAgent->slot_pool, &s);
    insert_at_head_of_dll(id->id->slots, s, next, prev);
    
    /* Context slots are goals and operators; operator slots get
     *  created with a goal (see create_new_context).
     */
    if ((id->id->isa_goal) && (attr == thisAgent->operator_symbol))
    {
        s->isa_context_slot = true;
    }
    else
    {
        s->isa_context_slot = false;
    }
    
    s->changed = NIL;
    s->acceptable_preference_changed = NIL;
    s->id = id;
    s->attr = attr;
    symbol_add_ref(thisAgent, id);
    symbol_add_ref(thisAgent, attr);
    s->wmes = NIL;
    s->all_preferences = NIL;
    s->CDPS = NIL;
    
    /* JC: This is the same as all_preferences
     *  except they are indexed by type.
     */
    for (i = 0; i < NUM_PREFERENCE_TYPES; i++)
    {
        s->preferences[i] = NIL;
    }
    
    s->impasse_type = NONE_IMPASSE_TYPE;
    s->impasse_id = NIL;
    s->acceptable_preference_wmes = NIL;
    s->marked_for_possible_removal = false;
    
    s->wma_val_references = NIL;
    
    return s;
}
Example #6
0
void update_for_top_state_wme_addition(wme * w)
{
    output_link *ol;
    soar_callback *cb;
    char link_name[LINK_NAME_SIZE];

    /* --- check whether the attribute is an output function --- */
    symbol_to_string(w->attr, FALSE, link_name, LINK_NAME_SIZE);

    cb = soar_exists_callback_id(soar_agent, OUTPUT_PHASE_CALLBACK, link_name);

    if (!cb)
        return;

    /* --- create new output link structure --- */
    allocate_with_pool(&current_agent(output_link_pool), &ol);
    insert_at_head_of_dll(current_agent(existing_output_links), ol, next, prev);

    ol->status = NEW_OL_STATUS;
    ol->link_wme = w;
    wme_add_ref(w);
    ol->ids_in_tc = NIL;
    ol->cb = cb;
    /* --- make wme point to the structure --- */
    w->output_link = ol;

    /* SW 07 10 2003
       previously, this wouldn't be done until the first OUTPUT phase.
       However, if we add an output command in the 1st decision cycle,
       Soar seems to ignore it.

       There may be two things going on, the first having to do with the tc 
       calculation, which may get done too late, in such a way that the
       initial calculation includes the command.  The other thing appears
       to be that some data structures are not initialized until the first 
       output phase.  Namely, id->associated_output_links does not seem
       reflect the current output links until the first output-phase.

       To get past these issues, we fake a transitive closure calculation
       with the knowledge that the only thing on the output link at this
       point is the output-link identifier itself.  This way, we capture
       a snapshot of the empty output link, so Soar can detect any changes
       that might occur before the first output_phase. */

    current_agent(output_link_tc_num) = get_new_tc_number();
    ol->link_wme->value->id.tc_num = current_agent(output_link_tc_num);
    current_agent(output_link_for_tc) = ol;
    /* --- add output_link to id's list --- */
    push(current_agent(output_link_for_tc), ol->link_wme->value->id.associated_output_links);

}
Example #7
0
	instantiation* make_fake_instantiation( agent* my_agent, Symbol* state, wme_set* conditions, symbol_triple_list* actions )
	{
		// make fake instantiation
		instantiation* inst;
		allocate_with_pool( my_agent, &( my_agent->instantiation_pool ), &inst );
		inst->prod = NULL;
		inst->next = inst->prev = NULL;
		inst->rete_token = NULL;
		inst->rete_wme = NULL;
		inst->match_goal = state;
		inst->match_goal_level = state->id.level;
		inst->reliable = true;
		inst->backtrace_number = 0;
		inst->in_ms = FALSE;
		inst->GDS_evaluated_already = FALSE;

		// create preferences
		inst->preferences_generated = NULL;
		{
			preference* pref;

			for ( symbol_triple_list::iterator a_it=actions->begin(); a_it!=actions->end(); a_it++ )
			{
				pref = make_preference( my_agent, ACCEPTABLE_PREFERENCE_TYPE, (*a_it)->id, (*a_it)->attr, (*a_it)->value, NIL );
				pref->o_supported = true;
				symbol_add_ref( pref->id );
				symbol_add_ref( pref->attr );
				symbol_add_ref( pref->value );

				pref->inst = inst;
				pref->inst_next = pref->inst_prev = NULL;

				insert_at_head_of_dll( inst->preferences_generated, pref, inst_next, inst_prev );
			}
		}

		// create conditions
		{
			condition *cond = NULL;
			condition *prev_cond = NULL;

			for ( wme_set::iterator c_it=conditions->begin(); c_it!=conditions->end(); c_it++ )
			{
				// construct the condition
				allocate_with_pool( my_agent, &( my_agent->condition_pool ), &cond );
				cond->type = POSITIVE_CONDITION;
				cond->prev = prev_cond;
				cond->next = NULL;
				if ( prev_cond != NULL )
				{
					prev_cond->next = cond;
				}
				else
				{
					inst->top_of_instantiated_conditions = cond;
					inst->bottom_of_instantiated_conditions = cond;
					inst->nots = NULL;
				}
				cond->data.tests.id_test = make_equality_test( (*c_it)->id );
				cond->data.tests.attr_test = make_equality_test( (*c_it)->attr );
				cond->data.tests.value_test = make_equality_test( (*c_it)->value );
				cond->test_for_acceptable_preference = (*c_it)->acceptable;
				cond->bt.wme_ = (*c_it);

				#ifndef DO_TOP_LEVEL_REF_CTS
				if ( inst->match_goal_level > TOP_GOAL_LEVEL )
				#endif
				{
					wme_add_ref( (*c_it) );
				}			
				
				cond->bt.level = (*c_it)->id->id.level;
				cond->bt.trace = (*c_it)->preference;
				
				if ( cond->bt.trace )
				{
					#ifndef DO_TOP_LEVEL_REF_CTS
					if ( inst->match_goal_level > TOP_GOAL_LEVEL )
					#endif
					{
						preference_add_ref( cond->bt.trace );
					}
				}				

        cond->bt.CDPS = NULL;

				prev_cond = cond;
			}
		}

		return inst;
	}
Example #8
0
void create_instantiation (production *prod,
                           struct token_struct *tok,
                           wme *w) {
  instantiation *inst;
  condition *cond;
  preference *pref;
  action *a;
  cons *c;
  bool need_to_do_support_calculations;
  bool trace_it;
  long index;
  Symbol **cell;
  
  allocate_with_pool (&current_agent(instantiation_pool), &inst);
  inst->next = current_agent(newly_created_instantiations);
  current_agent(newly_created_instantiations) = inst;
  inst->prod = prod;
  inst->rete_token = tok;
  inst->rete_wme = w;
  inst->okay_to_variablize = TRUE;
  inst->in_ms = TRUE;


  /* REW: begin   09.15.96 */
  /*  We want to initialize the GDS_evaluated_already flag
   *  when a new instantiation is created.
   */

  inst->GDS_evaluated_already = FALSE;

  if (current_agent(operand2_mode) == TRUE) {
    if (current_agent(soar_verbose_flag) == TRUE)
      print_with_symbols("\n   in create_instantiation: %y",
			 inst->prod->name);
  }
  /* REW: end   09.15.96 */


  current_agent(production_being_fired) = inst->prod;
  prod->firing_count++;
  current_agent(production_firing_count)++;
  
  /* --- build the instantiated conditions, and bind LHS variables --- */
  p_node_to_conditions_and_nots (prod->p_node, tok, w,
                                 &(inst->top_of_instantiated_conditions),
                                 &(inst->bottom_of_instantiated_conditions),
                                 &(inst->nots), NIL);

  /* --- record the level of each of the wmes that was positively tested --- */
  for (cond=inst->top_of_instantiated_conditions; cond!=NIL; cond=cond->next) {
    if (cond->type==POSITIVE_CONDITION) {
      cond->bt.level = cond->bt.wme->id->id.level;
      cond->bt.trace = cond->bt.wme->preference;
    }
  }

  /* --- print trace info --- */
  trace_it = trace_firings_of_inst (inst);
  if (trace_it) {
    if (get_printer_output_column()!=1) print ("\n");  /* AGR 617/634 */
    print ("Firing ");
    print_instantiation_with_wmes
      (inst, (wme_trace_type)(current_agent(sysparams)[TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM]));
  }

  /* --- initialize rhs_variable_bindings array with names of variables
     (if there are any stored on the production -- for chunks there won't
     be any) --- */
  index = 0;
  cell = current_agent(rhs_variable_bindings);
  for (c=prod->rhs_unbound_variables; c!=NIL; c=c->rest) {
    *(cell++) = c->first;
    index++;
  }
  firer_highest_rhs_unboundvar_index = index-1;

  /* 7.1/8 merge: Not sure about this.  This code in 704, but not in either 7.1 or 703/soar8 */
  /* --- Before executing the RHS actions, tell the user that the -- */
  /* --- phase has changed to output by printing the arrow --- */
  if (trace_it && current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) {
    print (" -->\n");}

  /* --- execute the RHS actions, collect the results --- */
  inst->preferences_generated = NIL;
  need_to_do_support_calculations = FALSE;
  for (a=prod->action_list; a!=NIL; a=a->next) {
    pref = execute_action (a, tok, w);
    if (pref) {
      pref->inst = inst;
      insert_at_head_of_dll (inst->preferences_generated, pref,
                             inst_next, inst_prev);
      if (inst->prod->declared_support==DECLARED_O_SUPPORT)
        pref->o_supported = TRUE;
      else if (inst->prod->declared_support==DECLARED_I_SUPPORT)
        pref->o_supported = FALSE;


      else {

	if (current_agent(operand2_mode) == TRUE) {
	  pref->o_supported =
	    (current_agent(FIRING_TYPE) == PE_PRODS) ? TRUE : FALSE;
	}
	/* REW: end   09.15.96 */

	else {
	  if (a->support==O_SUPPORT) pref->o_supported = TRUE;
	  else if (a->support==I_SUPPORT) pref->o_supported = FALSE;
	  else {
	    need_to_do_support_calculations = TRUE;
	    if (current_agent(soar_verbose_flag) == TRUE)
	      printf("\n\nin create_instantiation():  need_to_do_support_calculations == TRUE!!!\n\n");
	  }

	}

      }
    }
  }

  /* --- reset rhs_variable_bindings array to all zeros --- */
  index = 0;
  cell = current_agent(rhs_variable_bindings);
  while (index++ <= firer_highest_rhs_unboundvar_index) *(cell++) = NIL;

  /* --- fill in lots of other stuff --- */
  fill_in_new_instantiation_stuff (inst, need_to_do_support_calculations);

  /* --- print trace info: printing preferences --- */
  /* Note: can't move this up, since fill_in_new_instantiation_stuff gives
     the o-support info for the preferences we're about to print */
  if (trace_it && current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) {
    for (pref=inst->preferences_generated; pref!=NIL; pref=pref->inst_next) {
      print (" ");
      print_preference (pref);
    }
  }

  /* mvp 5-17-94 */
  build_prohibits_list (inst);

  current_agent(production_being_fired) = NIL;

  /* --- build chunks/justifications if necessary --- */
  chunk_instantiation (inst, (bool)current_agent(sysparams)[LEARNING_ON_SYSPARAM]);

#ifndef NO_CALLBACKS  /* kjc 1/00 */
  /* MVP 6-8-94 */
  if (!current_agent(system_halted)) {
  /* --- invoke callback function --- */
    soar_invoke_callbacks(soar_agent, 
			  FIRING_CALLBACK,
			  (soar_call_data) inst);

  }
#endif
}
Example #9
0
saved_test *simplify_test (agent* thisAgent, test *t, saved_test *old_sts) {
  test New, subtest;
  saved_test *saved;
  Symbol *var, *sym;
  cons *c, *prev_c, *next_c;
  complex_test *ct;

  if (test_is_blank_test(*t)) {
    sym = generate_new_variable (thisAgent, "dummy-");
    *t = make_equality_test_without_adding_reference (sym);
    return old_sts;
  }

  if (test_is_blank_or_equality_test(*t)) {
    return old_sts;
  }

  ct = complex_test_from_test(*t);
  
  switch (ct->type) {
    
  case CONJUNCTIVE_TEST:
    /* --- look at subtests for an equality test --- */
    sym = NIL;
    for (c=ct->data.conjunct_list; c!=NIL; c=c->rest) {
      subtest = static_cast<char *>(c->first);
      if (test_is_blank_or_equality_test(subtest))
        sym = referent_of_equality_test(subtest);
    }
    /* --- if no equality test was found, generate a variable for it --- */
    if (!sym) {
      sym = generate_new_variable (thisAgent, "dummy-");
      New = make_equality_test_without_adding_reference (sym);
      allocate_cons (thisAgent, &c);
      c->first = New;
      c->rest = ct->data.conjunct_list;
      ct->data.conjunct_list = c;
    }
    /* --- scan through, create saved_test for subtests except equality --- */
    prev_c = NIL;
    c = ct->data.conjunct_list;
    while (c) {
      next_c = c->rest;
      subtest = static_cast<char *>(c->first);
      if (! test_is_blank_or_equality_test(subtest)) {
        /* --- create saved_test, splice this cons out of conjunct_list --- */
        allocate_with_pool (thisAgent, &thisAgent->saved_test_pool, &saved);
        saved->next = old_sts;
        old_sts = saved;
        saved->var = sym;
        symbol_add_ref (sym);
        saved->the_test = subtest;
        if (prev_c)
          prev_c->rest = next_c;
        else
          ct->data.conjunct_list = next_c;
        free_cons (thisAgent, c);
      } else {
        prev_c = c;
      }
      c = next_c;
    }
    break;
    
  default:
    /* --- goal/impasse, disjunction, and non-equality relational tests --- */
    var = generate_new_variable (thisAgent, "dummy-");
    New = make_equality_test_without_adding_reference (var);
    allocate_with_pool (thisAgent, &thisAgent->saved_test_pool, &saved);
    saved->next = old_sts;
    old_sts = saved;
    saved->var = var;
    symbol_add_ref (var);
    saved->the_test = *t;
    *t = New;
    break;
  }
  return old_sts;
}
Example #10
0
void wma_activate_wme( agent* my_agent, wme* w, wma_reference num_references, wma_pooled_wme_set* o_set, bool o_only )
{
	// o-supported, non-architectural WME
	if ( wma_should_have_decay_element( w ) )
	{
		wma_decay_element* temp_el = w->wma_decay_el;

		// if decay structure doesn't exist, create it
		if ( !temp_el )
		{
			allocate_with_pool( my_agent, &( my_agent->wma_decay_element_pool ), &temp_el );

			temp_el->this_wme = w;
			temp_el->just_removed = false;

			temp_el->just_created = true;
			temp_el->num_references = wma_calculate_initial_boost( my_agent, w );

			temp_el->touches.history_ct = 0;
			temp_el->touches.next_p = 0;

			for ( int i=0; i<WMA_DECAY_HISTORY; i++ )
			{
				temp_el->touches.access_history[ i ].d_cycle = 0;
				temp_el->touches.access_history[ i ].num_references = 0;
			}

			temp_el->touches.history_references = 0;
			temp_el->touches.total_references = 0;
			temp_el->touches.first_reference = 0;

			// prevents confusion with delayed forgetting
			temp_el->forget_cycle = static_cast< wma_d_cycle >( -1 );

			w->wma_decay_el = temp_el;

			if ( my_agent->sysparams[ TRACE_WMA_SYSPARAM ] )
			{
				std::string msg( "WMA @" );
				std::string temp;

				to_string( my_agent->d_cycle_count, temp );
				msg.append( temp );
				msg.append( ": " );

				msg.append( "add " );

				to_string( w->timetag, temp );
				msg.append( temp );
				msg.append( " " );

				to_string( w->id->id.name_letter, temp );
				msg.append( temp );

				to_string( w->id->id.name_number, temp );
				msg.append( temp );
				msg.append( " " );

				switch ( w->attr->common.symbol_type )
				{
					case INT_CONSTANT_SYMBOL_TYPE:
						to_string( w->attr->ic.value, temp );
						break;

					case FLOAT_CONSTANT_SYMBOL_TYPE:
						to_string( w->attr->fc.value, temp );
						break;

					case SYM_CONSTANT_SYMBOL_TYPE:
						to_string( w->attr->sc.name, temp );
						break;
				}

				msg.append( temp );
				msg.append( " " );

				switch ( w->value->common.symbol_type )
				{
					case INT_CONSTANT_SYMBOL_TYPE:
						to_string( w->value->ic.value, temp );
						break;

					case FLOAT_CONSTANT_SYMBOL_TYPE:
						to_string( w->value->fc.value, temp );
						break;

					case SYM_CONSTANT_SYMBOL_TYPE:
						to_string( w->value->sc.name, temp );
						break;
				}

				msg.append( temp );
				msg.append( "\n" );

				print( my_agent, msg.c_str() );
				xml_generate_warning( my_agent, msg.c_str() );
			}
		}

		// add to o_set if necessary
		if ( o_set )
		{
			o_set->insert( w );
		}
		// otherwise update the decay element
		else
		{
			temp_el->num_references += num_references;
			my_agent->wma_touched_elements->insert( w );
		}
	}
	// i-supported, non-architectural WME
	else if ( !o_only && ( w->preference ) && ( w->preference->reference_count ) )
	{
		wma_pooled_wme_set* my_o_set = w->preference->wma_o_set;
		wma_pooled_wme_set::iterator wme_p;

		// if doesn't have an o_set, populate
		if ( !my_o_set )
		{
			allocate_with_pool( my_agent, &( my_agent->wma_wme_oset_pool ), &my_o_set );
#ifdef USE_MEM_POOL_ALLOCATORS
			my_o_set = new( my_o_set ) wma_pooled_wme_set( std::less< wme* >(), soar_module::soar_memory_pool_allocator< wme* >( my_agent ) );
#else
			my_o_set = new( my_o_set ) wma_pooled_wme_set();
#endif

			w->preference->wma_o_set = my_o_set;

			for ( condition* c=w->preference->inst->top_of_instantiated_conditions; c; c=c->next )
			{
				if ( c->type == POSITIVE_CONDITION )
				{
					wma_activate_wme( my_agent, c->bt.wme_, 0, my_o_set );
				}
			}

			for ( wme_p=my_o_set->begin(); wme_p!=my_o_set->end(); wme_p++ )
			{
				// add a ref to wmes on this list
				wme_add_ref( (*wme_p) );
			}
		}

		// iterate over the o_set
		for ( wme_p=my_o_set->begin(); wme_p!=my_o_set->end(); wme_p++ )
		{
			// if populating o_set, add
			if ( o_set )
			{
				o_set->insert( (*wme_p) );
			}
			// otherwise, "activate" the wme if it is
			// non-architectural (avoids dereferencing
			// the wme preference)
			else
			{
				if ( (*wme_p)->wma_decay_el )
				{
					(*wme_p)->wma_decay_el->num_references += num_references;
					my_agent->wma_touched_elements->insert( (*wme_p) );
				}
			}
		}
	}
	// architectural
	else if ( !o_only && !w->preference && ( w->reference_count != 0 ) )
	{
		// only action is to add it to the o_set
		if ( o_set )
		{
			o_set->insert( w );
		}
	}
}