/// <summary>
        /// Este metodo intenta recuperar los simbolos de la base de datos
        /// correspondiente a una imagen.
        /// </summary>
        /// <param name="image">
        /// La imagen cuyos simbolos asociados queremos encontrar.
        /// </param>
        /// <returns>
        /// Los simbolos que se puedieron asociar con la imagen.
        /// </returns>
        public override List <MathSymbol> Match(MathTextBitmap image)
        {
            List <MathSymbol> res = new List <MathSymbol>();

            FloatBitmap processedImage = image.LastProcessedImage;

            TristateCheckVector vector = CreateVector(processedImage);

            // We have this image vector, now we will compare with the stored ones.



            foreach (TristateCheckVector storedVector in symbolsDict)
            {
                // We consider a threshold.
                int threshold = (int)((storedVector.Length - storedVector.DontCares) * epsilon);

                // If the distance is below the threshold, we consider it valid.
                if (storedVector.Distance(vector) <= threshold)
                {
                    foreach (MathSymbol symbol in storedVector.Symbols)
                    {
                        // We don't want duplicated symbols.
                        if (!res.Contains(symbol))
                        {
                            res.Add(symbol);
                        }
                    }

                    string msg =
                        String.Format("Distancia({0}, {1}) <= {2}",
                                      vector.ToString(),
                                      storedVector.ToString(),
                                      threshold);

                    msg += "\nSe añadieron los símbolos almacenados.";

                    StepDoneInvoker(new StepDoneArgs(msg));
                }
                else
                {
                    string msg = String.Format("Distancia({0}, {1}) > {2}",
                                               vector.ToString(),
                                               storedVector.ToString(),
                                               threshold);

                    StepDoneInvoker(new StepDoneArgs(msg));
                }
            }

            return(res);
        }
        /// <summary>
        /// Creates a <see cref="TristateCheckVector"/> instance for a given
        /// <c>FloatBitmap</c> object.
        /// </summary>
        /// <param name="image">
        /// A <see cref="FloatBitmap"/> for which the vector is created.
        /// </param>
        /// <returns>
        /// The <see cref="TristateCheckVector"/> for the image.
        /// </returns>
        private TristateCheckVector CreateVector(FloatBitmap image)
        {
            // We create the receptors list.
            if (receptors == null)
            {
                receptors = Receptor.GenerateList(40);
            }

            TristateCheckVector vector = new TristateCheckVector();

            TristateValue checkValue;

            foreach (Receptor receptor in receptors)
            {
                checkValue =
                    receptor.CheckBressard(image)?
                    TristateValue.True:TristateValue.False;

                vector.Values.Add(checkValue);
                StepDoneArgs args =
                    new StepDoneArgs(String.Format("Comprobando receptor {0}: {1}",
                                                   String.Format("({0}, {1}) -> ({2}, {3})",
                                                                 receptor.X0, receptor.Y0,
                                                                 receptor.X1, receptor.Y1),
                                                   checkValue));

                StepDoneInvoker(args);
                Thread.Sleep(20);
            }

            foreach (BinaryCharacteristic characteristic in characteristics)
            {
                checkValue =
                    characteristic.Apply(image)?
                    TristateValue.True
                                                : TristateValue.False;

                vector.Values.Add(checkValue);

                StepDoneArgs args =
                    new StepDoneArgs(String.Format("Comprobando característica {0}: {1}",
                                                   characteristic.GetType().ToString(),
                                                   checkValue));

                StepDoneInvoker(args);
                Thread.Sleep(20);
            }

            return(vector);
        }
        /// <summary>
        /// This method is used to add new symbols to the database.
        /// </summary>
        /// <param name="bitmap">
        /// The image containing the symbol.
        /// </param>
        /// <param name="symbol">
        /// The symbol contained in the image.
        /// </param>
        public override bool Learn(MathTextBitmap bitmap, MathSymbol symbol)
        {
            FloatBitmap         processedBitmap = bitmap.LastProcessedImage;
            TristateCheckVector newVector       = CreateVector(processedBitmap);

            TristateCheckVector found = null;

            foreach (TristateCheckVector vector in symbolsDict)
            {
                if (vector.Symbols.Contains(symbol))
                {
                    found = vector;
                    break;
                }
            }

            if (found == null)
            {
                // The symbol wasnt present in the database.
                newVector.Symbols.Add(symbol);
                symbolsDict.Add(newVector);
            }
            else
            {
                // The symbol is present, we may have to retrain the database.
                if (newVector.Equals(found))
                {
                    // It's the same one, so there is a conflict.
                    return(false);
                }
                else
                {
                    // We have to find the differnces, and change them to
                    // don't care values.
                    for (int i = 0; i < found.Length; i++)
                    {
                        if (found[i] != TristateValue.DontCare &&
                            found[i] != newVector[i])
                        {
                            // If the value is different from what we had learned,
                            // then we make the vector more general in that point.
                            found[i] = TristateValue.DontCare;
                        }
                    }
                }
            }

            return(true);
        }