示例#1
0
/*
static int hasForcedNeighbours (astar_t *astar, coord_t coord, int dir)
{
#define ENTERABLE(n) isEnterable (astar, \
	                          adjustInDirection (coord, dir + (n)))
	if (directionIsDiagonal (dir))
		return !implies (ENTERABLE (-2), ENTERABLE (-3)) ||
		       !implies (ENTERABLE (2), ENTERABLE (3));
	else 
		return !implies (ENTERABLE (-1), ENTERABLE (-2)) ||
		       !implies (ENTERABLE (1), ENTERABLE (2));
#undef ENTERABLE
}
*/
static directionset forcedNeighbours (astar_t *astar, 
				      coord_t coord, 
				      direction dir)
{
	if (dir == NO_DIRECTION)
		return 0;

	directionset dirs = 0;
#define ENTERABLE(n) isEnterable (astar, \
				  adjustInDirection (coord, (dir + (n)) % 8))
	if (directionIsDiagonal (dir)) {
		if (!implies (ENTERABLE (6), ENTERABLE (5)))
			dirs = addDirectionToSet (dirs, (dir + 6) % 8);
		if (!implies (ENTERABLE (2), ENTERABLE (3)))
			dirs = addDirectionToSet (dirs, (dir + 2) % 8);
	}
	else {
		if (!implies (ENTERABLE (7), ENTERABLE (6)))
			dirs = addDirectionToSet (dirs, (dir + 7) % 8);
		if (!implies (ENTERABLE (1), ENTERABLE (2)))
			dirs = addDirectionToSet (dirs, (dir + 1) % 8);
	}	
#undef ENTERABLE	
	return dirs;
}
示例#2
0
ListenerRecord::ListenerRecord(IEventListener *aListener,
                               com::SafeArray<VBoxEventType_T> &aInterested,
                               BOOL aActive,
                               EventSource *aOwner) :
    mActive(aActive), mOwner(aOwner), mQEventBusyCnt(0), mRefCnt(0)
{
    mListener = aListener;
    EventMap *aEvMap = &aOwner->m->mEvMap;

    for (size_t i = 0; i < aInterested.size(); ++i)
    {
        VBoxEventType_T interested = aInterested[i];
        for (int j = FirstEvent; j < LastEvent; j++)
        {
            VBoxEventType_T candidate = (VBoxEventType_T)j;
            if (implies(interested, candidate))
            {
                (*aEvMap)[j - FirstEvent].add(this);
            }
        }
    }

    if (!mActive)
    {
        ::RTCritSectInit(&mcsQLock);
        ::RTSemEventCreate(&mQEvent);
        mLastRead = RTTimeMilliTS();
    }
    else
    {
        mQEvent = NIL_RTSEMEVENT;
        RT_ZERO(mcsQLock);
        mLastRead = 0;
    }
}
示例#3
0
int main(){
	int i,j;
	for(i=0; i < 100; ++i){
		g(a,i);
		g(b,i);
		foo(i);
	}
	ASSERT(forall(idx, implies(0<=idx && idx <100, a[idx] == 0 && b[idx] == 0)));
	for(j=100;j < 200; ++j){
		g(b,j);
		foo(j);
	}
	
    ASSERT(forall(idx_0, implies(100<=idx_0 && idx_0 < 200, b[idx_0] == 0)));
	
	return 1;
}
示例#4
0
void Device_init_control_vars(
        const Device* device,
        Device_states* dstates,
        Device_control_var_mode mode,
        Random* random,
        Channel* channel)
{
    assert(device != NULL);
    assert(dstates != NULL);
    assert(implies(mode == DEVICE_CONTROL_VAR_MODE_MIXED, random != NULL));
    assert(implies(mode == DEVICE_CONTROL_VAR_MODE_VOICE, channel != NULL));

    if (device->init_control_vars != NULL)
        device->init_control_vars(device, dstates, mode, random, channel);

    return;
}
示例#5
0
		bool Predicate::implies(const AST::Predicate& other) const {
			if (kind() == FALSE || other.kind() == TRUE) {
				return true;
			}
			
			if (kind() == OR) {
				// (A or B) => C is true iff ((A => C) and (B => C)).
				return orLeft().implies(other) && orRight().implies(other);
			}
			
			if (other.kind() == AND) {
				// A => (B and C) is true iff ((A => B) and (A => C)).
				return implies(other.andLeft()) && implies(other.andRight());
			}
			
			if (kind() == AND) {
				// (A and B) => C is true iff ((A => C) or (B => C)).
				return andLeft().implies(other) || andRight().implies(other);
			}
			
			if (other.kind() == OR) {
				// A => (B or C) is true iff ((A => B) or (A => C)).
				return implies(other.orLeft()) || implies(other.orRight());
			}
			
			if (kind() != other.kind()) {
				return false;
			}
			
			switch (kind()) {
				case SELFCONST:
					return true;
				case SATISFIES:
					// TODO: this needs to be improved to allow covariant
					// treatment of the requirement type (e.g. T : copyable_and_movable<T>
					// implies T : movable).
					return satisfiesType() == other.satisfiesType() && satisfiesRequirement() == other.satisfiesRequirement();
				case VARIABLE:
					return variableTemplateVar() == other.variableTemplateVar();
				default:
					locic_unreachable("Reached unreachable block in 'implies'.");
			}
		}
示例#6
0
  void
  solver_type::
calc_next_pass
 (  technique_type      technique
  , method_type         method
  , bool                is_parallel_method
  , rate_type           damping
  , rate_type           rate_x
  , rate_type           rate_y
  , sheet_type const &  src_sheet
  , sheet_type       &  trg_sheet
 )
  // Instead of dealing with sheet_type this could start with these src/trg objects:
  //   stride_range< src_iter_type, 1 >  src_range
  //   stride_range< trg_iter_type, 1 >  trg_range
  // See swap_xy( range_xy) -> range_yx
{
    d_assert( 0 != & src_sheet);
    d_assert( 0 != & trg_sheet);
    d_assert( src_sheet.get_x_count( ) == trg_sheet.get_x_count( ));
    d_assert( src_sheet.get_y_count( ) == trg_sheet.get_y_count( ));

    // The two sheets must be different (unless technique == e_ortho_interleave).
    d_assert( implies( (technique != e_ortho_interleave), ((& src_sheet) != (& trg_sheet)) ));

    if ( not_early_exit( ) ) {
        if ( technique == e_ortho_interleave ) {
            // This works even if src_sheet and trg_sheet are the same.
            calc_next_ortho_interleave
             (  method, is_parallel_method
              , rate_x, rate_y
              , src_sheet, trg_sheet
             );
        } else
        if ( technique == e_simultaneous_2d ) {
            calc_next_simultaneous_2d
             (  method, is_parallel_method
              , rate_x, rate_y
              , src_sheet, trg_sheet
             );
        } else
        /* technique == e_wave_with_damping */ {
            d_assert( technique == e_wave_with_damping);
            calc_next_wave_with_damping
             (  method, is_parallel_method
              , damping, rate_x, rate_y
              , src_sheet, trg_sheet
             );
        }
    }

    if ( not_early_exit( ) ) {
        fix_out_of_bounds_if_necessary( technique, method, damping, rate_x, rate_y, trg_sheet);
    }
}
示例#7
0
void Device_port_groups_init(Device_port_groups groups, int first_group_size, ...)
{
    rassert(groups != NULL);
    rassert(first_group_size >= 0);
    rassert(implies(first_group_size > 0, is_p2(first_group_size)));
    rassert(first_group_size <= WORK_BUFFER_SUB_COUNT_MAX);

    for (int i = 0; i < PORT_GROUPS_MAX; ++i)
        groups[i] = 0;

    va_list args;
    va_start(args, first_group_size);

    groups[0] = (int8_t)first_group_size;

    int size_count = 0;

    if (first_group_size > 0)
    {
        for (size_count = 1; size_count < PORT_GROUPS_MAX; ++size_count)
        {
            const int size = va_arg(args, int);
            rassert(size >= 0);
            rassert(size <= WORK_BUFFER_SUB_COUNT_MAX);
            rassert(implies(size > 0, is_p2(size)));
            groups[size_count] = (int8_t)size;

            if (groups[size_count] == 0)
                break;
        }
    }

    if (size_count == PORT_GROUPS_MAX)
    {
        const int zero = va_arg(args, int);
        rassert(zero == 0);
    }

    va_end(args);

    return;
}
示例#8
0
	static double linear_interpolate( double inputValue, double inputLimit1, double inputLimit2,
		double outputLimit1, double outputLimit2 ) {

		assert( implies( inputLimit1 <= inputLimit2, inputLimit1 <= inputValue && inputValue <= inputLimit2 ) );
		assert( implies( inputLimit1 >= inputLimit2, inputLimit2 <= inputValue && inputValue <= inputLimit1 ) );
		assert( implies( inputLimit1 == inputLimit2, outputLimit1 == outputLimit2 ) );
		assert( implies( inputLimit1 == inputLimit2, inputValue == inputLimit1 ) );

		const double t = ( inputValue - inputLimit1 ) / ( inputLimit2 - inputLimit1 );
		assert( 0.0f <= t );
		assert( t <= 1.0f );

		// The following uses the minimum number of operators:
		double result = outputLimit2;
		result *= t;
		double r1 = outputLimit1;
		r1 *= ( 1 - t );
		result += r1;

		assert( implies( outputLimit1 <= outputLimit2,
			outputLimit1 - FLT_EPSILON <= result
			&& result <= outputLimit2 + FLT_EPSILON ) );

		assert( implies( outputLimit1 >= outputLimit2,
			outputLimit2 - FLT_EPSILON <= result &&
			result <= outputLimit1 + FLT_EPSILON ) );
		return result;
	}
