From 25a5646093489ca37acb4188cb64aa32a8cb4528 Mon Sep 17 00:00:00 2001 From: Arity-T Date: Fri, 29 Nov 2024 20:38:29 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D1=81=D0=BE=D0=B1=D0=B5=D0=BD=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lab4/report/report.tex | 94 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/lab4/report/report.tex b/lab4/report/report.tex index 477c9d5..774409e 100644 --- a/lab4/report/report.tex +++ b/lab4/report/report.tex @@ -183,6 +183,100 @@ \newpage \section {Особенности реализации} + \subsection{Функция isCongruent} + + Код функции для проверки числовой конгруэнтности представлен в листинге~\ref{lst:is-congruent}. Функция \texttt{isCongruent} принимает три числа: \texttt{a}, \texttt{b} и \texttt{d}. Она возвращает \texttt{True}, если остатки от деления \texttt{a} и \texttt{b} на \texttt{d} равны, и \texttt{False} в противном случае. + +\begin{lstlisting}[caption={Функция для проверки числовой конгруэнтности.}, label={lst:is-congruent}] +isCongruent :: Int -> Int -> Int -> Bool +isCongruent a b d = a `mod` d == b `mod` d +\end{lstlisting} + + \subsection{Функция filterByPredicate} + + Код функции для фильтрации элементов списка на основе предиката представлен в листинге~\ref{lst:filter-by-predicate}. Функция \texttt{filterByPredicate} принимает предикат (\texttt{predicate}) и список (\texttt{[a]}). Она возвращает новый список, содержащий только те элементы исходного списка, для которых предикат возвращает \texttt{True}. + +\begin{lstlisting}[caption={Функция для фильтрации списка по предикату.}, label={lst:filter-by-predicate}] +filterByPredicate :: (a -> Bool) -> [a] -> [a] +filterByPredicate _ [] = [] +filterByPredicate predicate (x:xs) + | predicate x = x : filteredTail + | otherwise = filteredTail + where + filteredTail = filterByPredicate predicate xs +\end{lstlisting} + + +\subsection{Тесты для функции isCongruent} + +Для тестирования функции \texttt{isCongruent} использовались свойства, проверяемые с использованием библиотеки QuickCheck. Ниже приведены описания тестов, представленных в листинге~\ref{lst:congruent-tests}. + +\begin{itemize} + \item \texttt{propCongruentDifference}: Проверяет, что два числа конгруэнтны по модулю \texttt{m}, если и только если разность этих чисел делится на \texttt{m} без остатка. + \item \texttt{propCongruentSymmetric}: Проверяет симметричность конгруэнтности, то есть, если \texttt{a} конгруэнтно \texttt{b}, то \texttt{b} конгруэнтно \texttt{a}. + \item \texttt{propCongruentEqualNumbers}: Проверяет, что любое число \texttt{a} всегда конгруэнтно самому себе по любому ненулевому модулю. +\end{itemize} + +\begin{lstlisting}[caption={Тесты для функции \texttt{isCongruent} с использованием QuickCheck.}, label={lst:congruent-tests}] +propCongruentDifference :: Int -> Int -> Int -> Property +propCongruentDifference a b m = + m /= 0 ==> isCongruent a b m == ((a - b) `mod` m == 0) + +propCongruentSymmetric :: Int -> Int -> Int -> Property +propCongruentSymmetric a b m = + m /= 0 ==> isCongruent a b m == isCongruent b a m + +propCongruentEqualNumbers :: Int -> Int -> Property +propCongruentEqualNumbers a m = + m /= 0 ==> isCongruent a a m == True +\end{lstlisting} + + +\subsection{Тесты для функции filterByPredicate} + +Для тестирования функции \texttt{filterByPredicate} использовались свойства, проверяемые с использованием библиотеки QuickCheck. Описание тестов приведено в листинге~\ref{lst:filter-tests}. + +\begin{itemize} + \item \texttt{propFilterByPredicateSatisfiesPredicate}: Проверяет, что все элементы результирующего списка удовлетворяют переданному предикату. + \item \texttt{propFilterByPredicateLength}: Проверяет, что длина результирующего списка не превышает длину исходного списка. + \item \texttt{propFilterByPredicateAlwaysTrue}: Проверяет, что если предикат всегда возвращает \texttt{True}, результирующий список совпадает с исходным. +\end{itemize} + +\begin{lstlisting}[caption={Тесты для функции \texttt{filterByPredicate} с использованием QuickCheck.}, label={lst:filter-tests}] +propFilterByPredicateSatisfiesPredicate :: Fun Int Bool -> [Int] -> Bool +propFilterByPredicateSatisfiesPredicate (Fun _ predicate) xs = + all predicate (filterByPredicate predicate xs) + +propFilterByPredicateLength :: Fun Int Bool -> [Int] -> Bool +propFilterByPredicateLength (Fun _ predicate) xs = + length (filterByPredicate predicate xs) <= length xs + +propFilterByPredicateAlwaysTrue :: [Int] -> Bool +propFilterByPredicateAlwaysTrue xs = + filterByPredicate (\_ -> True) xs == xs +\end{lstlisting} + + +\subsection{Запуск тестов} + +Для выполнения всех тестов в проекте создан файл \texttt{Spec.hs}, в котором определена функция \texttt{main}. Она последовательно запускает все тесты, используя библиотеку \texttt{QuickCheck}. Код функции \texttt{main} приведён в листинге~\ref{lst:test-main}. + +Функция \texttt{quickCheck} используется для автоматического тестирования свойств. Она генерирует случайные входные данные, проверяет выполнение свойства на каждом из них и сообщает о результатах. В случае провала теста \texttt{quickCheck} предоставляет пример данных, на которых свойство не выполняется. + +Для сборки проекта и выполнения всех тестов достаточно выполнить команду \texttt{stack test}. + +\begin{lstlisting}[caption={Функция \texttt{main} для запуска тестов.}, label={lst:test-main}] +main :: IO () +main = do + quickCheck propCongruentDifference + quickCheck propCongruentSymmetric + quickCheck propCongruentEqualNumbers + + quickCheck propFilterByPredicateSatisfiesPredicate + quickCheck propFilterByPredicateLength + quickCheck propFilterByPredicateAlwaysTrue +\end{lstlisting} + \newpage