private static FPCoreAST.FPCore convertToFPCore( Group g, Fingerprint fingerprint, Dictionary<Source, ExpressionTools.EData> edatas, Depends.DAG graph, PreList prelist) { // get invocations for this function var f_invocations = g.Functions[fingerprint]; var invocation = f_invocations.First(); var faddr = invocation.First().Tail; // get bindings for this invocation var bindings = new Dictionary<Tuple<AST.Address,bool,bool>, string>(); foreach (var vectref in invocation) { var ref_resultant = ExceLint.Vector.RelativeVector(vectref.Head, vectref.Tail, graph); // not every vector gets a variable (e.g., references to functions) if (g.Variables[fingerprint].ContainsKey(ref_resultant)) { var variable = g.Variables[fingerprint][ref_resultant]; var key = AddrToBindingKey(vectref.Head); if (!bindings.ContainsKey(key)) { bindings.Add(key, variable); } } } return XL2FPCore.FormulaToFPCore(edatas[faddr].Expression, prelist, bindings, g.Provenance[fingerprint].ToArray()); }
public static string[] extractAll(Depends.DAG graph, Dictionary<AST.Address, string> formulas, List<ProblemReport> pr) { // init MemoDB var mdbo = MemoDBOpt.Some(new MemoDBO()); // group formulas by 'function' var g = groupFunctions(graph, formulas); // allocate return array var fpcores = new List<string>(); // produce a string for each fingerprinted 'function' foreach (var fkvp in g.Functions) { Fingerprint fingerprint = fkvp.Key; // the fingerprint that characterizes the 'function' var invocations = fkvp.Value; // invocations of this function Dictionary<Source, ExpressionTools.EData> edatas = null; try { // inline all formulas and index by invoking cell address edatas = invocations.Select(references => { var faddr = references[0].Tail; return new Tuple<Source, ExpressionTools.EData>(faddr, inlineExpression(faddr, graph, mdbo)); }).ToDictionary(kvp => kvp.Item1, kvp => kvp.Item2); } catch (Exception) { // TODO: fix occasional out-of-bounds error for invocations_for_addr[0] pr.Add(new NoReferencesForInvocation(fingerprint, graph.getWorkbookName())); continue; } PreList prelist = null; try { // generate prelist prelist = makePreList(g, fingerprint, edatas, graph); } catch (Exception) { // sometimes aliasing bugs pop up; if that happens, move on pr.Add(new AliasingDetected(fingerprint, graph.getWorkbookName())); continue; } // convert an arbitrary instance of this 'function' try { var fpcore = convertToFPCore(g, fingerprint, edatas, graph, prelist); fpcores.Add(fpcore.ToExpr(0)); } catch (Exception e) { // we can't convert everything; give up pr.Add(new CannotConvertExpression(fingerprint, graph.getWorkbookName(), e.Message)); } } return fpcores.ToArray(); }
public void NormalizedFullCVectorResultantTest() { // tests resultant normalization var dag = DAGWithMultipleFormulasAndConstants(); var wbname = dag.getWorkbookName(); var wsname = dag.getWorksheetNames()[0]; var path = dag.getWorkbookDirectory(); var formula_b1 = AST.Address.fromA1withMode(1, "B", AST.AddressMode.Relative, AST.AddressMode.Relative, wsname, wbname, path); var formula_b2 = AST.Address.fromA1withMode(2, "B", AST.AddressMode.Relative, AST.AddressMode.Relative, wsname, wbname, path); var formula_b3 = AST.Address.fromA1withMode(3, "B", AST.AddressMode.Relative, AST.AddressMode.Relative, wsname, wbname, path); var formula_b4 = AST.Address.fromA1withMode(4, "B", AST.AddressMode.Relative, AST.AddressMode.Relative, wsname, wbname, path); var resultant_b1 = (Resultant)ExceLint.Vector.ShallowInputVectorMixedFullCVectorResultantNotOSI.run(formula_b1, dag); var resultant_b1_shouldbe = Resultant.NewFullCVectorResultant(2, 1, 0, -1, 0, 0, 3); Assert.AreEqual(resultant_b1_shouldbe, resultant_b1); var resultant_b2 = (Resultant)ExceLint.Vector.ShallowInputVectorMixedFullCVectorResultantNotOSI.run(formula_b2, dag); var resultant_b2_shouldbe = Resultant.NewFullCVectorResultant(2, 2, 0, -1, 0, 0, 1); Assert.AreEqual(resultant_b2_shouldbe, resultant_b2); var resultant_b3 = (Resultant)ExceLint.Vector.ShallowInputVectorMixedFullCVectorResultantNotOSI.run(formula_b3, dag); var resultant_b3_shouldbe = Resultant.NewFullCVectorResultant(2, 3, 0, -1, 0, 0, 0); Assert.AreEqual(resultant_b3_shouldbe, resultant_b3); var resultant_b4 = (Resultant)ExceLint.Vector.ShallowInputVectorMixedFullCVectorResultantNotOSI.run(formula_b4, dag); var resultant_b4_shouldbe = Resultant.NewFullCVectorResultant(2, 4, 0, -2, -3, 0, 8); Assert.AreEqual(resultant_b4_shouldbe, resultant_b4); Resultant[] rs = { resultant_b1, resultant_b2, resultant_b3, resultant_b4 }; ExceLint.Countable[] rs_normalized = ExceLint.Countable.Normalize(rs); ExceLint.Countable rs_normalized_b1 = Resultant.NewFullCVectorResultant(0, 0, 0, 1.0, 1.0, 0.0, 0.375); ExceLint.Countable rs_normalized_b2 = Resultant.NewFullCVectorResultant(0, 1.0 / 3.0, 0, 1.0, 1.0, 0.0, 0.125); ExceLint.Countable rs_normalized_b3 = Resultant.NewFullCVectorResultant(0, 2.0 / 3.0, 0, 1.0, 1.0, 0.0, 0.0); ExceLint.Countable rs_normalized_b4 = Resultant.NewFullCVectorResultant(0, 1, 0, 0.0, 0.0, 0.0, 1.0); ExceLint.Countable[] rs_normalized_shouldbe = { rs_normalized_b1, rs_normalized_b2, rs_normalized_b3, rs_normalized_b4 }; Assert.AreEqual(rs_normalized[0], rs_normalized_b1); Assert.AreEqual(rs_normalized[1], rs_normalized_b2); Assert.AreEqual(rs_normalized[2], rs_normalized_b3); Assert.AreEqual(rs_normalized[3], rs_normalized_b4); }
private static PreList makePreList(Group g, Fingerprint fingerprint, Dictionary<Source, ExpressionTools.EData> edatas, Depends.DAG graph) { // produce prelist var prelist = new PreList(); foreach (var f_invocations in g.Functions[fingerprint]) { var bindings = new Dictionary<string, double>(); foreach (var vectref in f_invocations) { var ref_resultant = ExceLint.Vector.RelativeVector(vectref.Head, vectref.Tail, graph); // not every vector gets a variable (e.g., vectors that point to functions); // if so, move on if (g.Variables[fingerprint].ContainsKey(ref_resultant)) { var variable = g.Variables[fingerprint][ref_resultant]; // only bind values to variables if a reference refers // to data, not a formula if (edatas[vectref.Tail].Data.ContainsKey(vectref.Head)) { var value = edatas[vectref.Tail].Data[vectref.Head]; // have we already bound a variable to this value? if (bindings.ContainsKey(variable)) { // it had better be the same value, dude if (bindings[variable] != value) { throw new Exception("Same reference bound to different value!"); } else { continue; } } bindings.Add(variable, value); } } } prelist.Add(bindings); } return prelist; }
public CannotConvertExpression(Fingerprint f, string worksheet, string exception_message) { _f = f; _w = worksheet; _em = exception_message; }
public AliasingDetected(Fingerprint f, string worksheet) { _f = f; _w = worksheet; }
public NoReferencesForInvocation(Fingerprint f, string worksheet) { _f = f; _w = worksheet; }