Example #1
0
        public static IGate SimplifyMultiplicate(IGate g)
        {
            Debug.Assert(g.Type == GateType.AND);

            var or = new ORGate();
            or.AddInput(new TrueGate());

            IGate r = or;

            foreach (var e in g.GetInputs())
            {
                if (e.Type == GateType.OR)
                {
                    r = Gate.Multiply(r.GetInputs(), e.GetInputs());
                }
                else
                {
                    r = Gate.Multiply(r.GetInputs(), e);
                }
            }

            r = Gate.Simplify(r);

            TraceSimplify(g, r, "simplify AND");

            return r;
        }
Example #2
0
        public static IGate SimplifyMultiplicate(IGate g)
        {
            Debug.Assert(g.Type == GateType.AND);

            var or = new ORGate();

            or.AddInput(new TrueGate());

            IGate r = or;

            foreach (var e in g.GetInputs())
            {
                if (e.Type == GateType.OR)
                {
                    r = Gate.Multiply(r.GetInputs(), e.GetInputs());
                }
                else
                {
                    r = Gate.Multiply(r.GetInputs(), e);
                }
            }

            r = Gate.Simplify(r);

            TraceSimplify(g, r, "simplify AND");

            return(r);
        }
Example #3
0
        private static IGate ConsolidateList(List<IGate> list)
        {
            IGate gate;

            if (!list.Any())
            {
                // empty sum => FALSE
                gate = new FalseGate();
            }
            else if (list.Count == 1)
            {
                gate = list.First();
            }
            else
            {
                var or = new ORGate();
                or.AddInputRange(list);
                gate = or;
            }

            return gate;
        }
Example #4
0
        private static IGate ConsolidateList(List <IGate> list)
        {
            IGate gate;

            if (!list.Any())
            {
                // empty sum => FALSE
                gate = new FalseGate();
            }
            else if (list.Count == 1)
            {
                gate = list.First();
            }
            else
            {
                var or = new ORGate();
                or.AddInputRange(list);
                gate = or;
            }

            return(gate);
        }
Example #5
0
        /// <summary>
        /// Multiplies two sums of products
        /// </summary>
        /// <param name="list1"></param>
        /// <param name="list2"></param>
        /// <returns></returns>
        public static IGate Multiply(IEnumerable<IGate> list1, IEnumerable<IGate> list2)
        {
            var r = new ORGate();
            foreach (var a in list1)
            {
                foreach (var b in list2)
                {
                    r.AddInput(ComposeAND(a, b));
                }
            }

            return r;
        }
Example #6
0
        public static IGate ExtractCommonFactors(IGate gate)
        {
            var original = gate;

            if (gate.Type == GateType.OR)
            {
                // TraceOptimize("extract common factors from {0} ...", gate);
                var sop = gate.GetSOP();

                // count how many times each factor appears
                var inmap = new Dictionary<int, IInput>();
                var dict = new SortedList<int, int>();

                foreach (var p in sop.GetPrimitiveFactors())
                {
                    // a gate representing the factors (may be multiple per state variable)
                    var pg = p.ToGate();

                    foreach (var i in pg.GetInputs().OfType<IInput>())
                    {
                        var address = i.Address;
                        // TraceOptimize("check factor {0} @ {1:X6}", i, address);

                        if (!inmap.ContainsKey(i.Address))
                        {
                            inmap.Add(i.Address, i);
                        }

                        if (!dict.ContainsKey(address))
                        {
                            dict[address] = 1;
                        }
                        else
                        {
                            dict[address]++;
                        }

                    }

                }

                var m = dict.Values.Max();
                // TraceOptimize("maximum factor count {0}", m);

                if (m > 1)
                {
                    // go for it, take the first input with maximum multiplicity, inputs are ordered.
                    var pivotindex = dict.Where(e => e.Value == m).Select(e => e.Key).First();
                    var pivot = inmap[pivotindex];

                    var pivotlist = new List<Product>();
                    var otherlist = new List<Product>();

                    TraceOptimize("use pivot {0:X6} ...", pivot);

                    // split sop into two groups: factor or not
                    foreach (var p in sop)
                    {
                        if (p.ContainsFactor(pivot))
                        {
                            p.RemoveInput(pivot);
                            pivotlist.Add(p);
                        }
                        else
                        {
                            otherlist.Add(p);
                        }
                    }

                    IGate and = new ANDGate();
                    and.AddInput(pivot);

                    IGate inneror = new ORGate();
                    foreach (var p in pivotlist)
                    {
                        var z = p.ToGate().Simplify();
                        // Debug.Assert(z.GetInputs().Count() > 1);

                        Trace("adding pivot {0} [{1}]", z, z.GetType().Name);

                        inneror.AddInput(z);
                    }

                    inneror = ExtractCommonFactors(inneror);

                    and.AddInput(inneror);

                    if (otherlist.Any())
                    {
                        //var rh = ExtractCommonFactors(otherlist);

                        var or = new ORGate();
                        or.AddInput(and);

                        foreach (var p in otherlist)
                        {
                            var z = p.ToGate();
                            or.AddInput(z.Simplify());
                        }

                        gate = or;
                    }
                    else
                    {
                        gate = and;
                    }
                }
            }

            if (gate != original && TraceFlags.ShowOptimize)
            {
                Log.TraceGateOp2(original, gate, "optimize AND");
            }

            return gate;
        }
