Beispiel #1
0
 public VariableNode(StateNode par, string realName, Model.Element elt, string shortName)
     : base(par, realName, elt)
 {
     this.realName = realName;
     name          = new EdgeName(vm.GetUserVariableName(realName));
     ShortName     = shortName;
 }
Beispiel #2
0
        public bool MatchesWords(string[] words, Model.Element[] elts, Model.Element eq, int stateId)
        {
            var node = displayNodes[stateId];

            if (node == null)
            {
                return(false);
            }
            var s1 = LongName(stateId).ToLower();
            var s2 = node.Value.ToLower();

            if (eq != null && node.Element != eq)
            {
                return(false);
            }

            foreach (var w in words)
            {
                if (!s1.Contains(w) && !s2.Contains(w))
                {
                    return(false);
                }
            }

            foreach (var e in elts)
            {
                if (!node.References.Contains(e))
                {
                    return(false);
                }
            }

            return(true);
        }
 protected override void onElementValueChanged(Model.Element element, bool hasValue, int newValue)
 {
     if (NewStep != null)
     {
         NewStep(this, new SudokuNewStepEventArgs(
                     new SudokuSolveStep(element, hasValue ? newValue : default(int?))));
     }
 }
Beispiel #4
0
 public FieldNode(StateNode par, EdgeName realName, Model.Element elt)
     : base(par, realName, elt)
 {
     /*
      * var idx = realName.LastIndexOf('.');
      * if (idx > 0)
      * name = realName.Substring(idx + 1);
      */
 }
Beispiel #5
0
        public virtual void RegisterLocalValue(string name, Model.Element elt)
        {
            string curr;

            if (localValue.TryGetValue(elt, out curr) && CompareFieldNames(name, curr) >= 0)
            {
                return;
            }
            localValue[elt] = name;
        }
Beispiel #6
0
        public Model.Element Image(Model.Element elt, Model.Func f)
        {
            var r = f.AppWithResult(elt);

            if (r != null)
            {
                return(r.Args[0]);
            }
            return(null);
        }
Beispiel #7
0
 private object ToValue(Model.Element elem)
 {
     if (elem is Model.Integer)
     {
         return(Microsoft.BaseTypes.BigNum.FromInt((elem as Model.Integer).AsInt()));
     }
     if (elem is Model.Boolean)
     {
         return((elem as Model.Boolean).Value);
     }
     throw new NotImplementedException("Cannot yet handle this Model.Element type");
 }
Beispiel #8
0
            public FieldName(Model.Element elt, DafnyModel dm)
            {
                Field    = elt;
                NameArgs = new Model.Element[Dims];
                var tpl = dm.f_dim.AppWithArg(0, elt);

                if (tpl != null)
                {
                    Dims     = tpl.Result.AsInt();
                    NameArgs = new Model.Element[Dims];
                    for (int i = Dims; 0 <= --i;)
                    {
                        if (i == 0)
                        {
                            tpl         = dm.f_index_field.AppWithResult(elt);
                            NameArgs[i] = tpl.Args[0];
                        }
                        else
                        {
                            tpl         = dm.f_multi_index_field.AppWithResult(elt);
                            NameArgs[i] = tpl.Args[1];
                            elt         = tpl.Args[0];
                        }
                    }
                }
                // now for the name
                if (Dims == 0)
                {
                    NameFormat = Field.ToString();
                    foreach (var n in Field.Names)
                    {
                        NameFormat = n.Func.Name;
                        int dot = NameFormat.LastIndexOf('.');
                        if (0 <= dot)
                        {
                            NameFormat = NameFormat.Substring(dot + 1);
                        }
                        break;
                    }
                }
                else
                {
                    NameFormat = "[";
                    string sep = "";
                    for (int i = 0; i < Dims; i++)
                    {
                        NameFormat += sep + "%" + i;
                        sep         = ",";
                    }
                    NameFormat += "]";
                }
            }
