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; }
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); }
/// <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 ComposeOR(IEnumerable<IGate> gates) { IGate r = new FalseGate(); var it = gates.GetEnumerator(); while (it.MoveNext()) { r = ComposeOR(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 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; }
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); }