//metoda zwraca koniunkcje fluentow jako stringi public static List <string> GetFluentStrings(BoolExpr tree) { var list = new List <string>(); var token = _strings(tree, null, list); if (!string.IsNullOrEmpty(token)) { list.Add(token); } //usuwanie z list a & !a return((from s in list let f = s.Split('&') let isOk = f.All(s1 => !f.Contains("not_" + s1)) where isOk select s).ToList()); }
static string _strings(BoolExpr expr, BoolExpr parent, List <string> tokens) { if (expr.IsLeaf()) { if (parent != null && parent.Op == BoolExpr.Bop.Or) { tokens.Add(expr.Lit); return(""); } return(expr.Lit); } if (expr.Op == BoolExpr.Bop.Not) { if (parent != null && parent.Op == BoolExpr.Bop.And) { return("not_" + expr.Left.Lit); } tokens.Add("not_" + expr.Left.Lit); return(""); } if (expr.Op == BoolExpr.Bop.And) { if (parent != null && parent.Op == BoolExpr.Bop.Or) { tokens.Add(_strings(expr.Left, expr, tokens) + "&" + _strings(expr.Right, expr, tokens)); } else if (parent != null && parent.Op == BoolExpr.Bop.And) { return(_strings(expr.Left, expr, tokens) + "&" + _strings(expr.Right, expr, tokens)); } else if (parent == null) { tokens.Add(_strings(expr.Left, expr, tokens) + "&" + _strings(expr.Right, expr, tokens)); } } if (expr.Left != null) { _strings(expr.Left, expr, tokens); } if (expr.Right != null) { _strings(expr.Right, expr, tokens); } return(""); }
static void TraverseTree(BoolExpr expr, BoolExpr parent, List <string> tokens) { if (expr.IsLeaf()) { if (parent != null && parent.Op == BoolExpr.Bop.Not) { tokens.Add("!" + expr.Lit); } else { tokens.Add(expr.Lit); } return; } if (expr.Left != null) { TraverseTree(expr.Left, expr, tokens); } if (expr.Right != null) { TraverseTree(expr.Right, expr, tokens); } }
private static void _SimplifyIf(BoolExpr result) { if (result.IsLeaf()) { return; } if (result.Op == BoolExpr.Bop.If) { var nowy = BoolExpr.CreateOr(result.Right, BoolExpr.CreateNot(result.Left)); result.Left = nowy.Left; result.Right = nowy.Right; result.Op = nowy.Op; result.Lit = nowy.Lit; } else if (result.Op == BoolExpr.Bop.IfOnlyIf) { var nowy = BoolExpr.CreateAnd(BoolExpr.CreateIf(result.Left, result.Right), BoolExpr.CreateIf(result.Right, result.Left)); result.Left = nowy.Left; result.Right = nowy.Right; result.Op = nowy.Op; result.Lit = nowy.Lit; } if (result.Left != null) { _SimplifyIf(result.Left); } if (result.Right != null) { _SimplifyIf(result.Right); } }
public static BoolExpr CreateOr(BoolExpr left, BoolExpr right) { return(new BoolExpr(Bop.Or, left, right)); }
public static BoolExpr CreateNot(BoolExpr child) { return(new BoolExpr(Bop.Not, null, child)); }
public static BoolExpr CreateIfOnlyIf(BoolExpr left, BoolExpr right) { return(new BoolExpr(Bop.IfOnlyIf, left, right)); }
// // public factory // public static BoolExpr CreateAnd(BoolExpr left, BoolExpr right) { return(new BoolExpr(Bop.And, left, right)); }
//metoda zamienia wyrazenie(drzewo) w postac koniunkcji oddzielonych alternatywami np. (a&b)|(a&c) public static BoolExpr AndOrReformTree(BoolExpr tree) { var result = new BoolExpr(tree); var queue = new Queue <BoolExpr>(); bool isChanged; do { queue.Enqueue(result); do { isChanged = false; if (queue.Count == 0) { break; } var expr = queue.Dequeue(); if (expr.IsLeaf()) { continue; } if (expr.Op == BoolExpr.Bop.And) { if (expr.Left.Op == BoolExpr.Bop.Or) { BoolExpr nowy = BoolExpr.CreateOr(BoolExpr.CreateAnd(expr.Left.Right, expr.Right), BoolExpr.CreateAnd(expr.Left.Left, expr.Right)); expr.Left = nowy.Left; expr.Right = nowy.Right; expr.Op = nowy.Op; expr.Lit = nowy.Lit; isChanged = true; break; } if (expr.Right.Op == BoolExpr.Bop.Or) { BoolExpr nowy = BoolExpr.CreateOr(BoolExpr.CreateAnd(expr.Right.Right, expr.Left), BoolExpr.CreateAnd(expr.Right.Left, expr.Left)); expr.Left = nowy.Left; expr.Right = nowy.Right; expr.Op = nowy.Op; expr.Lit = nowy.Lit; isChanged = true; break; } } if (expr.Op == BoolExpr.Bop.Not) { if (expr.Left.Op == BoolExpr.Bop.And) { BoolExpr nowy = BoolExpr.CreateOr(BoolExpr.CreateNot(expr.Left.Right), BoolExpr.CreateNot(expr.Left.Left)); expr.Left = nowy.Left; expr.Right = nowy.Right; expr.Op = nowy.Op; expr.Lit = nowy.Lit; isChanged = true; break; } if (expr.Left.Op == BoolExpr.Bop.Or) { BoolExpr nowy = BoolExpr.CreateAnd(BoolExpr.CreateNot(expr.Left.Right), BoolExpr.CreateNot(expr.Left.Left)); expr.Left = nowy.Left; expr.Right = nowy.Right; expr.Op = nowy.Op; expr.Lit = nowy.Lit; isChanged = true; break; } if (expr.Left.Op == BoolExpr.Bop.Not) { var left = expr.Left.Left; expr.Left = left.Left; expr.Right = left.Right; expr.Op = left.Op; expr.Lit = left.Lit; isChanged = true; break; } } if (expr.Left != null) { queue.Enqueue(expr.Left); } if (expr.Right != null) { queue.Enqueue(expr.Right); } } while (true); queue.Clear(); } while (isChanged); return(result); }