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); }
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); }