Beispiel #1
0
void build_prohibits_list (instantiation *inst) {
  condition *cond;
  preference *pref, *new_pref;

  for (cond=inst->top_of_instantiated_conditions; cond!=NIL; cond=cond->next) {
    cond->bt.prohibits = NIL;
    if (cond->type==POSITIVE_CONDITION && cond->bt.trace) {
      if (cond->bt.trace->slot) {
        pref = cond->bt.trace->slot->preferences[PROHIBIT_PREFERENCE_TYPE];
        while (pref) {
          new_pref = NIL;
          if (pref->inst->match_goal_level == inst->match_goal_level && pref->in_tm) {
            push (pref, cond->bt.prohibits);
            preference_add_ref (pref);
          } else {
            new_pref = find_clone_for_level (pref, inst->match_goal_level);
            if (new_pref) {
              if (new_pref->in_tm) {
                push (new_pref, cond->bt.prohibits);
                preference_add_ref (new_pref);
              }
            }
          }
          pref = pref->next;
        }
      }
    }
  }
}
Beispiel #2
0
void process_o_rejects_and_deallocate_them(agent* thisAgent, preference* o_rejects, preference_list& bufdeallo)
{
    preference* pref, *next_pref, *p, *next_p;
    slot* s;

    for (pref = o_rejects; pref != NIL; pref = pref->next)
    {
        preference_add_ref(pref);  /* prevents it from being deallocated if it's
                                   a clone of some other pref we're about to
                                   remove */
    }

    pref = o_rejects;
    while (pref)
    {
        next_pref = pref->next;
        s = find_slot(pref->id, pref->attr);
        if (s)
        {
            /*  remove all pref's in the slot that have the same value */
            p = s->all_preferences;
            while (p)
            {
                next_p = p->all_of_slot_next;
                if (p->value == pref->value)
                {
                    // Buffer deallocation by adding a reference here and putting it
                    // on a list. These are deallocated after the inner elaboration
                    // loop completes.
                    preference_add_ref(p);
                    bufdeallo.push_back(p);
                    remove_preference_from_tm(thisAgent, p);
                }
                p = next_p;
            }
        }
        preference_remove_ref(thisAgent, pref);
        pref = next_pref;
    }
}
Beispiel #3
0
bool add_preference_to_tm(agent* thisAgent, preference* pref)
{

    slot* s = make_slot(thisAgent, pref->id, pref->attr);
    preference* p2;

    if (!thisAgent->Decider->settings[DECIDER_KEEP_TOP_OPREFS] && (pref->inst->match_goal == thisAgent->top_state) && pref->o_supported && !s->isa_context_slot && (pref->type == ACCEPTABLE_PREFERENCE_TYPE) )
    {
        /* We could potentially cache a list of all o-supported values in the slot so that we don't have to iterate
         * through all of the preferences. We would need to maintain the list as we decide non-context slots */
        bool already_top_o_supported = false;

        for (p2 = s->all_preferences; (p2 && !already_top_o_supported); p2 = p2->all_of_slot_next)
        {
            if ((p2->value == pref->value) && p2->o_supported && (p2->inst->match_goal == thisAgent->top_state))
            {
                already_top_o_supported = true;
            }
        }

        if (already_top_o_supported)
        {
            if (thisAgent->trace_settings[TRACE_FIRINGS_PREFERENCES_SYSPARAM])
            {
                thisAgent->outputManager->printa_sf(thisAgent,  "%e+ ");
                print_preference(thisAgent, pref, false);
                thisAgent->outputManager->printa_sf(thisAgent,  " (%y) ALREADY SUPPORTED ON TOP LEVEL.  IGNORING.\n", pref->inst->prod_name);
            }
            return false;
        }
    }

    pref->slot = s;

    insert_at_head_of_dll(s->all_preferences, pref, all_of_slot_next, all_of_slot_prev);

    /*  add to preference list of slot (according to match goal level of the instantiations) */

    if (!s->preferences[pref->type])
    {
        /*  this is the only pref. of its type, just put it at the head */
        insert_at_head_of_dll(s->preferences[pref->type], pref, next, prev);
    }
    else if (s->preferences[pref->type]->inst->match_goal_level >= pref->inst->match_goal_level)
    {
        /*  it belongs at the head of the list, so put it there */
        insert_at_head_of_dll(s->preferences[pref->type], pref, next, prev);
    }
    else
    {
        /*  scan through the pref. list, find the one to insert after */
        for (p2 = s->preferences[pref->type]; p2->next != NIL; p2 = p2->next)
        {
            if (p2->next->inst->match_goal_level >= pref->inst->match_goal_level)
            {
                break;
            }
        }

        /*  insert pref after p2 */
        pref->next = p2->next;
        pref->prev = p2;
        p2->next = pref;
        if (pref->next)
        {
            pref->next->prev = pref;
        }
    }

    pref->in_tm = true;
    preference_add_ref(pref);

    /* If the slot is unchanged but has some references laying around, we clear them
     * This does not lead to immediate memory deallocate/allocate but once the WMEs are
     * resolved, this should free the memory. */
    if (wma_enabled(thisAgent) && !s->isa_context_slot)
    {
        if (!s->changed)
        {
            if (s->wma_val_references != NIL)
            {
                s->wma_val_references->clear();
            }
        }
    }

    mark_slot_as_changed(thisAgent, s);

    if (wma_enabled(thisAgent) && !s->isa_context_slot)
    {
        bool exists = false;
        wme* w = pref->slot->wmes;
        while (!exists && w)
        {
            if (w->value == pref->value)
            {
                exists = true;
            }

            w = w->next;
        }

        /* If wme exists, it should already have been updated during assertion of new preferences */
        if (!exists)
        {
            if (s->wma_val_references == NIL)
            {
                thisAgent->memoryManager->allocate_with_pool(MP_wma_slot_refs, &(s->wma_val_references));
#ifdef USE_MEM_POOL_ALLOCATORS
                s->wma_val_references = new(s->wma_val_references) wma_sym_reference_map(std::less< Symbol* >(), soar_module::soar_memory_pool_allocator< std::pair< Symbol*, uint64_t > >());
#else
                s->wma_val_references = new(s->wma_val_references) wma_sym_reference_map();
#endif
            }

            (*s->wma_val_references)[ pref->value ]++;
        }
    }

    /*  update identifier levels */
    if (pref->value->symbol_type == IDENTIFIER_SYMBOL_TYPE)
    {
        post_link_addition(thisAgent, pref->id, pref->value);
    }
    if (preference_is_binary(pref->type))
    {
        if (pref->referent->symbol_type == IDENTIFIER_SYMBOL_TYPE)
        {
            post_link_addition(thisAgent, pref->id, pref->referent);
        }
    }

    /*  if acceptable/require pref for context slot, we may need to add a wme later */
    if ((s->isa_context_slot) &&  ((pref->type == ACCEPTABLE_PREFERENCE_TYPE) || (pref->type == REQUIRE_PREFERENCE_TYPE)))
    {
        mark_context_slot_as_acceptable_preference_changed(thisAgent, s);
    }
    if (thisAgent->trace_settings[TRACE_FIRINGS_PREFERENCES_SYSPARAM])
    {
        thisAgent->outputManager->printa_sf(thisAgent,  "%e+ ");
        print_preference(thisAgent, pref, false);
        thisAgent->outputManager->printa_sf(thisAgent,  " (%y)\n", pref->inst->prod_name);
    }

    return true;
}
Beispiel #4
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;
	}
