Guest User

Untitled

a guest
May 25th, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.54 KB | None | 0 0
  1.  
  2. QCNFClauseList propagate_literal(const QCNFLiteral& lit, const QCNFClause& c) {
  3.     LOG_PRINT(LOG_DEBUG) << "propagate_literal called with lit=" << lit.first->toString()
  4.             << " and clause c=" << convertFromQCNFClause(c).toString() << std::endl;
  5.     boost::shared_ptr<Sentence> cnfLit = lit.first;
  6.     // first figure out what kind of literal we have here.
  7.     std::queue<QCNFClause> toProcess;
  8.     QCNFClauseList processed;
  9.  
  10.     toProcess.push(c);
  11.     while (!toProcess.empty()) {
  12.         QCNFClause qClause = toProcess.front();
  13.         LOG_PRINT(LOG_DEBUG) << "working on " << convertFromQCNFClause(qClause).toString() << std::endl;
  14.         CNFClause cClause = qClause.first;
  15.         toProcess.pop();
  16.         bool addCurrentClause = true;
  17.         if (isSimpleLiteral(cnfLit)) {
  18.             // search for an occurrence of this atom in c
  19.             CNFClause::iterator it = cClause.begin();
  20.             while (it != cClause.end()) {
  21.                 boost::shared_ptr<Sentence> currentLit = *it;
  22.                 if (isSimpleLiteral(currentLit) && *cnfLit == *currentLit) {    // Propagating P into P
  23.                     // if they intersect, rewrite the clause over the time where they don't intersect and continue
  24.                     SISet litSet = lit.second;
  25.                     SISet currentSet = qClause.second;
  26.                     SISet intersect = intersection(litSet, currentSet);
  27.  
  28.                     if (intersect.size() != 0) {
  29.                         LOG_PRINT(LOG_DEBUG) << "propagating " << cnfLit->toString() << " into " << currentLit->toString() << std::endl;
  30.  
  31.                         // if there is still a timepoint that the clause applies to, rewrite and continue
  32.                         SISet leftover = currentSet;
  33.                         leftover.subtract(intersect);
  34.                         if (leftover.size() != 0) {
  35.                             QCNFClause qRestricted = qClause;
  36.                             qRestricted.second = leftover;
  37.                             toProcess.push(qRestricted);
  38.                             addCurrentClause = false;
  39.                             break;
  40.                         }
  41.                     }
  42.                 } else if (isSimpleLiteral(currentLit) && isNegatedLiteral(currentLit, cnfLit)) {
  43.                     // propagating !P into P (or vice versa)
  44.                     // if they intersect, generate two clauses
  45.                     SISet litSet = lit.second;
  46.                     SISet currentSet = qClause.second;
  47.                     SISet intersect = intersection(litSet, currentSet);
  48.  
  49.                     if (intersect.size() != 0) {
  50.                         LOG_PRINT(LOG_DEBUG) << "propagating " << cnfLit->toString() << " into " << currentLit->toString() << std::endl;
  51.  
  52.                         SISet leftover = currentSet;
  53.                         leftover.subtract(intersect);
  54.                         if (leftover.size() != 0) {
  55.                             // add a copy of this sentence only over leftover
  56.                             QCNFClause qRestricted = qClause;
  57.                             qRestricted.second = leftover;
  58.                             toProcess.push(qRestricted);
  59.                         }
  60.                         // delete the current literal and rewrite the time where it applies
  61.                         it = cClause.erase(it);
  62.                         qClause.first = cClause;
  63.                         qClause.second = intersect;
  64.                         continue;
  65.                     }
  66.                 } else if (boost::dynamic_pointer_cast<LiquidOp>(currentLit) != 0) {    // propagating P into [...]
  67.                     boost::shared_ptr<LiquidOp> liqLit = boost::dynamic_pointer_cast<LiquidOp>(currentLit);
  68.                     // first convert the time into a liquid interval
  69.                     SISet liqLitSet = lit.second;
  70.                     liqLitSet.setForceLiquid(true);
  71.                     SISet currentSet = qClause.second;
  72.                     SISet intersect = intersection(liqLitSet, currentSet);
  73.                     if (intersect.size() != 0) {
  74.                         // this is kinda cheap but it should work
  75.                         // call this function again on the inside and fix the resulting sentence if necessary
  76.                         QCNFLiteral newLit;
  77.                         newLit.first = lit.first;
  78.                         newLit.second = liqLitSet;
  79.  
  80.                         QCNFClause newClause;
  81.                         SISet liqClauseSet = currentSet;
  82.                         liqClauseSet.setForceLiquid(true);
  83.                         newClause.first = convertToCNFClause(liqLit);
  84.                         newClause.second = liqClauseSet;
  85.                         QCNFClauseList newClauseList = propagate_literal(newLit, newClause);
  86.  
  87.                         // TODO: complete this!
  88.                         throw std::runtime_error("unimplemented!");
  89.                     }
  90.                 } else if (boost::dynamic_pointer_cast<DiamondOp>(currentLit) != 0) {
  91.                     boost::shared_ptr<DiamondOp> diaCurrentLit = boost::dynamic_pointer_cast<DiamondOp>(currentLit);
  92.                     // check to make sure we can propagate here
  93.  
  94.                     if (!(*diaCurrentLit->sentence() == *cnfLit) && isNegatedLiteral(diaCurrentLit->sentence(), cnfLit)) {
  95.                         it++;
  96.                         continue;
  97.                     }
  98.  
  99.                     // double check that there is only one relation for now
  100.                     if (diaCurrentLit->relations().size() != 1) {
  101.                         throw std::runtime_error("handling more than one relation on a single diamond literal is currently unimplemented in unit_prop()");
  102.                     }
  103.  
  104.                     Interval::INTERVAL_RELATION rel = *(diaCurrentLit->relations().begin());
  105.                     SISet satisfiesRel = lit.second.satisfiesRelation(rel);
  106.                     std::cout << "satisfiesRel = " << satisfiesRel.toString() << ", qclause.second = " << qClause.second.toString() << std::endl;
  107.                     SISet intersect = intersection(satisfiesRel, qClause.second);
  108.                     std::cout << "intersect = " << intersect.toString() << std::endl;
  109.                     // if they don't intersect, nothing to propagate
  110.                     if (intersect.size() == 0) {
  111.                         it++;
  112.                         continue;
  113.                     }
  114.  
  115.                     if (*cnfLit == *diaCurrentLit->sentence()) {
  116.                         // clause is satisfied, we can drop it (over the intersection that is)
  117.                         SISet leftover = qClause.second;
  118.                         leftover.subtract(intersect);
  119.                         if (leftover.size() != 0) {
  120.                             QCNFClause qRestricted = qClause;
  121.                             qRestricted.second = leftover;
  122.                             toProcess.push(qRestricted);
  123.                             addCurrentClause = false;
  124.                             break;
  125.                         }
  126.                     } else if (isNegatedLiteral(cnfLit, diaCurrentLit->sentence())) {
  127.  
  128.                     }
  129.  
  130.  
  131.                 }
  132.                 it++;
  133.             }
  134.         }
  135.         if (addCurrentClause) processed.push_back(qClause);
  136.  
  137.     }
  138.     LOG_PRINT(LOG_DEBUG) << "returning..." << std::endl;
  139.     return processed;
  140. }
Add Comment
Please, Sign In to add comment