% !TeX spellcheck = cs_CZ
% !TeX root = ../BP_Prokopič_Martin_2021.tex

V~následujících sekcích seznámíme čtenáře s~knihovnou, do níž jsme implementovali algoritmy využívající \acrshort{bwt} představené v~kapitolách \ref{ch:bwt} a~\ref{ch:searching}. Poté popíšeme, jak jsme naše algoritmy začlenili do stávající architektury a~upozorníme na překážky, kterým jsme při práci čelili.

\section{Algoritmová knihovna}

\gls{alt} \cite{alt} je rozsáhlý softwarový projekt vyvíjený na Fakultě informačních technologií \acrshort{cvut}. Jedná se o~kolekci datových struktur a~algoritmů z~oblasti automatů a~práce s~řetězci vyvíjenou z~části i~studenty v~rámci závěrečných prací. Základní stavební kámen položil roku 2014 Bc.~Martin Žák v~bakalářské práci \cite{zak14} pod vedením Ing.~Jana Trávníčka,~Ph.D. Knihovna je psaná v~moderním jazyce C++ 20 s~využitím šablon a~je dostupná veřejně pod licencí \acrshort{gpl3}. To znamená, že do ní může přispívat kdokoliv a~lze ji využívat i~mimo fakultu.

První verze měla podobu malých programů v~duchu UNIXové filozofie\footnote{Pište takové programy, které dělají jen jednu věc a~dělají ji dobře. \cite{mcilroy78}}, které komunikovaly pomocí výměnného formátu \acrshort{xml}. Uživatel pak mohl programy kombinovat spojováním standardních proudů v~příkazovém řádku, a~vytvořit tak složitější celek.

Později se od tohoto přístupu upustilo a~nyní je projekt tvořen několika dynamickými knihovnami, které může uživatel ovládat textově pomocí dotazovacího jazyka \acrshort{aql} (interpreter \code{aql2}), spojováním bloků v~moderním webovém rozhraní, případně je přilinkovat do vlastní aplikace. Podpora výměnného formátu \acrshort{xml} ale zůstala zachována. Přidán byl modul \textsf{alib2measure} \cite{cerveny16} umožňující komplexní měření spotřebovaného času a~paměti při běhu algoritmů.

Knihovna nyní slouží jako pískoviště, ve kterém si lze snadno hrát s~datovými strukturami a~zkoušet kombinace různých algoritmů na vlastních i~náhodně generovaných vstupech. Používá se pro demonstraci probírané látky v~teoretických předmětech na katedře teoretické informatiky (např. BI-AAG \emph{Automaty a~gramatiky}, MI-EVY \emph{Efektivní vyhledávání v~textu} a~MI-AVY \emph{Automaty pro vyhledávání v~textu}). V~předmětu MI-EVY se probírá právě i~Burrows-Wheelerova transformace a~algoritmy, které ji využívají pro vyhledávání v~textu.

\section{Datové struktury}

V~rámci praktické části bakalářské práce jsme implementovali datové struktury pro reprezentaci řetězce, pomocných polí potřebných pro zpětnou \acrshort{bwt} a~zjednodušeného FM-indexu. Všechny implementované struktury podporují serializaci a~deserializaci do \acrshort{xml} formátu, stejně jako normalizaci potřebnou pro správnou funkčnost webového rozhraní.

\subsection{Řetězec s~ukončovacím symbolem}

Knihovna \gls{alt} je postavena na šablonách a~dynamickém systému objektů (třída \code{object::Object}). Řetězec tak nemusí být složen pouze ze symbolů typu \code{char}, ale z~libovolných objektů. Dokonce v~jednom řetězci může každý symbol mít jiný typ. Ačkoliv je tento systém abstrakce mocný a~podporuje dobré programátorské praktiky (zapouzdření objektů), jedná se o~dvousečný meč a~v~našem případě přináší do implementace několik komplikací.

