示例#1
0
        /**
         * extract verb information from NIH VerbEntry record, and add to a
         * simplenlg WordElement For now just extract transitive, instransitive,
         * and/or ditransitive
         *
         * @param wordElement
         * @param verbEntry
         */
        private void addVerbInfo(WordElement wordElement, VerbEntry verbEntry)
        {
            if (verbEntry == null)
            { // should only happen for aux verbs, which have
              // auxEntry instead of verbEntry in NIH Lex
              // just flag as transitive and return
                wordElement.setFeature(LexicalFeature.INTRANSITIVE, false);
                wordElement.setFeature(LexicalFeature.TRANSITIVE, true);
                wordElement.setFeature(LexicalFeature.DITRANSITIVE, false);
                return;
            }

            bool intransitiveVerb = verbEntry.GetIntran().Any();
            bool transitiveVerb   = verbEntry.GetTran().Any() || verbEntry.GetCplxtran().Any();
            bool ditransitiveVerb = verbEntry.GetDitran().Any();

            wordElement.setFeature(LexicalFeature.INTRANSITIVE, intransitiveVerb);
            wordElement.setFeature(LexicalFeature.TRANSITIVE, transitiveVerb);
            wordElement.setFeature(LexicalFeature.DITRANSITIVE, ditransitiveVerb);

            // add the inflectional variants
            List <string> variants = verbEntry.GetVariants();

            if (variants.Count > 0)
            {
                IList <Inflection> wordVariants = new List <Inflection>();

                foreach (string v in variants)
                {
                    int        index = v.IndexOf("|", StringComparison.Ordinal);
                    string     code;
                    Inflection?infl;

                    if (index > -1)
                    {
                        code = v.Substring(0, index).ToLower().Trim();
                        infl = Inflection.REGULAR.getInflCode(code);
                    }
                    else
                    {
                        infl = Inflection.REGULAR.getInflCode(v.ToLower().Trim());
                    }

                    if (infl != null)
                    {
                        wordElement.addInflectionalVariant((Inflection)infl);
                        wordVariants.Add((Inflection)infl);
                    }
                }

                // if the variants include "reg", this is the default, otherwise
                // just a random pick
                Inflection defaultVariant = wordVariants.Contains(Inflection.REGULAR) || wordVariants.Count == 0 ? Inflection.REGULAR : wordVariants[0];
                //			wordElement.setFeature(LexicalFeature.INFLECTIONS, wordVariants);
                //			wordElement.setFeature(LexicalFeature.DEFAULT_INFL, defaultVariant);
                wordElement.setDefaultInflectionalVariant(defaultVariant);
            }

            // ignore (for now) other info in record
        }
示例#2
0
 private void EnsurePluralForm()
 {
     if (_plural == null)
     {
         PluralForm = Inflection.PluralOfNoun(_singular);
     }
 }
示例#3
0
        /**
         * convenience method: parses an inflectional code such as
         * "irreg|woman|women" to retrieve the first element, which is the code
         * itself, then maps it to the value of <code>Inflection</code>.
         *
         * @param code
         *            -- the string representing the inflection. The strings are
         *            those defined in the NIH Lexicon.
         * @return the Inflection
         */
        public static Inflection?getInflCode(this Inflection inflection, string code)

        {
            code = code.ToLower().Trim();
            Inflection?infl = null;

            if (code.Equals("reg"))
            {
                infl = Inflection.REGULAR;
            }
            else if (code.Equals("irreg"))
            {
                infl = Inflection.IRREGULAR;
            }
            else if (code.Equals("regd"))
            {
                infl = Inflection.REGULAR_DOUBLE;
            }
            else if (code.Equals("glreg"))
            {
                infl = Inflection.GRECO_LATIN_REGULAR;
            }
            else if (code.Equals("uncount") || code.Equals("noncount") || code.Equals("groupuncount"))
            {
                infl = Inflection.UNCOUNT;
            }
            else if (code.Equals("inv"))
            {
                infl = Inflection.INVARIANT;
            }

            return(infl);
        }
        public static IEnumerable <Inflection> Parse(Response.Inflection[] sources, Language language, AudioFormat audioFormat)
        {
            foreach (var source in sources)
            {
                var inflection = new Inflection
                {
                    Label   = source.Label,
                    Cutback = source.Cutback,
                    Value   = source.Value,
                    SenseSpecificInflectionPluralLabel = source.SenseSpecificInflectionPluralLabel
                };

                if (source.Pronunciations.Any())
                {
                    inflection.Pronunciations = new List <Pronunciation>();
                    foreach (var pronunciation in source.Pronunciations)
                    {
                        inflection.Pronunciations.Add(PronunciationHelper.Parse(pronunciation, language, audioFormat));
                    }
                }

                if (source.Alternate != null)
                {
                    inflection.Alternate = new AlternateInflection
                    {
                        Cutback    = source.Alternate.Cutback,
                        Inflection = source.Alternate.Inflection
                    };
                }

                yield return(inflection);
            }
        }
示例#5
0
 /// <summary>
 /// Make sure the noun has a singular form.
 /// </summary>
 private void EnsureSingularForm()
 {
     if (_singular == null)
     {
         SingularForm = Inflection.SingularOfNoun(_plural);
     }
 }
示例#6
0
        public Inflection CreateInflection(decimal conjugation, string mood, string tense, bool isPassive)
        {
            Inflection inflection = new Inflection();


            if ((tense == "Perfect" || tense == "Pluperfect" || tense == "Future Perfect") && isPassive)
            {
                Passive passive = _passives.Where(p => p.Tense == tense && p.Mood == mood).FirstOrDefault();

                if (passive != null)
                {
                    inflection.singular_first  = $"{passive.singular_first} {_supineStem}us";
                    inflection.singular_second = $"{passive.singular_second} {_supineStem}us";
                    inflection.singular_third  = $"{passive.singular_third} {_supineStem}us";

                    inflection.plural_first  = $"{passive.plural_first} {_supineStem}i";
                    inflection.plural_second = $"{passive.plural_second} {_supineStem}i";
                    inflection.plural_third  = $"{passive.plural_third} {_supineStem}i";
                }
            }
            else
            {
                Suffix suffix = _suffixes.Where(s => s.Conjugation == conjugation && s.Mood == mood && s.Passive == isPassive && s.Tense == tense).FirstOrDefault();

                inflection.singular_first  = SplitSuffix(suffix.singular_first);
                inflection.singular_second = SplitSuffix(suffix.singular_second);
                inflection.singular_third  = SplitSuffix(suffix.singular_third);

                inflection.plural_first  = SplitSuffix(suffix.plural_first);
                inflection.plural_second = SplitSuffix(suffix.plural_second);
                inflection.plural_third  = SplitSuffix(suffix.plural_third);
            }

            return(inflection);
        }