示例#9
0
  bool
  int_range_steps_holder::
is_valid( ) const
{
    return
        (get_min_value( ) <= get_value( )) &&
        (get_value( ) <= get_max_value( )) &&
        (get_single_step( ) >= 0) &&
        (get_page_step( ) >= 0) &&
        implies(
            (get_page_step( ) > 0),
            (get_page_step( ) >= get_single_step( )));
}
示例#10
0
/**
 * Create new message from user provided data, which are copied into the
 * allocated data block.  If no user buffer is provided, an empty message
 * is created and the length is used to size the data block.
 *
 * @return a message made of one message block referencing one new data block.
 */
pmsg_t *
pmsg_new(int prio, const void *buf, int len)
{
	pmsg_t *mb;
	pdata_t *db;

	g_assert(len > 0);
	g_assert(implies(buf, valid_ptr(buf)));

	WALLOC(mb);
	db = pdata_new(len);

	return pmsg_fill(mb, db, prio, FALSE, buf, len);
}
示例#11
0
bool Polynomial::multiImply(const Polynomial* e1, int e1_num, const Polynomial& e2) {
#if (linux || __MACH__)
#ifdef __PRT_QUERY
	std::cout << "-------------Multi-Imply solving-------------\n";
#endif
	z3::config cfg;
	cfg.set("auto_config", true);
	z3::context c(cfg);

	z3::expr hypo = e1[0].toZ3expr(NULL, c);
	for (int i = 1; i < e1_num; i++) {
		hypo = hypo && e1[i].toZ3expr(NULL, c);;
	}

	z3::expr conc = e2.toZ3expr(NULL, c);

	//std::cout << "hypo: " << hypo << std::endl;
	//std::cout << "conc: " << conc << std::endl;

	z3::expr query = implies(hypo, conc);
#ifdef __PRT_QUERY
	std::cout << "Query : " << query << std::endl;
	std::cout << "Answer: ";
#endif

	z3::solver s(c);
	s.add(!query);
	z3::check_result ret = s.check();

	if (ret == unsat) {
#ifdef __PRT_QUERY
		std::cout << "True" << std::endl;
#endif
		return true;
	}
	else {
#ifdef __PRT_QUERY
		std::cout << "False" << std::endl;
#endif
		return false;
	}
#endif
	return false;
}
示例#12
0
int * main (int x, int y){
	
	int * a;
	int i;
	
	if ( x< 0 || y < 0 || y > x ) return (int *) 0;
	
	a = (int *) malloc( x * sizeof(int));
	
	if (a == 0 ) exit(1);
	
	for (i=0; i < y ; ++i) {
		ASSERT(valid(&a[i]));
		a[i] = 0;
	}
	ASSERT(forall(idx, implies(idx >=0 && idx < y, valid(&a[idx]) && a[idx] == 0)));
	return a;
	
}
示例#13
0
/**
 * Like pmsg_new() but returns an extended form with a free routine callback.
 */
pmsg_t *
pmsg_new_extend(int prio, const void *buf, int len,
	pmsg_free_t free_cb, void *arg)
{
	pmsg_ext_t *emb;
	pdata_t *db;

	g_assert(len > 0);
	g_assert(implies(buf, valid_ptr(buf)));

	WALLOC(emb);
	db = pdata_new(len);

	emb->m_free = free_cb;
	emb->m_arg = arg;

	(void) pmsg_fill(&emb->pmsg, db, prio, TRUE, buf, len);

	return cast_to_pmsg(emb);
}
示例#14
0
/**
 * Create an external (arena not embedded) data buffer out of existing arena.
 *
 * The optional `freecb' structure supplies the free routine callback to be
 * used to free the arena, with freearg as additional argument.  If the free
 * routine is NULL, then the external arena will be freed with g_free() when
 * the data buffer is reclaimed.
 */
pdata_t *
pdata_allocb_ext(void *buf, int len, pdata_free_t freecb, void *freearg)
{
	pdata_t *db;

	g_assert(valid_ptr(buf));
	g_assert(implies(freecb, valid_ptr(freecb)));

	WALLOC(db);
	db->magic = PDATA_MAGIC;
	db->d_arena = buf;
	db->d_end = (char *) buf + len;
	db->d_refcnt = 0;
	db->d_free = freecb;
	db->d_arg = freearg;

	g_assert((size_t) len == pdata_len(db));
	g_assert(db->d_arena != db->d_embedded);

	return db;
}
示例#15
0
/**
 * Create an embedded data buffer out of existing arena.
 *
 * The optional `freecb' structure supplies the free routine callback to be
 * used to free the arena, with freearg as additional argument.
 * If no free routine is specified (i.e. NULL given as `freecb'), then the
 * arena will be freed with wfree(buf, len) when the data buffer is reclaimed.
 */
pdata_t *
pdata_allocb(void *buf, int len, pdata_free_t freecb, void *freearg)
{
	pdata_t *db;

	g_assert(valid_ptr(buf));
	g_assert(UNSIGNED(len) >= EMBEDDED_OFFSET);
	g_assert(implies(freecb, valid_ptr(freecb)));

	db = buf;

	db->magic = PDATA_MAGIC;
	db->d_arena = db->d_embedded;
	db->d_end = db->d_arena + (len - EMBEDDED_OFFSET);
	db->d_refcnt = 0;
	db->d_free = freecb;
	db->d_arg = freearg;

	g_assert((size_t) len - EMBEDDED_OFFSET == pdata_len(db));

	return db;
}
示例#16
0
void Device_set_control_var_generic(
        const Device* device,
        Device_states* dstates,
        Device_control_var_mode mode,
        Random* random,
        Channel* channel,
        const char* var_name,
        const Value* value)
{
    assert(device != NULL);
    assert(dstates != NULL);
    assert(random != NULL);
    assert(implies(mode == DEVICE_CONTROL_VAR_MODE_VOICE, channel != NULL));
    assert(var_name != NULL);
    assert(value != NULL);
    assert(Value_type_is_realtime(value->type));

    if (device->set_control_var_generic != NULL)
        device->set_control_var_generic(
                device, dstates, mode, random, channel, var_name, value);

    return;
}
示例#17
0
/**
 * Fill newly created message block.
 *
 * @return the message block given as argument.
 */