Example #7
0
        /// <summary>
        /// Composes two gates with the logical OR operator.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns>The resulting gate.</returns>
        public static IGate ComposeOR(IGate a, IGate b, ComposeOptions options = ComposeOptions.None)
        {
            IGate result;

            DecomposeExchange(ref a, ref b);

            if (a.Type == GateType.OR && b.Type == GateType.OR)
            {
                var r = new ORGate();
                r.AddInputRange(a.GetInputs());
                r.AddInputRange(b.GetInputs());
                result = r;
            }
            else if (a.Type == GateType.OR)
            {
                var r = new ORGate();
                r.AddInputRange(a.GetInputs());
                r.AddInput(b);
                result = r;
            }
            else
            {
                var r = new ORGate();
                r.AddInput(a);
                r.AddInput(b);
                result = r;
            }

            if (0 == (options & ComposeOptions.NoSimplify))
            {
                result = Simplify(result);
            }

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

            return result;
        }
Example #8
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;
        }
Example #9
0
        private bool SimplifyRule1(ref IGate gate)
        {
            var original = gate;

            var garg = gate as ORGate;
            if(null == garg) return false;

            // handle the rules:
            // A + !A B = A + B
            // A + A B = A
            var gset = garg.GetSOP();

            int changes = 0;

            var gplan = gset.OrderBy(e => e.Inputs.Count()).ToList();
            for (int j = 0; j < gplan.Count; ++j)
            {
                var glist = gplan[j];
                if (glist.IsEmpty) continue;

                TraceSimplify("  product [{0}] : {1}", glist.Signature, glist.ToGate());

                for (int k = j + 1; k < gplan.Count; ++k)
                {
                    var olist = gplan[k];
                    switch (olist.ContainsFactor(glist))
                    {
                        case 1:
                            // contains the sequence => eliminate entry?

                            TraceSimplify("    is contained in {0} ...", olist.ToGate());

                            olist.Clear();
                            changes++;
                            break;

                        case 2:
                            // contains negation => remove negations

                            TraceSimplify("    negation is contained in {0} ...", olist.ToGate());

                            olist.Remove(glist);
                            if(olist.IsEmpty)
                            {
                                // full negation ==> ALL
                                glist.Clear();
                                gset.Fixed = new TrueGate();
                            }
                            changes++;
                            break;
                    }
                }
            }

            gset.Purge();

            if (gset.Fixed != null)
            {
                gate = gset.Fixed;
            }
            else
            {
                // construct an OR expression containing the ordered factors
                var or = new ORGate();
                foreach (var glist in gset.OrderBy(e => e.Signature, StringComparer.Ordinal))
                {
                    or.AddInput(glist.ToGate().Simplify());
                }

                if (or.Inputs.Count() == 0)
                {
                    gate = new FalseGate();
                }
                else if (or.Inputs.Count() == 1)
                {
                    gate = or.Inputs.First();
                }
                else
                {
                    gate = or;
                }
            }

            if (changes > 0)
            {
                TraceSimplify(original, gate, "simplify OR (1)");
            }

            return changes > 0;
        }
Example #10
0
        private bool SimplifyRule1(ref IGate gate)
        {
            var original = gate;

            var garg = gate as ORGate;

            if (null == garg)
            {
                return(false);
            }

            // handle the rules:
            // A + !A B = A + B
            // A + A B = A
            var gset = garg.GetSOP();

            int changes = 0;

            var gplan = gset.OrderBy(e => e.Inputs.Count()).ToList();

            for (int j = 0; j < gplan.Count; ++j)
            {
                var glist = gplan[j];
                if (glist.IsEmpty)
                {
                    continue;
                }

                TraceSimplify("  product [{0}] : {1}", glist.Signature, glist.ToGate());

                for (int k = j + 1; k < gplan.Count; ++k)
                {
                    var olist = gplan[k];
                    switch (olist.ContainsFactor(glist))
                    {
                    case 1:
                        // contains the sequence => eliminate entry?

                        TraceSimplify("    is contained in {0} ...", olist.ToGate());

                        olist.Clear();
                        changes++;
                        break;

                    case 2:
                        // contains negation => remove negations

                        TraceSimplify("    negation is contained in {0} ...", olist.ToGate());

                        olist.Remove(glist);
                        if (olist.IsEmpty)
                        {
                            // full negation ==> ALL
                            glist.Clear();
                            gset.Fixed = new TrueGate();
                        }
                        changes++;
                        break;
                    }
                }
            }

            gset.Purge();

            if (gset.Fixed != null)
            {
                gate = gset.Fixed;
            }
            else
            {
                // construct an OR expression containing the ordered factors
                var or = new ORGate();
                foreach (var glist in gset.OrderBy(e => e.Signature, StringComparer.Ordinal))
                {
                    or.AddInput(glist.ToGate().Simplify());
                }

                if (or.Inputs.Count() == 0)
                {
                    gate = new FalseGate();
                }
                else if (or.Inputs.Count() == 1)
                {
                    gate = or.Inputs.First();
                }
                else
                {
                    gate = or;
                }
            }

            if (changes > 0)
            {
                TraceSimplify(original, gate, "simplify OR (1)");
            }

            return(changes > 0);
        }
Example #11
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);
        }