Esempio n. 1
0
        private static List <WordInfo> ProcessWord(ArabicWord WordToProcess)
        {
            List <WordInfo> CurrentWordInfo = new List <WordInfo>();
            WordInfo        NewInfo;

            Morphology.CheckForSpecialWord(WordToProcess, ref CurrentWordInfo);
            Morphology.CheckForPronoun(WordToProcess, ref CurrentWordInfo);
            if (FastAnalysis && CurrentWordInfo.Count > 0) //للاكتفاء باحتمالات الكلمات الخاصة وعدم البحث عن تحليل صرفي لأسماء أو أفعال
            {
                return(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 = "N0001"
            });                                                         //اسم مذكر
            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;
                    ArabicRoot        CurrentRoot      = new ArabicRoot();
                    List <ArabicRoot> CheckRootResults = new List <ArabicRoot>();
                    for (int R = 0; R < Result.Count; R++)
                    {
                        CurrentResult = Result[R];
                        bool RootResult = Morphology.CheckRoot(Stem, CurrentResult[2], CurrentResult[4], CurrentResult[5], CurrentResult[6], CurrentResult[7], ref CurrentResult[3], ref CurrentRoot);
                        if (!RootResult) //اختبار وجود الجذر حسب الوزن
                        {
                            Result.RemoveAt(R);
                            R--;
                        }
                        else
                        {
                            if (CurrentRoot.IsCompatible)
                            {
                                for (int prev = 0; prev < R; prev++)
                                {
                                    //عثر على جذر متوافق احذف كل الأوزان السابقة التي ليس لها جذور متوافقة
                                    if (!CheckRootResults[prev].IsCompatible)
                                    {
                                        Result.RemoveAt(prev);
                                        CheckRootResults.RemoveAt(prev);
                                        R--;
                                        prev--;
                                    }
                                }
                                CheckRootResults.Add(CurrentRoot);
                            }
                            else
                            {
                                bool AddThisOne = true;
                                for (int prev = 0; prev < R; prev++)
                                {
                                    if (CheckRootResults[prev].IsCompatible)
                                    {
                                        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(CurrentRoot);
                                }
                            }
                        }
                    }
                    #endregion

                    for (int R = 0; R < Result.Count; R++)
                    {
                        NewInfo            = new WordInfo();
                        NewInfo.Word       = Stem;
                        NewInfo.Diacritics = Result[R][1];
                        NewInfo.Prefix     = ValidPrefixes[i];
                        NewInfo.Suffix     = ValidSuffixes[j];
                        Tashkeel.DiacritizeWord(NewInfo);
                        if (!IgnoreExistingDiacritics && !CheckOriginalDiacritics(WordToProcess.Original, NewInfo.FullDiacritics))
                        {
                            continue;
                        }

                        NewInfo.Template = Result[R][0];
                        NewInfo.Meaning  = Result[R][3];
                        NewInfo.Root     = CheckRootResults[R];
                        CurrentWordInfo.Add(NewInfo);
                    }
                }
            }

            for (int W = 0; W < CurrentWordInfo.Count; W++)
            {
                if (CurrentWordInfo[W].Root.IsCompatible)
                {
                    WordInfo Temp;
                    for (int prev = W; prev > 0; prev--)
                    {
                        Temp = CurrentWordInfo[prev];
                        CurrentWordInfo[prev]     = CurrentWordInfo[prev - 1];
                        CurrentWordInfo[prev - 1] = Temp;
                    }
                }
            }
            CurrentWordInfo = RecallCorrections(WordToProcess, CurrentWordInfo);
            return(CurrentWordInfo);
        }