Pro reprezentaci transformovaného textu $L$ potřebujeme řetězcový typ, který ale navíc dokáže rozlišit ukončovací symbol (v~předchozích kapitolách značený \texttt{\$}). V~experimentální části knihovny již byla implementovaná třída \code{string::LinearStringTerminatingSymbol}, která by většinu našich požadavků splňovala, ale její kód není na stejné úrovni jako zbytek projektu, a~to by v~budoucnu mohlo bránit dalšímu rozšiřování.

I~na základě doporučení vedoucího jsme se tak rozhodli implementovat vlastní třídu \code{string::LinearStringTerminatingSymbolBWT}, která navíc vyžaduje, aby v~řetězci byl přítomen právě jeden ukončovací symbol. Pro jeho reprezentaci jsme navrhli třídu \code{alphabet::MinimalEndSymbol}, která se pro integrální datové typy (\code{bool}, \code{char}, \code{int}\dots) chová jako $0$.

Komplikace ale nastává, když chceme porovnat dvě instance \code{object::Object}, z~nichž jedna drží \code{MinimalEndSymbol}. V~tom případě totiž dochází k~porovnání na základě datového typu, a~nelze zaručit správný výsledek. Proto jsme implementovali funktor \code{alphabet::SymbolCompare}, který rozbaluje instance \code{Object} a~při porovnání správně vyhodnotí \code{MinimalEndSymbol} jako vždy menší.

\subsection{Datové struktury pro zpětnou transformaci}

V~algoritmech dále potřebujeme pracovat s~pomocnými poli zavedenými v~sekci \ref{sec:auxiliary}. K~jejich uchování slouží třída \code{indexes::stringology::BWTAuxiliaryData}. Pro jednoduchost jsou pole $M$ a~$K$ uloženy jako mapy symbol-hodnota. Kvůli tomuto rozhodnutí ale stoupla časová složitost přístupu do těchto polí z~$\BigO(1)$ na $\BigO(\log\abs{\Sigma})$, což je ale stále vzhledem k~velikosti textu zanedbatelné. Třída dále uchovává kopii seřazené abecedy a~pozici ukončovacího symbolu v~$L$ pro urychlení algoritmů.

\subsection{Zjednodušený FM-index}

Poslední implementovanou datovou strukturou je zjednodušený FM-index uvedený v~sekci \ref{sec:fmsimple}. Reprezentuje ho třída \code{indexes::stringology::SimpleFMIndex}. Ta obaluje instanci \code{LinearStringTerminatingSymbolBWT} (řetězec $L$), a~k~němu přidává pomocná pole sloužící pro reprezentaci funkce \FMOcc a~řídkého sufixového pole. Třída je na rozdíl od \code{BWTAuxiliaryData} neměnná (\emph{immutable}).
%Označené řádky vybíráme podle Jak již bylo zmíněno v~sekci \ref{sec:fmsimple}, rozhodli jsme se označovat ty řádky matice $\mat{A}_s$, které končí jedním vybraným symbolem.

\section{Algoritmy}

Všechny implementované algoritmy jsme umístili do experimentálního modulu \code{alib2algo\_experimental}, odkud se po kontrole začlení do hlavního modulu \code{alib2algo}. Do tříd jsme také rozmístili návěstí měřícího modulu \code{alib2measure}, která umožňují uživatelům měřit čas a~paměť spotřebovanou při běhu jednotlivých fází algoritmů. Algoritmy jsme registrací do \code{registration::AbstractRegister} zpřístupnili z~dostupných uživatelských rozhraní. Všechny důležité metody jsme opatřili dokumentačními komentáři systému Doxygen.

\subsection{Dopředná a~zpětná BWT}

Do jmenného prostoru \code{stringology::transform} jsme implementovali dva algoritmy sloužící pro dopřednou \acrshort{bwt}. První z~nich, \code{BWTNaive} přidá k~řetězci ukončovací symbol, sestaví matici $\mat{A}$, a~potom její řádky seřadí, má tedy paměťovou složitost $\BigO(n^2)$. Lepší časové složitosti dosahuje algoritmus \code{BWTFromSuffixArray}, který zkonstruuje $L$ z~již existující datové struktury \code{indexes::stringology::SuffixArray} (sufixové pole). V~kombinaci s~existujícím algoritmem \code{stringology::indexing::SuffixArrayNaive} tak dostáváme řešení popsané v~sekci \ref{sec:fwimpl}. Příklad volání uvádíme v~obrázku \ref{fig:aqlsa}.

