char *
problem_string( const Problem *p, int full )
{
  Pool *pool = p->solver->pool;

  if (full == 0) {
    app_debugstart(pool,SAT_DEBUG_RESULT);
#if SATSOLVER_VERSION >= 1500
    solver_printcompleteprobleminfo(p->solver, p->id);
#endif
  }
  else if (full > 0) {
    app_debugstart(pool,SAT_DEBUG_RESULT);
#if SATSOLVER_VERSION < 1400
    solver_printprobleminfo(p->solver, &(p->request->queue), p->id);
#else
    solver_printprobleminfo(p->solver, p->id);
#endif
  }
  else {
    app_debugstart(pool,SAT_DEBUG_SOLUTIONS);
    solver_printproblem(p->solver, p->id);
  }
  return app_debugend();
}
Exemple #2
0
static void
refine_suggestion(Solver *solv, Id *problem, Id sug, Queue *refined, int essentialok)
{
  Pool *pool = solv->pool;
  int i, j;
  Id v;
  Queue disabled;
  int disabledcnt;

  IF_POOLDEBUG (SOLV_DEBUG_SOLUTIONS)
    {
      POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "refine_suggestion start\n");
      for (i = 0; problem[i]; i++)
	{
	  if (problem[i] == sug)
	    POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "=> ");
	  solver_printproblem(solv, problem[i]);
	}
    }
  queue_empty(refined);
  if (!essentialok && sug < 0 && (solv->job.elements[-sug - 1] & SOLVER_ESSENTIAL) != 0)
    return;
  queue_init(&disabled);
  queue_push(refined, sug);

  /* re-enable all problem rules with the exception of "sug"(gestion) */
  solver_reset(solv);

  for (i = 0; problem[i]; i++)
    if (problem[i] != sug)
      solver_enableproblem(solv, problem[i]);

  if (sug < 0)
    solver_reenablepolicyrules(solv, -sug);
  else if (sug >= solv->updaterules && sug < solv->updaterules_end)
    {
      /* enable feature rule */
      Rule *r = solv->rules + solv->featurerules + (sug - solv->updaterules);
      if (r->p)
	solver_enablerule(solv, r);
    }

  enableweakrules(solv);

  for (;;)
    {
      int njob, nfeature, nupdate, pass;
      queue_empty(&solv->problems);
      solver_reset(solv);

      if (!solv->problems.count)
        solver_run_sat(solv, 0, 0);

      if (!solv->problems.count)
	{
	  POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "no more problems!\n");
	  break;		/* great, no more problems */
	}
      disabledcnt = disabled.count;
      /* start with 1 to skip over proof index */
      njob = nfeature = nupdate = 0;
      for (pass = 0; pass < 2; pass++)
	{
	  for (i = 1; i < solv->problems.count - 1; i++)
	    {
	      /* ignore solutions in refined */
	      v = solv->problems.elements[i];
	      if (v == 0)
		break;	/* end of problem reached */
	      if (sug != v)
		{
		  /* check if v is in the given problems list
		   * we allow disabling all problem rules *after* sug in
		   * pass 2, to prevent getting the same solution twice */
		  for (j = 0; problem[j]; j++)
		    if (problem[j] == v || (pass && problem[j] == sug))
		      break;
		  if (problem[j] == v)
		    continue;
		}
	      if (v >= solv->featurerules && v < solv->featurerules_end)
		nfeature++;
	      else if (v > 0)
		nupdate++;
	      else
		{
		  if (!essentialok && (solv->job.elements[-v - 1] & SOLVER_ESSENTIAL) != 0)
		    continue;	/* not that one! */
		  njob++;
		}
	      queue_push(&disabled, v);
	    }
	  if (disabled.count != disabledcnt)
	    break;
	}
      if (disabled.count == disabledcnt)
	{
	  /* no solution found, this was an invalid suggestion! */
	  POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "no solution found!\n");
	  refined->count = 0;
	  break;
	}
      if (!njob && nupdate && nfeature)
	{
	  /* got only update rules, filter out feature rules */
	  POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "throwing away feature rules\n");
	  for (i = j = disabledcnt; i < disabled.count; i++)
	    {
	      v = disabled.elements[i];
	      if (v < solv->featurerules || v >= solv->featurerules_end)
	        disabled.elements[j++] = v;
	    }
	  disabled.count = j;
	  nfeature = 0;
	}
      if (disabled.count == disabledcnt + 1)
	{
	  /* just one suggestion, add it to refined list */
	  v = disabled.elements[disabledcnt];
	  if (!nfeature && v != sug)
	    queue_push(refined, v);	/* do not record feature rules */
	  solver_disableproblem(solv, v);
	  if (v >= solv->updaterules && v < solv->updaterules_end)
	    {
	      Rule *r = solv->rules + (v - solv->updaterules + solv->featurerules);
	      if (r->p)
		solver_enablerule(solv, r);	/* enable corresponding feature rule */
	    }
	  if (v < 0)
	    solver_reenablepolicyrules(solv, -v);
	}
      else
	{
	  /* more than one solution, disable all */
	  /* do not push anything on refine list, as we do not know which solution to choose */
	  /* thus, the user will get another problem if he selects this solution, where he
           * can choose the right one */
	  IF_POOLDEBUG (SOLV_DEBUG_SOLUTIONS)
	    {
	      POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "more than one solution found:\n");
	      for (i = disabledcnt; i < disabled.count; i++)
		solver_printproblem(solv, disabled.elements[i]);
	    }
	  for (i = disabledcnt; i < disabled.count; i++)
	    {
	      v = disabled.elements[i];
	      solver_disableproblem(solv, v);
	      if (v >= solv->updaterules && v < solv->updaterules_end)
		{
		  Rule *r = solv->rules + (v - solv->updaterules + solv->featurerules);
		  if (r->p)
		    solver_enablerule(solv, r);
		}
	    }
	}
    }
  /* all done, get us back into the same state as before */
  /* enable refined rules again */
  for (i = 0; i < disabled.count; i++)
    solver_enableproblem(solv, disabled.elements[i]);
  queue_free(&disabled);
  /* reset policy rules */
  for (i = 0; problem[i]; i++)
    solver_enableproblem(solv, problem[i]);
  solver_disablepolicyrules(solv);
  /* disable problem rules again */
  for (i = 0; problem[i]; i++)
    solver_disableproblem(solv, problem[i]);
  POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "refine_suggestion end\n");
}