File: Vertex.cs

package info (click to toggle)
mono 6.14.1%2Bds2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,282,732 kB
  • sloc: cs: 11,182,461; xml: 2,850,281; ansic: 699,123; cpp: 122,919; perl: 58,604; javascript: 30,841; asm: 21,845; makefile: 19,602; sh: 10,973; python: 4,772; pascal: 925; sql: 859; sed: 16; php: 1
file content (140 lines) | stat: -rw-r--r-- 4,521 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//---------------------------------------------------------------------
// <copyright file="Vertex.cs" company="Microsoft">
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//
// @owner Microsoft
// @backupOwner Microsoft
//---------------------------------------------------------------------

using System;
using System.Collections.Generic;

namespace System.Data.Common.Utils.Boolean
{
    using System.Diagnostics;
    using System.Globalization;

    /// <summary>
    /// A node in a Reduced Ordered Boolean Decision Diagram. Reads as:
    /// 
    /// if 'Variable' then 'Then' else 'Else'
    /// 
    /// Invariant: the Then and Else children must refer to 'deeper' variables,
    /// or variables with a higher value. Otherwise, the graph is not 'Ordered'.
    /// All creation of vertices is mediated by the Solver class which ensures
    /// each vertex is unique. Otherwise, the graph is not 'Reduced'.
    /// </summary>
    sealed class Vertex : IEquatable<Vertex>
    {
        /// <summary>
        /// Initializes a sink BDD node (zero or one)
        /// </summary>
        private Vertex()
        {
            this.Variable = int.MaxValue;
            this.Children = new Vertex[] { };
        }

        internal Vertex(int variable, Vertex[] children)
        {
            EntityUtil.BoolExprAssert(variable < int.MaxValue,
                "exceeded number of supported variables");

            AssertConstructorArgumentsValid(variable, children);
           
            this.Variable = variable;
            this.Children = children;
        }

        [Conditional("DEBUG")]
        private static void AssertConstructorArgumentsValid(int variable, Vertex[] children)
        {
            Debug.Assert(null != children, "internal vertices must define children");
            Debug.Assert(2 <= children.Length, "internal vertices must have at least two children");
            Debug.Assert(0 < variable, "internal vertices must have 0 < variable");
            foreach (Vertex child in children)
            {
                Debug.Assert(variable < child.Variable, "children must have greater variable");
            }
        }

        /// <summary>
        /// Sink node representing the Boolean function '1' (true)
        /// </summary>
        internal static readonly Vertex One = new Vertex();

        /// <summary>
        /// Sink node representing the Boolean function '0' (false)
        /// </summary>
        internal static readonly Vertex Zero = new Vertex();

        /// <summary>
        /// Gets the variable tested by this vertex. If this is a sink node, returns
        /// int.MaxValue since there is no variable to test (and since this is a leaf,
        /// this non-existent variable is 'deeper' than any existing variable; the 
        /// variable value is larger than any real variable)
        /// </summary>
        internal readonly int Variable;

        /// <summary>
        /// Note: do not modify elements.
        /// Gets the result when Variable evaluates to true. If this is a sink node,
        /// returns null.
        /// </summary>
        internal readonly Vertex[] Children;

        /// <summary>
        /// Returns true if this is '1'.
        /// </summary>
        internal bool IsOne()
        {
            return object.ReferenceEquals(Vertex.One, this);
        }

        /// <summary>
        /// Returns true if this is '0'.
        /// </summary>
        internal bool IsZero()
        {
            return object.ReferenceEquals(Vertex.Zero, this);
        }

        /// <summary>
        /// Returns true if this is '0' or '1'.
        /// </summary>
        internal bool IsSink()
        {
            return Variable == int.MaxValue;
        }

        public bool Equals(Vertex other)
        {
            return object.ReferenceEquals(this, other);
        }

        public override bool Equals(object obj)
        {
            Debug.Fail("used typed Equals");
            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override string ToString()
        {
            if (IsOne())
            {
                return "_1_";
            }
            if (IsZero())
            {
                return "_0_";
            }
            return String.Format(CultureInfo.InvariantCulture, "<{0}, {1}>", Variable, StringUtil.ToCommaSeparatedString(Children));
        }
    }
}