/// <summary> /// Adds inputs and outputs to <tt>source</tt> and <tt>target</tt> such /// that <tt>source</tt> becomes an input to <tt>target</tt>. /// </summary> /// <param name="source">A component.</param> /// <param name="target">A second component.</param> private static void Link(IComponent source, IComponent target) { source.AddOutput(target); target.AddInput(source); }
/// <summary> /// Adds an or gate connecting the inputs to produce the output. /// Handles special optimization cases like a true/false input. /// </summary> private static void Orify(ICollection<IComponent> inputs, IComponent output, IConstant falseProp) { //TODO: Look for already-existing ors with the same inputs? //Or can this be handled with a GDL transformation? //Special case: An input is the true constant IEnumerable<IComponent> trueConstants = inputs.Where(input => input is IConstant && input.Value); foreach (IComponent input in trueConstants) { //True constant: connect that to the component, done input.AddOutput(output); output.AddInput(input); return; } //Special case: An input is "or" //I'm honestly not sure how to handle special cases here... //What if that "or" gate has multiple outputs? Could that happen? //For reals... just skip over any false constants var or = _componentFactory.CreateOr(); IEnumerable<IComponent> nonConstants = inputs.Where(input => !(input is IConstant)); foreach (IComponent input in nonConstants) { input.AddOutput(or); or.AddInput(input); } //What if they're all false? (Or inputs is empty?) Then no inputs at this point... if (!or.Inputs.Any()) { //Hook up to "false" falseProp.AddOutput(output); output.AddInput(falseProp); return; } //If there's just one, on the other hand, don't use the or gate if (or.Inputs.Count == 1) { IComponent input = or.GetSingleInput(); input.RemoveOutput(or); or.RemoveInput(input); input.AddOutput(output); output.AddInput(input); return; } or.AddOutput(output); output.AddInput(or); }
private void Andify(List<IComponent> inputs, IComponent output, IConstant trueProp) { //Special case: If the inputs include false, connect false to thisComponent IEnumerable<IComponent> falseConstants = inputs.Where(c => c is IConstant && !c.Value); foreach (IComponent c in falseConstants) { //Connect false (c) to the output output.AddInput(c); c.AddOutput(output); return; } //For reals... just skip over any true constants var and = _componentFactory.CreateAnd(); IEnumerable<IComponent> nonConstants = inputs.Where(input => !(input is IConstant)); foreach (IComponent input in nonConstants) { input.AddOutput(and); and.AddInput(input); } //What if they're all true? (Or inputs is empty?) Then no inputs at this point... if (!and.Inputs.Any()) { //Hook up to "true" trueProp.AddOutput(output); output.AddInput(trueProp); return; } //If there's just one, on the other hand, don't use the and gate if (and.Inputs.Count == 1) { IComponent input = and.GetSingleInput(); input.RemoveOutput(and); and.RemoveInput(input); input.AddOutput(output); output.AddInput(input); return; } and.AddOutput(output); output.AddInput(and); }