Beispiel #9
0
        Model.Element Unbox(Model.Element elt)
        {
            var unboxed = f_box.AppWithResult(elt);

            if (unboxed != null)
            {
                return(unboxed.Args[0]);
            }
            else
            {
                return(elt);
            }
        }
Beispiel #10
0
        private IEnumerable <SkeletonItem> NamesFor(Model.Element elt)
        {
            var words = new string[0];
            var elts  = new Model.Element[0];

            foreach (var s in allItems)
            {
                if (s.isPrimary[CurrentState] && s.MatchesWords(words, elts, elt, CurrentState))
                {
                    yield return(s);
                }
            }
        }
Beispiel #11
0
        public virtual string CanonicalName(Model.Element elt)
        {
            string res;

            if (elt == null)
            {
                return("?");
            }
            if (canonicalName.TryGetValue(elt, out res))
            {
                return(res);
            }
            NameSeqSuffix suff;
            var           baseName = CanonicalBaseName(elt, out suff);

            if (baseName == "")
            {
                suff = NameSeqSuffix.Always;
            }

            if (viewOpts.DebugMode && !(elt is Model.Boolean) && !(elt is Model.Number))
            {
                baseName += string.Format("({0})", elt);
                suff      = NameSeqSuffix.WhenNonZero;
            }

            int cnt;

            if (!baseNameUse.TryGetValue(baseName, out cnt))
            {
                cnt = -1;
            }
            cnt++;

            if (suff == NameSeqSuffix.Always || (cnt > 0 && suff == NameSeqSuffix.WhenNonZero))
            {
                res = AppendSuffix(baseName, cnt);
            }
            else
            {
                res = baseName;
            }

            baseNameUse[baseName] = cnt;
            canonicalName.Add(elt, res);
            invCanonicalName[res.Replace(" ", "")] = elt;
            return(res);
        }
Beispiel #12
0
 private static string ExtractValueFromModelElement(Model.Element Element)
 {
     if (Element is Model.BitVector)
     {
         return(((Model.BitVector)Element).Numeral);
     }
     else if (Element is Model.Uninterpreted)
     {
         return("<irrelevant>");
     }
     else if (Element == null)
     {
         return("<null>");
     }
     return(Element.ToString()); //"<unknown>";
 }
Beispiel #13
0
        public DafnyModel(Model m, ViewOptions opts)
            : base(m, opts)
        {
            f_heap_select       = m.MkFunc("[3]", 3);
            f_set_select        = m.MkFunc("[2]", 2);
            f_seq_length        = m.MkFunc("Seq#Length", 1);
            f_seq_index         = m.MkFunc("Seq#Index", 2);
            f_box               = m.MkFunc("$Box", 1);
            f_dim               = m.MkFunc("FDim", 1);
            f_index_field       = m.MkFunc("IndexField", 1);
            f_multi_index_field = m.MkFunc("MultiIndexField", 2);
            f_dtype             = m.MkFunc("dtype", 1);
            f_null              = m.MkFunc("null", 0);

            // collect the array dimensions from the various array.Length functions, and
            // collect all known datatype values
            foreach (var fn in m.Functions)
            {
                if (Regex.IsMatch(fn.Name, "^_System.array[0-9]*.Length[0-9]*$"))
                {
                    int j    = fn.Name.IndexOf('.', 13);
                    int dims = j == 13 ? 1 : int.Parse(fn.Name.Substring(13, j - 13));
                    int idx  = j == 13 ? 0 : int.Parse(fn.Name.Substring(j + 7));
                    foreach (var tpl in fn.Apps)
                    {
                        var             elt = tpl.Args[0];
                        var             len = tpl.Result;
                        Model.Element[] ar;
                        if (!ArrayLengths.TryGetValue(elt, out ar))
                        {
                            ar = new Model.Element[dims];
                            ArrayLengths.Add(elt, ar);
                        }
                        Contract.Assert(ar[idx] == null);
                        ar[idx] = len;
                    }
                }
                else if (fn.Name.StartsWith("#") && fn.Name.IndexOf('.') != -1 && fn.Name[1] != '#')
                {
                    foreach (var tpl in fn.Apps)
                    {
                        var elt = tpl.Result;
                        DatatypeValues.Add(elt, tpl);
                    }
                }
            }
        }
