예제 #1
0
 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);
     }
 }
예제 #2
0
        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);
        }
예제 #3
0
        //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);
        }