/* * Caller is responsible for deleting returned Predicate* if necessary */ Predicate* Domain::getNonEvidenceAtom(const int& index) const { int predId = -1; int numAtomsPerPred; int numAtoms = 0; for (int i = 0; i < getNumPredicates(); i++) { numAtomsPerPred = (*numNonEvidAtomsPerPred_)[i]; if (numAtoms + numAtomsPerPred >= index + 1) { predId = i; break; } numAtoms += numAtomsPerPred; } assert(predId >= 0); // Get the newIndex-th grounding of f.o. pred with id predId Predicate* pred = createPredicate(predId, false); // Not all groundings of pred are non-evidence, so we need the while loop bool foundNE = false; while(!foundNE) { for (int i = 0; i < pred->getNumTerms(); i++) { int termType = pred->getTermTypeAsInt(i); const Array<int>* constantsByType = getConstantsByType(termType); int constIdx = random() % constantsByType->size(); pred->setTermToConstant(i, (*constantsByType)[constIdx]); } assert(pred->isGrounded()); if (!db_->getEvidenceStatus(pred)) foundNE = true; } return pred; }
/** * 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; } }
//add a constant tuple to the list of constant tuples inline void Clause::addConstantTuple(const Domain* const & domain, const Database* const & db, const Clause * const & varClause, Array<int> * const & constants, Array<Variable *> * const & eqVars, ClauseToSuperClauseMap* const & clauseToSuperClause, bool useImplicit) { // used to detect duplicates PredicateSet predSet; PredicateSet::iterator iter; Predicate *predicate; Clause *clause = new Clause(); //first make sure the clause is not satisfied (because of presence of two //identical gnd preds with opposite senses) for (int i = 0; i < predicates_->size(); i++) { predicate = (*predicates_)[i]; assert(predicate->isGrounded()); /* if (db->getValue(predicate) == UNKNOWN) { clause->appendPredicate(varClause->getPredicate(i)); 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()) { clause->removeAllPredicates(); delete clause; return; } // since the two gnd preds are identical, no point adding a dup continue; } else predSet.insert(predicate); } */ //- this so that it matches the hypercube representation. //There is no real need to simplify the clause! if (db->getValue(predicate) == UNKNOWN) { clause->appendPredicate(varClause->getPredicate(i)); } } SuperClause *superClause; ClauseToSuperClauseMap::iterator itr; Clause *keyClause; Array<int> * varIdToCanonicalVarId; Array<int> * canonicalConstants; Array<Variable *> * canonicalEqVars; //Slightly different Imeplementation for SuperClause bool useCT = false; IntArrayHashArray *neqConstraints = NULL; //nothing to do if the clause has no predicate if (clause->getNumPredicates() == 0) { delete clause; return; } itr = clauseToSuperClause->find(clause); if (itr == clauseToSuperClause->end()) { //it is best to create a completely new copy of the clause //at this point keyClause = new Clause(*clause); keyClause->setWt(this->getWt()); keyClause->setUtil(this->getUtil()); keyClause->setAction(this->isActionFactor()); //keyClause->setWt(1); int varCnt = constants->size(); varIdToCanonicalVarId = new Array<int>(varCnt, -1); keyClause->canonicalize(varIdToCanonicalVarId); canonicalEqVars = getCanonicalArray(eqVars, varIdToCanonicalVarId); //Slightly different Imeplementation for SuperClause superClause = new SuperClause(keyClause, neqConstraints, varIdToCanonicalVarId, useCT, wt_); (*clauseToSuperClause)[clause] = superClause; delete canonicalEqVars; //delete varIdToCanonicalVarId; } else { superClause = itr->second; //sort of a hack, but it works: //may need to increase the size of varIdToCanonicalVarId map int varCnt = constants->size(); varIdToCanonicalVarId = superClause->getVarIdToCanonicalVarId(); varIdToCanonicalVarId->growToSize(varCnt,-1); //delete the clause. Predicates should not be deleted, as //they belong to the varClause clause->removeAllPredicates(); delete clause; } varIdToCanonicalVarId = superClause->getVarIdToCanonicalVarId(); canonicalConstants = getCanonicalArray(constants, varIdToCanonicalVarId); //superClause->addNewConstantsAndIncrementCount(canonicalConstants,this->getWt()); superClause->addNewConstantsAndIncrementCount(canonicalConstants,1); //clean up delete canonicalConstants; }
//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; }