public static ProbableStrength Max(ProbableStrength one, ProbableStrength two)
 {
     if (one.strength * one.weight > two.strength * two.weight)
         return one;
     else
         return two;
 }
        // Guess whether or not a phrase is plural
        public static ProbableStrength SeemsPlural(InformedPhrase phrase)
        {
            ProbableStrength result = new ProbableStrength(0, 0);
            double strengthFactor = result.ImproveStrengthStart();

            // Noun count is well determined by ending in s
            ProbableStrength nounness = PartOSAttribute.SeemsA(phrase, SpeechPart.Noun);
            ProbableStrength nisplural;
            if (phrase.Name.ToLower().EndsWith("s"))
                nisplural = new ProbableStrength(1.0, 0.8);
            else
                nisplural = new ProbableStrength(0.0, 0.5);

            result.ImproveStrength(nounness.Relative(nisplural), ref strengthFactor);

            // Verbs that end in s are probably not plural
            ProbableStrength verbness = PartOSAttribute.SeemsA(phrase, SpeechPart.Verb);
            if (phrase.Name.ToLower().EndsWith("s"))
            {
                ProbableStrength visplural = new ProbableStrength(0.0, 0.8);
                result.ImproveStrength(verbness.Relative(visplural), ref strengthFactor);
            }

            result.ImproveStrengthFinish(strengthFactor);

            return result;
        }
        public ProbableStrength Relative(ProbableStrength other)
        {
            double newstrength = other.strength * strength; // <- use instead of RelativeStrength(other.strength, strength), because only used for strength [0, 1]
            double newweight   = RelativeWeight(other.weight, weight);

            return(new ProbableStrength(newstrength, newweight));
        }
        public ProbableStrength Better(ProbableStrength other)
        {
            if (strength * weight < other.strength * other.weight)
                return other;

            return this;
        }
        public ProbableStrength Combine(ProbableStrength other)
        {
            double newstrength = (strength * weight + other.strength * other.weight) / (weight + other.weight);
            double newweight   = weight + other.weight - weight * other.weight;

            return(new ProbableStrength(newstrength, newweight));
        }
        public virtual ProbableStrength Describes(PhraseSense sense)
        {
            ProbableStrength total = new ProbableStrength(0, 0);
            double strengthFactor = total.ImproveStrengthStart();

            foreach (PhraseAttribute attribute in sense.Attributes)
                total.ImproveStrength(Match(attribute), ref strengthFactor);

            if (strengthFactor == 0)
            {
                // do we match subphrases then?
                foreach (InformedPhrase subphrase in sense.Phrases)
                    total.ImproveStrength(Describes(subphrase).DownWeight(1.0 / sense.Phrases.Count), ref strengthFactor);
            }

            if (strengthFactor == 0)
            {
                // We never found an appropriate attribute-- so guess!
                List<KeyValuePair<PhraseSense, double>> senses = new List<KeyValuePair<PhraseSense, double>>();
                senses.Add(new KeyValuePair<PhraseSense,double>(sense, 1.0));
                InformedPhrase dummy = new InformedPhrase(sense.Name(), senses);
                ProbableStrength result = Match(Guess(dummy));
                total.ImproveStrength(result, ref strengthFactor);
            }

            total.ImproveStrengthFinish(strengthFactor);
            return total;
        }
        public static ProbableStrength SeemsReferee(InformedPhrase phrase, IWordLookup informer, ProbableStrength anaphora)
        {
            List<string> words = phrase.Generate();

            double weight = 0;
            foreach (string word in words)
                weight += informer.GetWeight(word, false);
            /* words weight result
             * 1     0      0
             * 1     1      1
             * 2     0      0
             * 2     .5     .4
             * 2     1      2/3
             * 2     1.5    .86
             * 2     2      1
             * 3     .5     .3
             * 3     1      .5
             * 3     2      .8
             */
            double myweight = 2.0 * weight / (words.Count + weight);
            if (words.Count == 1)
                myweight /= 2.0;    // down-score 1-word answers
            if (words.Count > 2)
                myweight /= Math.Log(words.Count);

            ProbableStrength notanaphora = anaphora.InverseProbability();

            return new ProbableStrength(Math.Sqrt(myweight * notanaphora.strength), notanaphora.weight + .5 - notanaphora.weight * .5);
        }
        // Does this appear to be a reference for something?
        // Checks the part of our senses, and our sub-parts
        public static ProbableStrength SeemsAnaphora(InformedPhrase phrase)
        {
            ProbableStrength total = new ProbableStrength(0, 0);
            double strengthFactor = total.ImproveStrengthStart();

            foreach (KeyValuePair<PhraseSense, double> sense in phrase.Senses)
            {
                if (sense.Key.Phrases.Count == 1)
                    total.ImproveStrength(SeemsAnaphora(sense.Key.Phrases[0]), ref strengthFactor);
                else
                {
                    ProbableStrength singletotal = sense.Key.SpeechPart().SeemsAnaphora().DownWeight(1.0 / (sense.Key.Phrases.Count + 1));

                    // Combine together results from subphrases
                    ProbableStrength phrasetotal = new ProbableStrength(0, 0);
                    double phraseFactor = phrasetotal.ImproveStrengthStart();
                    foreach (InformedPhrase subphrase in sense.Key.Phrases)
                        phrasetotal.ImproveStrength(SeemsAnaphora(subphrase).DownWeight(1.0 / sense.Key.Phrases.Count), ref phraseFactor);
                    phrasetotal.ImproveStrengthFinish(phraseFactor);

                    // Use both our and the recursive result
                    total.ImproveStrength(singletotal.Combine(phrasetotal), ref strengthFactor);
                }
            }

            total.ImproveStrengthFinish(strengthFactor);

            return total;
        }
        public ProbableStrength Better(ProbableStrength other)
        {
            if (strength * weight < other.strength * other.weight)
            {
                return(other);
            }

            return(this);
        }
 public static ProbableStrength Max(ProbableStrength one, ProbableStrength two)
 {
     if (one.strength * one.weight > two.strength * two.weight)
     {
         return(one);
     }
     else
     {
         return(two);
     }
 }
 public ProbableStrength Improve(ProbableStrength other)
 {
     if (other.strength > strength)
     {
         double newstrength = strength + (other.strength - strength) * other.weight / (weight + other.weight);
         double newweight   = (weight + other.weight) / 2;
         return(new ProbableStrength(newstrength, newweight));
     }
     else
     {
         return(this);
     }
 }
        // Could this be an anaphora for the given phrase?  Check the attributes
        public static ProbableStrength AnaphoraOf(InformedPhrase anaphora, PhraseSense prime)
        {
            if (anaphora.IsContained(prime) || prime.IsContained(anaphora))
                return ProbableStrength.Zero;   // can't refer to included structure

            ProbableStrength total = new ProbableStrength(0, 0);
            double strengthFactor = total.ImproveStrengthStart();

            foreach (KeyValuePair<PhraseSense, double> sense in anaphora.Senses)
            {
                ProbableStrength match = AnaphoraOf(sense.Key, prime);
                total.ImproveStrength(match.DownWeight(sense.Value), ref strengthFactor);
            }

            total.ImproveStrengthFinish(strengthFactor);

            return total;
        }
        public static ProbableStrength AnaphoraOf(PhraseSense anaphora, PhraseSense prime)
        {
            ProbableStrength total = new ProbableStrength(0, 0);
            double strengthFactor = total.ImproveStrengthStart();

            // Check if each attribute could describe the phrase
            foreach (PhraseAttribute attribute in anaphora.Attributes)
            {
                if (attribute is PartOSAttribute)
                    continue;   // ignore
                total.ImproveStrength(attribute.Describes(prime), ref strengthFactor);
            }

            // Check if subphrases could be anaphors for the given phrase
            foreach (InformedPhrase subphrase in anaphora.Phrases)
                total.ImproveStrength(AnaphoraOf(subphrase, prime).DownWeight(1.0 / anaphora.Phrases.Count), ref strengthFactor);

            total.ImproveStrengthFinish(strengthFactor);
            return total;
        }
 public void ImproveStrength(ProbableStrength addStrength, ref double strengthFactor)
 {
     ImproveStrength(addStrength.strength, addStrength.weight, ref strengthFactor);
 }
 public ProbableStrength Relative(ProbableStrength other)
 {
     double newstrength = other.strength * strength; // <- use instead of RelativeStrength(other.strength, strength), because only used for strength [0, 1]
     double newweight = RelativeWeight(other.weight, weight);
     return new ProbableStrength(newstrength, newweight);
 }
 public ProbableStrength Improve(ProbableStrength other)
 {
     if (other.strength > strength) {
         double newstrength = strength + (other.strength - strength) * other.weight / (weight + other.weight);
         double newweight = (weight + other.weight) / 2;
         return new ProbableStrength(newstrength, newweight);
     } else
         return this;
 }
        // Does this attribute describe the word?  Consider overriding this
        public ProbableStrength Describes(InformedPhrase word)
        {
            ProbableStrength total = new ProbableStrength(0, 0);
            double strengthFactor = total.ImproveStrengthStart();

            foreach (KeyValuePair<PhraseSense, double> sense in word.Senses)
                total.ImproveStrength(Describes(sense.Key).DownWeight(sense.Value), ref strengthFactor);

            if (strengthFactor == 0)
            {
                // We never found an appropriate attribute-- so guess!
                ProbableStrength result = Match(Guess(word));
                total.ImproveStrength(result, ref strengthFactor);
            }

            total.ImproveStrengthFinish(strengthFactor);
            return total;
        }
 public void ImproveStrength(ProbableStrength addStrength, ref double strengthFactor)
 {
     ImproveStrength(addStrength.strength, addStrength.weight, ref strengthFactor);
 }
 // Base constructor: just stores "how strong" the attribute is
 public PhraseAttribute(double strength, double weight)
 {
     this.strength = new ProbableStrength(strength, weight);
 }
 public void Deserialize(SerializationReader reader)
 {
     strength = (ProbableStrength) reader.ReadPointer();
 }
 public ProbableStrength Combine(ProbableStrength other)
 {
     double newstrength = (strength * weight + other.strength * other.weight) / (weight + other.weight);
     double newweight = weight + other.weight - weight * other.weight;
     return new ProbableStrength(newstrength, newweight);
 }
        public static ProbableStrength SeemsReferencePhrase(InformedPhrase phrase, bool not)
        {
            ProbableStrength total = new ProbableStrength(0, 0);
            double strengthFactor = total.ImproveStrengthStart();

            foreach (KeyValuePair<PhraseSense, double> sense in phrase.Senses)
            {
                if (sense.Key.Phrases.Count == 1)
                    total.ImproveStrength(SeemsReferencialVerb(sense.Key.Phrases[0]), ref strengthFactor);
                else
                {
                    // Is this a "helper" verb followed by an anaphora?
                    ProbableStrength foundHelper = ProbableStrength.None, foundBoth = ProbableStrength.None;
                    foreach (InformedPhrase subphr in sense.Key.Phrases)
                    {
                        if (!not)
                        {
                            foundHelper = foundHelper.Better(SeemsReferencialVerb(subphr));
                            foundBoth = foundBoth.Better(foundHelper.Relative(SeemsAnaphora(subphr)));
                        }
                        else
                        {
                            foundHelper = foundHelper.Better(SeemsReferencialVerb(subphr).InverseProbability());
                            foundBoth = foundBoth.Better(foundHelper.Relative(SeemsAnaphora(subphr).InverseProbability()));
                        }
                    }

                    foundBoth.weight = foundBoth.weight + .5 - foundBoth.weight * .5;

                    // Use both our and the recursive result
                    total.ImproveStrength(foundBoth, ref strengthFactor);
                }
            }

            total.ImproveStrengthFinish(strengthFactor);

            return total;
        }