コード例 #1
0
        private IGate SimplifyProductOfInputs(Product dict)
        {
            IGate result = null;

            var factors = new List <Factor>();

            foreach (var f in dict.Factors)
            {
                if (f.IsConstant)
                {
                    if (f.Constant is FalseGate)
                    {
                        result = f.Constant;
                        break;
                    }
                }
                else
                {
                    factors.Add(f);
                }
            }

            if (null == result)
            {
                var gatelist = factors.SelectMany(e => e.ToGateList()).GetEnumerator();
                if (!gatelist.MoveNext())
                {
                    result = new TrueGate();
                }
                else
                {
                    result = Gate.Simplify(gatelist.Current);
                    if (gatelist.MoveNext())
                    {
                        var and = new ANDGate();
                        and.AddInput(result);

                        do
                        {
                            var e = Gate.Simplify(gatelist.Current);
                            and.AddInput(e);
                        }while (gatelist.MoveNext());

                        result = and;
                    }
                }
            }

            return(result);
        }
コード例 #2
0
        private static void SimplifyConstants(ref IGate gate)
        {
            var inputs = gate.GetInputs();
            var list   = new List <IGate>();

            foreach (var i in inputs)
            {
                if (i is TrueGate)
                {
                    // sum is constant => TRUE
                    gate = new TrueGate();
                    return;
                }
                else if (i is FalseGate)
                {
                    // remove any FALSE gates ...
                }
                else if (i.GetNestingLevel() > 1)
                {
                    var r = i.Simplify();
                    if (r.Type == GateType.OR)
                    {
                        list.AddRange(r.GetInputs());
                    }
                    else
                    {
                        list.Add(r);
                    }
                }
                else
                {
                    var r = i.Simplify();
                    list.Add(r);
                }
            }

            gate = ConsolidateList(list);
        }
コード例 #3
0
ファイル: Gate.cs プロジェクト: thomas13335/smg
        /// <summary>
        /// Returns a gate that represents the inverted output of another gate.
        /// </summary>
        /// <param name="a">The gate to be inverted.</param>
        /// <returns>The inverted gate.</returns>
        public static IGate Invert(IGate g)
        {
            IGate result;
            IGate a = Decompose(g);

            if (a.Type == GateType.OR)
            {
                var it = a.GetInputs().GetEnumerator();
                it.MoveNext();
                var r = Invert(it.Current);
                while (it.MoveNext())
                {
                    r = ComposeAND(r, Invert(it.Current));
                }

                result = r;
            }
            else if (a.Type == GateType.AND)
            {
                var it = a.GetInputs().GetEnumerator();
                it.MoveNext();
                var r = Invert(it.Current);
                while (it.MoveNext())
                {
                    r = ComposeOR(r, Invert(it.Current));
                }

                result = r;
            }
            else if (a.Type == GateType.Input)
            {
                result = ((IInput)a).Invert();
            }
            else if(a.Type == GateType.Fixed)
            {
                if(a is TrueGate)
                {
                    result = new FalseGate();
                }
                else
                {
                    result = new TrueGate();
                }
            }
            else
            {
                throw new ArgumentException();
            }

            result = Simplify(result);

            TraceCompose(g, result, "invert");

            return result;
        }
コード例 #4
0
ファイル: Gate.cs プロジェクト: thomas13335/smg
        public static IGate ComposeAND(IEnumerable<IGate> gates)
        {
            IGate r = new TrueGate();
            var it = gates.GetEnumerator();
            while (it.MoveNext())
            {
                r = ComposeAND(r, it.Current);
            }

            return r;
        }
