Welcome to mirror list, hosted at ThFree Co, Russian Federation.

Visitor.cs « Boolean « Utils « Common « Data « System « System.Data.Entity « referencesource « class « mcs - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b02fa5d12a22c343c0f95f96e0fb55e60996f5ce (plain)
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
//---------------------------------------------------------------------
// <copyright file="Visitor.cs" company="Microsoft">
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//
// @owner Microsoft
// @backupOwner Microsoft
//---------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;

namespace System.Data.Common.Utils.Boolean
{
    /// <summary>
    /// Abstract visitor class. All Boolean expression nodes know how to
    /// 'accept' a visitor, and delegate to the appropriate visitor method.
    /// For instance, AndExpr invokes Visitor.VisitAnd.
    /// </summary>
    /// <typeparam name="T_Identifier">Type of leaf term identifiers in expression.</typeparam>
    /// <typeparam name="T_Return">Return type for visit methods.</typeparam>
    internal abstract class Visitor<T_Identifier, T_Return>
    {
        internal abstract T_Return VisitTrue(TrueExpr<T_Identifier> expression);
        internal abstract T_Return VisitFalse(FalseExpr<T_Identifier> expression);
        internal abstract T_Return VisitTerm(TermExpr<T_Identifier> expression);
        internal abstract T_Return VisitNot(NotExpr<T_Identifier> expression);
        internal abstract T_Return VisitAnd(AndExpr<T_Identifier> expression);
        internal abstract T_Return VisitOr(OrExpr<T_Identifier> expression);
    }

    /// <summary>
    /// Basic visitor which reproduces the given expression tree.
    /// </summary>
    /// <typeparam name="T_Identifier">Type of leaf term identifiers in expression.</typeparam>
    internal abstract class BasicVisitor<T_Identifier> : Visitor<T_Identifier, BoolExpr<T_Identifier>>
    {
        internal override BoolExpr<T_Identifier> VisitFalse(FalseExpr<T_Identifier> expression) { return expression; }
        internal override BoolExpr<T_Identifier> VisitTrue(TrueExpr<T_Identifier> expression) { return expression; }
        internal override BoolExpr<T_Identifier> VisitTerm(TermExpr<T_Identifier> expression) { return expression; }
        internal override BoolExpr<T_Identifier> VisitNot(NotExpr<T_Identifier> expression) 
        { 
            return new NotExpr<T_Identifier>(expression.Child.Accept(this)); 
        }
        internal override BoolExpr<T_Identifier> VisitAnd(AndExpr<T_Identifier> expression) 
        { 
            return new AndExpr<T_Identifier>(AcceptChildren(expression.Children)); 
        }
        internal override BoolExpr<T_Identifier> VisitOr(OrExpr<T_Identifier> expression) 
        {
            return new OrExpr<T_Identifier>(AcceptChildren(expression.Children));
        }
        private IEnumerable<BoolExpr<T_Identifier>> AcceptChildren(IEnumerable<BoolExpr<T_Identifier>> children)
        {
            foreach (BoolExpr<T_Identifier> child in children) { yield return child.Accept(this); }
        }
    }

    internal class TermCounter<T_Identifier> : Visitor<T_Identifier, int>
    {
        static readonly TermCounter<T_Identifier> s_instance = new TermCounter<T_Identifier>();

        internal static int CountTerms(BoolExpr<T_Identifier> expression)
        {
            Debug.Assert(null != expression);
            return expression.Accept(s_instance);
        }

        internal override int VisitTrue(TrueExpr<T_Identifier> expression)
        {
            return 0;
        }

        internal override int VisitFalse(FalseExpr<T_Identifier> expression)
        {
            return 0;
        }

        internal override int VisitTerm(TermExpr<T_Identifier> expression)
        {
            return 1;
        }

        internal override int VisitNot(NotExpr<T_Identifier> expression)
        {
            return expression.Child.Accept(this);
        }

        internal override int VisitAnd(AndExpr<T_Identifier> expression)
        {
            return VisitTree(expression);
        }

        internal override int VisitOr(OrExpr<T_Identifier> expression)
        {
            return VisitTree(expression);
        }

        private int VisitTree(TreeExpr<T_Identifier> expression)
        {
            int sum = 0;
            foreach (var child in expression.Children)
            {
                sum += child.Accept(this);
            }
            return sum;
        }
    }

    /// <summary>
    /// A Visitor class that returns all the leaves in a boolean expression
    /// </summary>
    /// <typeparam name="T_Identifier">Type of leaf term identifiers in expression.</typeparam>
    internal class LeafVisitor<T_Identifier> : Visitor<T_Identifier, bool>
    {
        readonly List<TermExpr<T_Identifier>> _terms;

        private LeafVisitor()
        {
            _terms = new List<TermExpr<T_Identifier>>();
        }

        internal static List<TermExpr<T_Identifier>> GetTerms(BoolExpr<T_Identifier> expression)
        {
            Debug.Assert(null != expression, "expression must be given");
            LeafVisitor<T_Identifier> visitor = new LeafVisitor<T_Identifier>();
            expression.Accept(visitor);
            return visitor._terms;
        }

