<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">%======================================================================
\newpage
\section{Your Next MOOS Application - Prime Factorization}
%======================================================================

In this exercise we will build our next MOOS application. The function
performed by the app is a bit harder: it handles a series of integers
and determines, for each, the list of prime factors. A primary issue
addressed in this exercise is how to build an app that performs an
operation that may be considerably longer than the time slice allotted
to a typical \cmd{Iterate()} loop. Your app should be able to handle
the case where a simple query is preceded by a more complex query,
without the simple query being blocked by the former. (Not unlike the
7-items-or-less aisle at the supermarket).

%---------------------------------------------------------------------
\subsection*{Getting Started}

Begin by repeating the same steps from the previous example:

\begin{packed_enumerate}[3]
\item Enter the \var{moos-ivp-extend/src} directory and run the
  \app{GenMOOSApp} script to build the bare-bones application:
  
\begin{consoleverb}
 $ GenMOOSApp PrimeFactor p "John Doe"
\end{consoleverb}
\postverb[0in]

\item Note: Please use the app name \app{pPrimeFactor}. It makes
  testing and grading much easier over many students.

\item Add your new app to the build system as before by editing the
  \var{CMakeLists.txt} and test that it builds.
\end{packed_enumerate}

%===================================================================
\subsection{The Specs of Your pPrimeFactor Application}

Your application should meet the following specifications:

\begin{packed_enumerate}[2]

\item Your app should accept mail on an incoming variable containing
  an 64-bit integer value, max value of 18,446,744,073,709,551,615
  (maximum for an unsigned long int ). You can build your app under the 
  assumption that the maximum query we will test for is $2^{48}$ however.

\item Note: The type \var{"unsigned long int"} is 64 bits long in most C++
  implementations, but technically there is no guarantee. You may want to 
  instead use the type \var{"uint64\_t"} by including the \var{stdint.h}
  library.

\item The incoming variable name should be \mvar{NUM\_VALUE}.

\item The incoming variable is of type {\em string}. You must convert it to 
  a numerical value in your code.

\item Your app should determine the list of prime factors for a given
  input, and generate the following output for each:

\begin{packed_itemize}[2]
  \item the original number, 
  \item an index indicating the order in which it was received,
  \item an index indicating the order in which it was calculated,
  \item the time it took to solve the factorization. This is in normal
    clock time, not CPU time. Use the \cmd{MOOSTime()} function to get
    the time when it was received and the time it was finished.
  \item the list of prime factors.
  \item a unique id specifying you, e.g., your Athena username.
\end{packed_itemize}

\item Your output variable should be \mvar{PRIME\_RESULT} with the
  following format (note if a number can be evenly divided by a 
prime factor more than once, like the example below with two 3's, list
each in the result):

\prevgreen[0in]
\begin{verbatim}
PRIME_RESULT = "orig=90090,received=34,calculated=33,solve_time=2.03,
                  primes=2:3:3:5:7:11:13,username=jane"
\end{verbatim}
\postverb

\item Your application should not be blocked by large numbers. We should
  be able to see a response to low-number queries almost immediately, regardless
  of the size of the preceding query.

\item You should handle the case of receiving a non-integer number by truncating.

\item Do not use a cache of known prime numbers. 

\item Implement the \var{--help}, \var{--interface}, and
  \var{--example} command line switches discussed in the lecture.

\item Your app should be called \app{pPrimeFactor}.

\end{packed_enumerate}

\pskip
\noindent
General Hints: The key issues in this exercise are (a) how to perform your key
operations in an \var{Iterate()} loop in an incremental manner to avoid blocking, 
(b) how to automatically tune your incremental operations so the \var{Iterate()}
loop is also not sitting idle for too long.

%===================================================================
\subsection{A Second MOOS Application - to Test Your First App}

Your next step is to build another MOOS app, \app{pPrimeFactorTester},
to check the correctness of your first application. It should meet the
following specs:

\begin{packed_enumerate}

\item It should accept mail on an incoming variable,
  \mvar{PRIME\_RESULT}, containing the output of your \app{pPrimeFactor}
  application. 

\item It parses the string input and determines whether the result
  concluded by \app{pPrimeFactor} is correct or not (by simply
  multiplying the primes to check if the product equals the original
  number).

\item It publishes the results of the correctness check in another
  MOOS variable, \mvar{PRIME\_RESULT\_VALID}, with the following format:
  
\prevgreen[0in]
\begin{verbatim}
PRIME_RESULT_VALID = "orig=90090,received=34,calculated=33,solve_time=2.03,
                     primes=2:3:3:5:7:11:13,username=jane,valid=true"
\end{verbatim}
\postverb

\item Your app should be called \app{pPrimeFactorTester}.
\end{packed_enumerate}

%===================================================================
\subsection{How to Test Your Applications}

You will need something to generate a sequence of random inputs to the
\app{pPrimeFactor} application. In this case, you may want to game the
inputs to test harder cases. To accomplish this, do the following:

