public static void CheckForPronoun(ArabicWord WordToProcess, ref List <WordInfo> Possibilities)
        {
            WordInfo NewInfo;

            HaifaDeafEntities km = new HaifaDeafEntities();
            var wproc            = from k in km.ProperNouns where k.Word == WordToProcess.word select k;

            foreach (var c in wproc)
            {
                NewInfo              = new WordInfo();
                NewInfo.Meaning      = c.Meaning;
                NewInfo.SpecialClass = "PN";
                NewInfo.Word         = WordToProcess.word;
                NewInfo.Diacritics   = c.Diacritics;
                Possibilities.Add(NewInfo);
            }
        }
        public static int StartInterpreting(ref GrammarRelation Relation, int StartIndex, string ExpectedMeaning, byte MaximumRecursion, bool RecursiveCall)
        {
            int  Offset    = 0;
            bool ValidRule = true;

            foreach (string[] Rule in GrammarRelation.GrammarRules)
            {
                if (!CompareMeanings(ExpectedMeaning, Rule[0], out ExpectedMeaning))    //القاعدة لا تحقق المعنى المطلوب
                {
                    continue;
                }
                WordInfo CurrentWord = Analyzer.AllWordsInfo[StartIndex][0];

                string[] expression = Rule[1].Split('+');    //فصل مكونات علاقة القاعدة النحوية
                string   ElementMeaning, ElementInterpretation = "";
                string[] InterpretFound;
                Relation  = new GrammarRelation();
                ValidRule = true;
                for (int Element = 0; Element < expression.Length; Element++)    //بدء مطابقة القاعدة
                {
                    if (StartIndex + Element + Offset >= Analyzer.AllWordsInfo.Count)
                    {
                        ValidRule = false;
                        break;
                    }
                    if (expression[Element].Contains(':'))
                    {
                        //فصل المعنى عن الإعراب
                        ElementMeaning        = expression[Element].Substring(0, expression[Element].IndexOf(':')).Trim();
                        ElementInterpretation = expression[Element].Substring(expression[Element].IndexOf(':') + 1).Trim();
                    }
                    else
                    {
                        ElementMeaning = expression[Element].Trim();    //حرف من الحروف ليس له إعراب
                    }
                    string InterpretedMeaning;
                    bool   ValidElement = CompareMeanings(Analyzer.AllWordsInfo[StartIndex + Element + Offset][0].Meaning, ElementMeaning, out InterpretedMeaning);
                    if (CurrentWord.Interpretations != null)
                    {
                        if (Element == 0 && ValidElement)    //العنصر الرئيسي معرب مسبقا ويصلح استخدامه
                        {
                            Relation.Elements.Add(StartIndex + Element + Offset, CurrentWord.Interpretations[0]);
                            continue;
                        }
                        else
                        {
                            ValidRule = false;
                            break;
                        }
                    }

                    for (int Possibility = 0; Possibility < Analyzer.AllWordsInfo[StartIndex + Element + Offset].Count; Possibility++)
                    {
                        if (Possibility > 0)
                        {
                            ValidElement = CompareMeanings(Analyzer.AllWordsInfo[StartIndex + Element + Offset][Possibility].Meaning, ElementMeaning, out InterpretedMeaning);
                            if (ValidElement)
                            {
                                //انقل المعنى المتوافق لبداية القائمة
                                WordInfo T = Analyzer.AllWordsInfo[StartIndex + Element + Offset][0];
                                Analyzer.AllWordsInfo[StartIndex + Element + Offset][0]           = Analyzer.AllWordsInfo[StartIndex + Element + Offset][Possibility];
                                Analyzer.AllWordsInfo[StartIndex + Element + Offset][Possibility] = T;
                            }
                        }
                        if (ValidElement && ElementMeaning[0] == 'T')               // إذا كان العنصر حرفا صالحا
                        {
                            MyInterpretation NewInterpret = new MyInterpretation(); //إعراب جديد
                            NewInterpret.Meaning = InterpretedMeaning;
                            Relation.Elements.Add(StartIndex + Element + Offset, NewInterpret);
                            NewInterpret.SuperRelation = Relation;
                            break;
                        }
                        if (!MyInterpretation.Interpretations.ContainsKey(ElementInterpretation))    //إذا كان الإعراب المخزن وصفه غير موجود
                        {
                            //خطأ في قاعدة البيانات أو حرف غير صالح للقاعدة
                            if (ElementMeaning[0] == 'T')
                            {
                                continue;
                            }
                            ValidElement = false;
                            ValidRule    = false;
                            break;
                        }
                        InterpretFound = MyInterpretation.Interpretations[ElementInterpretation];    //البحث عن معنى رمز الإعراب
                        if (ValidElement)
                        {
                            MyInterpretation NewInterpret = new MyInterpretation(); //إعراب جديد
                            NewInterpret.Description = InterpretFound[0];           //نحميل وصف الإعراب
                            //if (ElementMeaning[0] == 'N')//إضافة الإعراب إلى المعنى حسب نوع الكلمة
                            //{
                            //    CompareMeanings(InterpretedMeaning, "N000" + InterpretFound[1], out ElementMeaning);
                            //}
                            //else if (ElementMeaning[0] == 'V')
                            //{
                            //    CompareMeanings(InterpretedMeaning, "V000000" + InterpretFound[1], out ElementMeaning);
                            //}
                            NewInterpret.Meaning = InterpretedMeaning;
                            Relation.Elements.Add(StartIndex + Element + Offset, NewInterpret);
                            NewInterpret.SuperRelation = Relation;
                            break;
                        }
                        else if (MaximumRecursion > 0 && Element > 0)
                        {
                            //إذا كان العنصر لا يصلح للقاعدة وليس العنصر الرئيسي بها
                            //وهناك فرصة للجمل المتداخلة
                            //ابحث عن مجموعة كلمات تحقق المعنى المطلوب
                            GrammarRelation SubRelation    = new GrammarRelation();
                            int             ModifiedOffset = StartInterpreting(ref SubRelation, StartIndex + Element + Offset, ElementMeaning, --MaximumRecursion, true);
                            if (ModifiedOffset == 0)
                            {
                                //معنى الكلمة غير صالح؛ ابحث باقي احتمالات المعنى
                                continue;
                            }
                            //إذا نجح البحث عن مجموعة كلمات
                            Offset += ModifiedOffset;
                            SubRelation.Description   = InterpretFound[0];
                            SubRelation.Meaning       = InterpretedMeaning;
                            SubRelation.SuperRelation = Relation;
                            Relation.Elements.Add(-1, SubRelation);
                            ValidElement = true;
                            break;
                        }
                    }
                    if (!ValidElement)
                    {
                        ValidRule = false;
                        break;
                    }
                }
                if (!ValidRule)
                {
                    continue;
                }
                if (!RecursiveCall)
                {
                    ApplyGrammarRelation(Relation);
                }
                break;
            }
            if (ValidRule)
            {
                return(Relation.Elements.Count);
            }
            else
            {
                return(0);
            }
        }
