// Construct the H-Curve of order k LSystem::LSystem(Rules rules, std::string ax, uint k) : _order(k), _rules(rules), _axiom(ax) { // The production string begins as the axiom _production = _axiom; // For each Rule append the LHS to the nonTerminals String for (Rules::iterator R = rules.begin(); R != rules.end(); R++) { // (duplicates don't matter) _nonTerminals.append(1,R->first); } // Do exactly 'k' rewrites of the L-System for (int rewrites = 0; rewrites < _order; rewrites++) { rewrite(_production); } // Remove all occurrences of bad commands while (findAndRemove(_production, "+-")); while (findAndRemove(_production, "-+")); while (findAndRemove(_production, "A")); while (findAndRemove(_production, "B")); // Slightly modify the user's L-System to work with a DawBug while (findAndReplace(_production, "F", "W$")); while (findAndReplace(_production, "$+", "+")); while (findAndReplace(_production, "$-", "-")); }
void openInitial(Possibilities &possib, Rules &rules) { for (Rules::iterator i = rules.begin(); i != rules.end(); i++) { Rule *r = *i; if (r->applyOnStart()) r->apply(possib); } }
void getHintsQty(Rules &rules, int &vert, int &horiz) { vert = 0; horiz = 0; for (Rules::iterator i = rules.begin(); i != rules.end(); i++) { Rule::ShowOptions so = (*i)->getShowOpts(); switch (so) { case Rule::SHOW_VERT: vert++; break; case Rule::SHOW_HORIZ: horiz++; break; default: ; } } }
TEST(Rules, iterator) { Rules a { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, { 358, 288, 2 } }; std::vector<Rule> b { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, { 358, 288, 2 } }; Rule r { 0, 0, 0 }; { int ra = a.end() - a.begin(); int rb = b.end() - b.begin(); ASSERT_EQ(ra, rb); }; { auto ra = a.end() - 1; auto rb = b.end() - 1; ASSERT_EQ((Rule { 358, 288, 2}), *ra); ASSERT_EQ((Rule { 358, 288, 2}), *rb); }; { for (Rules::reference x : a) { x = r; } for (Rule& x : b) { x = r; } for (Rules::reference x : a) { ASSERT_EQ(x, r); } for (Rule& x : b) { ASSERT_EQ(x, r); } }; }
static void removeRules(SolvedPuzzle &puzzle, Rules &rules) { bool possible; do { possible = false; for (Rules::iterator i = rules.begin(); i != rules.end(); i++) { Rule *rule = *i; Rules excludedRules = rules; excludedRules.remove(rule); if (canSolve(puzzle, excludedRules)) { possible = true; rules.remove(rule); delete rule; break; } } } while (possible); }
TEST(Rules, reference) { Rules r { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, { 358, 288, 2 } }; ASSERT_EQ(r[0], (Rule {1, 2, 3})); ASSERT_EQ(r[1], (Rule {4, 5, 6})); ASSERT_EQ(r[2], (Rule {7, 8, 9})); ASSERT_EQ(r.size(), size_t(4)); swap(r[0], r[1]); ASSERT_EQ(r[0], (Rule {4, 5, 6})); ASSERT_EQ(r[1], (Rule {1, 2, 3})); std::sort(r.begin(), r.end(), rule_compare {}); ASSERT_EQ(r[0], (Rule {1, 2, 3})); ASSERT_EQ(r[1], (Rule {4, 5, 6})); ASSERT_EQ(r[2], (Rule {7, 8, 9})); ASSERT_EQ(r.size(), size_t(4)); }
static void genRules(SolvedPuzzle &puzzle, Rules &rules) { bool rulesDone = false; do { Rule *rule = genRule(puzzle); if (rule) { std::wstring s = rule->getAsText(); for (std::list<Rule*>::iterator i = rules.begin(); i != rules.end(); i++) if ((*i)->getAsText() == s) { delete rule; rule = NULL; break; } if (rule) { //printf("adding rule %s\n", rule->getAsText().c_str()); rules.push_back(rule); rulesDone = canSolve(puzzle, rules); } } } while (! rulesDone); }
static bool canSolve(SolvedPuzzle &puzzle, Rules &rules) { Possibilities pos; bool changed = false; do { changed = false; for (Rules::iterator i = rules.begin(); i != rules.end(); i++) { Rule *rule = *i; if (rule->apply(pos)) { changed = true; if (! pos.isValid(puzzle)) { std::cout << "after error:" << std::endl; pos.print(); throw Exception(L"Invalid possibilities after rule " + rule->getAsText()); } } } } while (changed); bool res = pos.isSolved(); return res; }
ItemTreePtr AtomIntroductionSolver::compute() { const auto nodeStackElement = app.getPrinter().visitNode(decomposition); assert(decomposition.getChildren().size() == 1); Decomposition& childNode = **decomposition.getChildren().begin(); ItemTreePtr childResult = childNode.getSolver().compute(); ItemTreePtr result; if(childResult) { result = extendRoot(childResult); assert(childResult->getChildren().empty() == false); // Find out which rules are satisfied by setting introducedAtom to true or false, respectively, and which disappear from the reduct by setting introducedAtom to true. // TODO unordered_set? Rules rulesSatisfiedByTrue; Rules rulesSatisfiedByFalse; Rules rulesDisappearingByTrue; for(String bagElement : decomposition.getNode().getBag()) { AtomsInRule::const_iterator it = heads.find(bagElement); if(it != heads.end() && it->second.find(introducedAtom) != it->second.end()) rulesSatisfiedByTrue.insert(bagElement); it = positiveBody.find(bagElement); if(it != positiveBody.end() && it->second.find(introducedAtom) != it->second.end()) rulesSatisfiedByFalse.insert(bagElement); it = negativeBody.find(bagElement); if(it != negativeBody.end() && it->second.find(introducedAtom) != it->second.end()) { rulesSatisfiedByTrue.insert(bagElement); rulesDisappearingByTrue.insert(bagElement); } } // Guess node to extend at depth 1 for(const ItemTreePtr& childCandidate : childResult->getChildren()) { // Make introducedAtom false ItemTreeNode::Items candidateItems = childCandidate->getNode()->getItems(); ItemTreeNode::Items candidateAuxItems = childCandidate->getNode()->getAuxItems(); // Add satisfied rules candidateAuxItems.insert(rulesSatisfiedByFalse.begin(), rulesSatisfiedByFalse.end()); ItemTreePtr candidate = extendCandidate(std::move(candidateItems), std::move(candidateAuxItems), childCandidate); for(const ItemTreePtr& childCertificate : childCandidate->getChildren()) { ItemTreeNode::Items certificateItems = childCertificate->getNode()->getItems(); ItemTreeNode::Items certificateAuxItems = childCertificate->getNode()->getAuxItems(); // Add satisfied rules certificateAuxItems.insert(rulesSatisfiedByFalse.begin(), rulesSatisfiedByFalse.end()); candidate->addChildAndMerge(extendCertificate(std::move(certificateItems), std::move(certificateAuxItems), childCertificate)); } result->addChildAndMerge(std::move(candidate)); // Make introducedAtom true candidateItems = childCandidate->getNode()->getItems(); candidateItems.insert(introducedAtom); candidateAuxItems = childCandidate->getNode()->getAuxItems(); // Add satisfied rules candidateAuxItems.insert(rulesSatisfiedByTrue.begin(), rulesSatisfiedByTrue.end()); candidate = extendCandidate(std::move(candidateItems), std::move(candidateAuxItems), childCandidate); for(const ItemTreePtr& childCertificate : childCandidate->getChildren()) { // Make introducedAtom false in certificate (and add "smaller" flag) ItemTreeNode::Items certificateItems = childCertificate->getNode()->getItems(); ItemTreeNode::Items certificateAuxItems = childCertificate->getNode()->getAuxItems(); certificateAuxItems.emplace("smaller"); certificateAuxItems.insert(rulesDisappearingByTrue.begin(), rulesDisappearingByTrue.end()); certificateAuxItems.insert(rulesSatisfiedByFalse.begin(), rulesSatisfiedByFalse.end()); candidate->addChildAndMerge(extendCertificate(std::move(certificateItems), std::move(certificateAuxItems), childCertificate)); // Make introducedAtom true in certificate certificateItems = childCertificate->getNode()->getItems(); certificateItems.insert(introducedAtom); certificateAuxItems = childCertificate->getNode()->getAuxItems(); certificateAuxItems.insert(rulesSatisfiedByTrue.begin(), rulesSatisfiedByTrue.end()); candidate->addChildAndMerge(extendCertificate(std::move(certificateItems), std::move(certificateAuxItems), childCertificate)); } result->addChildAndMerge(std::move(candidate)); } assert(!decomposition.isRoot()); if(result->finalize(app, false, app.isPruningDisabled() == false || decomposition.isRoot()) == false) result.reset(); } app.getPrinter().solverInvocationResult(decomposition, result.get()); return result; }