示例#7
0
        /**
         * extract noun information from NIH NounEntry record, and add to a
         * simplenlg WordElement For now just extract whether count/non-count and
         * whether proper or not
         *
         * @param wordElement
         * @param nounEntry
         */
        private void addNounInfo(WordElement wordElement, NounEntry nounEntry)
        {
            bool proper = nounEntry.IsProper();
            // bool nonCountVariant = false;
            // bool regVariant = false;

            // add the inflectional variants
            List <string> variants = nounEntry.GetVariants();

            if (variants.Count > 0)
            {
                IList <Inflection> wordVariants = new List <Inflection>();

                foreach (string v in variants)
                {
                    int    index = v.IndexOf("|", StringComparison.Ordinal);
                    string code;

                    if (index > -1)
                    {
                        code = v.Substring(0, index).ToLower().Trim();
                    }
                    else
                    {
                        code = v.ToLower().Trim();
                    }

                    Inflection?infl = Inflection.REGULAR.getInflCode(code);

                    if (infl != null)
                    {
                        wordVariants.Add((Inflection)infl);
                        wordElement.addInflectionalVariant((Inflection)infl);
                    }
                }

                // if the variants include "reg", this is the default, otherwise just a random pick
                Inflection defaultVariant = wordVariants.Contains(Inflection.REGULAR) || wordVariants.Count == 0 ? Inflection.REGULAR : wordVariants[0];
                wordElement.setFeature(LexicalFeature.DEFAULT_INFL, defaultVariant);
                wordElement.setDefaultInflectionalVariant(defaultVariant);
            }

            // for (String variant : variants) {
            // if (variant.startsWith("uncount")
            // || variant.startsWith("groupuncount"))
            // nonCountVariant = true;
            //
            // if (variant.startsWith("reg"))
            // regVariant = true;
            // // ignore other variant info
            // }

            // lots of words have both "reg" and "unCount", indicating they
            // can be used in either way. Regard such words as normal,
            // only flag as nonCount if unambiguous
            // wordElement.setFeature(LexicalFeature.NON_COUNT, nonCountVariant && !regVariant);
            wordElement.setFeature(LexicalFeature.PROPER, proper);
            // ignore (for now) other info in record
        }
示例#8
0
        public static void Main(string[] args)

        {
            string inFile  = "LEXICON";
            string outFile = "inflVars.data";

            if (args.Length == 2)

            {
                inFile  = args[0];
                outFile = args[1];
            }
            else if (args.Length > 0)

            {
                Console.WriteLine("** Usage: java GenerateInflVars <inFile> <outFile>");
                Environment.Exit(0);
            }

            Console.WriteLine("-- inFile: [" + inFile + "]");
            Console.WriteLine("-- outFile: [" + outFile + "]");


            try

            {
                List <InflVar> inflVars          = ToInflVarsApi.GetInflVarsFromTextFile(inFile);
                InflVarComparator <InflVar> comp = new InflVarComparator();
                inflVars.Sort(comp);

                System.IO.StreamWriter outWriter = Files.newBufferedWriter(Paths.get(outFile, new string[0]),
                                                                           Charset.forName("UTF-8"), new OpenOption[0]);


                for (int i = 0; i < inflVars.Count; i++)

                {
                    InflVar inflVar = (InflVar)inflVars[i];
                    if (inflVar.GetUnique() == true)

                    {
                        string outStr = inflVar.GetVar() + "|" + Category.ToValue(inflVar.GetCat()) + "|" +
                                        Inflection.ToValue(inflVar.GetInflection()) + "|" + inflVar.GetEui() + "|" +
                                        inflVar.GetUnInfl() + "|" + inflVar.GetCit();
                        outWriter.Write(outStr);
                        outWriter.WriteLine();
                    }
                }

                outWriter.Close();
            }
            catch (Exception x)

            {
                Console.WriteLine("** ERR@GenerateInflVars( ): " + x.ToString());
            }
        }
示例#9
0
        /**
         * creates a duplicate WordElement from an existing WordElement
         *
         * @param currentWord
         *            - An existing WordElement
         */

        public WordElement(WordElement currentWord)
        {
            baseForm = currentWord.getBaseForm();
            setCategory(currentWord.getCategory());
            id          = currentWord.getId();
            inflVars    = currentWord.getInflectionalVariants();
            defaultInfl = (Inflection)currentWord.getDefaultInflectionalVariant();
            setFeatures(currentWord);
        }
示例#10
0
 /**
  * Add an inflectional variant to this word element. This method is intended
  * for use by a <code>Lexicon</code>. The idea is that words which have more
  * than one inflectional variant (for example, a regular and an irregular
  * form of the past tense), can have a default variant (for example, the
  * regular), but also store information about the other variants. This comes
  * in useful in case the default inflectional variant is reset to a new one.
  * In that case, the stored forms for the new variant are used to inflect
  * the word.
  *
  * <P>
  * <strong>An example:</strong> The verb <i>lie</i> has both a regular form
  * (<I>lies, lied, lying</I>) and an irregular form (<I>lay, lain,</I> etc).
  * Assume that the <code>Lexicon</code> provides this information and treats
  * this as variant information of the same word (as does the
  * <code>NIHDBLexicon</code>, for example). Typically, the default
  * inflectional variant is the <code>Inflection.REGULAR</code>. This means
  * that morphology proceeds to inflect the verb as <I>lies, lying</I> and so
  * on. If the default inflectional variant is reset to
  * <code>Inflection.IRREGULAR</code>, the stored irregular forms will be
  * used instead.
  *
  * @param infl
  *            the Inflection pattern with which this form is associated
  * @param lexicalFeature
  *            the actual inflectional feature being set, for example
  *            <code>LexicalFeature.PRESENT_3S</code>
  * @param form
  *            the actual inflected word form
  */
 public virtual void addInflectionalVariant(Inflection infl, string lexicalFeature, string form)
 {
     if (inflVars.ContainsKey(infl))
     {
         inflVars[infl].addForm(lexicalFeature, form);
     }
     else
     {
         InflectionSet set = new InflectionSet(this, infl);
         set.addForm(lexicalFeature, form);
         inflVars[infl] = set;
     }
 }
