コード例 #1
0
        private Dictionary <AST.Address, string> getAllFormulas(Depends.DAG graph, bool showProgress)
        {
            var frms = graph.getAllFormulaAddrs();

            if (showProgress)
            {
                Progress p = new Progress("Marshaling", frms.Length);
                p.Show();
                p.Refresh();

                var d =
                    frms
                    .Select(addr => {
                    var t = new Tuple <AST.Address, string>(addr, graph.getFormulaAtAddress(addr));
                    p.increment();
                    return(t);
                }).ToDictionary(tup => tup.Item1, tup => tup.Item2);

                p.Hide();

                return(d);
            }
            else
            {
                return
                    (frms
                     .Select(addr => {
                    return new Tuple <AST.Address, string>(addr, graph.getFormulaAtAddress(addr));
                }).ToDictionary(tup => tup.Item1, tup => tup.Item2));
            }
        }
コード例 #2
0
        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());
        }
コード例 #3
0
        private static Group groupFunctions(Depends.DAG graph, Dictionary<AST.Address, string> formulas)
        {
            var functions = new Functions();
            var variables = new Variables();
            var provenance = new Provenance();

            // group formulas and invocations by resultant
            foreach (var f in formulas)
            {
                var addr = f.Key;

                // return all references
                var refs = ExpressionTools.transitiveRefs(addr, graph);

                // compute resultant
                var res = Vector.run(addr, graph);

                // save each 'function'
                if (!functions.ContainsKey(res))
                {
                    functions.Add(res, new List<ExpressionTools.Vector[]>());
                }
                functions[res].Add(refs);

                // assign a fresh variable to each unique reference
                if (!variables.ContainsKey(res))
                {
                    // never seen this function before
                    var vm = new VariableMaker();
                    variables.Add(res, new Dictionary<Countable, string>());

                    // we only want unique path resultants for data
                    var resultants =
                        refs
                            .Where(r => !graph.isFormula(r.Head))
                            .Select(r => ExceLint.Vector.RelativeVector(r.Head, r.Tail, graph))
                            .Distinct();

                    // assign variable
                    foreach (var r in resultants)
                    {
                        if (!variables[res].ContainsKey(r))
                        {
                            variables[res].Add(r, vm.nextVariable());
                        }
                    }
                }

                // track provenance
                if (!provenance.ContainsKey(res))
                {
                    var ps = new List<AST.Address>();
                    provenance.Add(res, ps);
                }
                provenance[res].Add(addr);
            }

            return new Group(functions, variables, provenance);
        }
コード例 #4
0
        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();
        }
コード例 #5
0
        private static ExpressionTools.EData inlineExpression(AST.Address addr, Depends.DAG graph, MemoDBOpt memodb)
        {
            // get top-level AST
            var ast = graph.getASTofFormulaAt(addr);

            // merge subtrees
            return ExpressionTools.flattenExpression(ast, graph, memodb);
        }
コード例 #6
0
 private Dictionary <List <AST.Address>, FPCoreOption> newConvertFormulaGroups(
     Dictionary <Countable, List <AST.Address> > grps,
     Dictionary <AST.Address, ExpressionTools.EData> fexprs,
     Depends.DAG graph,
     bool showProgress)
 {
     throw new Exception("heh");
 }
コード例 #7
0
        // gets the set of shallow intransitive mixed input vectors pointed to by the formula
        private static Tuple <int, int, int>[] getSIMIVs(AST.Address formula, Depends.DAG dag)
        {
            var vs = ExceLint.Vector.getRebasedVectors(formula, dag, isMixed: true, isTransitive: false, isFormula: true, isOffSheetInsensitive: true, isRelative: true, includeConstant: false);

            return(vs.Select(v =>
            {
                if (v.IsConstant)
                {
                    var c = (ExceLint.Vector.RelativeVector.Constant)v;
                    return new Tuple <int, int, int>(c.Item1, c.Item2, c.Item3);
                }
                else
                {
                    var c = (ExceLint.Vector.RelativeVector.NoConstant)v;
                    return new Tuple <int, int, int>(c.Item1, c.Item2, c.Item3);
                }
            }).ToArray());
        }
コード例 #8
0
        private void extractTest_Click(object sender, RibbonControlEventArgs e)
        {
            // get dependence graph
            var graph = new Depends.DAG(getWorkbook(), getApp(), ignore_parse_errors: false, dagBuilt: new DateTime());

            // get all formulas
            var formulas = getAllFormulas(graph, showProgress: true);

            // keep track of problem reports
            var prs = new List <ExtractionLogic.ProblemReport>();

            // extract all
            var fpcores = ExtractionLogic.Extract.extractAll(graph, formulas, prs);

            var output = String.Join("\n\n", fpcores);

            System.Windows.Forms.MessageBox.Show(output);
        }
コード例 #9
0
 public BasicTests()
 {
     _addressModeDAG = AddressModeDAG();
 }
コード例 #10
0
        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;
        }