void Solver::solve(const string &file_name) {
	stopwatch_.start();
	statistics_.input_file_ = file_name;

	createfromFile(file_name);
	initStack(num_variables());

	if (!config_.quiet) {
		cout << "Solving " << file_name << endl;
		statistics_.printShortFormulaInfo();
	}
	if (!config_.quiet)
		cout << endl << "Preprocessing .." << flush;
	bool notfoundUNSAT = simplePreProcess();
	if (!config_.quiet)
		cout << " DONE" << endl;

	if (notfoundUNSAT) {

		if (!config_.quiet) {
			statistics_.printShortFormulaInfo();
		}

		last_ccl_deletion_time_ = last_ccl_cleanup_time_ =
				statistics_.getTime();

		violated_clause.reserve(num_variables());

		component_analyzer_.initialize(literals_, literal_pool_);

		statistics_.exit_state_ = countSAT();

		mpz_class proj_count = stack_.top().getTotalModelCount();
		mpz_mul_2exp(proj_count.get_mpz_t(), proj_count.get_mpz_t(), statistics_.num_free_remembered_variables_);
		cout << "FINAL COUNT AFTER PROJECTION: " << proj_count << endl;

		statistics_.set_final_solution_count(stack_.top().getTotalModelCount());
		statistics_.num_long_conflict_clauses_ = num_conflict_clauses();
		statistics_.cache_bytes_memory_usage_ =
				component_analyzer_.cache().recompute_bytes_memory_usage();
	} else {
		statistics_.exit_state_ = SUCCESS;
		statistics_.set_final_solution_count(0.0);
		cout << endl << " FOUND UNSAT DURING PREPROCESSING " << endl;
	}

	stopwatch_.stop();
	statistics_.time_elapsed_ = stopwatch_.getElapsedSeconds();

	statistics_.writeToFile("data.out");
	if (!SolverConfiguration::quiet)
		statistics_.printShort();
}
void Solver::HardWireAndCompact() {
	compactClauses();
	compactVariables();
	literal_stack_.clear();

	for (auto l = LiteralID(1, false); l != literals_.end_lit(); l.inc()) {
		literal(l).activity_score_ = literal(l).binary_links_.size() - 1;
		literal(l).activity_score_ += occurrence_lists_[l].size();
	}

	statistics_.num_unit_clauses_ = unit_clauses_.size();

	statistics_.num_original_binary_clauses_ = statistics_.num_binary_clauses_;
	statistics_.num_original_unit_clauses_ = statistics_.num_unit_clauses_ =
			unit_clauses_.size();
	initStack(num_variables());
	original_lit_pool_size_ = literal_pool_.size();
}
void WitnessSet::send(ParallelismConfig & mpi_config, int target) const
{
    //send all the data to the other party
    

//
//	
//	std::vector< std::string > variable_names;
//	
//	boost::filesystem::path input_filename;
//	function input_file;
//	// end data members
    
    int *buffer = (int *) br_malloc(8*sizeof(int));
    buffer[0] = dimension();
    buffer[1] = component_number();
    buffer[2] = incidence_number();
    buffer[3] = num_variables();
    buffer[4] = num_natural_variables();
    buffer[5] = num_points();
    buffer[6] = num_linears();
    buffer[7] = num_patches();
    
    MPI_Send(buffer, 8, MPI_INT, WITNESS_SET, target, mpi_config.comm());
    
    free(buffer);
    
    for (unsigned int ii=0; ii<num_linears(); ii++) {
        send_vec_mp( linear(ii),target);
    }
    for (unsigned int ii=0; ii<num_patches(); ii++) {
        send_vec_mp( patch(ii),target);
    }
    for (unsigned int ii=0; ii<num_points(); ii++) {
        send_vec_mp( point(ii) ,target);
    }
    
    char * namebuffer = (char *) br_malloc(1024*sizeof(char));
    
	
    free(namebuffer);
    return;
}
Exemple #4
0
void colvarbias_abf::write_gradients_samples(const std::string &prefix, bool append)
{
  std::string  samples_out_name = prefix + ".count";
  std::string  gradients_out_name = prefix + ".grad";
  std::ios::openmode mode = (append ? std::ios::app : std::ios::out);

  std::ostream *samples_os =
    cvm::proxy->output_stream(samples_out_name, mode);
  if (!samples_os) return;
  samples->write_multicol(*samples_os);
  cvm::proxy->close_output_stream(samples_out_name);

  // In dimension higher than 2, dx is easier to handle and visualize
  if (num_variables() > 2) {
    std::string  samples_dx_out_name = prefix + ".count.dx";
    std::ostream *samples_dx_os = cvm::proxy->output_stream(samples_dx_out_name, mode);
    if (!samples_os) return;
    samples->write_opendx(*samples_dx_os);
    *samples_dx_os << std::endl;
    cvm::proxy->close_output_stream(samples_dx_out_name);
  }

  std::ostream *gradients_os =
    cvm::proxy->output_stream(gradients_out_name, mode);
  if (!gradients_os) return;
  gradients->write_multicol(*gradients_os);
  cvm::proxy->close_output_stream(gradients_out_name);

  if (b_integrate) {
    // Do numerical integration (to high precision) and output a PMF
    cvm::real err;
    pmf->integrate(integrate_initial_steps, integrate_initial_tol, err);
    pmf->set_zero_minimum();

    std::string  pmf_out_name = prefix + ".pmf";
    std::ostream *pmf_os = cvm::proxy->output_stream(pmf_out_name, mode);
    if (!pmf_os) return;
    pmf->write_multicol(*pmf_os);

    // In dimension higher than 2, dx is easier to handle and visualize
    if (num_variables() > 2) {
      std::string  pmf_dx_out_name = prefix + ".pmf.dx";
      std::ostream *pmf_dx_os = cvm::proxy->output_stream(pmf_dx_out_name, mode);
      if (!pmf_dx_os) return;
      pmf->write_opendx(*pmf_dx_os);
      *pmf_dx_os << std::endl;
      cvm::proxy->close_output_stream(pmf_dx_out_name);
    }

    *pmf_os << std::endl;
    cvm::proxy->close_output_stream(pmf_out_name);
  }

  if (b_CZAR_estimator) {
    // Write eABF CZAR-related quantities

    std::string  z_samples_out_name = prefix + ".zcount";

    std::ostream *z_samples_os =
      cvm::proxy->output_stream(z_samples_out_name, mode);
    if (!z_samples_os) return;
    z_samples->write_multicol(*z_samples_os);
    cvm::proxy->close_output_stream(z_samples_out_name);

    if (b_czar_window_file) {
      std::string  z_gradients_out_name = prefix + ".zgrad";

      std::ostream *z_gradients_os =
        cvm::proxy->output_stream(z_gradients_out_name, mode);
      if (!z_gradients_os) return;
      z_gradients->write_multicol(*z_gradients_os);
      cvm::proxy->close_output_stream(z_gradients_out_name);
    }

    // Calculate CZAR estimator of gradients
    for (std::vector<int> ix = czar_gradients->new_index();
          czar_gradients->index_ok(ix); czar_gradients->incr(ix)) {
      for (size_t n = 0; n < czar_gradients->multiplicity(); n++) {
        czar_gradients->set_value(ix, z_gradients->value_output(ix, n)
          - cvm::temperature() * cvm::boltzmann() * z_samples->log_gradient_finite_diff(ix, n), n);
      }
    }

    std::string  czar_gradients_out_name = prefix + ".czar.grad";

    std::ostream *czar_gradients_os =
      cvm::proxy->output_stream(czar_gradients_out_name, mode);
    if (!czar_gradients_os) return;
    czar_gradients->write_multicol(*czar_gradients_os);
    cvm::proxy->close_output_stream(czar_gradients_out_name);

    if (b_integrate) {
      // Do numerical integration (to high precision) and output a PMF
      cvm::real err;
      czar_pmf->set_div();
      czar_pmf->integrate(integrate_initial_steps, integrate_initial_tol, err);
      czar_pmf->set_zero_minimum();

      std::string  czar_pmf_out_name = prefix + ".czar.pmf";
      std::ostream *czar_pmf_os = cvm::proxy->output_stream(czar_pmf_out_name, mode);
      if (!czar_pmf_os) return;
      czar_pmf->write_multicol(*czar_pmf_os);

      // In dimension higher than 2, dx is easier to handle and visualize
      if (num_variables() > 2) {
        std::string  czar_pmf_dx_out_name = prefix + ".czar.pmf.dx";
        std::ostream *czar_pmf_dx_os = cvm::proxy->output_stream(czar_pmf_dx_out_name, mode);
        if (!czar_pmf_dx_os) return;
        czar_pmf->write_opendx(*czar_pmf_dx_os);
        *czar_pmf_dx_os << std::endl;
        cvm::proxy->close_output_stream(czar_pmf_dx_out_name);
      }

      *czar_pmf_os << std::endl;
      cvm::proxy->close_output_stream(czar_pmf_out_name);
    }
  }
  return;
}
Exemple #5
0
int colvarbias_abf::update()
{
  if (cvm::debug()) cvm::log("Updating ABF bias " + this->name);

  size_t i;
  for (i = 0; i < num_variables(); i++) {
    bin[i] = samples->current_bin_scalar(i);
  }
  if (cvm::proxy->total_forces_same_step()) {
    // e.g. in LAMMPS, total forces are current
    force_bin = bin;
  }

  if (cvm::step_relative() > 0 || cvm::proxy->total_forces_same_step()) {

    if (update_bias) {
//       if (b_adiabatic_reweighting) {
//         // Update gradients non-locally based on conditional distribution of
//         // fictitious variable TODO
//
//       } else
      if (samples->index_ok(force_bin)) {
        // Only if requested and within bounds of the grid...

        for (i = 0; i < num_variables(); i++) {
          // get total forces (lagging by 1 timestep) from colvars
          // and subtract previous ABF force if necessary
          update_system_force(i);
        }
        gradients->acc_force(force_bin, system_force);
        if ( b_integrate ) {
          pmf->update_div_neighbors(force_bin);
        }
      }
    }

    if ( z_gradients && update_bias ) {
      for (i = 0; i < num_variables(); i++) {
        z_bin[i] = z_samples->current_bin_scalar(i);
      }
      if ( z_samples->index_ok(z_bin) ) {
        for (i = 0; i < num_variables(); i++) {
          // If we are outside the range of xi, the force has not been obtained above
          // the function is just an accessor, so cheap to call again anyway
          update_system_force(i);
        }
        z_gradients->acc_force(z_bin, system_force);
      }
    }

    if ( b_integrate ) {
      if ( pabf_freq && cvm::step_relative() % pabf_freq == 0 ) {
        cvm::real err;
        int iter = pmf->integrate(integrate_steps, integrate_tol, err);
        if ( iter == integrate_steps ) {
          cvm::log("Warning: PMF integration did not converge to " + cvm::to_str(integrate_tol)
            + " in " + cvm::to_str(integrate_steps)
            + " steps. Residual error: " +  cvm::to_str(err));
        }
        pmf->set_zero_minimum(); // TODO: do this only when necessary
      }
    }
  }

  if (!cvm::proxy->total_forces_same_step()) {
    // e.g. in NAMD, total forces will be available for next timestep
    // hence we store the current colvar bin
    force_bin = bin;
  }

  // Reset biasing forces from previous timestep
  for (i = 0; i < num_variables(); i++) {
    colvar_forces[i].reset();
  }

  // Compute and apply the new bias, if applicable
  if (is_enabled(f_cvb_apply_force) && samples->index_ok(bin)) {

    cvm::real count = samples->value(bin);
    cvm::real fact = 1.0;

    // Factor that ensures smooth introduction of the force
    if ( count < full_samples ) {
      fact = (count < min_samples) ? 0.0 :
        (cvm::real(count - min_samples)) / (cvm::real(full_samples - min_samples));
    }

    std::vector<cvm::real>  grad(num_variables());

    if ( pabf_freq ) {
      // In projected ABF, the force is the PMF gradient estimate
      pmf->vector_gradient_finite_diff(bin, grad);
    } else {
      // Normal ABF
      gradients->vector_value(bin, grad);
    }

//     if ( b_adiabatic_reweighting) {
//       // Average of force according to conditional distribution of fictitious variable
//       // need freshly integrated PMF, gradient TODO
//     } else
    if ( fact != 0.0 ) {
      if ( (num_variables() == 1) && colvars[0]->periodic_boundaries() ) {
        // Enforce a zero-mean bias on periodic, 1D coordinates
        // in other words: boundary condition is that the biasing potential is periodic
        // This is enforced naturally if using integrated PMF
        colvar_forces[0].real_value = fact * (grad[0] - gradients->average ());
      } else {
        for (size_t i = 0; i < num_variables(); i++) {
          // subtracting the mean force (opposite of the FE gradient) means adding the gradient
          colvar_forces[i].real_value = fact * grad[i];
        }
      }
      if (cap_force) {
        for (size_t i = 0; i < num_variables(); i++) {
          if ( colvar_forces[i].real_value * colvar_forces[i].real_value > max_force[i] * max_force[i] ) {
            colvar_forces[i].real_value = (colvar_forces[i].real_value > 0 ? max_force[i] : -1.0 * max_force[i]);
          }
        }
      }
    }
  }

  // update the output prefix; TODO: move later to setup_output() function
  if (cvm::main()->num_biases_feature(colvardeps::f_cvb_calc_pmf) == 1) {
    // This is the only bias computing PMFs
    output_prefix = cvm::output_prefix();
  } else {
    output_prefix = cvm::output_prefix() + "." + this->name;
  }

  if (output_freq && (cvm::step_absolute() % output_freq) == 0) {
    if (cvm::debug()) cvm::log("ABF bias trying to write gradients and samples to disk");
    write_gradients_samples(output_prefix);
  }

  if (b_history_files && (cvm::step_absolute() % history_freq) == 0) {
    // file already exists iff cvm::step_relative() > 0
    // otherwise, backup and replace
    write_gradients_samples(output_prefix + ".hist", (cvm::step_relative() > 0));
  }

  if (shared_on && shared_last_step >= 0 && cvm::step_absolute() % shared_freq == 0) {
    // Share gradients and samples for shared ABF.
    replica_share();
  }

  // Prepare for the first sharing.
  if (shared_last_step < 0) {
    // Copy the current gradient and count values into last.
    last_gradients->copy_grid(*gradients);
    last_samples->copy_grid(*samples);
    shared_last_step = cvm::step_absolute();
    cvm::log("Prepared sample and gradient buffers at step "+cvm::to_str(cvm::step_absolute())+".");
  }

  // update UI estimator every step
  if (b_UI_estimator)
  {
    std::vector<double> x(num_variables(),0);
    std::vector<double> y(num_variables(),0);
    for (size_t i = 0; i < num_variables(); i++)
    {
      x[i] = colvars[i]->actual_value();
      y[i] = colvars[i]->value();
    }
    eabf_UI.update_output_filename(output_prefix);
    eabf_UI.update(cvm::step_absolute(), x, y);
  }

  return COLVARS_OK;
}
Exemple #6
0
int colvarbias_abf::init(std::string const &conf)
{
  colvarbias::init(conf);

  enable(f_cvb_scalar_variables);
  enable(f_cvb_calc_pmf);

  // TODO relax this in case of VMD plugin
  if (cvm::temperature() == 0.0)
    cvm::log("WARNING: ABF should not be run without a thermostat or at 0 Kelvin!\n");

  // ************* parsing general ABF options ***********************

  get_keyval_feature((colvarparse *)this, conf, "applyBias",  f_cvb_apply_force, true);
  if (!is_enabled(f_cvb_apply_force)){
    cvm::log("WARNING: ABF biases will *not* be applied!\n");
  }

  get_keyval(conf, "updateBias",  update_bias, true);
  if (update_bias) {
    enable(f_cvb_history_dependent);
  } else {
    cvm::log("WARNING: ABF biases will *not* be updated!\n");
  }

  get_keyval(conf, "hideJacobian", hide_Jacobian, false);
  if (hide_Jacobian) {
    cvm::log("Jacobian (geometric) forces will be handled internally.\n");
  } else {
    cvm::log("Jacobian (geometric) forces will be included in reported free energy gradients.\n");
  }

  get_keyval(conf, "fullSamples", full_samples, 200);
  if ( full_samples <= 1 ) full_samples = 1;
  min_samples = full_samples / 2;
  // full_samples - min_samples >= 1 is guaranteed

  get_keyval(conf, "inputPrefix",  input_prefix, std::vector<std::string>());
  get_keyval(conf, "outputFreq", output_freq, cvm::restart_out_freq);
  get_keyval(conf, "historyFreq", history_freq, 0);
  b_history_files = (history_freq > 0);

  // shared ABF
  get_keyval(conf, "shared", shared_on, false);
  if (shared_on) {
    if (!cvm::replica_enabled() || cvm::replica_num() <= 1) {
      cvm::error("Error: shared ABF requires more than one replica.");
      return COLVARS_ERROR;
    }
    cvm::log("shared ABF will be applied among "+ cvm::to_str(cvm::replica_num()) + " replicas.\n");
    if (cvm::proxy->smp_enabled() == COLVARS_OK) {
      cvm::error("Error: shared ABF is currently not available with SMP parallelism; "
                 "please set \"SMP off\" at the top of the Colvars configuration file.\n",
                 COLVARS_NOT_IMPLEMENTED);
      return COLVARS_NOT_IMPLEMENTED;
    }

    // If shared_freq is not set, we default to output_freq
    get_keyval(conf, "sharedFreq", shared_freq, output_freq);
  }

  // ************* checking the associated colvars *******************

  if (num_variables() == 0) {
    cvm::error("Error: no collective variables specified for the ABF bias.\n");
    return COLVARS_ERROR;
  }

  if (update_bias) {
    // Request calculation of total force
    if(enable(f_cvb_get_total_force)) return cvm::get_error();
  }

  bool b_extended = false;
  size_t i;
  for (i = 0; i < num_variables(); i++) {

    if (colvars[i]->value().type() != colvarvalue::type_scalar) {
      cvm::error("Error: ABF bias can only use scalar-type variables.\n");
    }
    colvars[i]->enable(f_cv_grid);
    if (hide_Jacobian) {
      colvars[i]->enable(f_cv_hide_Jacobian);
    }

    // If any colvar is extended-system, we need to collect the extended
    // system gradient
    if (colvars[i]->is_enabled(f_cv_extended_Lagrangian))
      b_extended = true;

    // Cannot mix and match coarse time steps with ABF because it gives
    // wrong total force averages - total force needs to be averaged over
    // every time step
    if (colvars[i]->get_time_step_factor() != time_step_factor) {
      cvm::error("Error: " + colvars[i]->description + " has a value of timeStepFactor ("
        + cvm::to_str(colvars[i]->get_time_step_factor()) + ") different from that of "
        + description + " (" + cvm::to_str(time_step_factor) + ").\n");
      return COLVARS_ERROR;
    }

    // Here we could check for orthogonality of the Cartesian coordinates
    // and make it just a warning if some parameter is set?
  }

  if (get_keyval(conf, "maxForce", max_force)) {
    if (max_force.size() != num_variables()) {
      cvm::error("Error: Number of parameters to maxForce does not match number of colvars.");
    }
    for (i = 0; i < num_variables(); i++) {
      if (max_force[i] < 0.0) {
        cvm::error("Error: maxForce should be non-negative.");
      }
    }
    cap_force = true;
  } else {
    cap_force = false;
  }

  bin.assign(num_variables(), 0);
  force_bin.assign(num_variables(), 0);
  system_force = new cvm::real [num_variables()];

  // Construct empty grids based on the colvars
  if (cvm::debug()) {
    cvm::log("Allocating count and free energy gradient grids.\n");
  }

  samples   = new colvar_grid_count(colvars);
  gradients = new colvar_grid_gradient(colvars);
  gradients->samples = samples;
  samples->has_parent_data = true;

  // Data for eAB F z-based estimator
  if ( b_extended ) {
    get_keyval(conf, "CZARestimator", b_CZAR_estimator, true);
    // CZAR output files for stratified eABF
    get_keyval(conf, "writeCZARwindowFile", b_czar_window_file, false,
               colvarparse::parse_silent);

    z_bin.assign(num_variables(), 0);
    z_samples   = new colvar_grid_count(colvars);
    z_samples->request_actual_value();
    z_gradients = new colvar_grid_gradient(colvars);
    z_gradients->request_actual_value();
    z_gradients->samples = z_samples;
    z_samples->has_parent_data = true;
    czar_gradients = new colvar_grid_gradient(colvars);
  }

  // For now, we integrate on-the-fly iff the grid is < 3D
  if ( num_variables() <= 3 ) {
    pmf = new integrate_potential(colvars, gradients);
    if ( b_CZAR_estimator ) {
      czar_pmf = new integrate_potential(colvars, czar_gradients);
    }
    get_keyval(conf, "integrate", b_integrate, true); // Integrate for output
    if ( num_variables() > 1 ) {
      // Projected ABF
      get_keyval(conf, "pABFintegrateFreq", pabf_freq, 0);
      // Parameters for integrating initial (and final) gradient data
      get_keyval(conf, "integrateInitSteps", integrate_initial_steps, 1e4);
      get_keyval(conf, "integrateInitTol", integrate_initial_tol, 1e-6);
      // for updating the integrated PMF on the fly
      get_keyval(conf, "integrateSteps", integrate_steps, 100);
      get_keyval(conf, "integrateTol", integrate_tol, 1e-4);
    }
  } else {
    b_integrate = false;
  }

  // For shared ABF, we store a second set of grids.
  // This used to be only if "shared" was defined,
  // but now we allow calling share externally (e.g. from Tcl).
  last_samples   = new colvar_grid_count(colvars);
  last_gradients = new colvar_grid_gradient(colvars);
  last_gradients->samples = last_samples;
  last_samples->has_parent_data = true;
  shared_last_step = -1;

  // If custom grids are provided, read them
  if ( input_prefix.size() > 0 ) {
    read_gradients_samples();
    // Update divergence to account for input data
    pmf->set_div();
  }

  // if extendedLangrangian is on, then call UI estimator
  if (b_extended) {
    get_keyval(conf, "UIestimator", b_UI_estimator, false);

    if (b_UI_estimator) {
    std::vector<double> UI_lowerboundary;
    std::vector<double> UI_upperboundary;
    std::vector<double> UI_width;
    std::vector<double> UI_krestr;

    bool UI_restart = (input_prefix.size() > 0);

    for (i = 0; i < num_variables(); i++)
    {
      UI_lowerboundary.push_back(colvars[i]->lower_boundary);
      UI_upperboundary.push_back(colvars[i]->upper_boundary);
      UI_width.push_back(colvars[i]->width);
      UI_krestr.push_back(colvars[i]->force_constant());
    }
      eabf_UI = UIestimator::UIestimator(UI_lowerboundary,
                                         UI_upperboundary,
                                         UI_width,
                                         UI_krestr,                // force constant in eABF
                                         output_prefix,              // the prefix of output files
                                         cvm::restart_out_freq,
                                         UI_restart,                    // whether restart from a .count and a .grad file
                                         input_prefix,   // the prefixes of input files
                                         cvm::temperature());
    }
  }

  cvm::log("Finished ABF setup.\n");
  return COLVARS_OK;
}
void Solver::recordAllUIPCauses() {
// note:
// variables of lower dl: if seen we dont work with them anymore
// variables of this dl: if seen we incorporate their
// antecedent and set to unseen
	bool seen[num_variables() + 1];
	memset(seen, false, sizeof(bool) * (num_variables() + 1));

	static vector<LiteralID> tmp_clause;
	tmp_clause.clear();

	assertion_level_ = 0;
	uip_clauses_.clear();

	unsigned lit_stack_ofs = literal_stack_.size();
	int DL = stack_.get_decision_level();
	unsigned lits_at_current_dl = 0;

	for (auto l : violated_clause) {
		if (var(l).decision_level == 0 || existsUnitClauseOf(l.var()))
			continue;
		if (var(l).decision_level < DL)
			tmp_clause.push_back(l);
		else
			lits_at_current_dl++;
		literal(l).increaseActivity();
		seen[l.var()] = true;
	}
	unsigned n = 0;
	LiteralID curr_lit;
	while (lits_at_current_dl) {
		assert(lit_stack_ofs != 0);
		curr_lit = literal_stack_[--lit_stack_ofs];

		if (!seen[curr_lit.var()])
			continue;

		seen[curr_lit.var()] = false;

		if (lits_at_current_dl-- == 1) {
			n++;
			if (!hasAntecedent(curr_lit)) {
				// this should be the decision literal when in first branch
				// or it is a literal decided to explore in failed literal testing
				//assert(stack_.TOS_decLit() == curr_lit);
				break;
			}
			// perform UIP stuff
			minimizeAndStoreUIPClause(curr_lit.neg(), tmp_clause, seen);
		}

		assert(hasAntecedent(curr_lit));

		if (getAntecedent(curr_lit).isAClause()) {
			updateActivities(getAntecedent(curr_lit).asCl());
			assert(curr_lit == *beginOf(getAntecedent(curr_lit).asCl()));

			for (auto it = beginOf(getAntecedent(curr_lit).asCl()) + 1;
					*it != SENTINEL_CL; it++) {
				if (seen[it->var()] || var(*it).decision_level == 0
						|| existsUnitClauseOf(it->var()))
					continue;
				if (var(*it).decision_level < DL)
					tmp_clause.push_back(*it);
				else
					lits_at_current_dl++;
				seen[it->var()] = true;
			}
		} else {
			LiteralID alit = getAntecedent(curr_lit).asLit();
			literal(alit).increaseActivity();
			literal(curr_lit).increaseActivity();
			if (!seen[alit.var()] && !var(alit).decision_level == 0
					&& !existsUnitClauseOf(alit.var())) {
				if (var(alit).decision_level < DL)
					tmp_clause.push_back(alit);
				else
					lits_at_current_dl++;
				seen[alit.var()] = true;
			}
		}
	}
	if (!hasAntecedent(curr_lit)) {
		minimizeAndStoreUIPClause(curr_lit.neg(), tmp_clause, seen);
	}
//	if (var(curr_lit).decision_level > assertion_level_)
//		assertion_level_ = var(curr_lit).decision_level;
}
// this is IBCP 30.08
bool Solver::implicitBCP() {
	static vector<LiteralID> test_lits(num_variables());
	static LiteralIndexedVector<unsigned char> viewed_lits(num_variables() + 1,
			0);

	unsigned stack_ofs = stack_.top().literal_stack_ofs();
	unsigned num_curr_lits = 0;
	while (stack_ofs < literal_stack_.size()) {
		test_lits.clear();
		for (auto it = literal_stack_.begin() + stack_ofs;
				it != literal_stack_.end(); it++) {
			for (auto cl_ofs : occurrence_lists_[it->neg()])
				if (!isSatisfied(cl_ofs)) {
					for (auto lt = beginOf(cl_ofs); *lt != SENTINEL_LIT; lt++)
						if (isActive(*lt) && !viewed_lits[lt->neg()]) {
							test_lits.push_back(lt->neg());
							viewed_lits[lt->neg()] = true;

						}
				}
		}
		num_curr_lits = literal_stack_.size() - stack_ofs;
		stack_ofs = literal_stack_.size();
		for (auto jt = test_lits.begin(); jt != test_lits.end(); jt++)
			viewed_lits[*jt] = false;

		vector<float> scores;
		scores.clear();
		for (auto jt = test_lits.begin(); jt != test_lits.end(); jt++) {
			scores.push_back(literal(*jt).activity_score_);
		}
		sort(scores.begin(), scores.end());
		num_curr_lits = 10 + num_curr_lits / 20;
		float threshold = 0.0;
		if (scores.size() > num_curr_lits) {
			threshold = scores[scores.size() - num_curr_lits];
		}

		statistics_.num_failed_literal_tests_ += test_lits.size();

		for (auto lit : test_lits)
			if (isActive(lit) && threshold <= literal(lit).activity_score_) {
				unsigned sz = literal_stack_.size();
				// we increase the decLev artificially
				// s.t. after the tentative BCP call, we can learn a conflict clause
				// relative to the assignment of *jt
				stack_.startFailedLitTest();
				setLiteralIfFree(lit);

				assert(!hasAntecedent(lit));

				bool bSucceeded = BCP(sz);
				if (!bSucceeded)
					recordAllUIPCauses();

				stack_.stopFailedLitTest();

				while (literal_stack_.size() > sz) {
					unSet(literal_stack_.back());
					literal_stack_.pop_back();
				}

				if (!bSucceeded) {
					statistics_.num_failed_literals_detected_++;
					sz = literal_stack_.size();
					for (auto it = uip_clauses_.rbegin();
							it != uip_clauses_.rend(); it++) {
						// DEBUG
						if (it->size() == 0)
							cout << "EMPTY CLAUSE FOUND" << endl;
						// END DEBUG
						setLiteralIfFree(it->front(),
								addUIPConflictClause(*it));
					}
					if (!BCP(sz))
						return false;
				}
			}
	}

	// BEGIN TEST
//	float max_score = -1;
//	float score;
//	unsigned max_score_var = 0;
//	for (auto it =
//			component_analyzer_.superComponentOf(stack_.top()).varsBegin();
//			*it != varsSENTINEL; it++)
//		if (isActive(*it)) {
//			score = scoreOf(*it);
//			if (score > max_score) {
//				max_score = score;
//				max_score_var = *it;
//			}
//		}
//	LiteralID theLit(max_score_var,
//			literal(LiteralID(max_score_var, true)).activity_score_
//					> literal(LiteralID(max_score_var, false)).activity_score_);
//	if (!fail_test(theLit.neg())) {
//		cout << ".";
//
//		statistics_.num_failed_literals_detected_++;
//		unsigned sz = literal_stack_.size();
//		for (auto it = uip_clauses_.rbegin(); it != uip_clauses_.rend(); it++) {
//			setLiteralIfFree(it->front(), addUIPConflictClause(*it));
//		}
//		if (!BCP(sz))
//			return false;
//
//	}
	// END
	return true;
}