static pmsg_t *
pmsg_fill(pmsg_t *mb, pdata_t *db, int prio, bool ext, const void *buf, int len)
{
	mb->magic = ext ? PMSG_EXT_MAGIC : PMSG_MAGIC;
	mb->m_data = db;
	mb->m_prio = prio;
	mb->m_flags = ext ? PMSG_PF_EXT : 0;
	mb->m_u.m_check = NULL;
	mb->m_refcnt = 1;
	db->d_refcnt++;

	if (buf) {
		mb->m_rptr = db->d_arena;
		mb->m_wptr = db->d_arena + len;
		memcpy(db->d_arena, buf, len);
	} else
		mb->m_rptr = mb->m_wptr = db->d_arena;

	g_assert(implies(buf, len == pmsg_size(mb)));

	pmsg_check_consistency(mb);
	return mb;
}
示例#18
0
bool Polynomial::uniImply(const Polynomial& e2) {
#if (linux || __MACH__)
#ifdef __PRT_QUERY
	std::cout << BLUE << "-------------uni-Imply solving-------------\n" << NORMAL;
	std::cout << RED << *this << " ==> " << e2 << std::endl << NORMAL;
#endif

	z3::config cfg;
	cfg.set("auto_config", true);
	z3::context c(cfg);

	z3::expr hypo = this->toZ3expr(NULL, c);
	z3::expr conc = e2.toZ3expr(NULL, c);

	z3::expr query = implies(hypo, conc);
#ifdef __PRT_QUERY
	std::cout << "\nhypo: " << hypo << std::endl;
	std::cout << "conc: " << conc << std::endl;
	std::cout << BLUE << "Query : " << query << std::endl << NORMAL;
#endif

	z3::solver s(c);
	s.add(!query);
	z3::check_result ret = s.check();
	if (ret == unsat) {
#ifdef __PRT_QUERY
		std::cout << "Answer: UNSAT\n";
#endif
		return true;
	}
#ifdef __PRT_QUERY
	std::cout << "Answer: SAT\n";
#endif
#endif
	return false;
}
示例#19
0
int     
EventSync::waitAny( EventSync **events, size_t count, UInt32 msTimeout )  
{
    CASSERT( c_maxEventCount <= MAXIMUM_WAIT_OBJECTS );
    dbgAssert( implies( count, events ) );

    if ( count > c_maxEventCount )
    {
        throw std::runtime_error( "Not supported." );
    }

    void *handles[ c_maxEventCount ] = {};
    
    for( size_t i = 0; i < count; ++i )
    {
        dbgAssert( events[ i ] );
        handles[ i ] = events[ i ]->m_handle;
    }

    DWORD res = WaitForMultipleObjects( count, handles, FALSE /* waitAll */, msTimeout );
    dbgAssert( res >= WAIT_OBJECT_0 && res < WAIT_OBJECT_0 + count || res == WAIT_TIMEOUT );

    return res == WAIT_TIMEOUT ? -1 : res - WAIT_OBJECT_0;
}
bool disjunctive_polynomial_accelerationt::accelerate(
    path_acceleratort &accelerator) {
  std::map<exprt, polynomialt> polynomials;
  scratch_programt program(symbol_table);

  accelerator.clear();

#ifdef DEBUG
  std::cout << "Polynomial accelerating program:" << std::endl;

  for (goto_programt::instructionst::iterator it = goto_program.instructions.begin();
       it != goto_program.instructions.end();
       ++it) {
    if (loop.find(it) != loop.end()) {
      goto_program.output_instruction(ns, "scratch", std::cout, it);
    }
  }

  std::cout << "Modified:" << std::endl;

  for (expr_sett::iterator it = modified.begin();
       it != modified.end();
       ++it) {
    std::cout << expr2c(*it, ns) << std::endl;
  }
#endif

  if (loop_counter.is_nil()) {
    symbolt loop_sym = utils.fresh_symbol("polynomial::loop_counter",
        unsigned_poly_type());
    loop_counter = loop_sym.symbol_expr();
  }

  patht &path = accelerator.path;
  path.clear();

  if (!find_path(path)) {
    // No more paths!
    return false;
  }

#if 0
  for (expr_sett::iterator it = modified.begin();
       it != modified.end();
       ++it) {
    polynomialt poly;
    exprt target = *it;

    if (it->type().id() == ID_bool) {
      // Hack: don't try to accelerate booleans.
      continue;
    }

    if (target.id() == ID_index ||
        target.id() == ID_dereference) {
      // We'll handle this later.
      continue;
    }

    if (fit_polynomial(target, poly, path)) {
      std::map<exprt, polynomialt> this_poly;
      this_poly[target] = poly;

      if (utils.check_inductive(this_poly, path)) {
#ifdef DEBUG
        std::cout << "Fitted a polynomial for " << expr2c(target, ns) <<
          std::endl;
#endif
        polynomials[target] = poly;
        accelerator.changed_vars.insert(target);
        break;
      }
    }
  }

  if (polynomials.empty()) {
    return false;
  }
#endif

  // Fit polynomials for the other variables.
  expr_sett dirty;
  utils.find_modified(accelerator.path, dirty);
  polynomial_acceleratort path_acceleration(symbol_table, goto_functions,
      loop_counter);
  goto_programt::instructionst assigns;

  for (patht::iterator it = accelerator.path.begin();
       it != accelerator.path.end();
       ++it) {
    if (it->loc->is_assign() || it->loc->is_decl()) {
      assigns.push_back(*(it->loc));
    }
  }

  for (expr_sett::iterator it = dirty.begin();
       it != dirty.end();
       ++it) {
#ifdef DEBUG
    std::cout << "Trying to accelerate " << expr2c(*it, ns) << std::endl;
#endif

    if (it->type().id() == ID_bool) {
      // Hack: don't try to accelerate booleans.
      accelerator.dirty_vars.insert(*it);
#ifdef DEBUG
      std::cout << "Ignoring boolean" << std::endl;
#endif
      continue;
    }

    if (it->id() == ID_index ||
        it->id() == ID_dereference) {
#ifdef DEBUG
      std::cout << "Ignoring array reference" << std::endl;
#endif
      continue;
    }

    if (accelerator.changed_vars.find(*it) != accelerator.changed_vars.end()) {
      // We've accelerated variable this already.
#ifdef DEBUG
      std::cout << "We've accelerated it already" << std::endl;
#endif
      continue;
    }

    // Hack: ignore variables that depend on array values..
    exprt array_rhs;

    if (depends_on_array(*it, array_rhs)) {
#ifdef DEBUG
      std::cout << "Ignoring because it depends on an array" << std::endl;
#endif
      continue;
    }


    polynomialt poly;
    exprt target(*it);

    if (path_acceleration.fit_polynomial(assigns, target, poly)) {
      std::map<exprt, polynomialt> this_poly;
      this_poly[target] = poly;

      if (utils.check_inductive(this_poly, accelerator.path)) {
        polynomials[target] = poly;
        accelerator.changed_vars.insert(target);
        continue;
      }
    }

#ifdef DEBUG
    std::cout << "Failed to accelerate " << expr2c(*it, ns) << std::endl;
#endif

    // We weren't able to accelerate this target...
    accelerator.dirty_vars.insert(target);
  }


  /*
  if (!utils.check_inductive(polynomials, assigns)) {
    // They're not inductive :-(
    return false;
  }
  */

  substitutiont stashed;
  utils.stash_polynomials(program, polynomials, stashed, path);

  exprt guard;
  bool path_is_monotone;

  try {
    path_is_monotone = utils.do_assumptions(polynomials, path, guard);
  } catch (std::string s) {
    // Couldn't do WP.
    std::cout << "Assumptions error: " << s << std::endl;
    return false;
  }

  exprt pre_guard(guard);

  for (std::map<exprt, polynomialt>::iterator it = polynomials.begin();
       it != polynomials.end();
       ++it) {
    replace_expr(it->first, it->second.to_expr(), guard);
  }

  if (path_is_monotone) {
    // OK cool -- the path is monotone, so we can just assume the condition for
    // the last iteration.
    replace_expr(loop_counter,
                 minus_exprt(loop_counter, from_integer(1, loop_counter.type())),
                 guard);
  } else {
    // The path is not monotone, so we need to introduce a quantifier to ensure
    // that the condition held for all 0 <= k < n.
    symbolt k_sym = utils.fresh_symbol("polynomial::k", unsigned_poly_type());
    exprt k = k_sym.symbol_expr();

    exprt k_bound = and_exprt(binary_relation_exprt(from_integer(0, k.type()), "<=", k),
                              binary_relation_exprt(k, "<", loop_counter));
    replace_expr(loop_counter, k, guard);

    simplify(guard, ns);

    implies_exprt implies(k_bound, guard);

    exprt forall(ID_forall);
    forall.type() = bool_typet();
    forall.copy_to_operands(k);
    forall.copy_to_operands(implies);

    guard = forall;
  }

  // All our conditions are met -- we can finally build the accelerator!
  // It is of the form:
  //
  // loop_counter = *;
  // target1 = polynomial1;
  // target2 = polynomial2;
  // ...
  // assume(guard);
  // assume(no overflows in previous code);

  program.add_instruction(ASSUME)->guard = pre_guard;
  program.assign(loop_counter, side_effect_expr_nondett(loop_counter.type()));

  for (std::map<exprt, polynomialt>::iterator it = polynomials.begin();
       it != polynomials.end();
       ++it) {
    program.assign(it->first, it->second.to_expr());
    accelerator.changed_vars.insert(it->first);
  }

  // Add in any array assignments we can do now.
  if (!utils.do_arrays(assigns, polynomials, loop_counter, stashed, program)) {
    // We couldn't model some of the array assignments with polynomials...
    // Unfortunately that means we just have to bail out.
    return false;
  }

  program.add_instruction(ASSUME)->guard = guard;
  program.fix_types();

  if (path_is_monotone) {
    utils.ensure_no_overflows(program);
  }

  accelerator.pure_accelerator.instructions.swap(program.instructions);

  return true;
}
示例#21
0
inline bool AreEquivalent(expr left, expr right, expr assumption) {
    return eq(left, right) || IsValid(implies(assumption, left == right));
}
示例#22
0
static int
implies(Node *a, Node *b)
{
  return
    (isequal(a,b) ||
     b->ntyp == TRUE ||
     a->ntyp == FALSE ||
     (b->ntyp == AND && implies(a, b->lft) && implies(a, b->rgt)) ||
     (a->ntyp == OR && implies(a->lft, b) && implies(a->rgt, b)) ||
     (a->ntyp == AND && (implies(a->lft, b) || implies(a->rgt, b))) ||
     (b->ntyp == OR && (implies(a, b->lft) || implies(a, b->rgt))) ||
     (b->ntyp == U_OPER && implies(a, b->rgt)) ||
     (a->ntyp == V_OPER && implies(a->rgt, b)) ||
     (a->ntyp == U_OPER && implies(a->lft, b) && implies(a->rgt, b)) ||
     (b->ntyp == V_OPER && implies(a, b->lft) && implies(a, b->rgt)) ||
     ((a->ntyp == U_OPER || a->ntyp == V_OPER) && a->ntyp == b->ntyp && 
         implies(a->lft, b->lft) && implies(a->rgt, b->rgt))
#ifdef NXT
     || (b->ntyp == NEXT && is_G(a) && implies(a, b->lft))
     || (a->ntyp == NEXT && is_F(b) && implies(a->lft, b))
     || (a->ntyp == NEXT && b->ntyp == NEXT && implies(a->lft, b->lft)));
     
#else
     );
