public static void ConvertToDnf(QueryToken root) { PropagateNegations(root); bool change; do { change = false; DistributeAndOverOr(root, ref change); } while (change); }
public static void OutputDisjunct(QueryToken node) { if (GetTokenType(node) == TokenType.Term) { Console.Write("[" + node + "]"); } if (node.Children != null) { OutputDisjunct(node.Children[0]); OutputDisjunct(node.Children[1]); } }
public static void OutputDisjuncts(QueryToken node) { if (node == "AND" || GetTokenType(node) == TokenType.Term) { OutputDisjunct(node); Console.WriteLine(); } else if (node.Children != null) { OutputDisjuncts(node.Children[0]); OutputDisjuncts(node.Children[1]); } }
private static void DistributeAndOverOr(QueryToken node, ref bool change) { if (node.Children != null) { List<QueryToken> children = node.Children.ToList(); if (node == "AND" && children.Any(child => child == "OR")) { QueryToken orNode = children.First(child => child == "OR"); QueryToken otherNode = children.First(child => child != orNode); node.Parts[0] = "OR"; QueryToken andOp1 = "AND"; QueryToken andOp2 = "AND"; node.Children = new[] { andOp1, andOp2 }; andOp1.Children = new[] { otherNode, orNode.Children[0] }; andOp2.Children = new[] { otherNode, orNode.Children[1] }; change = true; } foreach (QueryToken child in node.Children) { DistributeAndOverOr(child, ref change); } } }
/* Debugging */ public static void OutputQueryTree(QueryToken root, string tab = "") { Console.WriteLine(tab + root); if (root.Children != null) { OutputQueryTree(root.Children[0], tab + " "); OutputQueryTree(root.Children[1], tab + " "); } }
private static void PropagateNegations(QueryToken node) { if (node.Children != null) { if (node.Negated && GetTokenType(node) == TokenType.Operator) { if (node == "OR") { node.Parts[0] = "AND"; } else { node.Parts[0] = "OR"; } node.Negated = false; foreach (QueryToken child in node.Children) { child.Negated = !child.Negated; } } foreach (QueryToken child in node.Children) { PropagateNegations(child); } } }
private static void GetDisjunct(QueryToken node, ArrayList<QueryToken> tokens) { if (GetTokenType(node) == TokenType.Term) { tokens.Add(node); } if (node.Children != null) { GetDisjunct(node.Children[0], tokens); GetDisjunct(node.Children[1], tokens); } }
private static bool Contains(QueryToken token, ArrayList<string> text, IEqualityComparer<string> tokenComparer) { for (int i = 0; i < text.Count - (token.Parts.Length - 1); i++) { bool success = true; for (int j = 0; j < token.Parts.Length; j++) { string textWord = text[i + j]; string queryWord = token.Parts[j]; if (!tokenComparer.Equals(queryWord, textWord)) { success = false; break; } } if (success) { return true; } } return false; }
public static void GetDisjuncts(QueryToken node, ArrayList<ArrayList<QueryToken>> disjuncts) { if (node == "AND" || GetTokenType(node) == TokenType.Term) { ArrayList<QueryToken> tokens = new ArrayList<QueryToken>(); GetDisjunct(node, tokens); disjuncts.Add(tokens); } else if (node.Children != null) { GetDisjuncts(node.Children[0], disjuncts); GetDisjuncts(node.Children[1], disjuncts); } }
private static ArrayList<ArrayList<QueryToken>> ConvertSingleDisjunctUmlauts(ArrayList<QueryToken> disjunct) { ArrayList<ArrayList<QueryToken>> convertedDisjuncts = new ArrayList<ArrayList<QueryToken>>(); // convert each umlaut twice, i.e. ü -> ue, u; and retain also the original ü foreach (var mode in Enum.GetValues(typeof(UmlautConversionMode)).Cast<UmlautConversionMode>()) { ArrayList<QueryToken> convertedDisjunct = new ArrayList<QueryToken>(); // convert each part of the token seperately foreach (QueryToken token in disjunct) { QueryToken convertedToken = new QueryToken(token); convertedToken.Parts = new string[token.Parts.Length]; token.Parts.CopyTo(convertedToken.Parts, 0); for (int s = 0; s < token.Parts.Length; ++s) convertedToken.Parts[s] = QueryConverterUtils.ConvertSingleTokenUmlauts(token.Parts[s], mode); convertedDisjunct.Add(convertedToken); } convertedDisjuncts.Add(convertedDisjunct); } return convertedDisjuncts; }