private IGate SimplifyNormalize(IGate gate) { var list = new List <IGate>(); var inputs = gate.GetInputs(); foreach (var e in gate.GetInputs()) { if (e.Type == GateType.AND) { list.AddRange(e.GetInputs()); } else if (e.Type.IsFixed()) { if (e is FalseGate) { return(e); } } else { list.Add(e); } } var and = new ANDGate(); and.AddInputRange(list); return(and); }
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); }
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> /// 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; }
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; }
private IGate SimplifyNormalize(IGate gate) { var list = new List<IGate>(); var inputs = gate.GetInputs(); foreach (var e in gate.GetInputs()) { if (e.Type == GateType.AND) { list.AddRange(e.GetInputs()); } else if (e.Type.IsFixed()) { if (e is FalseGate) { return e; } } else { list.Add(e); } } var and = new ANDGate(); and.AddInputRange(list); return and; }
public Gate ToGate() { var and = new ANDGate(); and.AddInputRange(Factors.SelectMany(e => e.ToGateList())); return and; }