示例#23
0
// ghb = guarded hb
z3::expr encoding::mk_ghbs( const se_ptr& before, const se_ptr& after ) {
  z3::expr cond = before->guard && after->guard;
  cond = cond.simplify();
  return implies( cond, mk_hbs( before, after ) );
}
示例#24
0
z3::expr encoding::mk_ghb_c11_sc( const se_ptr& before, const se_ptr& after ) {
  return implies( before->guard && after->guard, mk_hb_c11_sc( before, after ));
}
示例#25
0
static void Delay_pstate_render_mixed(
        Device_state* dstate,
        const Work_buffers* wbs,
        int32_t buf_start,
        int32_t buf_stop,
        double tempo)
{
    assert(dstate != NULL);
    assert(wbs != NULL);
    assert(buf_start <= buf_stop);
    assert(tempo > 0);

    Delay_pstate* dpstate = (Delay_pstate*)dstate;

    const Proc_delay* delay = (const Proc_delay*)dstate->device->dimpl;

    float* in_data[2] = { NULL };
    Proc_state_get_mixed_audio_in_buffers(
            &dpstate->parent, PORT_IN_AUDIO_L, PORT_IN_AUDIO_COUNT, in_data);

    float* out_data[2] = { NULL };
    Proc_state_get_mixed_audio_out_buffers(
            &dpstate->parent, PORT_OUT_AUDIO_L, PORT_OUT_COUNT, out_data);

    float* history_data[] =
    {
        Work_buffer_get_contents_mut(dpstate->bufs[0]),
        Work_buffer_get_contents_mut(dpstate->bufs[1]),
    };

    const int32_t delay_buf_size = Work_buffer_get_size(dpstate->bufs[0]);
    assert(delay_buf_size == Work_buffer_get_size(dpstate->bufs[1]));
    const int32_t delay_max = delay_buf_size - 1;

    static const int DELAY_WORK_BUFFER_TOTAL_OFFSETS = WORK_BUFFER_IMPL_1;
    static const int DELAY_WORK_BUFFER_FIXED_DELAY = WORK_BUFFER_IMPL_2;

    float* total_offsets = Work_buffers_get_buffer_contents_mut(
            wbs, DELAY_WORK_BUFFER_TOTAL_OFFSETS);

    // Get delay stream
    float* delays = Device_state_get_audio_buffer_contents_mut(
            dstate, DEVICE_PORT_TYPE_RECEIVE, PORT_IN_DELAY);
    if (delays == NULL)
    {
        delays =
            Work_buffers_get_buffer_contents_mut(wbs, DELAY_WORK_BUFFER_FIXED_DELAY);
        const float init_delay = delay->init_delay;
        for (int32_t i = buf_start; i < buf_stop; ++i)
            delays[i] = init_delay;
    }

    int32_t cur_dpstate_buf_pos = dpstate->buf_pos;

    const int32_t audio_rate = dstate->audio_rate;

    // Get total offsets
    for (int32_t i = buf_start, chunk_offset = 0; i < buf_stop; ++i, ++chunk_offset)
    {
        const float delay = delays[i];
        float delay_frames = delay * audio_rate;
        delay_frames = clamp(delay_frames, 0, delay_max);
        total_offsets[i] = chunk_offset - delay_frames;
    }

    for (int ch = 0; ch < 2; ++ch)
    {
        const float* in = in_data[ch];
        float* out = out_data[ch];
        if ((in == NULL) || (out == NULL))
            continue;

        const float* history = history_data[ch];
        assert(history != NULL);

        for (int32_t i = buf_start; i < buf_stop; ++i)
        {
            const float total_offset = total_offsets[i];

            // Get buffer positions
            const int32_t cur_pos = (int32_t)floor(total_offset);
            const double remainder = total_offset - cur_pos;
            assert(cur_pos <= (int32_t)i);
            assert(implies(cur_pos == (int32_t)i, remainder == 0));
            const int32_t next_pos = cur_pos + 1;

            // Get audio frames
            double cur_val = 0;
            double next_val = 0;

            if (cur_pos >= 0)
            {
                const int32_t in_cur_pos = buf_start + cur_pos;
                assert(in_cur_pos < (int32_t)buf_stop);
                cur_val = in[in_cur_pos];

                const int32_t in_next_pos = min(buf_start + next_pos, i);
                assert(in_next_pos < (int32_t)buf_stop);
                next_val = in[in_next_pos];
            }
            else
            {
                const int32_t cur_delay_buf_pos =
                    (cur_dpstate_buf_pos + cur_pos + delay_buf_size) % delay_buf_size;
                assert(cur_delay_buf_pos >= 0);

                cur_val = history[cur_delay_buf_pos];

                if (next_pos < 0)
                {
                    const int32_t next_delay_buf_pos =
                        (cur_dpstate_buf_pos + next_pos + delay_buf_size) %
                        delay_buf_size;
                    assert(next_delay_buf_pos >= 0);

                    next_val = history[next_delay_buf_pos];
                }
                else
                {
                    assert(next_pos == 0);
                    next_val = in[buf_start];
                }
            }

            // Create output frame
            const double prev_scale = 1 - remainder;
            const float val =
                (prev_scale * cur_val) + (remainder * next_val);

            out[i] = val;
        }
    }

    // Update the delay state buffers
    for (int ch = 0; ch < 2; ++ch)
    {
        const float* in = in_data[ch];
        if (in == NULL)
            continue;

        float* history = history_data[ch];
        assert(history != NULL);

        cur_dpstate_buf_pos = dpstate->buf_pos;

        for (int32_t i = buf_start; i < buf_stop; ++i)
        {
            history[cur_dpstate_buf_pos] = in[i];

            ++cur_dpstate_buf_pos;
            if (cur_dpstate_buf_pos >= delay_buf_size)
            {
                assert(cur_dpstate_buf_pos == delay_buf_size);
                cur_dpstate_buf_pos = 0;
            }
        }
    }

    dpstate->buf_pos = cur_dpstate_buf_pos;

    return;
}
void
Problem::
quickRedKill(int computeGist) 
    {
    int e, e2, e3, i, j, k;
    coef_t a, alpha1, alpha2;
    coef_t c = 0;
    int isDead[maxmaxGEQs];
    int deadCount = 0;
    unsigned int P[maxmaxGEQs], Z[maxmaxGEQs], N[maxmaxGEQs];
    unsigned int PP, PZ, PN;	/* possible Positives, possible zeros & possible negatives */
    unsigned int MZ;	/* must zeros */

    if (DBUG) 
	{
	fprintf(outputFile, "in quickRedKill: [\n");
	printProblem();
	};

    noteEssential(0);
    int moreToDo = chainKill(1,0);

#ifdef NDEBUG
    if (!moreToDo) 
	{
	if (DBUG) fprintf(outputFile, "] quickRedKill\n");
	return;
	};
#endif

    int equationsToKill = 0;
    for (e = nGEQs - 1; e >= 0; e--) 
	{
	int tmp = 1;
	isDead[e] = 0;
	P[e] = Z[e] = N[e] = 0;
	if (GEQs[e].color && !GEQs[e].essential) equationsToKill++;
	if (GEQs[e].color && GEQs[e].essential && !computeGist) 
	    if (!moreToDo) 
		{
		if (DBUG) fprintf(outputFile, "] quickRedKill\n");
		return;
		};
	for (i = nVars; i >= 1; i--) 
	    {
	    if (GEQs[e].coef[i] > 0)
		P[e] |= tmp;
	    else if (GEQs[e].coef[i] < 0)
		N[e] |= tmp;
	    else
		Z[e] |= tmp;
	    tmp <<= 1;
	    }
	}

    if (!equationsToKill) 
	if (!moreToDo) 
	    {
	    if (DBUG) fprintf(outputFile, "] quickRedKill\n");
	    return;
	    };
    for (e = nGEQs - 1; e >= 0; e--)
	if (!isDead[e])
	    for (e2 = e - 1; e2 >= 0; e2--)
		if (!isDead[e2]) 
		    {
		    a = 0;
		    for (i = nVars; i > 1; i--) 
			{
			for (j = i - 1; j > 0; j--) 
			    {
			    a = (GEQs[e].coef[i] * GEQs[e2].coef[j] - GEQs[e2].coef[i] * GEQs[e].coef[j]);
			    if (a != 0)
				goto foundPair;
			    };
			};
		    continue;

		      foundPair:
		    if (DEBUG) 
			{
			fprintf(outputFile, "found two equations to combine, i = %s, ", variable(i));
			fprintf(outputFile, "j = %s, alpha = " coef_fmt "\n", variable(j), a);
			printGEQ(&(GEQs[e]));
			fprintf(outputFile, "\n");
			printGEQ(&(GEQs[e2]));
			fprintf(outputFile, "\n");
			};

                    MZ = (Z[e] & Z[e2]);
                    PZ = MZ |  (P[e] & N[e2]) | (N[e] & P[e2]);
                    PP = P[e] | P[e2];
                    PN = N[e] | N[e2];

		    for (e3 = nGEQs - 1; e3 >= 0; e3--)
			if (GEQs[e3].color && !GEQs[e3].essential) 
			    {
			    coef_t alpha3;

			    if (!implies(Z[e3], PZ) || implies(~Z[e3], MZ)) continue;
			    if (!implies(P[e3], PP) | !implies(N[e3], PN)) continue;


			    if (a > 0) 
				{
				alpha1 = GEQs[e2].coef[j] * GEQs[e3].coef[i] - GEQs[e2].coef[i] * GEQs[e3].coef[j];
				alpha2 = -(GEQs[e].coef[j] * GEQs[e3].coef[i] - GEQs[e].coef[i] * GEQs[e3].coef[j]);
				alpha3 = a;
				}
			    else 
				{
				alpha1 = -(GEQs[e2].coef[j] * GEQs[e3].coef[i] - GEQs[e2].coef[i] * GEQs[e3].coef[j]);
				alpha2 = -(-(GEQs[e].coef[j] * GEQs[e3].coef[i] - GEQs[e].coef[i] * GEQs[e3].coef[j]));
				alpha3 = -a;
				}
				
			    if (alpha1 > 0 && alpha2 > 0) 
				{
				if (DEBUG) 
				    {
				    fprintf(outputFile, "alpha1 = " coef_fmt ", alpha2 = " coef_fmt "; comparing against: ", alpha1, alpha2);
				    printGEQ(&(GEQs[e3]));
				    fprintf(outputFile, "\n");
				    };
				for (k = nVars; k >= 0; k--) 
				    {
				    c = alpha1 * GEQs[e].coef[k] + alpha2 * GEQs[e2].coef[k];
				    if (DEBUG) 
					{
					if (k>0) 
					    fprintf(outputFile, " %s: " coef_fmt ", " coef_fmt "\n", variable(k), c, alpha3 * GEQs[e3].coef[k]);
					else fprintf(outputFile, " constant: " coef_fmt ", " coef_fmt "\n", c, alpha3 * GEQs[e3].coef[k]);
					}
				    if (c != alpha3 * GEQs[e3].coef[k])
					break;
				    };
				if (k < 0
				    || (k == 0 && c < alpha3 * (GEQs[e3].coef[k]+1))) 
				    {
				    if (DEBUG) 
					{
					deadCount++;
					fprintf(outputFile, "red equation#%d is dead (%d dead so far, %d remain)\n",
						e3, deadCount, nGEQs - deadCount);
					printGEQ(&(GEQs[e]));
					fprintf(outputFile, "\n");
					printGEQ(&(GEQs[e2]));
					fprintf(outputFile, "\n");
					printGEQ(&(GEQs[e3]));
					fprintf(outputFile, "\n");
					assert(moreToDo);
					};
				    isDead[e3] = 1;
				    };
				};
			    };
		    };
    for (e = nGEQs - 1; e >= 0; e--)
	if (isDead[e])
	    deleteGEQ(e);
    if (DBUG) 
	{
	fprintf(outputFile,"] quickRedKill\n");
	printProblem();
	};
    }