示例#11
0
        /**
         * Add an inflectional variant to this word element. This method is intended
         * for use by a <code>Lexicon</code>. The idea is that words which have more
         * than one inflectional variant (for example, a regular and an irregular
         * form of the past tense), can have a default variant (for example, the
         * regular), but also store information about the other variants. This comes
         * in useful in case the default inflectional variant is reset to a new one.
         * In that case, the stored forms for the new variant are used to inflect
         * the word.
         *
         * <P>
         * <strong>An example:</strong> The verb <i>lie</i> has both a regular form
         * (<I>lies, lied, lying</I>) and an irregular form (<I>lay, lain,</I> etc).
         * Assume that the <code>Lexicon</code> provides this information and treats
         * this as variant information of the same word (as does the
         * <code>NIHDBLexicon</code>, for example). Typically, the default
         * inflectional variant is the <code>Inflection.REGULAR</code>. This means
         * that morphology proceeds to inflect the verb as <I>lies, lying</I> and so
         * on. If the default inflectional variant is reset to
         * <code>Inflection.IRREGULAR</code>, the stored irregular forms will be
         * used instead.
         *
         * @param infl
         *            the Inflection pattern with which this form is associated
         * @param lexicalFeature
         *            the actual inflectional feature being set, for example
         *            <code>LexicalFeature.PRESENT_3S</code>
         * @param form
         *            the actual inflected word form
         */

        public void addInflectionalVariant(Inflection infl, string lexicalFeature,
                                           string form)
        {
            if (inflVars.containsKey(infl))
            {
                inflVars[infl].addForm(lexicalFeature, form);
            }
            else
            {
                var set = new InflectionSet(infl);
                set.addForm(lexicalFeature, form);
                inflVars.put(infl, set);
            }
        }
示例#12
0
    private Noun GetCommonNoun(string[] text)
    {
        var noun = (CommonNoun)Noun.Find(text);

        if (noun != null)
        {
            var singular = noun.SingularForm.SameAs(text);
            if (singular && Number == Syntax.Number.Plural && !noun.SingularForm.SameAs(noun.PluralForm))
            {
                throw new GrammaticalError($"The singular noun '{Text.Untokenize()}' was used without 'a' or 'an' before it",
                                           $"The singular noun '<i>{Text.Untokenize()}</i>' was used without 'a' or 'an' before it");
            }
            if (!singular && Number == Syntax.Number.Singular)
            {
                throw new GrammaticalError($"The plural noun '{Text.Untokenize()}' was used with 'a' or 'an'",
                                           $"The plural noun '<i>{Text.Untokenize()}</i>' was used with 'a' or 'an' before it");
            }
            return(noun);
        }

        noun = new CommonNoun();

        if (!Number.HasValue)
        {
            // Don't know syntactically if it's supposed to be singular or plural, so guess.
            Number = Inflection.NounAppearsPlural(text)
                ? Syntax.Number.Plural
                : Syntax.Number.Singular;
        }
        if (Number == Syntax.Number.Singular)
        {
            noun.SingularForm = text;
        }
        else
        {
            // Note: this guarantees there is a singular form.
            noun.PluralForm = text;
        }

        Driver.AppendResponseLine($"Learned the new common noun <b><i>{noun.SingularForm.Untokenize()}</i></b>.");

        MaybeLoadDefinitions(noun);

        return(noun);
    }
示例#13
0
            public bool TryTransform(Inflection inflection, out DeinflectedString newValue)
            {
                // Note: Using culture-sensitive string comparisons for this is horribly slow.
                if (Text.EndsWith(inflection.From, StringComparison.Ordinal) && (TypeMask & inflection.TypeMask) != 0)
                {
                    newValue = new DeinflectedString()
                    {
                        Text     = Text.Substring(0, Text.Length - inflection.From.Length) + inflection.To,
                        TypeMask = inflection.TypeMask >> 8
                    };
                    newValue.Inflections.AddRange(Inflections);
                    newValue.Inflections.Add(inflection);
                    return(true);
                }

                newValue = null;
                return(false);
            }
示例#14
0
        /**
         * Set the default inflectional variant of a word. This is mostly relevant
         * if the word has more than one possible inflectional variant (for example,
         * it can be inflected in both a regular and irregular way).
         *
         * <P>
         * If the default inflectional variant is set, the inflectional forms of the
         * word may change as a result. This depends on whether inflectional forms
         * have been specifically associated with this variant, via
         * {@link #addInflectionalVariant(Inflection, String, String)}.
         *
         * <P>
         * The <code>NIHDBLexicon</code> associates different inflectional variants
         * with words, if they are so specified, and adds the correct forms.
         *
         * @param variant
         *            The variant
         */
        public virtual void setDefaultInflectionalVariant(Inflection variant)
        {
            setFeature(LexicalFeature.DEFAULT_INFL, variant);
            defaultInfl = variant;

            if (inflVars.ContainsKey(variant))
            {
                InflectionSet set   = inflVars[variant];
                string[]      forms = LexicalFeature.getInflectionalFeatures(Category);

                if (forms != null)
                {
                    foreach (string f in forms)
                    {
                        setFeature(f, set.getForm(f));
                    }
                }
            }
        }