Beispiel #14
0
        protected override string CanonicalBaseName(Model.Element elt, out NameSeqSuffix suff)
        {
            Model.FuncTuple fnTuple;
            suff = NameSeqSuffix.WhenNonZero;
            if (DatatypeValues.TryGetValue(elt, out fnTuple))
            {
                // elt is s a datatype value, make its name be the name of the datatype constructor
                string nm = fnTuple.Func.Name;
                if (fnTuple.Func.Arity == 0)
                {
                    return(nm);
                }
                else
                {
                    return(nm + "(...)");
                }
            }
            var seqLen = f_seq_length.AppWithArg(0, elt);

            if (seqLen != null)
            {
                // elt is a sequence
                return(string.Format("[Length {0}]", seqLen.Result.AsInt()));
            }

            if (elt == f_null.GetConstant())
            {
                return("null");
            }

            var tp = f_dtype.TryEval(elt);

            if (tp != null)
            {
                foreach (var app in tp.References)
                {
                    if (app.Args.Length == 0 && app.Func.Name.StartsWith("class."))
                    {
                        suff = NameSeqSuffix.Always;
                        return(app.Func.Name.Substring(6));
                    }
                }
            }

            return(base.CanonicalBaseName(elt, out suff));
        }
Beispiel #15
0
        // Elements (other than integers and Booleans) get canonical names of the form
        // "<base>'<idx>", where <base> is returned by this function, and <idx> is given
        // starting with 0, and incrementing when there are conflicts between bases.
        //
        // This function needs to return an appropriate base name for the element. It is given
        // the element.
        //
        // A reasonable strategy is to check if it's a name of the local, and if so return it,
        // and otherwise use the type of element (e.g., return "seq" for elements representing
        // sequences). It is also possible to return "" in such cases.
        //
        // The suff output parameter specifies whether the number sequence suffix should be
        // always added, only when it's non-zero, or never.
        protected virtual string CanonicalBaseName(Model.Element elt, out NameSeqSuffix suff)
        {
            string res;

            if (elt is Model.Integer || elt is Model.Boolean)
            {
                suff = NameSeqSuffix.None;
                return(elt.ToString());
            }
            suff = NameSeqSuffix.Always;
            if (UseLocalsForCanonicalNames)
            {
                if (localValue.TryGetValue(elt, out res))
                {
                    return(res);
                }
            }
            return("");
        }
Beispiel #16
0
 internal DafnyModelVariable(DafnyModelState state, Model.Element element,
                             string name, DafnyModelVariable parent)
 {
     this.state = state;
     Element    = element;
     Type       = state.Model.GetDafnyType(element);
     children   = new Dictionary <string, HashSet <DafnyModelVariable> >();
     state.AddVar(element, this);
     if (parent == null)
     {
         Name = name;
     }
     else
     {
         // TODO: a case can be made for refactoring this so that the indices
         // are model-wide rather than state-wide
         Name = "@" + state.VarIndex++;
         parent.AddChild(name, this);
     }
     state.AddVarName(ShortName);
 }
