/// <summary> /// Multiplies a sum of products with a gate other than an OR gate. /// </summary> /// <param name="list"></param> /// <param name="b"></param> /// <returns></returns> public static IGate Multiply(IEnumerable <IGate> list, IGate b) { var r = new ORGate(); foreach (var a in list) { r.AddInput(ComposeAND(a, b)); } return(r); }
/// <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); }
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); }