Example #3
0
        /// <summary>
        /// الإجراء الرئيسي في التحليل الصرفي؛ يقوم بتحليل الكلمة وإنتاج قائمة باحتمالات التحليل الصرفي.
        /// </summary>
        /// <param name="WordToProcess"></param>
        /// <returns></returns>
        private static List <WordInfo> ProcessWord(ArabicWord WordToProcess)
        {
            List <WordInfo> CurrentWordInfo = new List <WordInfo>();
            WordInfo        NewInfo;

            Morphology.CheckForSpecialWord(WordToProcess, ref CurrentWordInfo);
            if (CurrentWordInfo.Count > 0)
            {
                goto AddWord;
            }
            Morphology.CheckForPronoun(WordToProcess, ref CurrentWordInfo);
            List <WordPrefix> ValidPrefixes = WordPrefix.CheckPrefix(WordToProcess.word);
            List <WordSuffix> ValidSuffixes = WordSuffix.CheckSuffixes(WordToProcess.word);

            //المعاني الافتراضية عند عدم وجود إضافات
            ValidPrefixes.Add(new WordPrefix()
            {
                WordClass = "N1"
            });                                                      //الأسماء نكرة
            ValidPrefixes.Add(new WordPrefix()
            {
                WordClass = "V1"
            });                                                      //فعل ماض
            ValidPrefixes.Add(new WordPrefix()
            {
                WordClass = "V3"
            });                                                      //فعل أمر

            ValidSuffixes.Add(new WordSuffix()
            {
                WordClass = "N001"
            });                                                        //اسم مذكر
            ValidSuffixes.Add(new WordSuffix()
            {
                WordClass = "V10311"
            });                                                          //فعل ماض غائب مفرد مذكر
            ValidSuffixes.Add(new WordSuffix()
            {
                WordClass = "V20211"
            });                                                          //فعل مضارع مخاطب مفرد مذكر
            ValidSuffixes.Add(new WordSuffix()
            {
                WordClass = "V201"
            });                                                        //فعل مضارع متكلم
            ValidSuffixes.Add(new WordSuffix()
            {
                WordClass = "V2031"
            });                                                         //فعل مضارع غائب مفرد
            ValidSuffixes.Add(new WordSuffix()
            {
                WordClass = "V30011"
            });                                                          //فعل أمر مفرد مذكر
            List <string[]> Result = new List <string[]>();
            string          Stem;

            for (int i = 0; i < ValidPrefixes.Count; i++)
            {
                for (int j = 0; j < ValidSuffixes.Count; j++)
                {
                    Result = new List <string[]>();
                    if (WordToProcess.word.Length <= (ValidSuffixes[j].Text.Length + ValidPrefixes[i].Text.Length))
                    {   //طول الإضافات يغطي طول الكلمة بأكملها
                        continue;
                    }
                    List <string> CompatibleAdditions = Morphology.CheckAdditionsCompatibility(ValidPrefixes[i].WordClass, ValidSuffixes[j].WordClass);
                    if (CompatibleAdditions.Count == 0)
                    {   //إضافات غير متوافقة
                        continue;
                    }
                    Stem = WordToProcess.word.Substring(ValidPrefixes[i].Text.Length, WordToProcess.word.Length - (ValidPrefixes[i].Text.Length + ValidSuffixes[j].Text.Length));
                    //ابحث عن الأوزان المتوافقة مع الإضافات المحددة
                    Result = Morphology.LookForTemplate(Stem, CompatibleAdditions, Result);
                    if (Result.Count == 0)
                    {
                        continue;
                    }

                    /* اختبار وجود جذر للكلمة متوافق مع الوزن المحدد
                     * واختبار توافق الجذر الموجود مع هذا الوزن
                     * يمكن الاستغناء عن بعض هذه الخطوات عند إكمال قاعدة البيانات
                     *
                     */

                    #region اختبار توافق الوزن والجذر
                    string[]          CurrentResult;
                    string            CurrentRoot      = "";
                    List <ArabicRoot> CheckRootResults = new List <ArabicRoot>();
                    for (int R = 0; R < Result.Count; R++)
                    {
                        CurrentResult = Result[R];
                        Morphology.RootCompatibility RootResult = Morphology.CheckRoot(Stem, CurrentResult[2], CurrentResult[4], CurrentResult[5], CurrentResult[6], CurrentResult[7], ref CurrentRoot);
                        switch (RootResult) //اختبار وجود الجذر حسب الوزن
                        {
                        case Morphology.RootCompatibility.InvalidRoot:
                            Result.RemoveAt(R);
                            R--;
                            break;

                        case Morphology.RootCompatibility.CompatibleRoot:
                            for (int prev = 0; prev < R; prev++)
                            {
                                //عثر على جذر متوافق احذف كل الأوزان السابقة التي ليس لها جذور متوافقة
                                //if (CurrentResult[2] == Result[prev][2]) //نفس نمط الوزن
                                {
                                    if (CheckRootResults[prev].RootCompatibility == Morphology.RootCompatibility.IncompatibleValidRoot)
                                    {
                                        Result.RemoveAt(prev);
                                        CheckRootResults.RemoveAt(prev);
                                        R--;
                                        prev--;
                                    }
                                }
                            }
                            CheckRootResults.Add(new ArabicRoot()
                            {
                                Root = CurrentRoot, RootCompatibility = RootResult
                            });
                            break;

                        case Morphology.RootCompatibility.IncompatibleValidRoot:
                            bool AddThisOne = true;
                            for (int prev = 0; prev < R; prev++)
                            {
                                if (CurrentResult[2] == Result[prev][2])     //نفس نمط الوزن
                                {
                                    if (CheckRootResults[prev].RootCompatibility == Morphology.RootCompatibility.CompatibleRoot)
                                    {
                                        AddThisOne = false;     //عثر من قبل على جذور متوافقة لها أولوية
                                        Result.RemoveAt(R--);
                                        break;
                                    }
                                }
                                //مفاضلة الأوزان من نفس قاعدة الاشتقاق
                                byte CompareResult = Morphology.CompareRules(CurrentResult[7], Result[prev][7]);
                                if (CompareResult == 1)
                                {
                                    CheckRootResults.RemoveAt(prev);
                                    Result.RemoveAt(prev--);
                                    R--;
                                }
                                else if (CompareResult == 2)    //الوزن المضاف مسبقا أولى
                                {
                                    AddThisOne = false;
                                    Result.RemoveAt(R--);
                                    break;
                                }
                            }
                            if (AddThisOne)
                            {
                                CheckRootResults.Add(new ArabicRoot()
                                {
                                    Root = CurrentRoot, RootCompatibility = RootResult, DerivationRules = CurrentResult[7]
                                });
                            }
                            break;
                        }
                    }
                    #endregion

                    for (int R = 0; R < Result.Count; R++)
                    {
                        NewInfo            = new WordInfo();
                        NewInfo.Word       = Stem;
                        NewInfo.Diacritics = Result[R][1];
                        NewInfo.Template   = Result[R][0];
                        NewInfo.Meaning    = Result[R][3];
                        NewInfo.Root       = CheckRootResults[R];
                        NewInfo.Prefix     = ValidPrefixes[i];
                        NewInfo.Suffix     = ValidSuffixes[j];
                        Tashkeel.DiacritizeWord(NewInfo);
                        CurrentWordInfo.Add(NewInfo);
                    }
                }
            }

AddWord:
            for (int W = 0; W < CurrentWordInfo.Count; W++)
            {
                if (CurrentWordInfo[W].Root.RootCompatibility == Morphology.RootCompatibility.CompatibleRoot)
                {
                    WordInfo Temp;
                    for (int prev = W; prev > 0; prev--)
                    {
                        Temp = CurrentWordInfo[prev];
                        CurrentWordInfo[prev]     = CurrentWordInfo[prev - 1];
                        CurrentWordInfo[prev - 1] = Temp;
                    }
                }
            }
            return(CurrentWordInfo);
        }