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