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