public static IGate SimplifyMultiplicate(IGate g) { Debug.Assert(g.Type == GateType.AND); var or = new ORGate(); or.AddInput(new TrueGate()); IGate r = or; foreach (var e in g.GetInputs()) { if (e.Type == GateType.OR) { r = Gate.Multiply(r.GetInputs(), e.GetInputs()); } else { r = Gate.Multiply(r.GetInputs(), e); } } r = Gate.Simplify(r); TraceSimplify(g, r, "simplify AND"); return r; }
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); }
private IGate EvaluateRecurse(ICodeLabelEvaluator cg, IGate g) { if (g.Type == GateType.Input) { if (g is LabelGate) { var lg = (LabelGate)g; lg.Label.Evaluate(cg); } } else { var list = new List<IGate>(); foreach (var i in g.GetInputs()) { var u = i; var l = _gc.GetScheduledLabel(u); if (null != l) { u = l; } else { u = EvaluateRecurse(cg, u); } list.Add(u); } g = SMG.Common.Gate.Compose(g.Type, list); } return g; }
/// <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; }
/// <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 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; }