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; }
/// <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; }
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); }
/// <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); }