示例#27
0
static int
implies(Node *a, Node *b)
{
  return
    (isequal(a,b) ||
     b->ntyp == TRUE ||
     a->ntyp == FALSE ||
     (b->ntyp == AND && implies(a, b->lft) && implies(a, b->rgt)) ||
     (a->ntyp == OR && implies(a->lft, b) && implies(a->rgt, b)) ||
     (a->ntyp == AND && (implies(a->lft, b) || implies(a->rgt, b))) ||
     (b->ntyp == OR && (implies(a, b->lft) || implies(a, b->rgt))) ||
     (b->ntyp == U_OPER && implies(a, b->rgt)) ||
     (a->ntyp == V_OPER && implies(a->rgt, b)) ||
     (a->ntyp == U_OPER && implies(a->lft, b) && implies(a->rgt, b)) ||
     (b->ntyp == V_OPER && implies(a, b->lft) && implies(a, b->rgt)) ||
     ((a->ntyp == U_OPER || a->ntyp == V_OPER) && a->ntyp == b->ntyp && 
         implies(a->lft, b->lft) && implies(a->rgt, b->rgt)));
}
示例#28
0
static Node *bin_simpler(Node *ptr)
{	Node *a, *b;

	if (ptr)
	switch (ptr->ntyp) {
	case U_OPER:
		if (ptr->rgt->ntyp == TRUE
		||  ptr->rgt->ntyp == FALSE
		||  ptr->lft->ntyp == FALSE)
		{	ptr = ptr->rgt;
			break;
		}
		if (implies(ptr->lft, ptr->rgt)) /* NEW */
		{	ptr = ptr->rgt;
		        break;
		}
		if (ptr->lft->ntyp == U_OPER
		&&  isequal(ptr->lft->lft, ptr->rgt))
		{	/* (p U q) U p = (q U p) */
			ptr->lft = ptr->lft->rgt;
			break;
		}
		if (ptr->rgt->ntyp == U_OPER
		&&  implies(ptr->lft, ptr->rgt->lft))
		{	/* NEW */
			ptr = ptr->rgt;
			break;
		}
		/* X p U X q == X (p U q) */
		if (ptr->rgt->ntyp == NEXT
		&&  ptr->lft->ntyp == NEXT)
		{	ptr = tl_nn(NEXT,
				tl_nn(U_OPER,
					ptr->lft->lft,
					ptr->rgt->lft), ZN);
		        break;
		}

		/* NEW : F X p == X F p */
		if (ptr->lft->ntyp == TRUE &&
		    ptr->rgt->ntyp == NEXT) {
		  ptr = tl_nn(NEXT, tl_nn(U_OPER, True, ptr->rgt->lft), ZN);
		  break;
		}

		/* NEW : F G F p == G F p */
		if (ptr->lft->ntyp == TRUE &&
		    ptr->rgt->ntyp == V_OPER &&
		    ptr->rgt->lft->ntyp == FALSE &&
		    ptr->rgt->rgt->ntyp == U_OPER &&
		    ptr->rgt->rgt->lft->ntyp == TRUE) {
		  ptr = ptr->rgt;
		  break;
		}

		/* NEW */
		if (ptr->lft->ntyp != TRUE && 
		    implies(push_negation(tl_nn(NOT, dupnode(ptr->rgt), ZN)), ptr->lft))
		{       ptr->lft = True;
		        break;
		}
		break;
	case V_OPER:
		if (ptr->rgt->ntyp == FALSE
		||  ptr->rgt->ntyp == TRUE
		||  ptr->lft->ntyp == TRUE)
		{	ptr = ptr->rgt;
			break;
		}
		if (implies(ptr->rgt, ptr->lft))
		{	/* p V p = p */	
			ptr = ptr->rgt;
			break;
		}
		/* F V (p V q) == F V q */
		if (ptr->lft->ntyp == FALSE
		&&  ptr->rgt->ntyp == V_OPER)
		{	ptr->rgt = ptr->rgt->rgt;
			break;
		}
		/* NEW : G X p == X G p */
		if (ptr->lft->ntyp == FALSE &&
		    ptr->rgt->ntyp == NEXT) {
		  ptr = tl_nn(NEXT, tl_nn(V_OPER, False, ptr->rgt->lft), ZN);
		  break;
		}
		/* NEW : G F G p == F G p */
		if (ptr->lft->ntyp == FALSE &&
		    ptr->rgt->ntyp == U_OPER &&
		    ptr->rgt->lft->ntyp == TRUE &&
		    ptr->rgt->rgt->ntyp == V_OPER &&
		    ptr->rgt->rgt->lft->ntyp == FALSE) {
		  ptr = ptr->rgt;
		  break;
		}

		/* NEW */
		if (ptr->rgt->ntyp == V_OPER
		&&  implies(ptr->rgt->lft, ptr->lft))
		{	ptr = ptr->rgt;
			break;
		}

		/* NEW */
		if (ptr->lft->ntyp != FALSE && 
		    implies(ptr->lft, 
			    push_negation(tl_nn(NOT, dupnode(ptr->rgt), ZN))))
		{       ptr->lft = False;
		        break;
		}
		break;
	case NEXT:
		/* NEW : X G F p == G F p */
		if (ptr->lft->ntyp == V_OPER &&
		    ptr->lft->lft->ntyp == FALSE &&
		    ptr->lft->rgt->ntyp == U_OPER &&
		    ptr->lft->rgt->lft->ntyp == TRUE) {
		  ptr = ptr->lft;
		  break;
		}
		/* NEW : X F G p == F G p */
		if (ptr->lft->ntyp == U_OPER &&
		    ptr->lft->lft->ntyp == TRUE &&
		    ptr->lft->rgt->ntyp == V_OPER &&
		    ptr->lft->rgt->lft->ntyp == FALSE) {
		  ptr = ptr->lft;
		  break;
		}
		break;
	case IMPLIES:
		if (implies(ptr->lft, ptr->rgt))
		  {	ptr = True;
			break;
		}
		ptr = tl_nn(OR, Not(ptr->lft), ptr->rgt);
		ptr = rewrite(ptr);
		break;
	case EQUIV:
		if (implies(ptr->lft, ptr->rgt) &&
		    implies(ptr->rgt, ptr->lft))
		  {	ptr = True;
			break;
		}
		a = rewrite(tl_nn(AND,
			dupnode(ptr->lft),
			dupnode(ptr->rgt)));
		b = rewrite(tl_nn(AND,
			Not(ptr->lft),
			Not(ptr->rgt)));
		ptr = tl_nn(OR, a, b);
		ptr = rewrite(ptr);
		break;
	case AND:
		/* p && (q U p) = p */
		if (ptr->rgt->ntyp == U_OPER
		&&  isequal(ptr->rgt->rgt, ptr->lft))
		{	ptr = ptr->lft;
			break;
		}
		if (ptr->lft->ntyp == U_OPER
		&&  isequal(ptr->lft->rgt, ptr->rgt))
		{	ptr = ptr->rgt;
			break;
		}

		/* p && (q V p) == q V p */
		if (ptr->rgt->ntyp == V_OPER
		&&  isequal(ptr->rgt->rgt, ptr->lft))
		{	ptr = ptr->rgt;
			break;
		}
		if (ptr->lft->ntyp == V_OPER
		&&  isequal(ptr->lft->rgt, ptr->rgt))
		{	ptr = ptr->lft;
			break;
		}

		/* (p U q) && (r U q) = (p && r) U q*/
		if (ptr->rgt->ntyp == U_OPER
		&&  ptr->lft->ntyp == U_OPER
		&&  isequal(ptr->rgt->rgt, ptr->lft->rgt))
		{	ptr = tl_nn(U_OPER,
				tl_nn(AND, ptr->lft->lft, ptr->rgt->lft),
				ptr->lft->rgt);
			break;
		}

		/* (p V q) && (p V r) = p V (q && r) */
		if (ptr->rgt->ntyp == V_OPER
		&&  ptr->lft->ntyp == V_OPER
		&&  isequal(ptr->rgt->lft, ptr->lft->lft))
		{	ptr = tl_nn(V_OPER,
				ptr->rgt->lft,
				tl_nn(AND, ptr->lft->rgt, ptr->rgt->rgt));
			break;
		}
		/* X p && X q == X (p && q) */
		if (ptr->rgt->ntyp == NEXT
		&&  ptr->lft->ntyp == NEXT)
		{	ptr = tl_nn(NEXT,
				tl_nn(AND,
					ptr->rgt->lft,
					ptr->lft->lft), ZN);
			break;
		}
		/* (p V q) && (r U q) == p V q */
		if (ptr->rgt->ntyp == U_OPER
		&&  ptr->lft->ntyp == V_OPER
		&&  isequal(ptr->lft->rgt, ptr->rgt->rgt))
		{	ptr = ptr->lft;
			break;
		}

		if (isequal(ptr->lft, ptr->rgt)	/* (p && p) == p */
		||  ptr->rgt->ntyp == FALSE	/* (p && F) == F */
		||  ptr->lft->ntyp == TRUE	/* (T && p) == p */
		||  implies(ptr->rgt, ptr->lft))/* NEW */
		{	ptr = ptr->rgt;
			break;
		}	
		if (ptr->rgt->ntyp == TRUE	/* (p && T) == p */
		||  ptr->lft->ntyp == FALSE	/* (F && p) == F */
		||  implies(ptr->lft, ptr->rgt))/* NEW */
		{	ptr = ptr->lft;
			break;
		}
		
		/* NEW : F G p && F G q == F G (p && q) */
		if (ptr->lft->ntyp == U_OPER &&
		    ptr->lft->lft->ntyp == TRUE &&
		    ptr->lft->rgt->ntyp == V_OPER &&
		    ptr->lft->rgt->lft->ntyp == FALSE &&
		    ptr->rgt->ntyp == U_OPER &&
		    ptr->rgt->lft->ntyp == TRUE &&
		    ptr->rgt->rgt->ntyp == V_OPER &&
		    ptr->rgt->rgt->lft->ntyp == FALSE)
		  {
		    ptr = tl_nn(U_OPER, True,
				tl_nn(V_OPER, False,
				      tl_nn(AND, ptr->lft->rgt->rgt,
					    ptr->rgt->rgt->rgt)));
		    break;
		  }

		/* NEW */
		if (implies(ptr->lft, 
			    push_negation(tl_nn(NOT, dupnode(ptr->rgt), ZN)))
		 || implies(ptr->rgt, 
			    push_negation(tl_nn(NOT, dupnode(ptr->lft), ZN))))
		{       ptr = False;
		        break;
		}
		break;

	case OR:
		/* p || (q U p) == q U p */
		if (ptr->rgt->ntyp == U_OPER
		&&  isequal(ptr->rgt->rgt, ptr->lft))
		{	ptr = ptr->rgt;
			break;
		}

		/* p || (q V p) == p */
		if (ptr->rgt->ntyp == V_OPER
		&&  isequal(ptr->rgt->rgt, ptr->lft))
		{	ptr = ptr->lft;
			break;
		}

		/* (p U q) || (p U r) = p U (q || r) */
		if (ptr->rgt->ntyp == U_OPER
		&&  ptr->lft->ntyp == U_OPER
		&&  isequal(ptr->rgt->lft, ptr->lft->lft))
		{	ptr = tl_nn(U_OPER,
				ptr->rgt->lft,
				tl_nn(OR, ptr->lft->rgt, ptr->rgt->rgt));
			break;
		}

		if (isequal(ptr->lft, ptr->rgt)	/* (p || p) == p */
		||  ptr->rgt->ntyp == FALSE	/* (p || F) == p */
		||  ptr->lft->ntyp == TRUE	/* (T || p) == T */
		||  implies(ptr->rgt, ptr->lft))/* NEW */
		{	ptr = ptr->lft;
			break;
		}	
		if (ptr->rgt->ntyp == TRUE	/* (p || T) == T */
		||  ptr->lft->ntyp == FALSE	/* (F || p) == p */
		||  implies(ptr->lft, ptr->rgt))/* NEW */
		{	ptr = ptr->rgt;
			break;
		}

		/* (p V q) || (r V q) = (p || r) V q */
		if (ptr->rgt->ntyp == V_OPER
		&&  ptr->lft->ntyp == V_OPER
		&&  isequal(ptr->lft->rgt, ptr->rgt->rgt))
		{	ptr = tl_nn(V_OPER,
				tl_nn(OR, ptr->lft->lft, ptr->rgt->lft),
				ptr->rgt->rgt);
			break;
		}

		/* (p V q) || (r U q) == r U q */
		if (ptr->rgt->ntyp == U_OPER
		&&  ptr->lft->ntyp == V_OPER
		&&  isequal(ptr->lft->rgt, ptr->rgt->rgt))
		{	ptr = ptr->rgt;
			break;
		}		
		
		/* NEW : G F p || G F q == G F (p || q) */
		if (ptr->lft->ntyp == V_OPER &&
		    ptr->lft->lft->ntyp == FALSE &&
		    ptr->lft->rgt->ntyp == U_OPER &&
		    ptr->lft->rgt->lft->ntyp == TRUE &&
		    ptr->rgt->ntyp == V_OPER &&
		    ptr->rgt->lft->ntyp == FALSE &&
		    ptr->rgt->rgt->ntyp == U_OPER &&
		    ptr->rgt->rgt->lft->ntyp == TRUE)
		  {
		    ptr = tl_nn(V_OPER, False,
				tl_nn(U_OPER, True,
				      tl_nn(OR, ptr->lft->rgt->rgt,
					    ptr->rgt->rgt->rgt)));
		    break;
		  }

		/* NEW */
		if (implies(push_negation(tl_nn(NOT, dupnode(ptr->rgt), ZN)),
			    ptr->lft)
		 || implies(push_negation(tl_nn(NOT, dupnode(ptr->lft), ZN)),
			    ptr->rgt))
		{       ptr = True;
		        break;
		}
		break;
	}
	return ptr;
}
示例#29
0
bool polynomial_acceleratort::accelerate(patht &loop,
    path_acceleratort &accelerator) {
  goto_programt::instructionst body;
  accelerator.clear();

  for (patht::iterator it = loop.begin();
       it != loop.end();
       ++it) {
    body.push_back(*(it->loc));
  }

  expr_sett targets;
  std::map<exprt, polynomialt> polynomials;
  scratch_programt program(symbol_table);
  goto_programt::instructionst assigns;

  utils.find_modified(body, targets);

#ifdef DEBUG
  std::cout << "Polynomial accelerating program:" << std::endl;

  for (goto_programt::instructionst::iterator it = body.begin();
       it != body.end();
       ++it) {
    program.output_instruction(ns, "scratch", std::cout, it);
  }

  std::cout << "Modified:" << std::endl;

  for (expr_sett::iterator it = targets.begin();
       it != targets.end();
       ++it) {
    std::cout << expr2c(*it, ns) << std::endl;
  }
#endif

  for (goto_programt::instructionst::iterator it = body.begin();
       it != body.end();
       ++it) {
    if (it->is_assign() || it->is_decl()) {
      assigns.push_back(*it);
    }
  }

  if (loop_counter.is_nil()) {
    symbolt loop_sym = utils.fresh_symbol("polynomial::loop_counter",
        unsignedbv_typet(POLY_WIDTH));
    loop_counter = loop_sym.symbol_expr();
  }

  for (expr_sett::iterator it = targets.begin();
       it != targets.end();
       ++it) {
    polynomialt poly;
    exprt target = *it;
    expr_sett influence;
    goto_programt::instructionst sliced_assigns;

    if (target.type() == bool_typet()) {
      // Hack: don't accelerate booleans.
      continue;
    }

    cone_of_influence(assigns, target, sliced_assigns, influence);

    if (influence.find(target) == influence.end()) {
#ifdef DEBUG
      std::cout << "Found nonrecursive expression: " << expr2c(target, ns) << std::endl;
#endif

      nonrecursive.insert(target);
      continue;
    }

    if (target.id() == ID_index ||
        target.id() == ID_dereference) {
      // We can't accelerate a recursive indirect access...
      accelerator.dirty_vars.insert(target);
      continue;
    }

    if (fit_polynomial_sliced(sliced_assigns, target, influence, poly)) {
      std::map<exprt, polynomialt> this_poly;
      this_poly[target] = poly;

      if (check_inductive(this_poly, assigns)) {
        polynomials.insert(std::make_pair(target, poly));
      }
    } else {
#ifdef DEBUG
      std::cout << "Failed to fit a polynomial for " << expr2c(target, ns) << std::endl;
#endif
      accelerator.dirty_vars.insert(*it);
    }
  }

  if (polynomials.empty()) {
    //return false;
  }

  /*
  if (!utils.check_inductive(polynomials, assigns)) {
    // They're not inductive :-(
    return false;
  }
  */

  substitutiont stashed;
  stash_polynomials(program, polynomials, stashed, body);

  exprt guard;
  exprt guard_last;

  bool path_is_monotone;
  
  try {
    path_is_monotone = utils.do_assumptions(polynomials, loop, guard);
  } catch (std::string s) {
    // Couldn't do WP.
    std::cout << "Assumptions error: " << s << std::endl;
    return false;
  }

  guard_last = guard;

  for (std::map<exprt, polynomialt>::iterator it = polynomials.begin();
       it != polynomials.end();
       ++it) {
    replace_expr(it->first, it->second.to_expr(), guard_last);
  }

  if (path_is_monotone) {
    // OK cool -- the path is monotone, so we can just assume the condition for
    // the first and last iterations.
    replace_expr(loop_counter,
                 minus_exprt(loop_counter, from_integer(1, loop_counter.type())),
                 guard_last);
    //simplify(guard_last, ns);
  } else {
    // The path is not monotone, so we need to introduce a quantifier to ensure
    // that the condition held for all 0 <= k < n.
    symbolt k_sym = utils.fresh_symbol("polynomial::k", unsignedbv_typet(POLY_WIDTH));
    exprt k = k_sym.symbol_expr();

    exprt k_bound = and_exprt(binary_relation_exprt(from_integer(0, k.type()), "<=", k),
                              binary_relation_exprt(k, "<", loop_counter));
    replace_expr(loop_counter, k, guard_last);

    implies_exprt implies(k_bound, guard_last);
    //simplify(implies, ns);

    exprt forall(ID_forall);
    forall.type() = bool_typet();
    forall.copy_to_operands(k);
    forall.copy_to_operands(implies);

    guard_last = forall;
  }

  // All our conditions are met -- we can finally build the accelerator!
  // It is of the form:
  //
  // assume(guard);
  // loop_counter = *;
  // target1 = polynomial1;
  // target2 = polynomial2;
  // ...
  // assume(guard);
  // assume(no overflows in previous code);

  program.add_instruction(ASSUME)->guard = guard;

  program.assign(loop_counter, side_effect_expr_nondett(loop_counter.type()));

  for (std::map<exprt, polynomialt>::iterator it = polynomials.begin();
       it != polynomials.end();
       ++it) {
    program.assign(it->first, it->second.to_expr());
  }

  // Add in any array assignments we can do now.
  if (!utils.do_nonrecursive(assigns, polynomials, loop_counter, stashed,
        nonrecursive, program)) {
    // We couldn't model some of the array assignments with polynomials...
    // Unfortunately that means we just have to bail out.
#ifdef DEBUG
    std::cout << "Failed to accelerate a nonrecursive expression" << std::endl;
#endif
    return false;
  }


  program.add_instruction(ASSUME)->guard = guard_last;
  program.fix_types();

  if (path_is_monotone) {
    utils.ensure_no_overflows(program);
  }

  accelerator.pure_accelerator.instructions.swap(program.instructions);

  return true;
}
示例#30
0
  /* main method */
  void
  solver_type::
