/** * 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; } }
//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; }