コード例 #5
0
ファイル: Gate.cs プロジェクト: thomas13335/smg
        /// <summary>
        /// Composes two gates with the logical AND operator.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns>The resulting gate.</returns>
        public static IGate ComposeAND(IGate a, IGate b)
        {
            IGate result;

            DecomposeExchange(ref a, ref b);

            if(a.Type == GateType.Fixed && b.Type == GateType.Fixed)
            {
                if(a is TrueGate && b is TrueGate)
                {
                    result = new TrueGate();
                }
                else
                {
                    result = new FalseGate();
                }
            }
            else if(b.Type == GateType.Fixed)
            {
                if(b is TrueGate)
                {
                    result = a;
                }
                else
                {
                    result = new FalseGate();
                }
            }
            else if (a.Type == GateType.OR && b.Type == GateType.OR)
            {
                result = Multiply(a.GetInputs(), b.GetInputs());
            }
            else if (a.Type == GateType.OR)
            {
                result = Multiply(a.GetInputs(), b);
            }
            else if (a.Type == GateType.AND && b.Type == GateType.AND)
            {
                // compose
                var r = new ANDGate();
                r.AddInputRange(a.GetInputs());
                r.AddInputRange(b.GetInputs());
                result = r;
            }
            else if (a.Type == GateType.AND)
            {
                // compose
                var r = new ANDGate();
                r.AddInputRange(a.GetInputs());
                r.AddInput(b);
                result = r;
            }
            else
            {
                var r = new ANDGate();
                r.AddInput(a);
                r.AddInput(b);
                result = r;
            }

            // simplify and cache
            result = Simplify(result);

            TraceCompose(a, b, result, "AND");

            return result;
        }
コード例 #6
0
ファイル: ANDGate.cs プロジェクト: thomas13335/smg
        private IGate SimplifyProductOfInputs(Product dict)
        {
            IGate result = null;

            var factors = new List<Factor>();

            foreach (var f in dict.Factors)
            {
                if (f.IsConstant)
                {
                    if (f.Constant is FalseGate)
                    {
                        result = f.Constant;
                        break;
                    }
                }
                else
                {
                    factors.Add(f);
                }
            }

            if (null == result)
            {
                var gatelist = factors.SelectMany(e => e.ToGateList()).GetEnumerator();
                if (!gatelist.MoveNext())
                {
                    result = new TrueGate();
                }
                else
                {
                    result = Gate.Simplify(gatelist.Current);
                    if (gatelist.MoveNext())
                    {
                        var and = new ANDGate();
                        and.AddInput(result);

                        do
                        {
                            var e = Gate.Simplify(gatelist.Current);
                            and.AddInput(e);
                        }
                        while (gatelist.MoveNext());

                        result = and;
                    }
                }
            }

            return result;
        }
コード例 #7
0
ファイル: ORGate.cs プロジェクト: thomas13335/smg
        private static void SimplifyConstants(ref IGate gate)
        {
            var inputs = gate.GetInputs();
            var list = new List<IGate>();

            foreach (var i in inputs)
            {
                if (i is TrueGate)
                {
                    // sum is constant => TRUE
                    gate = new TrueGate();
                    return;
                }
                else if (i is FalseGate)
                {
                    // remove any FALSE gates ...
                }
                else if (i.GetNestingLevel() > 1)
                {
                    var r = i.Simplify();
                    if (r.Type == GateType.OR)
                    {
                        list.AddRange(r.GetInputs());
                    }
                    else
                    {
                        list.Add(r);
                    }
                }
                else
                {
                    var r = i.Simplify();
                    list.Add(r);
                }
            }

            gate = ConsolidateList(list);
        }
