private static bool FixSentinel(ref Signal signal, Dictionary<Guid, Signal> sentinels, Dictionary<Guid, Signal> signalReplacements) { bool ret = false; while(sentinels.ContainsKey(signal.InstanceId)) // is a sentinel { ret = true; Signal original = sentinels[signal.InstanceId]; Signal final; if(signalReplacements.TryGetValue(original.InstanceId, out final) && !signal.Equals(final)) signal = final; // sentinel was replaced -> replace with replacement else signal = original; // sentinel was not replaced -> replace with original } return ret; // is not a sentinel }
public override bool LeaveSignal(Signal signal, Port parent, bool again, bool root) { // ## POST-MANIPULATE (REPLACED) SIGNALS Signal rep; if(_signalRep.TryGetValue(signal.InstanceId, out rep)) _signalRep[signal.InstanceId] = _visitor.ManipulateSignal(signal, rep, !signal.Equals(rep)); else _signalRep[signal.InstanceId] = _visitor.ManipulateSignal(signal, signal, false); return base.LeaveSignal(signal, parent, again, root); }
/// <summary> /// Returns the coefficient factor in the monomial <see cref="signal"/> /// </summary> /// <returns> /// Constant UndefinedSymbol if <see cref="signal"/> is not a single-variable monomial. /// Otherwise the coefficient factor of the term. /// </returns> /// </returns> /// <remarks><see cref="signal"/> is assumed to be automatic simplified.</remarks> public static Signal MonomialCoefficient(Signal signal, Signal variable, out ValueStructure degree) { if(IsConstantAdditiveIdentity(signal)) { degree = NegativeInfinitySymbol.Instance; return signal; } if(IsAlwaysRational(signal)) { degree = IntegerValue.Zero; return signal; } Signal coeff = IntegerValue.ConstantOne(signal.Context); if(signal.IsDrivenByPortEntity("Multiply", "Std") && signal.DrivenByPort.InputSignalCount == 2 && IsAlwaysRational(signal.DrivenByPort.InputSignals[0])) { coeff = signal.DrivenByPort.InputSignals[0]; signal = signal.DrivenByPort.InputSignals[1]; } if(signal.Equals(variable)) { degree = IntegerValue.One; return coeff; } if(signal.IsDrivenByPortEntity("Power", "Std")) { Signal b = signal.DrivenByPort.InputSignals[0]; Signal e = signal.DrivenByPort.InputSignals[1]; if(b.Equals(variable) && Std.IsAlwaysPositiveInteger(e)) { degree = e.Value; return coeff; } } degree = UndefinedSymbol.Instance; return UndefinedSymbol.Constant(signal.Context); }
/// <summary> /// Evaluates the degree of the single-variable monomial <see cref="signal"/>. /// </summary> /// <returns> /// <see cref="UndefinedSymbol"/> if <see cref="signal"/> is not a single-variable monomial. /// <see cref="NegativeInfinitySymbol"/> if <see cref="signal"/> is zero. /// Otherwise an <see cref="IntegerValue"/> representing the asked degree. /// </returns> /// <remarks><see cref="signal"/> is assumed to be automatic simplified.</remarks> public static ValueStructure MonomialDegree(Signal signal, Signal variable) { if(IsConstantAdditiveIdentity(signal)) return NegativeInfinitySymbol.Instance; if(IsAlwaysRational(signal)) return IntegerValue.Zero; if(signal.IsDrivenByPortEntity("Multiply", "Std") && signal.DrivenByPort.InputSignalCount == 2 && IsAlwaysRational(signal.DrivenByPort.InputSignals[0])) signal = signal.DrivenByPort.InputSignals[1]; if(signal.Equals(variable)) return IntegerValue.One; if(signal.IsDrivenByPortEntity("Power", "Std")) { Signal b = signal.DrivenByPort.InputSignals[0]; Signal e = signal.DrivenByPort.InputSignals[1]; if(b.Equals(variable) && Std.IsAlwaysPositiveInteger(e)) return e.Value; } return UndefinedSymbol.Instance; }
/// <summary> /// Checks whether a signal is a single variable monomial, e.g. '2*x^3' /// </summary> /// <remarks><see cref="signal"/> is assumed to be automatic simplified</remarks> public static bool IsMonomial(Signal signal, Signal variable) { if(IsAlwaysRational(signal)) return true; if(signal.IsDrivenByPortEntity("Multiply", "Std") && signal.DrivenByPort.InputSignalCount == 2 && IsAlwaysRational(signal.DrivenByPort.InputSignals[0])) signal = signal.DrivenByPort.InputSignals[1]; if(signal.Equals(variable)) return true; if(signal.IsDrivenByPortEntity("Power", "Std")) { Signal b = signal.DrivenByPort.InputSignals[0]; Signal e = signal.DrivenByPort.InputSignals[1]; if(b.Equals(variable) && Std.IsAlwaysPositiveInteger(e)) return true; } return false; }
private static IManipulationVisitor CreateSubstituteVisitor(Signal subject, Signal replacement) { return new BasicManipulationVisitor( delegate(Port p) { // ## ESTIMATE PLAN if(p.InputSignals.Contains(subject)) return ManipulationPlan.DoAlter; else return ManipulationPlan.CloneIfChildsAltered; }, delegate(Port port, SignalSet manipulatedInputs, bool hasManipulatedInputs) { // ## MANIPULATE PORT /* NOTE: manipulatedInputs could contain sentinels, that's why * we use the original port inputs instead. */ ReadOnlySignalSet inputs = port.InputSignals; for(int i = 0; i < inputs.Count; i++) if(subject.Equals(inputs[i])) manipulatedInputs[i] = replacement; return port.CloneWithNewInputs(manipulatedInputs).OutputSignals; }, delegate(Signal original, Signal replaced, bool isReplaced) { // ## POST-MANIPULATE SIGNAL if(subject.Equals(replaced)) return replacement; else return replaced; }); }