public TapeElement Visit(NaryFunc func)
            {
                return(Compile(func, () =>
                {
                    var terms = func.Terms;
                    var indices = new TapeElement[terms.Count];
                    for (var i = 0; i < terms.Count; ++i)
                    {
                        indices[i] = terms[i].Accept(this);
                    }

                    var element = new Compiled.NaryFunc(func.Eval, func.Diff)
                    {
                        Inputs = MakeInputEdges(() =>
                        {
                            for (var i = 0; i < terms.Count; ++i)
                            {
                                edges.Add(new InputEdge {
                                    Element = indices[i]
                                });
                            }
                        }),
                    };

                    return element;
                }));
            }
            public int Visit(NaryFunc func)
            {
                return(Compile(func, () =>
                {
                    var indicesQuery = from term in func.Terms
                                       select term.Accept(this);
                    var indices = indicesQuery.ToArray();

                    var element = new Compiled.NaryFunc
                    {
                        Eval = func.Eval,
                        Diff = func.Diff,
                        Terms = indices,
                        Inputs = indices.Select(x => new Compiled.InputEdge {
                            Index = x
                        }).ToArray(),
                    };

                    return element;
                }));
            }