Exemple #1
0
bool SimpSMTSolver::eliminateVar(Var v, bool fail)
{
  if (!fail && asymm_mode && !asymmVar(v))    return false;

  const vec<Clause*>& cls = getOccurs(v);

  //  if (value(v) != l_Undef || cls.size() == 0) return true;
  if (value(v) != l_Undef) return true;

  // Split the occurrences into positive and negative:
  vec<Clause*>  pos, neg;
  for (int i = 0; i < cls.size(); i++)
    (find(*cls[i], Lit(v)) ? pos : neg).push(cls[i]);

  // Check if number of clauses decreases:
  int cnt = 0;
  for (int i = 0; i < pos.size(); i++)
    for (int j = 0; j < neg.size(); j++)
      if (merge(*pos[i], *neg[j], v) && ++cnt > cls.size() + grow)
	return true;
#ifdef PEDANTIC_DEBUG
  cerr << "XXY gonna-remove" << endl;
#endif
  // Delete and store old clauses:
  setDecisionVar(v, false);
  elimtable[v].order = elimorder++;
  assert(elimtable[v].eliminated.size() == 0);
  for (int i = 0; i < cls.size(); i++)
  {
    elimtable[v].eliminated.push(Clause_new(*cls[i]));
    removeClause(*cls[i]);
  }

  // Produce clauses in cross product:
  int top = clauses.size();
  vec<Lit> resolvent;
  for (int i = 0; i < pos.size(); i++)
    for (int j = 0; j < neg.size(); j++)
      if (merge(*pos[i], *neg[j], v, resolvent) && !addClause(resolvent))
	return false;

  // DEBUG: For checking that a clause set is saturated with respect to variable elimination.
  //        If the clause set is expected to be saturated at this point, this constitutes an
  //        error.
  if (fail){
    reportf("eliminated var %d, %d <= %d\n", v+1, cnt, cls.size());
    reportf("previous clauses:\n");
    for (int i = 0; i < cls.size(); i++){
      printClause(*cls[i]); reportf("\n"); }
    reportf("new clauses:\n");
    for (int i = top; i < clauses.size(); i++){
      printClause(*clauses[i]); reportf("\n"); }
    assert(0); }

    return backwardSubsumptionCheck();
}
bool SimpSolver::asymmVar(Var v)
{
    assert(!frozen[v]);
    assert(use_simplification);

    vec<Clause*>  pos, neg;
    const vec<Clause*>& cls = getOccurs(v);

    if (value(v) != l_Undef || cls.size() == 0)
        return true;

    for (int i = 0; i < cls.size(); i++)
        if (!asymm(v, *cls[i]))
            return false;

    return backwardSubsumptionCheck();
}
bool SimpSolver::eliminate(bool turn_off_elim)
{
    if (!ok || !use_simplification)
        return ok;

    // Main simplification loop:
    //assert(subsumption_queue.size() == 0);
    //gatherTouchedClauses();
    while (subsumption_queue.size() > 0 || elim_heap.size() > 0){

        //fprintf(stderr, "subsumption phase: (%d)\n", subsumption_queue.size());
        if (!backwardSubsumptionCheck(true))
            return false;

        //fprintf(stderr, "elimination phase:\n (%d)", elim_heap.size());
        for (int cnt = 0; !elim_heap.empty(); cnt++){
            Var elim = elim_heap.removeMin();

            if (verbosity >= 2 && cnt % 100 == 0)
                reportf("elimination left: %10d\r", elim_heap.size());

            if (!frozen[elim] && !eliminateVar(elim))
                return false;
        }

        assert(subsumption_queue.size() == 0);
        gatherTouchedClauses();
    }

    // Cleanup:
    cleanUpClauses();
    order_heap.filter(VarFilter(*this));

#ifdef INVARIANTS
    // Check that no more subsumption is possible:
    reportf("Checking that no more subsumption is possible\n");
    for (int i = 0; i < clauses.size(); i++){
        if (i % 1000 == 0)
            reportf("left %10d\r", clauses.size() - i);

        assert(clauses[i]->mark() == 0);
        for (int j = 0; j < i; j++)
            assert(clauses[i]->subsumes(*clauses[j]) == lit_Error);
    }
    reportf("done.\n");

    // Check that no more elimination is possible:
    reportf("Checking that no more elimination is possible\n");
    for (int i = 0; i < nVars(); i++)
        if (!frozen[i]) eliminateVar(i, true);
    reportf("done.\n");
    checkLiteralCount();
#endif

    // If no more simplification is needed, free all simplification-related data structures:
    if (turn_off_elim){
        use_simplification = false;
        touched.clear(true);
        occurs.clear(true);
        n_occ.clear(true);
        subsumption_queue.clear(true);
        elim_heap.clear(true);
        remove_satisfied = true;
    }


    return true;
}