public bool FormulasAreTheSame(IFormula firstFormula, IFormula secondFormula) { if (firstFormula == null && secondFormula == null) { return(true); } if (firstFormula == null || secondFormula == null) { return(false); } var firstType = firstFormula.GetType(); var secondType = secondFormula.GetType(); if (firstType != secondType) { return(false); } //nothing more to check for distributed formula or black box formula if (firstFormula.IsDistributed() || firstFormula.IsBlackBox() || firstFormula.IsDynamic()) { return(true); } if (firstFormula.IsConstant()) { var firstConstFormula = firstFormula.DowncastTo <ConstantFormula>(); var secondConstFormula = secondFormula.DowncastTo <ConstantFormula>(); return(firstConstFormula.Value == secondConstFormula.Value); } if (firstFormula.IsExplicit()) { var firstExplicit = firstFormula.DowncastTo <ExplicitFormula>(); var secondExplicit = secondFormula.DowncastTo <ExplicitFormula>(); if (!string.Equals(firstExplicit.FormulaString, secondExplicit.FormulaString)) { return(false); } //check that formula have the same references using the same alias var firstObjectPathCache = new Cache <string, IFormulaUsablePath>(x => x.Alias); firstObjectPathCache.AddRange(firstExplicit.ObjectPaths); var secondObjectPathCache = new Cache <string, IFormulaUsablePath>(x => x.Alias); secondObjectPathCache.AddRange(secondExplicit.ObjectPaths); if (firstObjectPathCache.Count() != secondObjectPathCache.Count()) { return(false); } foreach (var keyValue in firstObjectPathCache.KeyValues) { if (!secondObjectPathCache.Contains(keyValue.Key)) { return(false); } var path = secondObjectPathCache[keyValue.Key]; if (!path.Equals(keyValue.Value)) { return(false); } } } return(true); }