File: System\Text\RegularExpressions\Symbolic\BitVectorSolver.cs
Web Access
Project: src\src\libraries\System.Text.RegularExpressions\src\System.Text.RegularExpressions.csproj (System.Text.RegularExpressions)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
namespace System.Text.RegularExpressions.Symbolic
{
    /// <summary>Provides an <see cref="ISolver{BitVector}"/> over arbitrary-length bit vectors.</summary>
    internal sealed class BitVectorSolver : ISolver<BitVector>
    {
        private readonly BDD[] _minterms;
        internal readonly MintermClassifier _classifier;
        private readonly BitVector[] _mintermVectors;
 
        public BitVectorSolver(BDD[] minterms)
        {
            _minterms = minterms;
 
            _classifier = new MintermClassifier(minterms);
 
            var singleBitVectors = new BitVector[minterms.Length];
            for (int i = 0; i < singleBitVectors.Length; i++)
            {
                singleBitVectors[i] = BitVector.CreateSingleBit(minterms.Length, i);
            }
            _mintermVectors = singleBitVectors;
 
            Empty = BitVector.CreateFalse(minterms.Length);
            Full = BitVector.CreateTrue(minterms.Length);
        }
 
        public BitVector Empty { get; }
        public BitVector Full { get; }
 
        public bool IsFull(BitVector set) => set.Equals(Full);
 
        public bool IsEmpty(BitVector set) => set.Equals(Empty);
 
        public BitVector And(BitVector set1, BitVector set2) => BitVector.And(set1, set2);
 
        public BitVector Not(BitVector set) => BitVector.Not(set);
 
        public BitVector Or(ReadOnlySpan<BitVector> sets) => BitVector.Or(sets);
 
        public BitVector Or(BitVector set1, BitVector set2) => BitVector.Or(set1, set2);
 
        /// <summary>
        /// Assumes that set is a union of some minterms (or empty).
        /// If null then null is returned.
        /// </summary>
        public BitVector ConvertFromBDD(BDD set, CharSetSolver solver)
        {
            BDD[] partition = _minterms;
 
            BitVector result = Empty;
            for (int i = 0; i < partition.Length; i++)
            {
                if (!solver.IsEmpty(solver.And(partition[i], set)))
                {
                    result = BitVector.Or(result, _mintermVectors[i]);
                }
            }
 
            return result;
        }
 
        public BitVector[] GetMinterms() => _mintermVectors;
 
#if DEBUG
        /// <summary>Pretty print the bitvector bv as the character set it represents.</summary>
        public string PrettyPrint(BitVector bv, CharSetSolver solver) => solver.PrettyPrint(ConvertToBDD(bv, solver));
 
        public BDD ConvertToBDD(BitVector set, CharSetSolver solver)
        {
            BDD[] partition = _minterms;
 
            // the result will be the union of all minterms in the set
            BDD result = solver.Empty;
            if (!set.Equals(Empty))
            {
                for (int i = 0; i < partition.Length; i++)
                {
                    // include the i'th minterm in the union if the i'th bit is set
                    if (set[i])
                    {
                        result = solver.Or(result, partition[i]);
                    }
                }
            }
 
            return result;
        }
#endif
    }
}