From ec8d0557e8c65c85c63062b48cbee0a0aa5190e3 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 4 Sep 2018 02:02:26 +0200 Subject: [PATCH] ChainSearch: draft interface and possible implementation approach The intention is to augment the iterator based (linear) search used in EventLog to allow for real backtracking, based on a evaluation tree. This should be rather staight forward to implement, relying on the exploreChildren() functionality of TreeExplorer. The trick is to package the chained search step as a monadic flatMap operation --- src/lib/iter-chain-search.hpp | 181 +++++++++++++++++++++++ src/lib/iter-tree-explorer.hpp | 2 +- tests/library/iter-chain-search-test.cpp | 145 ++++++++++++++++++ wiki/thinkPad.ichthyo.mm | 105 ++++++++++++- 4 files changed, 427 insertions(+), 6 deletions(-) create mode 100644 src/lib/iter-chain-search.hpp create mode 100644 tests/library/iter-chain-search-test.cpp diff --git a/src/lib/iter-chain-search.hpp b/src/lib/iter-chain-search.hpp new file mode 100644 index 000000000..fd4fc98af --- /dev/null +++ b/src/lib/iter-chain-search.hpp @@ -0,0 +1,181 @@ +/* + ITER-CHAIN-SEARCH.hpp - chained search with backtracking based on (bidirectional) iterator + + Copyright (C) Lumiera.org + 2018, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +/** @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). + ** + ** @see IterCursor_test + ** @see iter-adapter.hpp + ** @see [usage example](event-log.hpp) + ** + */ + + +#ifndef SRC_LIB_ITER_CHAIN_SEARCH_H +#define SRC_LIB_ITER_CHAIN_SEARCH_H + + +#include "lib/error.hpp" +//#include "lib/iter-adapter.hpp" + +//#include +//#include +#include +#include + + +namespace lib { + + using std::move; + using std::string; + + namespace iter { + + /** + * @internal implementation for.... + */ + template + class Cur + { + + + public: + }; + + + } // namespace iter + + + + + /** + * Iterator based linear search mechanism, with the ability to perform consecutive search with backtracking. + * The IterChainSearch can be configured with a sequence of search goals (filter conditions), and will + * apply these in succession on the underlying iterator. It will search for the first hit of the first + * condition, and then continue to search _from there_ matching on the second condition, and so on. + * After the first combination of matches is exhausted, the search will backtrack and try to evaluate + * the next combination, leading to a tree of search solutions. + */ +// template + class IterChainSearch + { +// using _Core = iter::CursorGear; +// using _Parent = IterStateWrapper; + + public: +// IterChainSearch() =default; +// IterChainSearch (IterChainSearch&&) =default; +// IterChainSearch (IterChainSearch const&) =default; +// IterChainSearch& operator= (IterChainSearch&&) =default; +// IterChainSearch& operator= (IterChainSearch const&) =default; + + +// template +// explicit +// IterChainSearch (CON& container) +//// : _Parent(_Core(container.begin(), container.end())) +// { } +// +// IterChainSearch (IT&& begin, IT&& end) +//// : _Parent(_Core(std::forward(begin), std::forward(end))) +// { } + + + operator bool() const + { + UNIMPLEMENTED ("solution test"); + } + + bool + empty() const + { + return not(*this); + } + + + /** */ + IterChainSearch&& + search (string target) + { + UNIMPLEMENTED ("configure additional chained search condition"); + return move(*this); + } + + IterChainSearch&& + clearFilter() + { + UNIMPLEMENTED ("drop all search condition frames"); + return move(*this); + } + + + /////////////////////////TODO dummy placeholder code. Replace by real iterator access + string& + operator*() const + { + static string boo{"bääääh"}; + return boo; + } + + IterChainSearch& + operator++() + { + return *this; + } + /////////////////////////TODO dummy placeholder code. Replace by real iterator access + }; + + + + + /* ==== convenient builder free function ==== */ + + /** setup a chain search configuration by suitably wrapping the given container. + * @return a TreeEplorer, which is an Iterator to yield all the source elements, + * but may also be used to build an processing pipeline. + * @warning if you capture the result of this call by an auto variable, + * be sure to understand that invoking any further builder operation on + * TreeExplorer will invalidate that variable (by moving it into the + * augmented iterator returned from such builder call). + */ + template + inline auto + chainSearch (CON&& srcData) + { +// using SrcIter = typename _DecoratorTraits::SrcIter; +// using Base = iter_explorer::BaseAdapter; + + UNIMPLEMENTED ("figure out the Iterator type and build a suitable IterChainSearch instance"); + return IterChainSearch(); +// return TreeExplorer (std::forward (srcSeq)); + } + + + +} // namespace lib +#endif /*SRC_LIB_ITER_CHAIN_SEARCH_H*/ diff --git a/src/lib/iter-tree-explorer.hpp b/src/lib/iter-tree-explorer.hpp index abfa7c684..45ea45e40 100644 --- a/src/lib/iter-tree-explorer.hpp +++ b/src/lib/iter-tree-explorer.hpp @@ -1445,7 +1445,7 @@ namespace lib { /** _terminal builder_ to package the processing pipeline as IterSource. * Invoking this function moves the whole iterator compound, as assembled by the preceding - * builder calls, into heap allocated memory and returns a [iterator front-end](\ref IterExploreSource). + * builder calls, into heap allocated memory and returns an [iterator front-end](\ref IterExploreSource). * Any iteration and manipulation on that front-end is passed through virtual function calls into * the back-end, thereby concealing all details of the processing pipeline. */ diff --git a/tests/library/iter-chain-search-test.cpp b/tests/library/iter-chain-search-test.cpp new file mode 100644 index 000000000..0967a50c9 --- /dev/null +++ b/tests/library/iter-chain-search-test.cpp @@ -0,0 +1,145 @@ +/* + IterChainSearch(Test) - verify chained search operations with backtracking + + Copyright (C) Lumiera.org + 2018, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +/** @file iter-chain-search-test.cpp + ** unit test \ref IterChainSearch_test + */ + + + +#include "lib/test/run.hpp" +#include "lib/test/test-helper.hpp" +#include "lib/format-util.hpp" +#include "lib/iter-chain-search.hpp" +#include "lib/util.hpp" + +#include +#include + + + +namespace lib { +namespace test{ + + using ::Test; + using util::join; + using util::isnil; + using util::isSameObject; + using std::vector; + using std::string; + + using lumiera::error::LERR_(ITER_EXHAUST); + + + namespace { // test fixture + + using Spam = vector; + + const Spam SPAM{"spam" + ,"sausage" + ,"spam" + ,"spam" + ,"bacon" + ,"spam" + ,"tomato" + ,"and" + ,"spam" + }; + + } // (END)fixture + + + + + + + + /*****************************************************************//** + * @test verify a setup for consecutive searches with backtracking. + * + * @see iter-chain-search.hpp + * @see iter-cursor.hpp + * @see [usage example](event-log.hpp) + */ + class IterChainSearch_test : public Test + { + + virtual void + run (Arg) + { + simpleSearch(); + chainedIteration(); + backtracking(); + } + + + /** @test simple basic use case. */ + void + simpleSearch () + { + auto search = chainSearch(SPAM) + .search("bacon") + .search("tomato"); + + CHECK (search); + CHECK (not isnil(search)); + CHECK ("tomato" == *search); + CHECK (isSameObject (*search, SPAM[6])); + + search.clearFilter(); + CHECK ("tomato" == *search); + ++search; + CHECK ("and" == *search); + search.search("spam"); + CHECK ("spam" == *search); + CHECK (isSameObject (*search, SPAM[8])); + + ++search; + CHECK (not search); + CHECK (isnil (search)); + VERIFY_ERROR (ITER_EXHAUST, *search); + } + + + + /** @test verify the + */ + void + chainedIteration () + { + } + + + + /** @test verify the + */ + void + backtracking () + { + } + }; + + LAUNCHER (IterChainSearch_test, "unit common"); + + +}} // namespace lib::test + diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 83bc81ce0..d0ce3ca79 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -31173,6 +31173,8 @@ + + @@ -31197,15 +31199,98 @@ - + - - + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - @@ -31213,6 +31298,16 @@ + + + + + + + + + +