Esempio n. 2
0
        public static bool CheckRoot(string word, string Template, string ف, string ع, string ل, string rules, ref string Meaning, ref ArabicRoot WordRoot)
        {
            List <string> Roots = new List <string>();

            word = word.Replace('ء', 'أ');
            word = word.Replace('إ', 'أ');
            word = word.Replace('ؤ', 'أ');
            word = word.Replace('ئ', 'أ');
            word = word.Replace("آ", "أا");
            word = word.Replace("ى", "ا");

            List <char> First  = new List <char>();
            List <char> Second = new List <char>();
            List <char> Third  = new List <char>();
            List <char> Fourth = new List <char>();

            for (int i = 0; i < word.Length; i++)//تجميع حروف الجذر الموجودة في الكلمة
            {
                if (Template[i] == 'ف')
                {
                    First.Add(word[i]);
                }
                if (Template[i] == 'ع')
                {
                    Second.Add(word[i]);
                }
                if (Template[i] == 'ل')
                {
                    if (Third.Count == 0)
                    {
                        Third.Add(word[i]);
                        if (word[i] == 'و' || word[i] == 'ي')
                        {
                            Third.Add('ا');
                        }
                    }
                    else
                    {
                        Fourth.Add(word[i]);
                    }
                }
            }

            #region فحص توافق الحروف
            if (ف.Length > 0)
            {
                if (First.Count == 0)
                {
                    foreach (char item in ف)
                    {
                        First.Add(item);
                    }
                }
                else
                {
                    bool match = false;
                    foreach (char item in ف)
                    {
                        if (First[0] == item)
                        {
                            match = true;
                            break;
                        }
                    }
                    if (!match)
                    {
                        return(false);
                    }
                }
            }
            if (ع.Length > 0)
            {
                if (Second.Count == 0)
                {
                    foreach (char item in ع)
                    {
                        Second.Add(item);
                    }
                }
                else
                {
                    bool match = false;
                    foreach (char item in ع)
                    {
                        if (Second[0] == item)
                        {
                            match = true;
                            break;
                        }
                    }
                    if (!match)
                    {
                        return(false);
                    }
                }
            }
            if (ل.Length > 0)
            {
                if (Third.Count == 0)
                {
                    if (ل == "ع")//جذر مضعف
                    {
                        Third.Add(Second[0]);
                    }
                    else
                    {
                        if (ل.Contains('و') || ل.Contains('ي'))
                        {
                            Third.Add('ا');
                        }
                        foreach (char item in ل)
                        {
                            Third.Add(item);
                        }
                    }
                }
                else
                {
                    bool match = false;
                    foreach (char item in ل)
                    {
                        if (Third[0] == item)
                        {
                            match = true;
                            break;
                        }
                    }
                    if (!match)
                    {
                        return(false);
                    }
                }
            }
            #endregion

            StringBuilder RootBuilder;
            foreach (char L1 in First)
            {
                foreach (char L2 in Second)
                {
                    foreach (char L3 in Third)
                    {
                        RootBuilder = new StringBuilder();
                        RootBuilder.Append(L1);
                        RootBuilder.Append(L2);
                        RootBuilder.Append(L3);
                        if (Fourth.Count > 0)
                        {
                            RootBuilder.Append(Fourth[0]);
                        }
                        Roots.Add(RootBuilder.ToString());
                    }
                }
            }

            OleDbCommand com = new OleDbCommand();
            com.Connection = Analyzer.con;
            OleDbDataReader dread;
            foreach (string root in Roots)
            {
                com.CommandText = "select * from roots where StrComp(Root,'" + root + "',0)=0";
                dread           = com.ExecuteReader();
                if (dread.Read())
                {
                    string[] RootIntrans   = dread["intrans"].ToString().Split(',');
                    string[] RootTrans1    = dread["trans1"].ToString().Split(',');
                    string[] RootTrans2    = dread["trans2"].ToString().Split(',');
                    string[] RootSingulars = dread["Singular"].ToString().Split(',');
                    string[] RootPlurals   = dread["Plural"].ToString().Split(',');
                    string[] TemplateRules = rules.Split(',');
                    string   Temp;//للتخزين المؤقت لناتج مقارنة المعنى
                    for (int X = 0; X < TemplateRules.Length; X++)
                    {
                        for (int Y = 0; Y < RootIntrans.Length; Y++)//البحث في الأفعال اللازمة
                        {
                            if (RootIntrans[Y] == TemplateRules[X])
                            {
                                if (Meaning.StartsWith("V"))
                                {
                                    Interpreter.CompareMeanings("V01", Meaning, out Meaning);
                                }
                                dread.Close();
                                WordRoot.Root            = root;
                                WordRoot.IsCompatible    = true;
                                WordRoot.DerivationRules = RootIntrans[Y];
                                if (Meaning.StartsWith("N") && Meaning.Length > 2)
                                {
                                    WordRoot.DerivationType = (ArabicRoot.Derivatives)Meaning[2] - 48;
                                }
                                return(true);
                            }
                        }
                        for (int Y = 0; Y < RootTrans1.Length; Y++)//البحث في الأفعال المتعدية لمفعول
                        {
                            if (RootTrans1[Y] == TemplateRules[X])
                            {
                                if (Meaning.StartsWith("V"))
                                {
                                    Interpreter.CompareMeanings("V02", Meaning, out Meaning);
                                }
                                dread.Close();
                                WordRoot.Root            = root;
                                WordRoot.IsCompatible    = true;
                                WordRoot.DerivationRules = RootTrans1[Y];
                                if (Meaning.StartsWith("N") && Meaning.Length > 2)
                                {
                                    WordRoot.DerivationType = (ArabicRoot.Derivatives)Meaning[2] - 48;
                                }
                                return(true);
                            }
                        }
                        for (int Y = 0; Y < RootTrans2.Length; Y++)//البحث في الأفعال المتعدية لمفعولين
                        {
                            if (RootTrans2[Y] == TemplateRules[X])
                            {
                                if (Meaning.StartsWith("V"))
                                {
                                    Interpreter.CompareMeanings("V03", Meaning, out Meaning);
                                }
                                dread.Close();
                                WordRoot.Root            = root;
                                WordRoot.IsCompatible    = true;
                                WordRoot.DerivationRules = RootTrans2[Y];
                                if (Meaning.StartsWith("N") && Meaning.Length > 2)
                                {
                                    WordRoot.DerivationType = (ArabicRoot.Derivatives)Meaning[2] - 48;
                                }
                                return(true);
                            }
                        }
                        if (Interpreter.CompareMeanings("N004", Meaning, out Temp))
                        {
                            for (int Y = 0; Y < RootPlurals.Length; Y++)//البحث في الأسماء الجمع
                            {
                                if (RootPlurals[Y] == TemplateRules[X])
                                {
                                    dread.Close();
                                    WordRoot.Root            = root;
                                    WordRoot.IsCompatible    = true;
                                    WordRoot.DerivationRules = RootPlurals[Y];
                                    return(true);
                                }
                            }
                        }
                        if (Interpreter.CompareMeanings("N001", Meaning, out Temp) ||
                            Interpreter.CompareMeanings("N002", Meaning, out Temp) ||
                            Interpreter.CompareMeanings("N003", Meaning, out Temp))
                        {
                            for (int Y = 0; Y < RootSingulars.Length; Y++)//البحث في الأسماء المفردة
                            {
                                Meaning = Temp;
                                if (RootSingulars[Y] == TemplateRules[X])
                                {
                                    dread.Close();
                                    WordRoot.Root            = root;
                                    WordRoot.IsCompatible    = true;
                                    WordRoot.DerivationRules = RootSingulars[Y];
                                    return(true);
                                }
                            }
                        }
                    }
                    //جذر موجود لكن توافقه مع الوزن غير أكيد
                    dread.Close();
                    WordRoot.Root            = root;
                    WordRoot.DerivationRules = rules;
                    WordRoot.IsCompatible    = false;
                    if (Meaning.StartsWith("N") && Meaning.Length > 2)
                    {
                        WordRoot.DerivationType = (ArabicRoot.Derivatives)Meaning[2] - 48;
                    }
                    return(true);
                }
                dread.Close();
            }
            //جذر غير موجود
            return(false);
        }