示例#15
0
        /**
         * Set the default inflectional variant of a word. This is mostly relevant
         * if the word has more than one possible inflectional variant (for example,
         * it can be inflected in both a regular and irregular way).
         *
         * <P>
         * If the default inflectional variant is set, the inflectional forms of the
         * word may change as a result. This depends on whether inflectional forms
         * have been specifically associated with this variant, via
         * {@link #addInflectionalVariant(Inflection, string, string)}.
         *
         * <P>
         * The <code>NIHDBLexicon</code> associates different inflectional variants
         * with words, if they are so specified, and adds the correct forms.
         *
         * @param variant
         *            The variant
         */

        public void setDefaultInflectionalVariant(Inflection variant)
        {
            if (getFeature(LexicalFeature.DEFAULT_INFL) != null)
            {
                removeFeature(LexicalFeature.DEFAULT_INFL);
            }
            setFeature(LexicalFeature.DEFAULT_INFL, variant);
            defaultInfl = variant;

            if (inflVars.containsKey(variant))
            {
                var set   = inflVars[variant];
                var forms = LexicalFeature.getInflectionalFeatures(getCategory());

                if (forms != null)
                {
                    foreach (var f in forms)
                    {
                        setFeature(f, set.getForm(f));
                    }
                }
            }
        }
示例#16
0
 internal InflectionSet(WordElement outerInstance, Inflection infl)
 {
     this.outerInstance = outerInstance;
     this.infl          = infl;
     forms = new Dictionary <string, string>();
 }
示例#17
0
        public static void Main(string[] args)

        {
            if ((args.Length == 0) || (args.Length > 2))

            {
                Console.Error.WriteLine("** Usage: java ToJavaObjectFromXmlFile <inFile(Xml)> <-i>");
                Console.Error.WriteLine("");
                Console.Error.WriteLine("Options:");
                Console.Error.WriteLine("  -i: generate inflection vars");
                Environment.Exit(1);
            }

            bool inflVarFlag = false;

            for (int i = 0; i < args.Length; i++)

            {
                if (args[i].Equals("-i"))

                {
                    inflVarFlag = true;
                    break;
                }
            }

            try

            {
                List <LexRecord> lexRecords = ToJavaObjApi.ToJavaObjsFromXmlFile(args[0]);
                if (lexRecords.Count <= 0)

                {
                    Environment.Exit(1);
                }
                else

                {
                    for (int i = 0; i < lexRecords.Count; i++)

                    {
                        LexRecord lexRecord = (LexRecord)lexRecords[i];
                        Console.Write(lexRecord.GetText());
                        if (inflVarFlag == true)

                        {
                            Console.WriteLine("---------- Inflection Vars ----------");

                            List <InflVar> inflVars = lexRecord.GetInflVarsAndAgreements().GetInflValues();
                            for (int j = 0; j < inflVars.Count; j++)

                            {
                                InflVar inflVar = (InflVar)inflVars[j];
                                Console.WriteLine(inflVar.GetVar() + "|" + Category.ToValue(inflVar.GetCat()) + "|" +
                                                  Inflection.ToValue(inflVar.GetInflection()) + "|" + inflVar.GetEui() +
                                                  "|" + inflVar.GetUnInfl() + "|" + inflVar.GetCit());
                            }
                        }
                    }
                }
            }
            catch (Exception e)

            {
                Console.WriteLine(e.ToString());
                Console.Write(e.StackTrace);
            }
        }
示例#18
0
        /**
         * make a WordElement from a lexical record. Currently just specifies basic
         * params and inflections Should do more in the future!
         *
         * @param record
         * @return
         */

        private WordElement makeWord(LexRecord record)
        {
            // get basic data
            string           baseForm = record.GetBase();
            ILexicalCategory category = getSimplenlgCategory(record);
            string           id       = record.GetEui();

            // create word class
            var wordElement = new WordElement(baseForm, (LexicalCategory)category, id);

            // now add type information
            switch (category.lexType)
            {
            case LexicalCategoryEnum.ADJECTIVE:
                addAdjectiveInfo(wordElement, record.GetCatEntry().GetAdjEntry());
                break;

            case LexicalCategoryEnum.ADVERB:
                addAdverbInfo(wordElement, record.GetCatEntry().GetAdvEntry());
                break;

            case LexicalCategoryEnum.NOUN:
                addNounInfo(wordElement, record.GetCatEntry().GetNounEntry());
                break;

            case LexicalCategoryEnum.VERB:
                addVerbInfo(wordElement, record.GetCatEntry().GetVerbEntry());
                break;
                // ignore closed class words
            }

            var defaultInfl = (Inflection)wordElement
                              .getDefaultInflectionalVariant();

            // now add inflected forms
            // if (keepStandardInflections || !standardInflections(record,
            // category)) {
            foreach (InflVar inflection in record.GetInflVarsAndAgreements()
                     .GetInflValues())
            {
                string simplenlgInflection = getSimplenlgInflection(inflection
                                                                    .GetInflection());

                if (simplenlgInflection != null)
                {
                    string     inflectedForm = inflection.GetVar();
                    Inflection inflType      = Inflection.getInflCode(inflection
                                                                      .GetType());

                    // store all inflectional variants, except for regular ones
                    // unless explicitly set
                    if (inflType != null &&
                        !(Inflection.REGULAR.Equals(inflType) && !this.keepStandardInflections))
                    {
                        wordElement.addInflectionalVariant(inflType,
                                                           simplenlgInflection, inflectedForm);
                    }

                    // if the infl variant is the default, also set this feature on
                    // the word
                    if (defaultInfl == null ||
                        (defaultInfl.Equals(inflType) && !(Inflection.REGULAR
                                                           .Equals(inflType) && !this.keepStandardInflections)))
                    {
                        wordElement.setFeature(simplenlgInflection, inflectedForm);
                    }

                    // wordElement
                    // .setFeature(simplenlgInflection, inflection.GetVar());
                }
            }
            // }

            // add acronym info
            addAcronymInfo(wordElement, record);

            // now add spelling variants
            addSpellingVariants(wordElement, record);

            return(wordElement);
        }
示例#19
0
 public InflectionSet(Inflection infl)
 {
     this.infl = infl;
 }
示例#20
0
 private static bool VerbGerundForm(VerbSegment s)
 {
     s.Conjugation = VerbConjugation.Gerund;
     return(Inflection.IsGerund(s.Text));
 }