Beispiel #5
0
void assert_new_preferences (void) {
  instantiation *inst, *next_inst;
  preference *pref, *next_pref;
  preference *o_rejects;

  o_rejects = NIL;  


  /* REW: begin 09.15.96 */
  if ((current_agent(operand2_mode) == TRUE) &&
      (current_agent(soar_verbose_flag) == TRUE))
     printf("\n   in assert_new_preferences:");
  /* REW: end   09.15.96 */


  for (inst=current_agent(newly_created_instantiations);
       inst!=NIL;
       inst=next_inst) {
    next_inst = inst->next;
    if (inst->in_ms)
      insert_at_head_of_dll (inst->prod->instantiations, inst, next, prev);


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


    for (pref=inst->preferences_generated; pref!=NIL; pref=next_pref) {
      next_pref = pref->inst_next;
      if ((pref->type==REJECT_PREFERENCE_TYPE)&&(pref->o_supported)) {
        /* --- o-reject: just put it in the buffer for later --- */
        pref->next = o_rejects;
        o_rejects = pref;


	/* REW: begin 09.15.96 */
	/* No knowledge retrieval necessary in Operand2 */
	/* REW: end   09.15.96 */

      } else if (inst->in_ms || pref->o_supported) {
        /* --- normal case --- */
        add_preference_to_tm (pref);


	/* REW: begin 09.15.96 */
	/* No knowledge retrieval necessary in Operand2 */
	/* REW: end   09.15.96 */


      } else {
        /* --- inst. is refracted chunk, and pref. is not o-supported:
           remove the preference --- */
        /* --- first splice it out of the clones list--otherwise we might
           accidentally deallocate some clone that happens to have refcount==0
           just because it hasn't been asserted yet --- */
        if (pref->next_clone) pref->next_clone->prev_clone = pref->prev_clone;
        if (pref->prev_clone) pref->prev_clone->next_clone = pref->next_clone;
        pref->next_clone = pref->prev_clone = NIL;
        /* --- now add then remove ref--this should result in deallocation */
        preference_add_ref (pref);
        preference_remove_ref (pref);
      }
    }
  }

  if (o_rejects) process_o_rejects_and_deallocate_them (o_rejects);
}
Beispiel #6
0
void fill_in_new_instantiation_stuff (instantiation *inst,
                                      bool need_to_do_support_calculations) {
  condition *cond;
  preference *p;
  goal_stack_level level;

  production_add_ref (inst->prod);
  
  find_match_goal (inst);

  level = inst->match_goal_level;

  /* Note: since we'll never backtrace through instantiations at the top
     level, it might make sense to not increment the reference counts
     on the wmes and preferences here if the instantiation is at the top
     level.  As it stands now, we could gradually accumulate garbage at
     the top level if we have a never-ending sequence of production
     firings at the top level that chain on each other's results.  (E.g.,
     incrementing a counter on every decision cycle.)  I'm leaving it this
     way for now, because if we go to S-Support, we'll (I think) need to
     save these around (maybe). */

  /* KJC 6/00:  maintaining all the top level ref cts does have a big
     impact on memory pool usage and also performance (due to malloc).
	 (See tests done by Scott Wallace Fall 99.)	 Therefore added 
	 preprocessor macro so that by setting macro the top level ref cts are not 
	 incremented.  It's possible that in some systems, these ref cts may 
	 be desireable: they can be added by defining DO_TOP_LEVEL_REF_CTS
	 */

  for (cond=inst->top_of_instantiated_conditions; cond!=NIL; cond=cond->next)
    if (cond->type==POSITIVE_CONDITION) {
        #ifdef DO_TOP_LEVEL_REF_CTS
		wme_add_ref (cond->bt.wme);
        #else
		if (level > TOP_GOAL_LEVEL) wme_add_ref (cond->bt.wme);
        #endif
		/* --- if trace is for a lower level, find one for this level --- */
      if (cond->bt.trace) {
        if (cond->bt.trace->inst->match_goal_level > level) { 
          cond->bt.trace = find_clone_for_level (cond->bt.trace, level);
		} 
        #ifdef DO_TOP_LEVEL_REF_CTS
		if (cond->bt.trace) preference_add_ref (cond->bt.trace);
        #else
		if ((cond->bt.trace) && (level > TOP_GOAL_LEVEL)) 
			preference_add_ref (cond->bt.trace);
        #endif
      }
    }



  if (inst->match_goal) {
    for (p=inst->preferences_generated; p!=NIL; p=p->inst_next) {
      insert_at_head_of_dll (inst->match_goal->id.preferences_from_goal, p,
                             all_of_goal_next, all_of_goal_prev);
      p->on_goal_list = TRUE;
    }
  }
  inst->backtrace_number = 0;

  if ((current_agent(o_support_calculation_type) == 0) ||
	  (current_agent(o_support_calculation_type) == 3))  {
    /* --- do calc's the normal Soar 6 way --- */  
    if (need_to_do_support_calculations)
      calculate_support_for_instantiation_preferences (inst);
  } else if (current_agent(o_support_calculation_type) == 1) {
    if (need_to_do_support_calculations)
      calculate_support_for_instantiation_preferences (inst);
    /* --- do calc's both ways, warn on differences --- */
    if ((inst->prod->declared_support!=DECLARED_O_SUPPORT) &&
        (inst->prod->declared_support!=DECLARED_I_SUPPORT)) {
      /* --- At this point, we've done them the normal way.  To look for
             differences, save o-support flags on a list, then do Doug's
             calculations, then compare and restore saved flags. --- */
      list *saved_flags;
      preference *pref;
      bool difference_found;
      saved_flags = NIL;
      for (pref=inst->preferences_generated; pref!=NIL; pref=pref->inst_next)
        push ((pref->o_supported ? pref : NIL), saved_flags);
      saved_flags = destructively_reverse_list (saved_flags);
      dougs_calculate_support_for_instantiation_preferences (inst);
      difference_found = FALSE;
      for (pref=inst->preferences_generated; pref!=NIL; pref=pref->inst_next){
        cons *c; bool b;
        c = saved_flags; saved_flags = c->rest;
        b = (c->first ? TRUE : FALSE); free_cons (c);
        if (pref->o_supported != b) difference_found = TRUE;
        pref->o_supported = b;
      }
      if (difference_found) {
        print_with_symbols("\n*** O-support difference found in production %y",
                           inst->prod->name);
      }
    }
  }
  else {
    /* --- do calc's Doug's way --- */
    if ((inst->prod->declared_support!=DECLARED_O_SUPPORT) &&
        (inst->prod->declared_support!=DECLARED_I_SUPPORT)) {
      dougs_calculate_support_for_instantiation_preferences (inst);
    }
  }
}