\begin{packed_enumerate}

\item Configure a \app{uTimerScript} script to endlessly generate a
  sequence of random integer string postings, e.g.,
  \mvar{NUM\_VALUE=1999}, \mvar{NUM\_VALUE=112}, etc.

\item Make a single \var{.moos} mission file with the script and your
  two applications configured and launched with pAntler to demonstrate
  the full working setup.

\end{packed_enumerate}

\noindent
You can use the below configuration for \app{uTimerScript}. 

\begin{consoleverb}
ProcessConfig = uTimerScript
{
  AppTick   = 4
  CommsTick = 4

  paused     = false
  event      = var=NUM_VALUE, val="$(15)", time=0.25
  event      = var=NUM_VALUE, val="$(9)", time=0.50
  event      = var=NUM_VALUE, val="$(7)", time=0.75
  event      = var=NUM_VALUE, val="$(5)", time=1.00
  reset_max  = nolimit
  reset_time = all-posted
}
\end{consoleverb}

\noindent
The \var{"\$(15)"} notation above indicates that a 15-digit number is
desired, but posted as type string. (The reason why we choose to pass
the number as a string is that really big numbers are not able to be
precisely represented as a \var{double}. The result is a rounded
number different from the original, with different prime factors.)

%===================================================================
\subsection{How to Test Your Applications - Part 2}

Here's another timer script. In this case, rather than leaving things
to chance, we post some really big numbers {\em that we know are
  prime}, and then a couple small composite numbers. We should see
that the small numbers don't get blocked by the big ones:

\begin{consoleverb}
ProcessConfig = uTimerScript
{
  AppTick   = 4
  CommsTick = 4

  event  = var=NUM_VALUE, val="112272535095293", time=0.25
  event  = var=NUM_VALUE, val="112582705942171", time=0.50
  event  = var=NUM_VALUE, val="115280095190773", time=0.75
  event  = var=NUM_VALUE, val="115797848077099", time=1.00
  event  = var=NUM_VALUE, val="117450548693743", time=1.25
  event  = var=NUM_VALUE, val="117463495419967", time=1.50
  event  = var=NUM_VALUE, val="118813069318813", time=1.75

  event  = var=NUM_VALUE, val="125", time=2.00
  event  = var=NUM_VALUE, val="225", time=2.25
  event  = var=NUM_VALUE, val="325", time=2.50

  event  = var=NUM_VALUE, val="121642554638287", time=2.75
  event  = var=NUM_VALUE, val="123939877913659", time=3.00
  event  = var=NUM_VALUE, val="125673790649527", time=3.25
  event  = var=NUM_VALUE, val="126794093929207", time=3.50
  event  = var=NUM_VALUE, val="127691861505847", time=3.75
  event  = var=NUM_VALUE, val="129263144299543", time=4.00

  reset_max  = 0
  reset_time = all-posted
}
\end{consoleverb}

\vspace{0.15in}
\noindent
Note also that we set \var{reset\_max=0} so that the script is only
executed once.

\vspace{0.15in}
\noindent
To further check your results, let's use the logger. Make sure you add
\app{pLogger} to your Antler block with a line like:

\vspace{0.1in}
\begin{consoleverb}
  Run = pLogger         @ NewConsole = false
\end{consoleverb}
\vspace{0.1in}

\noindent
And configure \app{pLogger} with its own configuration block:

\vspace{0.1in}
\begin{consoleverb}
ProcessConfig = pLogger
{
  AsyncLog = true
  WildCardLogging = true
  WildCardOmitPattern = *_STATUS

  LOG =  PRIME_RESULT @ 0
}
\end{consoleverb}
\vspace{0.1in}

\noindent
Re-launch your mission and let it run for say a minute or so, which should
give your app enough time to process all the incoming values, even the
long ones. Then let's check the log file. Your mission should have created
a folder like:

\vspace{0.1in}
\begin{consoleverb}
  MOOSLog_2_1_2017_____11_04_36/
\end{consoleverb}
\vspace{0.1in}

\noindent
This is where \app{pLogger} generated all its output. The key file in
here is the \var{.alog} file:

\vspace{0.1in}
\begin{consoleverb}
  $ cd MOOSLog_2_1_2017_____11_04_36/
  MOOSLog_2_1_2017_____11_04_36._moos  MOOSLog_2_1_2017_____11_04_36.blog
  MOOSLog_2_1_2017_____11_04_36.alog   MOOSLog_2_1_2017_____11_04_36.ylog  
\end{consoleverb}
\vspace{0.1in}

\noindent
Now you can see the sequencing of your application by "grepping" on the
the \mvar{PRIME\_RESULT} variable:

\vspace{0.1in}
\begin{consoleverb}
  $ aloggrep MOOSLog_2_1_2017_____11_04_36.alog PRIME_RESULT

\end{consoleverb}
\vspace{0.1in}








</pre></body></html>