        internal static IEnumerable<T_Identifier> GetLeaves(BoolExpr<T_Identifier> expression) 
        {
            return GetTerms(expression).Select(term => term.Identifier);
        }

        internal override bool VisitTrue(TrueExpr<T_Identifier> expression)
        {
            return true;
        }

        internal override bool VisitFalse(FalseExpr<T_Identifier> expression)
        {
            return true;
        }

        internal override bool VisitTerm(TermExpr<T_Identifier> expression)
        {
            _terms.Add(expression);
            return true;
        }

        internal override bool VisitNot(NotExpr<T_Identifier> expression)
        {
            return expression.Child.Accept(this);
        }

        internal override bool VisitAnd(AndExpr<T_Identifier> expression)
        {
            return VisitTree(expression);
        }

        internal override bool VisitOr(OrExpr<T_Identifier> expression)
        {
            return VisitTree(expression);
        }

        private bool VisitTree(TreeExpr<T_Identifier> expression)
        {
            foreach (BoolExpr<T_Identifier> child in expression.Children)
            {
                child.Accept(this);
            }
            return true;
        }            
    }

    /// <summary>
    /// Rewrites the terms in a Boolean expression tree.
    /// </summary>
    /// <typeparam name="T_From">Term type for leaf nodes of input</typeparam>
    /// <typeparam name="T_To">Term type for leaf nodes of output</typeparam>
    internal class BooleanExpressionTermRewriter<T_From, T_To> : Visitor<T_From, BoolExpr<T_To>>
    {
        private readonly Func<TermExpr<T_From>, BoolExpr<T_To>> _translator;

        /// <summary>
        /// Initialize a new translator
        /// </summary>
        /// <param name="translator">Translator delegate; must not be null</param>
        internal BooleanExpressionTermRewriter(Func<TermExpr<T_From>, BoolExpr<T_To>> translator)
        {
            Debug.Assert(null != translator);
            _translator = translator;
        }

        internal override BoolExpr<T_To> VisitFalse(FalseExpr<T_From> expression)
        {
            return FalseExpr<T_To>.Value;
        }

        internal override BoolExpr<T_To> VisitTrue(TrueExpr<T_From> expression)
        {
            return TrueExpr<T_To>.Value;
        }

        internal override BoolExpr<T_To> VisitNot(NotExpr<T_From> expression)
        {
            return new NotExpr<T_To>(expression.Child.Accept(this));
        }

        internal override BoolExpr<T_To> VisitTerm(TermExpr<T_From> expression)
        {
            return _translator(expression);
        }

        internal override BoolExpr<T_To> VisitAnd(AndExpr<T_From> expression)
        {
            return new AndExpr<T_To>(VisitChildren(expression));
        }

        internal override BoolExpr<T_To> VisitOr(OrExpr<T_From> expression)
        {
            return new OrExpr<T_To>(VisitChildren(expression));
        }

        private IEnumerable<BoolExpr<T_To>> VisitChildren(TreeExpr<T_From> expression)
        {
            foreach (BoolExpr<T_From> child in expression.Children)
            {
                yield return child.Accept(this);
            }
        }
    }

    /// <summary>
    /// Converts a BoolExpr to a Vertex within a solver.
    /// </summary>
    internal class ToDecisionDiagramConverter<T_Identifier> : Visitor<T_Identifier, Vertex>
    {
        private readonly ConversionContext<T_Identifier> _context;

        private ToDecisionDiagramConverter(ConversionContext<T_Identifier> context)
        {
            Debug.Assert(null != context, "must provide a context");
            _context = context;
        }

        internal static Vertex TranslateToRobdd(BoolExpr<T_Identifier> expr, ConversionContext<T_Identifier> context)
        {
            Debug.Assert(null != expr, "must provide an expression");
            ToDecisionDiagramConverter<T_Identifier> converter =
                new ToDecisionDiagramConverter<T_Identifier>(context);
            return expr.Accept(converter);
        }

        internal override Vertex VisitTrue(TrueExpr<T_Identifier> expression)
        {
            return Vertex.One;
        }

        internal override Vertex VisitFalse(FalseExpr<T_Identifier> expression)
        {
            return Vertex.Zero;
        }

        internal override Vertex VisitTerm(TermExpr<T_Identifier> expression)
        {
            return _context.TranslateTermToVertex(expression);
        }

        internal override Vertex VisitNot(NotExpr<T_Identifier> expression)
        {
            return _context.Solver.Not(expression.Child.Accept(this));
        }

        internal override Vertex VisitAnd(AndExpr<T_Identifier> expression)
        {
            return _context.Solver.And(expression.Children.Select(child => child.Accept(this)));
        }

        internal override Vertex VisitOr(OrExpr<T_Identifier> expression)
        {
            return _context.Solver.Or(expression.Children.Select(child => child.Accept(this)));
        }
    }
}