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); } }
static BoolExpr Make(ref List <Token> .Enumerator polishNotationTokensEnumerator) { if (polishNotationTokensEnumerator.Current == null) { throw new ArgumentNullException(); } if (polishNotationTokensEnumerator.Current.Type == Token.TokenType.Literal) { var lit = BoolExpr.CreateBoolVar(polishNotationTokensEnumerator.Current.Value); polishNotationTokensEnumerator.MoveNext(); return(lit); } switch (polishNotationTokensEnumerator.Current.Value) { case "NOT": { polishNotationTokensEnumerator.MoveNext(); var operand = Make(ref polishNotationTokensEnumerator); return(BoolExpr.CreateNot(operand)); } case "AND": { polishNotationTokensEnumerator.MoveNext(); var left = Make(ref polishNotationTokensEnumerator); var right = Make(ref polishNotationTokensEnumerator); return(BoolExpr.CreateAnd(left, right)); } case "OR": { polishNotationTokensEnumerator.MoveNext(); var left = Make(ref polishNotationTokensEnumerator); var right = Make(ref polishNotationTokensEnumerator); return(BoolExpr.CreateOr(left, right)); } case "IF": { polishNotationTokensEnumerator.MoveNext(); var left = Make(ref polishNotationTokensEnumerator); var right = Make(ref polishNotationTokensEnumerator); return(BoolExpr.CreateIf(left, right)); } case "IFONLYIF": { polishNotationTokensEnumerator.MoveNext(); var left = Make(ref polishNotationTokensEnumerator); var right = Make(ref polishNotationTokensEnumerator); return(BoolExpr.CreateIfOnlyIf(left, right)); } } return(null); }
//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); }