//********************************************************************************************** // AbstractGenericRule // // Verify if the facts provided are a rule or not. Compares two inputs and two outputs // to abstract a rule from them (if there is a applicability pattern). //********************************************************************************************** public bool AbstractGenericRule(string input1, string output1, string input2, string output2, string end) { // Do not learn trivial mappings... (they have to be at least two words of one character in input) if (input1.Length < 3 || input2.Length < 3 || !input1.Contains(' ') || !input2.Contains(' ')) { return(false); } // We don't want to abstract a rule from two rather equal samples if (input1 == input2) { return(false); } // If it has end of sentence character, take it out -we don't want it tied to the last word. bool inputHasEndChar = Syntax.RemoveEndCharIfPresent(ref input1, ref input2, end); bool inputHasEndSpace = Syntax.RemoveEndCharIfPresent(ref input1, ref input2, " "); bool outputHasEndChar = Syntax.RemoveEndCharIfPresent(ref output1, ref output2, end); bool outputHasEndSpace = Syntax.RemoveEndCharIfPresent(ref output1, ref output2, " "); string[] inputWords1 = Syntax.GetWords(input1); string[] inputWords2 = Syntax.GetWords(input2); string[] outputWords1 = Syntax.GetWords(output1); string[] outputWords2 = Syntax.GetWords(output2); // The number of words must match if (inputWords1.Length != inputWords2.Length || outputWords1.Length != outputWords2.Length) { return(false); } // Find the words that are common between both input and output and mark them to skip them when exploding IDs if (!WordGenericRules.FindCommonWords(inputWords1, inputWords2, out string inputVariability)) { return(false); } // Locate common chars between inputs and outputs and generalize the strings AbstractRepeatedChars(inputWords1, outputWords1, inputVariability, out string inputPattern1, out string outputPattern1); AbstractRepeatedChars(inputWords2, outputWords2, inputVariability, out string inputPattern2, out string outputPattern2); if (!ValidateEquivalentPatterns(inputPattern1, outputPattern1, input1, output1, inputPattern2, outputPattern2, input2, output2, out string inputPattern, out string outputPattern)) { return(false); } if (inputHasEndSpace) { inputPattern += ' '; } if (inputHasEndChar) { inputPattern += end; } if (outputHasEndSpace) { outputPattern += ' '; } if (outputHasEndChar) { outputPattern += end; } // We have a new rule! Rule existingRule = GetRule(inputPattern, input1, input2); if (existingRule == null) { Rule newRule = new Rule(inputPattern, outputPattern); rules.Add(newRule); return(true); } return(false); }
//********************************************************************************************** // AbstractGenericRule // // Verify if the facts provided are a rule or not. Compares two inputs and two outputs // to abstract a rule from them (if there is a applicability pattern). //********************************************************************************************** public bool AbstractGenericRule(string input1, string output1, string input2, string output2, string end) { // Do not learn trivial mappings... (they have to be at least two words of one character in input) if (input1.Length < 3 || input2.Length < 3) { return(false); } // We don't want to abstract a rule from two rather equal samples if (input1 == input2) { return(false); } // If it has end of sentence character, take it out -we don't want it tied to the last word. bool inputHasEndChar = Syntax.RemoveEndCharIfPresent(ref input1, ref input2, end); bool inputHasEndSpace = Syntax.RemoveEndCharIfPresent(ref input1, ref input2, " "); bool outputHasEndChar = Syntax.RemoveEndCharIfPresent(ref output1, ref output2, end); bool outputHasEndSpace = Syntax.RemoveEndCharIfPresent(ref output1, ref output2, " "); string[] inputWords1 = Syntax.GetWordsAndOperands(input1); string[] inputWords2 = Syntax.GetWordsAndOperands(input2); string[] outputWords1 = Syntax.GetWordsAndOperands(output1); string[] outputWords2 = Syntax.GetWordsAndOperands(output2); // The number of words must match or the outputs have more than one word if (inputWords1.Length != inputWords2.Length || outputWords1.Length != outputWords2.Length) { return(false); } // Find the words that are common between both input and output and mark them to skip them when exploding IDs if (!WordGenericRules.FindCommonWords(inputWords1, inputWords2, out string inputVariability)) { return(false); } WordGenericRules.FindCommonWords(outputWords1, outputWords2, out string outputVariability); // We support two operand with one result rules only (i.e. A + B -> C) if (inputVariability.Replace("C", "").Length != 2 || outputVariability.Replace("C", "").Length != 1) { return(false); } // Locate common chars between inputs and outputs and generalize the strings if (!AbstractOperation(inputWords1, outputWords1, inputVariability, outputVariability, out string inputPattern1, out string outputPattern1)) { return(false); } if (!AbstractOperation(inputWords2, outputWords2, inputVariability, outputVariability, out string inputPattern2, out string outputPattern2)) { return(false); } // They must match completely if (inputPattern1 != inputPattern2 || outputPattern1 != outputPattern2) { return(false); } if (inputHasEndSpace) { inputPattern1 += ' '; } if (inputHasEndChar) { inputPattern1 += end; } if (outputHasEndSpace) { outputPattern1 += ' '; } if (outputHasEndChar) { outputPattern1 += end; } // We have a new rule! Rule existingRule = GetRule(inputPattern1); if (existingRule == null) { Rule newRule = new Rule(inputPattern1, outputPattern1); rules.Add(newRule); return(true); } return(false); }