From 0eec4d3b5f5d57c5e8057fae1c8fe9dac9935cfe Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 9 Sep 2018 23:44:32 +0200 Subject: [PATCH] ChainSearch: now use the improved TreeExplorer capabilities to address the shortcoming ...the solution built thus far was logically broken, since it retained the unfiltered source sequence within the base layer. Thus it would backtrack into this unfiltered sequence eventually. The idea was to build a special treatment for attaching the first filter condition; in fact the first one does not need to be added to the chain, but rather should be planted directly into the base layer. WIP: this is a solution draft, but does not work yet - when attaching the base layer, the filter is pulled twice - an overconstrained filter raises an Assertion failure (instead of just transitioning into exhausted state) --- src/lib/iter-chain-search.hpp | 40 +++++++++++++++++------- wiki/thinkPad.ichthyo.mm | 59 +++++++++++++++++++++++------------ 2 files changed, 68 insertions(+), 31 deletions(-) diff --git a/src/lib/iter-chain-search.hpp b/src/lib/iter-chain-search.hpp index e839d37cf..beeb69469 100644 --- a/src/lib/iter-chain-search.hpp +++ b/src/lib/iter-chain-search.hpp @@ -21,13 +21,17 @@ */ -/** @file iter-cursor.hpp - ** An iterator with the ability to switch direction. - ** This wrapper relies on the ability of typical STL container iterators - ** to work in both directions, similar to std::reverse_iterator. - ** Yet it is a single, self-contained element and in compliance to the - ** ["Lumiera Forward Iterator"](iter-adapter.hpp) concept. But it has - ** the additional ability to [switch the working direction](\ref IterCursor::switchDir). +/** @file iter-chain-search.hpp + ** Evaluation mechanism to apply a sequence of conditions onto a linear search. + ** This search algorithm is implemented on top of a tree expanding (monadic) filter pipeline, + ** to allow for backtracking. The intention is not to combine the individual conditions, but + ** rather to apply them one by one. After finding a match for the first condition, we'll search + ** for the next condition _starting at the position of the previous match_. In the most general + ** case, this immediate progression down the search chain might be too greedy; it could be that + ** we don't find a match for the next condition, but if we backtrack and first search further + ** on the previous condition, continuing with the search from that further position might + ** then lead to a match. Basically we have to try all combinations of all possible local + ** matches, to find a solution to satisfy the whole chain of conditions. ** ** @see IterCursor_test ** @see iter-adapter.hpp @@ -130,8 +134,12 @@ namespace iter { using Filter = typename _Trait::Filter; using Step = typename _Trait::StepFunctor; - std::vector stepChain_; + /** @internal access embedded filter sub-Pipeline */ + Filter& filter() { return *this; } + /** Storage for a sequence of filter configuration functors */ + std::vector stepChain_; + public: /** Build a chain-search mechanism based on the given source data sequence. * @remark iterators will be copied or moved as appropriate, while from a STL compliant @@ -144,7 +152,10 @@ namespace iter { IterChainSearch (SEQ&& srcData) : _Base{_Trait::configurePipeline (forward (srcData) ,[this](Filter const& curr){ return configureFilterChain(curr); })} - { } + , stepChain_{} + { // mark initial pristine state + _Base::disableFilter(); + } // inherited default ctor and standard copy operations using _Base::_Base; @@ -170,8 +181,14 @@ namespace iter { IterChainSearch&& > search (FUN&& configureSearchStep) { - stepChain_.emplace_back (Step{forward (configureSearchStep)}); - this->iterNext(); // establish invariant: expand to leaf and forward to first match + Step nextStep{forward (configureSearchStep)}; + + if (_Base::isDisabled()) + this-> filter() = move (nextStep (*this)); // immediately apply first step + else // + stepChain_.emplace_back (move (nextStep)); // append all further steps into the chain... + // then establish invariant: + this->iterNext(); // expand to leaf and forward to first match return move(*this); } @@ -200,6 +217,7 @@ namespace iter { { //////////////////////////////////////////////////////TODO logically broken. We need also to get rid of the current expansions, while retaining the current position stepChain_.clear(); + _Base::disableFilter(); return move(*this); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 3ad762420..886e792a8 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -30834,8 +30834,8 @@ - - + + @@ -31135,7 +31135,7 @@ - + @@ -31201,7 +31201,7 @@ - + @@ -31211,7 +31211,7 @@ - + @@ -31327,13 +31327,13 @@ - + - + @@ -31373,7 +31373,7 @@ - + @@ -31507,7 +31507,7 @@ - + @@ -31570,8 +31570,8 @@ - - + + @@ -32093,26 +32093,45 @@ - + - - - + + + - + - + - + + + + + + + + + + + + + + + + + - - + + + + +