Ejemplo n.º 1
0
void Goal::solve(Program *p, int level, TermVarMapping *map)
{   indent(level); std::cout << "solve@"  << level << ": ";
                   this->print(); std::cout << "\n";
    for (Program *q = p; q != NULL; q = q->pcdr)
    {   Trail *t = Trail::Note();
        Clause *c = q->pcar->copy();
        Trail::Undo(t);
        indent(level); std::cout << "  try:"; c->print(); std::cout << "\n";
        if (car->unify(c->head))
        {   Goal *gdash = c->body==NULL ? cdr : c->body->append(cdr);
            if (gdash == NULL) map->showanswer();
            else gdash->solve(p, level+1, map);
        }
        else
        {   indent(level); std::cout << "  nomatch.\n";
        }
        Trail::Undo(t);
    }
}
Ejemplo n.º 2
0
/**
 * Creates and adds a ground active clause.
 * 
 * @param activeGroundClauses If not NULL, then active GroundClauses are
 * accumulated here.
 * @param seenGndPreds GroundPredicates which have been seen before. Used when
 * accumulating GroundClauses.
 * @param db Database used to check truth values and evidence status of
 * predicates.
 * @param getSatisfied If true, satisfied clauses are also retrieved.
 */
bool Clause::createAndAddActiveClause(
                           Array<GroundClause *> * const & activeGroundClauses,
                           GroundPredicateHashArray* const& seenGndPreds,
		                   const Database* const & db,
                           bool const & getSatisfied)
{
  bool accumulateClauses = activeGroundClauses;
  Predicate *cpred;
  PredicateSet predSet; // used to detect duplicates
  PredicateSet::iterator iter;
 
  GroundClause *groundClause;
  
  Clause* clause = NULL;
  bool isEmpty = true;
  for (int i = 0; i < predicates_->size(); i++)
  {
    Predicate* predicate = (*predicates_)[i];
    assert(predicate); 
	assert(predicate->isGrounded());
    if ( (iter = predSet.find(predicate)) != predSet.end() )
    {
        // The two gnd preds are of opp sense, so clause must be satisfied
        // and no point in adding it 
	  if (wt_ >= 0 && !getSatisfied &&
          (*iter)->getSense() !=  predicate->getSense())
      {
        if (clause) delete clause;
		return false;
      }

        // Since the two gnd preds are identical, no point adding a dup
      continue;
	}
    else
      predSet.insert(predicate);
      
	bool isEvidence = db->getEvidenceStatus(predicate);
    
    if (clausedebug >= 2)
    {
      cout << "isEvidence " << isEvidence << endl;
      predicate->printWithStrVar(cout, db->getDomain());
      cout << endl;
    }
	if (!isEvidence)
      isEmpty = false;
	  
      // True evidence in a neg. clause: Discard clause
    if (wt_ < 0 && isEvidence && !getSatisfied &&
        db->sameTruthValueAndSense(db->getValue(predicate),
                                   predicate->getSense()))
    {
      if (clause) delete clause;
      return false;
    }
    
	  // Add only non-evidence prdicates
	if (accumulateClauses && !isEvidence)
	{
	  if (!clause) clause = new Clause();
        
	  cpred = new Predicate(*predicate, clause);
      assert(cpred);
      if (clausedebug >= 2)
      {
        cout << "Appending pred ";
        predicate->printWithStrVar(cout, db->getDomain());
        cout << " to clause ";
        clause->print(cout, db->getDomain());
        cout << endl;
      }
	  clause->appendPredicate(cpred);
      if (clausedebug >= 2) cout << "Appended pred to clause" << endl;
	}
  }

    // If the clause is empty after taking evidence into account, it should 
    // be discarded
  if (isEmpty)
  {
    if (clausedebug >= 2) cout << "Clause is empty" << endl;
	assert(!clause);
    return false;
  }
    // Came to this point means that the clause is active (and hence nonEmpty)
  else
  {
   	  // Add the corresponding ground clause if accumulateClauses is true
   	if (accumulateClauses)
   	{
      assert(clause);	
      if (clausedebug >= 2) cout << "Canonicalizing clause" << endl;
      clause->canonicalizeWithoutVariables();

      groundClause = new GroundClause(clause, seenGndPreds);
      if (isHardClause_)
        groundClause->setWtToHardWt();
      if (clausedebug >= 2) cout << "Appending ground clause to active set" << endl;
      activeGroundClauses->appendUnique(groundClause);
      delete clause;
    }
    return true;
  } 
}
Ejemplo n.º 3
0
  //returns true if the (ground) clause has two literals with opposite sense
  //i.e. the clause is satisfied; otherwise returns false
bool Clause::createAndAddUnknownClause(
                                Array<GroundClause*>* const& unknownGndClauses,
                                Array<Clause*>* const& unknownClauses,
                                double* const & numUnknownClauses,
                                const AddGroundClauseStruct* const & agcs,
                                const Database* const & db)
{ 
  PredicateSet predSet; // used to detect duplicates
  PredicateSet::iterator iter;
  
  Clause* clause = NULL;
  for (int i = 0; i < predicates_->size(); i++)
  {
	Predicate* predicate = (*predicates_)[i];
    assert(predicate->isGrounded());
    if (db->getValue(predicate) == UNKNOWN)
    {
      if ( (iter=predSet.find(predicate)) != predSet.end() )
      {
          // the two gnd preds are of opp sense, so clause must be satisfied
        if ((*iter)->getSense() !=  predicate->getSense())
        {
          if (clause) delete clause;
          return true;
        }
        // since the two gnd preds are identical, no point adding a dup
        continue;
      }
      else
        predSet.insert(predicate);
      
      if (clause == NULL) clause = new Clause();
      Predicate* pred = new Predicate(*predicate, clause);
      clause->appendPredicate(pred);
    }
  }
  
  if (clause) 
  {
    if (numUnknownClauses) (*numUnknownClauses)++;

    clause->setWt(wt_);
    clause->canonicalizeWithoutVariables();
    
    if (agcs)
    {
      if (clausedebug >= 2)
      {
        cout << "Appending unknown clause to MRF ";
        clause->print(cout, db->getDomain());
        cout << endl;
      }
      MRF::addUnknownGndClause(agcs, this, clause, isHardClause_);
    }
    
    // MARC: The case with unknownGndClauses appears to be obsolete!
	if (unknownGndClauses)
    {
      if (clausedebug >= 2)
      {
        cout << "Appending unknown ground clause ";
        clause->print(cout, db->getDomain());
        cout << endl;
      }
      unknownGndClauses->append(new GroundClause(clause, agcs->gndPreds));
	  if (isHardClause_) unknownGndClauses->lastItem()->setWtToHardWt();
    }
    else if (unknownClauses)
    {
      if (clausedebug >= 2)
      {
        cout << "Appending unknown clause ";
        clause->print(cout, db->getDomain());
        cout << endl;
      }
      unknownClauses->append(clause);
      if (isHardClause_) clause->setIsHardClause(true);
    }
    if (unknownClauses == NULL) delete clause;
  }
  return false;
}