示例#21
0
        /**
         * Check whether this word has a particular inflectional variant
         *
         * @param infl
         *            the variant
         * @return <code>true</code> if this word has the variant
         */

        public bool hasInflectionalVariant(Inflection infl)
        {
            return(inflVars.containsKey(infl));
        }
示例#22
0
        /**
         * extract verb information from NIH VerbEntry record, and add to a
         * simplenlg WordElement For now just extract transitive, instransitive,
         * and/or ditransitive
         *
         * @param wordElement
         * @param verbEntry
         */

        private void addVerbInfo(WordElement wordElement, VerbEntry verbEntry)
        {
            if (verbEntry == null)
            {
                // should only happen for aux verbs, which have
                // auxEntry instead of verbEntry in NIH Lex
                // just flag as transitive and return
                wordElement.setFeature(LexicalFeature.INTRANSITIVE, false);
                wordElement.setFeature(LexicalFeature.TRANSITIVE, true);
                wordElement.setFeature(LexicalFeature.DITRANSITIVE, false);
                return;
            }

            bool intransitiveVerb = notEmpty(verbEntry.GetIntran());
            bool transitiveVerb   = notEmpty(verbEntry.GetTran()) ||
                                    notEmpty(verbEntry.GetCplxtran());
            bool ditransitiveVerb = notEmpty(verbEntry.GetDitran());

            wordElement.setFeature(LexicalFeature.INTRANSITIVE, intransitiveVerb);
            wordElement.setFeature(LexicalFeature.TRANSITIVE, transitiveVerb);
            wordElement.setFeature(LexicalFeature.DITRANSITIVE, ditransitiveVerb);

            // add the inflectional variants
            List <string> variants = verbEntry.GetVariants();

            if (!variants.isEmpty())
            {
                var wordVariants = new List <Inflection>();

                foreach (var v in variants)
                {
                    int        index = v.indexOf("|");
                    string     code;
                    Inflection infl;

                    if (index > -1)
                    {
                        code = v.substring(0, index).toLowerCase().trim();
                        infl = Inflection.getInflCode(code);
                    }
                    else
                    {
                        infl = Inflection.getInflCode(v.toLowerCase().trim());
                    }

                    if (infl != null)
                    {
                        wordElement.addInflectionalVariant(infl);
                        wordVariants.add(infl);
                    }
                }

                // if the variants include "reg", this is the default, otherwise
                // just a random pick
                Inflection defaultVariant = wordVariants
                                            .contains(Inflection.REGULAR) ||
                                            wordVariants.isEmpty()
                    ? Inflection.REGULAR
                    : wordVariants.get(0);
//			wordElement.setFeature(LexicalFeature.INFLECTIONS, wordVariants);
//			wordElement.setFeature(LexicalFeature.DEFAULT_INFL, defaultVariant);
                wordElement.setDefaultInflectionalVariant(defaultVariant);
            }

            // ignore (for now) other info in record
            return;
        }
示例#23
0
        /**
         * Specify that this word has an inflectional variant (e.g. irregular)
         *
         * @param infl
         *            the variant
         */

        public void addInflectionalVariant(Inflection infl)
        {
            inflVars.put(infl, new InflectionSet(infl));
        }
示例#24
0
 /**
  * Check whether this word has a particular inflectional variant
  *
  * @param infl
  *            the variant
  * @return <code>true</code> if this word has the variant
  */
 public virtual bool hasInflectionalVariant(Inflection infl)
 {
     return(inflVars.ContainsKey(infl));
 }
示例#25
0
        /**
         * create a simplenlg WordElement from a Word node in a lexicon XML file
         *
         * @param wordNode
         * @return
         * @throws XPathUtilException
         */
        private WordElement convertNodeToWord(XmlNode wordNode)
        {
            // if this isn't a Word node, ignore it
            if (!wordNode.Name.Equals(XML_WORD, StringComparison.CurrentCultureIgnoreCase))
            {
                return(null);
            }

            // if there is no base, flag an error and return null
            // String base = XPathUtil.extractValue(wordNode, Constants.XML_BASE);
            // if (base == null) {
            // System.out.println("Error in loading XML lexicon: Word with no base");
            // return null;
            // }

            // create word
            WordElement        word        = new WordElement();
            IList <Inflection> inflections = new List <Inflection>();

            // now copy features
            XmlNodeList nodes = wordNode.ChildNodes;

            for (int i = 0; i < nodes.Count; i++)
            {
                XmlNode featureNode = nodes.Item(i);

                if (featureNode.NodeType == XmlNodeType.Element)
                {
                    string feature = featureNode.Name.Trim();
                    string value   = featureNode.InnerText;

                    if (!ReferenceEquals(value, null))
                    {
                        value = value.Trim();
                    }

                    if (ReferenceEquals(feature, null))
                    {
                        Console.Error.WriteLine("Error in XML lexicon node for " + word.ToString());
                        break;
                    }

                    if (feature.Equals(XML_BASE, StringComparison.OrdinalIgnoreCase))
                    {
                        word.BaseForm = value;
                    }
                    else if (feature.Equals(XML_CATEGORY, StringComparison.OrdinalIgnoreCase))
                    {
                        Enum.TryParse(value.ToUpper(), out LexicalCategory.LexicalCategoryEnum lexcat);
                        word.Category = new LexicalCategory(lexcat);
                    }
                    else if (feature.Equals(XML_ID, StringComparison.OrdinalIgnoreCase))
                    {
                        word.Id = value;
                    }

                    else if (ReferenceEquals(value, null) || value.Equals(""))
                    {
                        // if this is an infl code, add it to inflections
                        Inflection?infl = Inflection.REGULAR.getInflCode(feature);

                        if (infl != null)
                        {
                            inflections.Add((Inflection)infl);
                        }
                        else
                        {
                            // otherwise assume it's a boolean feature
                            word.setFeature(feature, true);
                        }
                    }
                    else
                    {
                        word.setFeature(feature, value);
                    }
                }
            }

            // if no infl specified, assume regular
            if (inflections.Count == 0)
            {
                inflections.Add(Inflection.REGULAR);
            }

            // default inflection code is "reg" if we have it, else random pick form infl codes available
            Inflection defaultInfl = inflections.Contains(Inflection.REGULAR) ? Inflection.REGULAR : inflections[0];

            word.setFeature(LexicalFeature.DEFAULT_INFL, defaultInfl);
            word.setDefaultInflectionalVariant(defaultInfl);

            foreach (Inflection infl in inflections)
            {
                word.addInflectionalVariant(infl);
            }

            // done, return word
            return(word);
        }