Beispiel #17
0
    public DafnyModel(Model m, ViewOptions opts)
      : base(m, opts)
    {
      f_heap_select = m.MkFunc("[3]", 3);
      f_set_select = m.MkFunc("[2]", 2);
      f_seq_length = m.MkFunc("Seq#Length", 1);
      f_seq_index = m.MkFunc("Seq#Index", 2);
      f_box = m.MkFunc("$Box", 1);
      f_dim = m.MkFunc("FDim", 1);
      f_index_field = m.MkFunc("IndexField", 1);
      f_multi_index_field = m.MkFunc("MultiIndexField", 2);
      f_dtype = m.MkFunc("dtype", 1);
      f_null = m.MkFunc("null", 0);

      // collect the array dimensions from the various array.Length functions, and
      // collect all known datatype values
      foreach (var fn in m.Functions) {
        if (Regex.IsMatch(fn.Name, "^_System.array[0-9]*.Length[0-9]*$")) {
          int j = fn.Name.IndexOf('.', 13);
          int dims = j == 13 ? 1 : int.Parse(fn.Name.Substring(13, j - 13));
          int idx = j == 13 ? 0 : int.Parse(fn.Name.Substring(j + 7));
          foreach (var tpl in fn.Apps) {
            var elt = tpl.Args[0];
            var len = tpl.Result;
            Model.Element[] ar;
            if (!ArrayLengths.TryGetValue(elt, out ar)) {
              ar = new Model.Element[dims];
              ArrayLengths.Add(elt, ar);
            }
            Contract.Assert(ar[idx] == null);
            ar[idx] = len;
          }
        } else if (fn.Name.StartsWith("#") && fn.Name.IndexOf('.') != -1 && fn.Name[1] != '#') {
          foreach (var tpl in fn.Apps) {
            var elt = tpl.Result;
            DatatypeValues.Add(elt, tpl);
          }
        }
      }
    }
Beispiel #18
0
 /// <summary>
 /// Create a new variable to be associated with the given model element in
 /// a given counterexample state or return such a variable if one already
 /// exists.
 /// </summary>
 /// <param name="state"></param>
 /// <param name="element"></param>
 /// <param name="name">the name to be assigned to the variable OR,
 /// if parent != null, the name of the field associated with it. In the later
 /// case, Name is set to some unique id.</param>
 /// <param name="parent">if not null, this variable represents the field of
 /// some parent object</param>
 /// <param name="duplicate">forces the creation of a new variable even if
 /// one already exists </param>
 /// <returns></returns>
 public static DafnyModelVariable Get(DafnyModelState state,
                                      Model.Element element, string name, DafnyModelVariable parent = null,
                                      bool duplicate = false)
 {
     if (state.ExistsVar(element))
     {
         parent?.AddChild(name, state.GetVar(element));
         if (!duplicate)
         {
             return(state.GetVar(element));
         }
         return(new DuplicateVariable(state, state.GetVar(element), name, parent));
     }
     if (state.Model.GetDafnyType(element).Name == "seq")
     {
         return(new SeqVariable(state, element, name, parent));
     }
     if (state.Model.GetDafnyType(element).Name == "map")
     {
         return(new MapVariable(state, element, name, parent));
     }
     return(new DafnyModelVariable(state, element, name, parent));
 }
Beispiel #19
0
 public DisplayNode(ILanguageSpecificModel model, EdgeName n, Model.Element elt)
 {
     langModel = model;
     name      = n;
     element   = elt;
 }
 public SudokuSolveStep(Model.Element element, int?newValue)
 {
     this.element     = element;
     this.originValue = element.Value;
     this.newValue    = newValue;
 }
Beispiel #21
0
        public IEnumerable <ElementNode> GetExpansion(StateNode state, Model.Element elt)
        {
            List <ElementNode> result = new List <ElementNode>();

            return(result);
        }
Beispiel #22
0
 public DisplayNode(ILanguageSpecificModel model, string n, Model.Element elt)
     : this(model, new EdgeName(n), elt)
 {
 }
Beispiel #23
0
 public ElementNode(StateNode st, string name, Model.Element elt)
     : this(st, new EdgeName(name), elt)
 {
 }
Beispiel #24
0
 protected abstract void onElementValueChanged(Model.Element element, bool hasValue, int newValue);