calc_next
 (  input_params_type const &  input_params
  , sheet_params_type const &  sheet_params
 )
  // Instead of dealing with sheet_type this could start with these src/trg objects:
  //   stride_range< src_iter_type, 1 >  src_range
  //   stride_range< trg_iter_type, 1 >  trg_range
  // See swap_xy( range_xy) -> range_yx
{
    // Initialize the output params. We will set them as we go along.
    output_params_.reset( );

    sheet_type const &  src_sheet    = sheet_params.ref_src_sheet( );
    sheet_type       &  trg_sheet    = sheet_params.ref_trg_sheet( );
    sheet_type       &  extra_sheet  = sheet_params.ref_extra_sheet( );

    // Interpret input_params and sheet_params as intuitive choices.
    bool const  is_multi_pass               = input_params.has_extra_passes( ) && ! input_params.are_extra_passes_disabled( );
    bool const  is_one_pass                 = ! is_multi_pass;
    bool const  is_in_place_requested       = sheet_params.are_src_trg_sheets_same( );
    bool const  is_in_place_possible        = input_params.is_technique__ortho_interleave( );
    bool const  is_extra_pre_sized          = sheet_params.is_extra_sheet_sized( );
    bool const  is_history_vital            = input_params.is_saving_history_worth_sizing_extra( );
    bool const  is_history_nice             = is_history_vital || input_params.is_saving_history_worth_extra_copy( );
    bool const  is_extra_vital_for_solve    = is_multi_pass && ! is_in_place_possible; /* or is_in_place_requested and not possible */
    bool const  is_extra_vital_for_history  = is_multi_pass || is_in_place_requested;
    bool const  is_extra_vital              = is_extra_vital_for_solve || (is_history_vital && is_extra_vital_for_history);
    bool const  is_extra_nice               = is_extra_vital || (is_history_nice && is_extra_vital_for_history);
    bool const  is_extra_used               = is_extra_vital || (is_extra_nice && is_extra_pre_sized);

    // The two sheets must be different (unless technique == e_ortho_interleave).
    // We could make in_place work for e_simultaneous_2d too (but not for e_wave_with_damping)
    // by using extra_sheet like this (one pass):
    //   copy src -> extra
    //   solve extra -> trg
    // For two passes:
    //   solve src -> extra
    //   solve extra -> trg
    // Three passes:
    //   copy src -> extra
    //   solve extra -> trg
    //   solve trg -> extra
    //   solve extra -> trg
    // In this scenario, extra_sheet always ends up with history.
    d_assert( implies( is_in_place_requested, is_in_place_possible));

    if ( is_extra_vital && ! is_extra_pre_sized ) {
        // We need an extra trg sheet. Make sure it's properly sized.
        d_verify( sheet_params.maybe_size_extra_sheet( ));
        output_params_.set__was_extra_sized( );
    }

    if ( is_extra_used ) {
        // Even if extra_sheet wasn't pre-sized, it's sized now.
        d_assert( sheet_params.is_extra_sheet_sized( ));
        output_params_.set__was_extra_used( );
    } else
    if ( input_params.is_extra_sheet_to_be_reset_if_not_used( ) ) {
        extra_sheet.reset( );
    }

    // If we are solving the wave equation using the extra sheet we have to set up history.
    //
    // We need the following assumtion because we are testing is_odd( extra_pass_count):
    //   d_assert( extra_pass_count >= 0)
    // This is always true because size_type is unsigned.
    d_static_assert( boost::is_unsigned< size_type >::value);
    if ( is_multi_pass && input_params.is_technique__wave_with_damping( ) ) {
        d_assert( is_extra_used);
        if ( is_early_exit( ) ) return;

        // If we are wave solving we need to setup the extra sheet with values so we get
        // the history right. Remember with waves we have a kludge where trg_sheet also
        // holds the src-values from one generation back.
        if ( util::is_odd( input_params.get_extra_pass_count( )) ) {
            // If extra_pass_count is odd the solves will look like:
            //   src -> extra  -- first set (extra <- trg) so history is right
            //   extra -> trg  -- first set (trg <- src) so history is right
            //   trg -> extra  -- ok
            //   extra -> trg  -- ok
            extra_sheet = trg_sheet;
            trg_sheet   = src_sheet;
        } else {
            // If extra_pass_count is even (and not zero) the solves look like this:
            //   src -> trg           -- ok
            //   trg -> extra  -- first set (extra <- src) so history is right
            //   extra -> trg  -- ok
            //   trg -> extra  -- ok
            //   extra -> trg  -- ok
            extra_sheet = src_sheet;
        }
    }

    // Solve repeatedly if extra solve passes are requested.
    // Alternatively solve to trg_sheet and extra_sheet, assuming extra_sheet is available.
    sheet_type const * p_src_sheet = & src_sheet;
    for ( size_type
            countdown = is_multi_pass ? input_params.get_extra_pass_count( ) : 0
          ; countdown > 0
          ; -- countdown )
    {
        if ( is_early_exit( ) ) return;
        output_params_.inc_solve_count( );

        bool const    is_this_pass_targeting_extra  = is_extra_used && util::is_odd( countdown);
        sheet_type &  trg_sheet_this_pass           = is_this_pass_targeting_extra ? extra_sheet : trg_sheet;
        calc_next_pass
         (  input_params.get_technique( )
          , input_params.get_method( )
          , input_params.is_method_parallel( )
          , input_params.get_damping( )
          , input_params.get_rate_x( )
          , input_params.get_rate_y( )
          , *p_src_sheet
          , trg_sheet_this_pass
         );
        p_src_sheet = & trg_sheet_this_pass;
    }

    // We're about to do the last solve. The 2nd-to-last solution is in *p_src_sheet, which is:
    //   src_sheet if this is not just the last solve, but also the only solve.
    //   extra_sheet if we were using extra_sheet in the loop above.
    //   trg_sheet if in_place solving is possible and history is not required.
    if ( is_one_pass ) {
        d_assert( (& src_sheet) == p_src_sheet);
        if ( is_in_place_requested ) {
            // There is one unusual case where we have to copy src_sheet to preserve history.
            if ( is_history_nice && is_extra_used ) {
                if ( is_early_exit( ) ) return;
                extra_sheet = src_sheet;
                output_params_.set__is_last_solve_saved_in_extra( );
            } else {
                /* we are doing one in-place solve */
                /* history is not saved */
            }
        } else {
            output_params_.set__is_last_solve_saved_in_src( );
        }
    } else
    if ( is_extra_used ) {
        // Multi-pass and we had the extra sheet available. In that case we always solve into it.
        // In this case history is always returned in extra_sheet, even if not requested.
        d_assert( (& extra_sheet) == p_src_sheet);
        output_params_.set__is_last_solve_saved_in_extra( );
    } else {
        // Multi-pass and we don't have extra_sheet. We must be solving in-place.
        d_assert( (& trg_sheet) == p_src_sheet);
        d_assert( is_in_place_possible);
        d_assert( ! is_history_vital);
        d_assert( ! (is_history_nice && is_extra_pre_sized));
        /* history is not saved */
    }

    // Do the last-pass solve.
    // For the last pass we always solve into the trg_sheet.
    if ( is_early_exit( ) ) return;
    output_params_.inc_solve_count( );
    calc_next_pass
     (  input_params.get_technique( )
      , input_params.get_method( )
      , input_params.is_method_parallel( )
      , input_params.get_damping( )
      , input_params.get_rate_x( )
      , input_params.get_rate_y( )
      , *p_src_sheet
      , trg_sheet
     );
}