\begin{figure}
	\begin{lstlisting}
	print stringology::indexing::SuffixArrayNaive "mississippi" | stringology::transform::BWTFromSuffixArray -
	\end{lstlisting}\caption{\acrshort{aql} příkaz pro dopřednou \acrshort{bwt} pomocí sufixového pole}\label{fig:aqlsa}
\end{figure}

Pro dekódování textu slouží \code{BWTDecode}, který nejprve zkonstruuje pomocná pole pomocí \code{stringology::indexing::BWTAuxiliaryDataConstruct}. Po dekódování algoritmus odebere ukončovací symbol. Pokud bychom potřebovali během zpětné \acrshort{bwt} vytvářet i~sufixové pole (algoritmus \ref{algo:sadec}), můžeme použít \code{stringology::indexing::SuffixArrayFromBWT}.

\subsection{Vyhledávání v~textu}

V~rámci praktické části práce jsme do \gls{alt} implementovali vyhledávací algoritmy představené v~kapitole \ref{ch:searching}. U~algoritmů, kde to dává smysl, umožňujeme uživateli předat jako argument již předpočítaná pomocná pole (třída \code{BWTAuxiliaryData}). V~případě jejich nepřitomnosti jsou potřebná pole vygenerována pomocí algoritmu \code{BWTAuxiliaryDataConstruct}.

\subsubsection*{Boyer-Moore pro BWT}

V~knihovně se již nachází implementace algoritmu Boyer-Moore, který využívá třídy \code{BadCharacterShiftTable} a~\code{GoodSuffixShiftTable} ze jmenného prostoru \code{string::properties} pro konstrukci polí posunů pro vzorkek $P$. Naše implementace modifikace Boyer-Moore pro BWT, která se nachází ve třídě \code{BWTBoyerMoore}, příslušící do jmenného prostoru \code{stringology::exact}, využívá tyto již existující pomocné algoritmy a~předchází tak zbytečné duplikaci kódu.

\subsubsection*{Binární vyhledávání a~sufixové pole}

Hledání vzorku pomocí půlení intervalů (sekce \ref{sec:bs}) jsme implementovali ve třídě \code{stringology::exact::BWTBinarySearch}. Vyhledávání s~využitím sufixového pole obstarává již existující algoritmus \code{stringology::query::SuffixArrayFactors}. V~kombinaci s~\code{SuffixArrayFromBWT} tak dostáváme algoritmus ze sekce~\ref{sec:sasearch}.

\subsubsection*{FM-index}

Metody pro konstrukci zjednodušeného FM-indexu jsme implementovali ve třídě \code{stringology::indexing::SimpleFMIndexConstruct}. Uživatel si může pomocí argumentů zvolit velikost přihrádek a~podpřihrádek a~určit hustotu označených řádků. Algoritmus poté vybere takový symbol, jehož relativní četnost je nejblíže zadané hustotě.

Obě operace \method{Count} a~\method{Locate} pracující s~FM-indexem potřebují přístup k~funkci \FMOcc. Vytvořili jsme tak třídu \code{stringology::common::FMIndexCommon}, která se právě stará o~zjištění hodnoty této funkce pro dané argumenty, a~zároveň abstrahuje pole $M$ a~práci s~označenými řádky matice $\mat{A}_s$.

V~případě rozšiřování knihovny o~plnou verzi FM-indexu včetně komprese, bylo by potřeba do této třídy akorát přidat přetížení metod pro nově implementovanou datovou strukturu, samotný kód operací \method{Count} a~\method{Locate} umístěný v~\code{stringology::query::FMIndexCount} a~\code{stringology::query::FMIndexLocate} by mohl zůstat beze změny.