コード例 #8
0
ファイル: ORGate.cs プロジェクト: thomas13335/smg
        /// <summary>
        /// Looks for common subfactors.
        /// </summary>
        /// <param name="gate"></param>
        private bool SimplifyRule2(ref IGate gate)
        {
            var originalgate = gate;

            var gset = gate.GetSOP();

            // try all elementary factors ...
            foreach (var elementaryfactor in gset.GetPrimitiveFactors().ToArray())
            {
                // Trace("trying factor {0}", elementaryfactor);

                // collect all products that contain the factor as candidates
                var candidates = new List<Product>();
                foreach (var p in gset)
                {
                    if (1 == p.ContainsFactor(elementaryfactor))
                    {
                        candidates.Add(p);
                    }
                }

                // need at least two
                if (candidates.Count < 2)
                {
                    continue;
                }

                TraceSimplify("common factor {0} found in {1} ...", elementaryfactor, candidates.ToSeparatorList());

                // construct a new gate consisting of the sum of remaining products
                var reducedsum = new ORGate();
                Gate newgate = reducedsum;

                foreach (var involvedproduct in candidates)
                {
                    var reducedproduct = involvedproduct.Clone();
                    reducedproduct.Remove(elementaryfactor);
                    if (reducedproduct.Factors.Any())
                    {
                        reducedsum.AddInput(reducedproduct.ToGate());
                    }
                    else
                    {
                        // candidate equals elementary factor => TRUE
                        newgate = new TrueGate();
                        break;
                    }
                }

                // remove original elements from the set
                foreach (var x in candidates)
                {
                    gset.Remove(x);
                }

                // simplify the resulting gate recursively
                var partialsum = newgate.Simplify();

                var factor = elementaryfactor.ToGate();

                TraceSimplify("  is ({0}) AND {1}", partialsum, factor);

                if (partialsum.Type == GateType.Fixed)
                {
                    if (partialsum is TrueGate)
                    {
                        // factor only
                        gate = factor;
                    }
                    else
                    {
                        // simplification yields FALSE
                        gate = partialsum;
                    }
                }
                else if (partialsum.Type == GateType.AND)
                {
                    // multiply with factor
                    gate = Gate.Multiply(factor.GetInputs(), partialsum);
                }
                else if (partialsum.Type == GateType.OR)
                {
                    // multiply with all factors
                    gate = Gate.Multiply(factor.GetInputs(), partialsum.GetInputs());
                }
                else
                {
                    // multiply with factor
                    gate = Gate.Multiply(factor.GetInputs(), partialsum);
                }

                // compose with the remaining terms
                foreach (var term in gset.Select(e => e.ToGate()))
                {
                    gate = Gate.ComposeOR(gate, term, ComposeOptions.NoSimplify);
                }
                break;
            }

            if (gate != originalgate)
            {
                Gate.TraceSimplify(originalgate, gate, "simplify OR (2)");
            }

            return gate != originalgate;
        }
コード例 #9
0
        /// <summary>
        /// Looks for common subfactors.
        /// </summary>
        /// <param name="gate"></param>
        private bool SimplifyRule2(ref IGate gate)
        {
            var originalgate = gate;

            var gset = gate.GetSOP();

            // try all elementary factors ...
            foreach (var elementaryfactor in gset.GetPrimitiveFactors().ToArray())
            {
                // Trace("trying factor {0}", elementaryfactor);

                // collect all products that contain the factor as candidates
                var candidates = new List <Product>();
                foreach (var p in gset)
                {
                    if (1 == p.ContainsFactor(elementaryfactor))
                    {
                        candidates.Add(p);
                    }
                }

                // need at least two
                if (candidates.Count < 2)
                {
                    continue;
                }

                TraceSimplify("common factor {0} found in {1} ...", elementaryfactor, candidates.ToSeparatorList());

                // construct a new gate consisting of the sum of remaining products
                var  reducedsum = new ORGate();
                Gate newgate    = reducedsum;

                foreach (var involvedproduct in candidates)
                {
                    var reducedproduct = involvedproduct.Clone();
                    reducedproduct.Remove(elementaryfactor);
                    if (reducedproduct.Factors.Any())
                    {
                        reducedsum.AddInput(reducedproduct.ToGate());
                    }
                    else
                    {
                        // candidate equals elementary factor => TRUE
                        newgate = new TrueGate();
                        break;
                    }
                }

                // remove original elements from the set
                foreach (var x in candidates)
                {
                    gset.Remove(x);
                }

                // simplify the resulting gate recursively
                var partialsum = newgate.Simplify();

                var factor = elementaryfactor.ToGate();

                TraceSimplify("  is ({0}) AND {1}", partialsum, factor);

                if (partialsum.Type == GateType.Fixed)
                {
                    if (partialsum is TrueGate)
                    {
                        // factor only
                        gate = factor;
                    }
                    else
                    {
                        // simplification yields FALSE
                        gate = partialsum;
                    }
                }
                else if (partialsum.Type == GateType.AND)
                {
                    // multiply with factor
                    gate = Gate.Multiply(factor.GetInputs(), partialsum);
                }
                else if (partialsum.Type == GateType.OR)
                {
                    // multiply with all factors
                    gate = Gate.Multiply(factor.GetInputs(), partialsum.GetInputs());
                }
                else
                {
                    // multiply with factor
                    gate = Gate.Multiply(factor.GetInputs(), partialsum);
                }

                // compose with the remaining terms
                foreach (var term in gset.Select(e => e.ToGate()))
                {
                    gate = Gate.ComposeOR(gate, term, ComposeOptions.NoSimplify);
                }
                break;
            }

            if (gate != originalgate)
            {
                Gate.TraceSimplify(originalgate, gate, "simplify OR (2)");
            }

            return(gate != originalgate);
        }