Beispiel #25
0
 public ElementNode(BaseState st, string name, Model.Element elt) : base(st.m, name, elt)
 {
     this.st = st;
 }
Beispiel #26
0
 public ElementNode(StateNode st, EdgeName name, Model.Element elt)
     : base(st.dm, name, elt)
 {
     this.stateNode = st;
     this.elt       = elt;
 }
Beispiel #27
0
 public MapletNode(StateNode par, EdgeName realName, Model.Element elt)
     : base(par, realName, elt)
 {
 }
 protected override void onElementValueChanged(Model.Element element, bool hasValue, int newValue)
 {
     element.Value = hasValue ? newValue : default(int?);
 }
Beispiel #29
0
        /// <summary>
        /// Execute a script function
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="elemt"></param>
        /// <returns></returns>
        public static T ExecuteFunction <T>(Model.Element elemt, FunctionOperation funcOp) where T : struct
        {
            if (funcOp == FunctionOperation.ForReading)
            {
                if (string.IsNullOrWhiteSpace(elemt.Structure.funcr))
                {
                    return((T)Convert.ChangeType(elemt.Value, Type.GetTypeCode(typeof(T))));
                }
            }

            if (funcOp == FunctionOperation.ForWriting)
            {
                if (string.IsNullOrWhiteSpace(elemt.Structure.funcw))
                {
                    return((T)Convert.ChangeType(elemt.Value, Type.GetTypeCode(typeof(T))));
                }
            }

            switch (elemt.Type)
            {
            case ElementValueType.Float:
            case ElementValueType.Int:
            case ElementValueType.Short:
            case ElementValueType.UInt:
            case ElementValueType.UShort:
                break;

            default:
                return((T)Convert.ChangeType(elemt.Value, Type.GetTypeCode(typeof(T))));
            }

            // Parse function name ElementValueType
            string func = elemt.Structure.funcr;

            if (funcOp == FunctionOperation.ForWriting)
            {
                func = elemt.Structure.funcw;
            }
            string[] s1       = func.Split('(');
            string   funcName = s1[0];

            PyFunctionDefinition pyFunc;

            if (!_pyDictionary.TryGetValue(funcName, out pyFunc))
            {
                string msg = "ExecuteReadingFunction: The '" + funcName + "' function doesn't exist !!!";
                MessageBox.Show(msg, "TESSnip Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return((T)Convert.ChangeType(elemt.Value, Type.GetTypeCode(typeof(T))));
            }

            object function = _objOps.GetMember(_snipClassObj, funcName); // get function

            // Parse parameters
            string p     = s1[1].Replace("(", "").Replace(")", "").Trim();
            var    param = new object[0];

            if (!string.IsNullOrWhiteSpace(p))
            {
                string[] parameters = p.Split(',');
                param = new object[parameters.Length];
                for (int i = 0; i < parameters.Length; i++)
                {
                    // management of the decimal separator
                    parameters[i] = parameters[i].Trim();
                    parameters[i] = parameters[i].Replace(".", _ni.CurrencyDecimalSeparator);
                    parameters[i] = parameters[i].Replace(",", _ni.CurrencyDecimalSeparator);
                }

                try
                {
                    for (int i = 0; i < parameters.Length; i++)
                    {
                        switch (pyFunc.Parameters[i + 3]) //+2 jump self, element and value parameter
                        {
                        case "float":
                            param[i] = float.Parse(parameters[i], _ni);
                            break;

                        case "int":
                            param[i] = int.Parse(parameters[i], _ni);
                            break;

                        case "short":
                            param[i] = short.Parse(parameters[i], _ni);
                            break;

                        case "uint":
                            param[i] = uint.Parse(parameters[i], _ni);
                            break;

                        case "ushort":
                            param[i] = ushort.Parse(parameters[i], _ni);
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(string.Format(@"ExecuteReadingFunction: {0}", ex.Message), @"TESSnip Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    throw;
                }
            }

            var result = elemt.Value;

            try
            {
                var el = new PyElement
                {
                    Name       = elemt.Structure.name,
                    Desc       = elemt.Structure.desc,
                    CondId     = elemt.Structure.CondID,
                    FormIdType = elemt.Structure.FormIDType,
                    Flags      = elemt.Structure.flags,
                    Group      = elemt.Structure.@group,
                    Multiline  = elemt.Structure.multiline,
                    NotInInfo  = elemt.Structure.notininfo,
                    Optional   = elemt.Structure.optional,
                    Options    = elemt.Structure.options,
                    Repeat     = elemt.Structure.repeat,
                    FuncRead   = elemt.Structure.funcr,
                    FuncWrite  = elemt.Structure.funcw,
                    ValueType  = elemt.Structure.type
                };

                switch (elemt.Type)
                {
                case ElementValueType.Float:
                    result = _objOps.Invoke(function, el, (float)elemt.Value, param);
                    break;

                case ElementValueType.Int:
                    result = _objOps.Invoke(function, el, (int)elemt.Value, param);
                    break;

                case ElementValueType.Short:
                    result = _objOps.Invoke(function, el, (short)elemt.Value, param);
                    break;

                case ElementValueType.UInt:
                    result = _objOps.Invoke(function, el, (uint)elemt.Value, param);
                    break;

                case ElementValueType.UShort:
                    result = _objOps.Invoke(function, el, (ushort)elemt.Value, param);
                    break;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("ExecuteReadingFunction: {0}", ex.Message), @"TESSnip Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                throw;
            }

            return((T)Convert.ChangeType(result, Type.GetTypeCode(typeof(T))));
        }
Beispiel #30
0
 public FieldName(Model.Element elt, DafnyModel dm) {
   Field = elt;
   NameArgs = new Model.Element[Dims];
   var tpl = dm.f_dim.AppWithArg(0, elt);
   if (tpl != null) {
     Dims = tpl.Result.AsInt();
     NameArgs = new Model.Element[Dims];
     for (int i = Dims; 0 <= --i; ) {
       if (i == 0) {
         tpl = dm.f_index_field.AppWithResult(elt);
         NameArgs[i] = tpl.Args[0];
       } else {
         tpl = dm.f_multi_index_field.AppWithResult(elt);
         NameArgs[i] = tpl.Args[1];
         elt = tpl.Args[0];
       }
     }
   }
   // now for the name
   if (Dims == 0) {
     NameFormat = Field.ToString();
     foreach (var n in Field.Names) {
       NameFormat = n.Func.Name;
       int dot = NameFormat.LastIndexOf('.');
       if (0 <= dot)
         NameFormat = NameFormat.Substring(dot + 1);
       break;
     }
   } else {
     NameFormat = "[";
     string sep = "";
     for (int i = 0; i < Dims; i++) {
       NameFormat += sep + "%" + i;
       sep = ",";
     }
     NameFormat += "]";
   }
 }
Beispiel #31
0
 public ElementNode(StateNode st, EdgeName name, Model.Element elt)
   : base(st.dm, name, elt)
 {
   this.stateNode = st;
   this.elt = elt;
 }
Beispiel #32
0
        private void UpdateMatches(bool force)
        {
            var bad = false;

            Model.Element eltEq  = null;
            var           eltRef = new List <Model.Element>();
            var           words  = new List <string>();

            foreach (var w in textBox1.Text.Split(' '))
            {
                if (w == "")
                {
                    continue;
                }
                if (w.StartsWith("eq:"))
                {
                    if (eltEq != null)
                    {
                        bad = true;
                    }
                    else
                    {
                        eltEq = LangModel.FindElement(w.Substring(3));
                        if (eltEq == null)
                        {
                            bad = true;
                        }
                    }
                }
                else if (w.StartsWith("use:"))
                {
                    var e = LangModel.FindElement(w.Substring(4));
                    if (e == null)
                    {
                        bad = true;
                    }
                    else
                    {
                        eltRef.Add(e);
                    }
                }
                else
                {
                    words.Add(w.ToLower());
                }
            }

            textBox1.ForeColor = bad ? Color.Red : Color.Black;

            var wordsA = words.ToArray();
            var refsA  = eltRef.ToArray();

            if (eltEq == null && wordsA.Length == 0 && refsA.Length == 0)
            {
                bad = true;
            }

            var changed = true; // force;
            var matches = new List <SkeletonItem>();

            foreach (var s in allItems)
            {
                var newMatch = false;
                if (s.isPrimary[CurrentState] && !bad)
                {
                    newMatch = s.MatchesWords(wordsA, refsA, eltEq, CurrentState);
                }
                if (newMatch)
                {
                    matches.Add(s);
                }
                if (s.isMatch != newMatch)
                {
                    changed   = true;
                    s.isMatch = newMatch;
                }
            }

            if (PreviousState >= 0)
            {
                stateList.Items[PreviousState].ForeColor = previousStateBrush.Color;
            }
            stateList.Items[CurrentState].ForeColor = currentStateBrush.Color;

            if (changed)
            {
                SyncListView(matches, matchesList, (di, _) => { di.IsMatchListItem = true; });
                SyncCurrentStateView();
            }
        }
Beispiel #33
0
        public IEnumerable <ElementNode> GetExpansion(StateNode state, Model.Element elt)
        {
            List <ElementNode> result = new List <ElementNode>();

            if (elt.Kind != Model.ElementKind.Uninterpreted)
            {
                return(result);
            }

            // Perhaps elt is a known datatype value
            Model.FuncTuple fnTuple;
            if (DatatypeValues.TryGetValue(elt, out fnTuple))
            {
                // elt is a datatype value
                int i = 0;
                foreach (var arg in fnTuple.Args)
                {
                    var edgname = new EdgeName(this, i.ToString());
                    result.Add(new FieldNode(state, edgname, arg));
                    i++;
                }
                return(result);
            }

            // Perhaps elt is a sequence
            var seqLen = f_seq_length.AppWithArg(0, elt);

            if (seqLen != null)
            {
                // elt is a sequence
                foreach (var tpl in f_seq_index.AppsWithArg(0, elt))
                {
                    var edgname = new EdgeName(this, "[%0]", tpl.Args[1]);
                    result.Add(new FieldNode(state, edgname, Unbox(tpl.Result)));
                }
                return(result);
            }

            // Perhaps elt is a set
            foreach (var tpl in f_set_select.AppsWithArg(0, elt))
            {
                var setElement  = tpl.Args[1];
                var containment = tpl.Result;
                var edgname     = new EdgeName(this, "[%0]", Unbox(setElement));
                result.Add(new FieldNode(state, edgname, containment));
            }
            if (result.Count != 0)
            {
                return(result); // elt is a set
            }
            // It seems elt is an object or array
            Model.Element[] lengths;
            if (ArrayLengths.TryGetValue(elt, out lengths))
            {
                int i = 0;
                foreach (var len in lengths)
                {
                    var name    = lengths.Length == 1 ? "Length" : "Length" + i;
                    var edgname = new EdgeName(this, name);
                    result.Add(new FieldNode(state, edgname, len));
                    i++;
                }
            }
            var heap = state.State.TryGet("$Heap");

            if (heap != null)
            {
                foreach (var tpl in f_heap_select.AppsWithArgs(0, heap, 1, elt))
                {
                    var field = new FieldName(tpl.Args[2], this);
                    if (field.NameFormat != "alloc")
                    {
                        var edgname = new EdgeName(this, field.NameFormat, field.NameArgs);
                        result.Add(new FieldNode(state, edgname, Unbox(tpl.Result)));
                    }
                }
            }
            return(result);
        }