示例#26
0
        /// <summary>
        /// Add the built-in primitives to the global module.
        /// </summary>
        internal static void DefineGlobals()
        {
            var g = Module.Global;

            Documentation.SectionIntroduction("comparison",
                                              "Predicates that test whether two values are the same or different.  Many of these use unification, in which case they are testing whether the values can be made identical through binding variables.");

            g["="] = new GeneralPrimitive("=", (args, o, e, predecessor, k) =>
            {
                ArgumentCountException.Check("=", 2, args);
                return(e.Unify(args[0], args[1], e.Unifications, out var newBindings) &&
                       k(o, newBindings, e.State, predecessor));
            }).Arguments("a", "b")
                     .Documentation("comparison", "Matches (unifies) a and b, and succeeds when they're the same.");

            g["Different"] = new SimplePredicate <object, object>("Different",
                                                                  (a, b) => !a.Equals(b) && !(a is LogicVariable) && !(b is LogicVariable))
                             .Arguments("a", "b")
                             .Documentation("comparison", "Attempts to match a and b and succeeds if they *can't* be matched");

            g[">"] = new SimplePredicate <float, float>(">", (a, b) => a > b)
                     .Arguments("a", "b")
                     .Documentation("comparison", "True when a and b are both numbers and a is larger");
            g["<"] = new SimplePredicate <float, float>("<", (a, b) => a < b)
                     .Arguments("a", "b")
                     .Documentation("comparison", "True when a and b are both numbers and a is smaller");
            g[">="] = new SimplePredicate <float, float>(">=", (a, b) => a >= b)
                      .Arguments("a", "b")
                      .Documentation("comparison", "True when a and b are both numbers and a is at least as large as b");
            g["<="] = new SimplePredicate <float, float>("<=", (a, b) => a <= b)
                      .Arguments("a", "b")
                      .Documentation("comparison", "True when a and b are both numbers and a is no larger than b");

            Documentation.SectionIntroduction("output",
                                              "Tasks that print things.");

            g["Paragraph"] = new DeterministicTextGenerator("Paragraph",
                                                            () => new[] { TextUtilities.NewParagraphToken })
                             .Arguments()
                             .Documentation("output", "Starts a new paragraph");
            g["NewLine"] = new DeterministicTextGenerator("NewLine",
                                                          () => new[] { TextUtilities.NewLineToken })
                           .Arguments()
                           .Documentation("output", "Starts a new line");
            g["FreshLine"] = new DeterministicTextGenerator("FreshLine",
                                                            () => new[] { TextUtilities.FreshLineToken })
                             .Arguments()
                             .Documentation("output", "Starts a new line, unless we're already at the start of a new line");
            g["ForceSpace"] = new DeterministicTextGenerator("ForceSpace",
                                                             () => new[] { TextUtilities.ForceSpaceToken })
                              .Arguments()
                              .Documentation("output", "Forces a space to be inserted between two tokens that wouldn't normally be separated.  For example, \"a .\" prints as \"a.\" but \"a [ForceSpace] .\" prints as \"a .\"");

            Documentation.SectionIntroduction("control flow//controlling backtracking",
                                              "Tasks that control how or whether execution backtracks.");

            g["Fail"] = new SimplePredicate("Fail", () => false)
                        .Arguments()
                        .Documentation("control flow//controlling backtracking", "Never succeeds; forces the system to backtrack immediately.");

            Documentation.SectionIntroduction("debugging",
                                              "Tasks used to help debug code.");

            g["Break"] = new SimplePredicate("Break", Break)
                         .Arguments()
                         .Documentation("debugging", "Breakpoint; pauses execution and displays the current stack in the debugger.");

            g["Throw"] = new SimpleNAryPredicate("Throw", Throw)
                         .Arguments("message", "...")
                         .Documentation("control flow", "Throws an exception (error) containing the specified message.");

            g["StringForm"] =
                new GeneralPredicate <object, string>("StringForm",
                                                      (o, s) => o.ToString() == s,
                                                      o => new [] { o.ToString() },
                                                      null, null)
                .Arguments("object", "?string_form")
                .Documentation("output", "Matches ?string_form with the printed representation of object");

            g["WriteVerbatim"] = new DeterministicTextMatcher("WriteVerbatim", (o =>
            {
                switch (o)
                {
                case null:
                    return(new[] { "null" });

                case string[] tokens:
                    return(tokens);

                default:
                    return(new[] { Writer.TermToString(o) });
                }
            }))
                                 .Arguments("object")
                                 .Documentation("output", "Prints object; _'s are printed as themselves rather than changed to spaces,");

            WritePrimitive = new DeterministicTextMatcher("Write", (o =>
            {
                switch (o)
                {
                case null:
                    return(new[] { "null" });

                case string[] tokens:
                    return(tokens.Length == 0? tokens : tokens.Skip(1).Prepend(tokens[0].Capitalize()).ToArray());

                default:
                    return(new[] { Writer.TermToString(o).Replace('_', ' ') });
                }
            }));

            g["Write"] = WritePrimitive
                         .Arguments("object")
                         .Documentation("output", "Prints object, transforming _'s to spaces");

            g["WriteCapitalized"] = new DeterministicTextMatcher("WriteCapitalized", (o =>
            {
                switch (o)
                {
                case null:
                    return(new[] { "null" });

                case string[] tokens:
                    return(tokens.Length == 0 ? tokens : tokens.Skip(1).Prepend(tokens[0].Capitalize()).ToArray());

                default:
                    return(new[] { Writer.TermToString(o).Replace('_', ' ').Capitalize() });
                }
            }))
                                    .Arguments("object")
                                    .Documentation("output", "Prints object, transforming _'s to spaces.  If the first character of the output is a lower-case letter, it will capitalize it.");

            g["WriteConcatenated"] = new DeterministicTextGenerator <object, object>("WriteConcatenated",
                                                                                     (s1, s2) => { return(new[] { $"{Writer.TermToString(s1).Replace('_', ' ')}{Writer.TermToString(s2).Replace('_', ' ')}" }); })
                                     .Arguments("object1", "object2")
                                     .Documentation("output", "Prints both objects, without a space between them, and changes and _'s to spaces.");

            Documentation.SectionIntroduction("data structures",
                                              "Predicates that create or access complex data objects.  Note that dictionaries and lists can also be used as predicates.  So [dictionary ?key ?value] is true when ?key has ?value in the dictinoary and and [list ?element] is true when ?element is an element of the list.");

            Documentation.SectionIntroduction("data structures//lists",
                                              "Predicates access lists in particular.  These work with any C# object that implements the IList interface, including Step tuples (which are the C# type object[]).");

            g["Member"] = new GeneralPredicate <object, IEnumerable <object> >("Member", (member, collection) => collection != null && collection.Contains(member), null, collection => collection ?? EmptyArray, null)
                          .Arguments("element", "collection")
                          .Documentation("data structures//lists", "True when element is an element of collection.");

            g["Length"] = new SimpleFunction <IList, int>("Length", l => l.Count)
                          .Arguments("list", "?length")
                          .Documentation("data structures//list", "True when list has exactly ?length elements");

            g["Nth"] = new GeneralNAryPredicate("Nth",
                                                args =>
            {
                ArgumentCountException.Check("Nth", 3, args);
                var list       = ArgumentTypeException.Cast <IList>("Nth", args[0], args);
                var indexVar   = args[1] as LogicVariable;
                var elementVar = args[2] as LogicVariable;

                if (indexVar == null)
                {
                    var index = ArgumentTypeException.Cast <int>("Nth", args[1], args);
                    return(new[] { new[] { list, index, list[index] } });
                }
                else if (elementVar == null)
                {
                    var elt   = args[2];
                    var index = list.IndexOf(elt);
                    if (index >= 0)
                    {
                        return new[] { new[] { list, index, args[2] } }
                    }
                    ;
                    else
                    {
                        return(new object[0][]);
                    }
                }

                throw new ArgumentInstantiationException("Nth", new BindingEnvironment(), args);
            })
                       .Arguments("list", "index", "?element")
                       .Documentation("data structures//list", "True when element of list at index is ?element");

            g["Cons"] = new GeneralNAryPredicate("Cons", args =>
            {
                ArgumentCountException.Check("Cons", 3, args);
                if (args[2] is object[] tuple)
                {
                    return new[] { new[] { tuple[0], tuple.Skip(1).ToArray(), tuple } }
                }
                ;
                if (args[1] is object[] restTuple)
                {
                    return new[] { new[] { args[0], restTuple, restTuple.Prepend(args[0]).ToArray() } }
                }
                ;
                throw new ArgumentException("Either the second or argument of Cons must be a tuple.");
            })
                        .Arguments("firstElement", "restElements", "tuple")
                        .Documentation("True when tuple starts with firstElement and continues with restElements.");

            Documentation.SectionIntroduction("metalogical",
                                              "Predicates that test the binding state of a variable.");

            g["Var"] = new SimplePredicate <object>("Var", o => o is LogicVariable)
                       .Arguments("x")
                       .Documentation("metalogical", "Succeeds when its argument is an uninstantiated variable (a variable without a value)");
            g["NonVar"] = new SimplePredicate <object>("NonVar", o => !(o is LogicVariable))
                          .Arguments("x")
                          .Documentation("metalogical", "Succeeds when its argument is a *not* an uninstantiated variable.");

            g["CopyTerm"] = new GeneralPrimitive("CopyTerm",
                                                 (args, t, b, f, k) =>
            {
                ArgumentCountException.Check("CopyTerm", 2, args);
                return(b.Unify(args[1], b.CopyTerm(args[0]), out var u) && k(t, u, b.State, f));
            })
                            .Arguments("in", "out")
                            .Documentation("metalogical",
                                           "Sets out to a copy of in with fresh variables, so that unifications to one don't affect the other");

            Documentation.SectionIntroduction("type testing",
                                              "Predicates that test what type of data object their argument is.  These fail when the argument is an unbound variable.");

            g["String"] = new SimplePredicate <object>("String", o => o is string)
                          .Arguments("x")
                          .Documentation("type testing", "Succeeds when its argument is a string");
            g["Number"] = new SimplePredicate <object>("Number", o => o is int || o is float || o is double)
                          .Arguments("x")
                          .Documentation("type testing", "Succeeds when its argument is a number");
            g["Tuple"] = new SimplePredicate <object>("Tuple", o => o is object[])
                         .Arguments("x")
                         .Documentation("type testing", "Succeeds when its argument is a tuple");
            g["BinaryTask"] = new SimplePredicate <object>("BinaryTask",
                                                           o => (o is Task c && c.ArgumentCount == 2))
                              .Arguments("x")
                              .Documentation("type testing", "Succeeds when its argument is 2-argument task");
            g["Empty"] = Cons.Empty;

            g["CountAttempts"] = new GeneralPrimitive("CountAttempts", (args, o, bindings, p, k) =>
            {
                ArgumentCountException.Check("CountAttempts", 1, args);
                ArgumentInstantiationException.Check("CountAttempts", args[0], false, bindings, args);
                int count = 0;
                while (true)
                {
                    if (k(o,
                          BindingList <LogicVariable> .Bind(bindings.Unifications, (LogicVariable)args[0], count++),
                          bindings.State,
                          p))
                    {
                        return(true);
                    }
                }
                // ReSharper disable once FunctionNeverReturns
            }).Arguments("?count")
                                 .Documentation("control flow", "Binds ?count to 0, then to increasing numbers each time the system backtracks to the call.  Used in a loop to run something repeatedly: [CountAttempts ?count] [DoSomething] [= ?count 100] will run DoSomething until ?count is 100.");

            Documentation.SectionIntroduction("randomization",
                                              "Tasks that choose random numbers or list elements.");

            g["RandomIntegerInclusive"] = new SimpleFunction <int, int, int>("RandomIntegerInclusive", Randomization.IntegerInclusive)
                                          .Arguments("min", "max", "?random")
                                          .Documentation("randomization", "Sets ?random to a random integer such that min <= ?random <= max");

            g["RandomIntegerExclusive"] = new SimpleFunction <int, int, int>("RandomIntegerExclusive", Randomization.IntegerExclusive)
                                          .Arguments("min", "max", "?random")
                                          .Documentation("randomization", "Sets ?random to a random integer such that min <= ?random < max");

            g["RandomElement"] = new GeneralPredicate <IList, object>(
                "RandomElement",
                (list, elt) => list.Contains(elt),
                list => list.BadShuffle().Cast <object>(),
                null,
                null)
                                 .Arguments("list", "?element")
                                 .Documentation("randomization", "Sets ?element to a random element of list.  If this is backtracked, it generates a random shuffle of the elements of this list.  However, not all shuffles are possible; it starts with a random element and moves to subsequent elements with a random step size.");

            Documentation.SectionIntroduction("string processing",
                                              "Predicates that test the spelling of strings.");

            g["Format"] = new SimpleFunction <string, object[], string>("Format", string.Format)
                          .Arguments("format_string, argument_list, ?formatted_string")
                          .Documentation("string processing",
                                         "True when formatted_string is the result of formatting format_string with the arguments.  This is just a wrapper for .NET's string.Format routine.");

            g["Downcase"] = new SimpleFunction <string, string>("DownCase", from =>
            {
                var b = new StringBuilder();
                foreach (var c in from)
                {
                    b.Append(char.ToLower(c));
                }
                return(b.ToString());
            })
                            .Arguments("string, ?downcased")
                            .Documentation("string processing",
                                           "True when downcased is the string with all alphabetic characters converted to lowercase.");

            g["Downcased"] = new SimpleFunction <string, string>("Downcased", from =>
            {
                var b = new StringBuilder();
                foreach (var c in from)
                {
                    b.Append(char.ToLower(c));
                }
                return(b.ToString());
            })
                             .Arguments("string, ?downcased")
                             .Documentation("string processing",
                                            "True when downcased is the string with all alphabetic characters converted to lowercase.");

            g["Upcased"] = new SimpleFunction <string, string>("Upcased", from =>
            {
                var b = new StringBuilder();
                foreach (var c in from)
                {
                    b.Append(char.ToUpper(c));
                }
                return(b.ToString());
            })
                           .Arguments("string, ?upcased")
                           .Documentation("string processing",
                                          "True when upcased is the string with all alphabetic characters converted to uppercase.");

            g["Capitalized"] = new SimpleFunction <string, string>("Downcase", from =>
            {
                var b           = new StringBuilder();
                var startOfWord = true;
                foreach (var c in from)
                {
                    b.Append(startOfWord ? char.ToUpper(c) : c);
                    startOfWord = c == ' ' || c == '_';
                }
                return(b.ToString());
            })
                               .Arguments("string, ?capitalized")
                               .Documentation("string processing",
                                              "True when capitalized is the a copy of string, which the start of each word capitalized.");


            g["StartsWithVowel"] = new SimplePredicate <object>("StartsWithVowel",
                                                                x =>
            {
                switch (x)
                {
                case string s:
                    return(StartsWithVowel(s));

                case string[] tokens:
                    return(tokens.Length > 0 && StartsWithVowel(tokens[0]));

                default:
                    return(false);
                }
            })
                                   .Arguments("string")
                                   .Documentation("string processing", "True if the string starts with a vowel.");

            g["NounSingularPlural"] =
                new GeneralPredicate <string, string>("NounSingularPlural", (s, p) => Inflection.PluralOfNoun(s) == p, s => new[] { Inflection.PluralOfNoun(s) }, p => new[] { Inflection.SingularOfNoun(p) }, null)
                .Arguments("?singular", "?plural")
                .Documentation("string processing", "True if ?plural is the English plural form of ?singular");

            Documentation.SectionIntroduction("StepRepl",
                                              "Tasks that control the behavior of StepRepl or whatever other game engine the Step code is running inside of.");

            g["EnvironmentOption"] = new SimpleNAryPredicate("EnvironmentOption",
                                                             arglist =>
            {
                ArgumentCountException.CheckAtLeast("EnvironmentOption", 1, arglist);
                var optionName = ArgumentTypeException.Cast <string>("EnvironmentOption", arglist[0], arglist);
                EnvironmentOption.Handle(optionName, arglist.Skip(1).ToArray());
                return(true);
            })
                                     .Arguments("argument", "...")
                                     .Documentation("StepRepl", "Asks StepRepl or whatever other program this Step code is running in to change its handling of step code.");

            g["Hashtable"] = new SimpleNAryFunction(
                "Hashtable",
                data =>
            {
                if ((data.Length % 2) != 0)
                {
                    throw new ArgumentException(
                        "Hashtable requires an odd number of arguments, one for the output and an equal number of keys and values");
                }
                var h = new Hashtable();
                for (var i = 0; i < data.Length; i += 2)
                {
                    h[data[i]] = data[i + 1];
                }
                return(h);
            })
                             .Arguments("?h")
                             .Documentation("data structures", "Creates a new empty hash table and stores it in ?h");

            g["Contains"] =
                new SimplePredicate <string, string>("Contains", (super, sub) => super.Contains(sub))
                .Arguments("string", "substring")
                .Documentation("string processing", "True if substring is a substring of string");

            HigherOrderBuiltins.DefineGlobals();
            ReflectionBuiltins.DefineGlobals();
            Documentation.DefineGlobals(Module.Global);
        }
示例#27
0
 /**
  * Specify that this word has an inflectional variant (e.g. irregular)
  *
  * @param infl
  *            the variant
  */
 public virtual void addInflectionalVariant(Inflection infl)
 {
     inflVars[infl] = new InflectionSet(this, infl);
 }