public static DefineTreeItem Or(DefineTreeItem a, DefineTreeItem b)
 {
     if (a == null && b == null)
     {
         return(null);
     }
     if (a == Always.Instance || b == Always.Instance)
     {
         return(Always.Instance);
     }
     if (a == null)
     {
         return(b);
     }
     if (b == null)
     {
         return(a);
     }
     if (a == b)
     {
         return(a);
     }
     if (a.Type == DefineTreeItemType.Or && b.Type == DefineTreeItemType.Or)
     {
         return new Or {
                    Operands = ((Or)a).Operands.Concat(((Or)b).Operands).Distinct().ToList()
         }
     }
     ;
     if (a.Type == DefineTreeItemType.Or)
     {
         return new Or {
                    Operands = ((Or)a).Operands.Concat(new[] { b }).Distinct().ToList()
         }
     }
     ;
     if (b.Type == DefineTreeItemType.Or)
     {
         return new Or {
                    Operands = ((Or)b).Operands.Concat(new[] { a }).Distinct().ToList()
         }
     }
     ;
     return(new Or {
         Operands = new[] { a, b }
     });
 }
 public static DefineTreeItem And(DefineTreeItem a, DefineTreeItem b)
 {
     if (a == null && b == null)
     {
         return(null);
     }
     if (a == null || a == Always.Instance)
     {
         return(b);
     }
     if (b == null || b == Always.Instance)
     {
         return(a);
     }
     if (a == b)
     {
         return(a);
     }
     if (a.Type == DefineTreeItemType.And && b.Type == DefineTreeItemType.And)
     {
         return new And {
                    Operands = ((And)a).Operands.Concat(((And)b).Operands).Distinct().ToList()
         }
     }
     ;
     if (a.Type == DefineTreeItemType.And)
     {
         return new And {
                    Operands = ((And)a).Operands.Concat(new[] { b }).Distinct().ToList()
         }
     }
     ;
     if (b.Type == DefineTreeItemType.And)
     {
         return new And {
                    Operands = ((And)b).Operands.Concat(new[] { a }).Distinct().ToList()
         }
     }
     ;
     return(new And {
         Operands = new[] { a, b }
     });
 }
        private BinaryTreeItem Visit(DefineTreeItem item)
        {
            switch (item.Type)
            {
            case DefineTreeItemType.Always:
                return(new True());

            case DefineTreeItemType.Defined:
                return(new Defined(GetMask(((DefineTree.Defined)item).Value)));

            case DefineTreeItemType.Undefined:
                return(new Undefined(GetMask(((DefineTree.Undefined)item).Value)));

            case DefineTreeItemType.And:
                return(new And(((DefineTree.And)item).Operands.Select(_ => Visit(_))));

            case DefineTreeItemType.Or:
                return(new Or(((DefineTree.Or)item).Operands.Select(_ => Visit(_))));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
 public BinaryTree(DefineTreeItem item)
 {
     _tree = Visit(item);
 }