Esempio n. 1
0
bool splitOffAnchoredAcyclic(RoseBuild &rose, const NGHolder &h,
                             const CompileContext &cc) {
    if (!cc.grey.allowAnchoredAcyclic) {
        return false;
    }

    if (!isAnchored(h)) {
        DEBUG_PRINTF("fail, not anchored\n");
        return false;
    }

    if (!isAcyclic(h)) {
        DEBUG_PRINTF("fail, not acyclic\n");
        return false;
    }

    if (rose.addAnchoredAcyclic(h)) {
        return true;
    } else {
        DEBUG_PRINTF("failed to add anchored nfa\n");
        return false;
    }
}
Esempio n. 2
0
void UIWidget::onVisibilityChange(bool visible)
{
    if(!isAnchored())
        bindRectToParent();
    callLuaField("onVisibilityChange", visible);
}
Esempio n. 3
0
 /**
  * Since UICoord path specifications may contain gaps and wildcards, we may attempt
  * to fill in these missing parts by matching against the topological structure of an actual UI.
  * In the general case, finding a solution requires a depth-first exponential brute-force search
  * over the whole structure tree, since we have to try every possible branch until we can disprove
  * the possibility of a match. Implemented as depth-first search with backtracking, this scanning
  * pass produces a list of possible matches, from which we pick the first one with maximum
  * coverage, to yield a single solution.
  * @remark the search and matching is based on an iterator pipeline builder, with the special ability
  *         to expand and recurse into the children of the current element on demand: when `expandChildren()`
  *         was invoked, the next iteration will continue with the first child element; there is a stack of
  *         such "child expansions" -- meaning that the search will backtrack and explore further possibilities
  *         later on. Each position where the pattern matches the actual tree is marked as possible solution.
  *         As a sideeffect, a new coordinate spec to reflect the actual coverage is built and re-written,
  *         while the algorithm proceeds. Thus, at any point marked as solution, the current (partial)
  *         solution can be retrieved and copied from this PathManipulator buffer.
  *         An additional filter layer discriminates the first maximal solutions seen thus far.
  */
 bool
 UICoordResolver::pathResolution()
 {
   // Helper to detect a wildcard match
   auto wildMatch = [&](Literal patt, Literal curr, size_t depth)
                       {
                         return patt == Symbol::ANY
                             or patt == Symbol::EMPTY
                             or patt == UIC_ELIDED // "existentially quantified"
                             or (isAnchored() and curr == res_.anchor and depth == UIC_WINDOW);
                       };    // transitive argument: assuming res_.anchor was computed for
                            //  the same coordinate pattern used here for patch resolution
   // algorithm state
   size_t maxDepth = 0;
   PathManipulator coverage;
   const size_t coordDepth = this->uic_.size();
   const size_t minSolutionDepth = find_wildcardFree_suffix (uic_);
   
   auto searchAlgo = query_.getChildren (uic_, 0)
                           .expandOnIteration()
                           .filter ([&](auto& iter)
                                       {
                                          size_t depth = iter.depth();     // we are at that depth in target tree
                                          if (depth >= coordDepth)         // search pattern exhausted without match...
                                            return false;
                                          Literal patt = uic_[depth];      // pick search pattern component at that depth
                                          Literal curr = *iter;            // iterator points at current tree position (ID)
                                          if (patt == curr or              // if either direct match
                                              wildMatch(patt,curr,depth))  // or wildcard match
                                            {
                                              coverage.setAt (depth,curr); // record match rsp. interpolate wildcard into output
                                              iter.expandChildren();       // next iteration will match one level down into the tree
                                            }
                                          return patt == curr              // direct match counts as (partial) solution
                                              or patt == UIC_ELIDED;       // existentially quantified elements also accepted
                                       })
                           .filter ([&](auto& iter)
                                       {
                                          if (iter.depth() < minSolutionDepth)
                                            return false;                  // filter solutions which did not bind all wildcards
                                          if (iter.depth()+1 <= maxDepth)  // filter for maximum solution length
                                            return false;
                                          maxDepth = 1 + iter.depth();
                                          return true;
                                       })
                           .transform ([&](auto&) -> UICoord const&
                                       {
                                          return coverage.retrieveResult();
                                       });
    // is (partial) coverage possible?
   //  search computes definitive answer!
   res_.isResolved = true;
   
   // perform the matching
   if (isnil (searchAlgo))
     return false;     // no solution found
   
   while (searchAlgo)  // pull first maximal solution
     {
       if (not res_.covfefe)
         res_.covfefe.reset (new UICoord {*searchAlgo});
       else
         *res_.covfefe = *searchAlgo;
       ++searchAlgo;
     }
   
   ENSURE (res_.covfefe and res_.covfefe->size() >= 1);
   res_.anchor = res_.covfefe->getWindow();
   
   // but depth reflects only that part coverable without wildcards
   if (res_.depth == 0)
     res_.depth = query_.determineCoverage(uic_);
   if (res_.depth == 0 and res_.anchor)
     res_.depth = 1;
   
   // signal success only when total coverage is possible
   return res_.covfefe->size() == uic_.size();
 }