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