示例#1
0
    public static IEnumerable<object> EvaluateTacnyExpression(ProofState state, Expression expr) {
      Contract.Requires<ArgumentNullException>(state != null, "state");
      Contract.Requires<ArgumentNullException>(expr != null, "expr");
      if (expr is NameSegment) {
        var ns = (NameSegment)expr;
        if (state.HasLocalValue(ns.Name)) {
          yield return state.GetLocalValue(ns.Name);
        } else {
          yield return ns;
        }
      } else if (expr is ApplySuffix) {
        var aps = (ApplySuffix)expr;
        if (state.IsTacticCall(aps)) {
          var us = new UpdateStmt(aps.tok, aps.tok, new List<Expression>() { aps.Lhs },
            new List<AssignmentRhs>() { new ExprRhs(aps) });
          foreach (var item in ApplyNestedTactic(state, state.DafnyVars(), us).Select(x => x.GetGeneratedCode())) {
            yield return item;
          }
        }
        // rewrite the expression
        if (aps.Lhs is ExprDotName) {
          foreach (var item in EvaluateTacnyExpression(state, aps.Lhs)) {
            if (item is Expression) {
              yield return new ApplySuffix(aps.tok, (Expression)item, aps.Args);
            } else {
              Contract.Assert(false, "Unexpected ExprNotName case");
            }
          }
        } else {
          // try to evaluate as tacny expression
          string sig = Util.GetSignature(aps);
          // using reflection find all classes that extend EAtomic
          var types =
            Assembly.GetAssembly(typeof(EAtomic.EAtomic)).GetTypes().Where(t => t.IsSubclassOf(typeof(EAtomic.EAtomic)));
          foreach (var type in types) {
            var resolverInstance = Activator.CreateInstance(type) as EAtomic.EAtomic;
            if (sig == resolverInstance?.Signature) {
              //TODO: validate input countx
              foreach (var item in resolverInstance?.Generate(aps, state))
                yield return item;
            }
            // if we reached this point, rewrite  the apply suffix
            foreach (var item in EvaluateTacnyExpression(state, aps.Lhs)) {
              if (!(item is NameSegment)) {
                //TODO: warning
              } else {
                var argList = new List<Expression>();
                foreach (var arg in aps.Args) {
                  foreach (var result in EvaluateTacnyExpression(state, arg)) {
                    if (result is Expression)
                      argList.Add(result as Expression);
                    else
                      argList.Add(Util.VariableToExpression(result as IVariable));
                    break;
                  }
                }
                yield return new ApplySuffix(aps.tok, aps.Lhs, argList);
              }
            }

          }
        }
      } else if (expr is ExprDotName) {
        var edn = (ExprDotName)expr;
        var ns = edn.Lhs as NameSegment;
        if (ns != null && state.ContainsVariable(ns)) {
          var newLhs = state.GetLocalValue(ns);
          var lhs = newLhs as Expression;
          if (lhs != null)
            yield return new ExprDotName(edn.tok, lhs, edn.SuffixName, edn.OptTypeArguments);
        }
        yield return edn;
      } else if (expr is UnaryOpExpr) {
        var op = (UnaryOpExpr)expr;
        foreach (var result in EvaluateTacnyExpression(state, op.E)) {
          switch (op.Op) {
            case UnaryOpExpr.Opcode.Cardinality:
              if (!(result is IEnumerable)) {
                var resultExp = result is IVariable
                  ? Util.VariableToExpression(result as IVariable)
                  : result as Expression;
                yield return new UnaryOpExpr(op.tok, op.Op, resultExp);
              } else {
                var enumerator = result as IList;
                if (enumerator != null)
                  yield return new Dafny.LiteralExpr(op.tok, enumerator.Count);
              }
              yield break;
            case UnaryOpExpr.Opcode.Not:
              if (result is Dafny.LiteralExpr) {
                var lit = (Dafny.LiteralExpr)result;
                if (lit.Value is bool) {
                  // inverse the bool value
                  yield return new Dafny.LiteralExpr(op.tok, !(bool)lit.Value);
                } else {
                  Contract.Assert(false);
                  //TODO: error message
                }
              } else {
                var resultExp = result is IVariable ? Util.VariableToExpression(result as IVariable) : result as Expression;
                yield return new UnaryOpExpr(op.tok, op.Op, resultExp);
              }
              yield break;
            default:
              Contract.Assert(false, "Unsupported Unary Operator");
              yield break;
          }
        }
      } else if (expr is DisplayExpression) {
        var dexpr = (DisplayExpression)expr;
        if (dexpr.Elements.Count == 0) {
          yield return dexpr.Copy();
        } else {
          foreach (var item in ResolveDisplayExpression(state, dexpr)) {
            yield return item;
          }

        }
      } else { yield return expr; }
    }
示例#2
0
        public static IEnumerable <object> EvaluateTacnyExpression(ProofState state, Expression expr)
        {
            Contract.Requires <ArgumentNullException>(state != null, "state");
            Contract.Requires <ArgumentNullException>(expr != null, "expr");
            if (expr is NameSegment)
            {
                var ns = (NameSegment)expr;
                if (state.HasLocalValue(ns.Name))
                {
                    yield return(state.GetLocalValue(ns.Name));
                }
                else
                {
                    yield return(ns);
                }
            }
            else if (expr is ApplySuffix)
            {
                var aps = (ApplySuffix)expr;
                if (state.IsTacticCall(aps))
                {
                    var us = new UpdateStmt(aps.tok, aps.tok, new List <Expression>()
                    {
                        aps.Lhs
                    },
                                            new List <AssignmentRhs>()
                    {
                        new ExprRhs(aps)
                    });
                    foreach (var item in ApplyNestedTactic(state, state.DafnyVars(), us).Select(x => x.GetGeneratedCode()))
                    {
                        yield return(item);
                    }
                }
                // rewrite the expression
                if (aps.Lhs is ExprDotName)
                {
                    foreach (var item in EvaluateTacnyExpression(state, aps.Lhs))
                    {
                        if (item is Expression)
                        {
                            yield return(new ApplySuffix(aps.tok, (Expression)item, aps.Args));
                        }
                        else
                        {
                            Contract.Assert(false, "Unexpected ExprNotName case");
                        }
                    }
                }
                else
                {
                    // try to evaluate as tacny expression
                    string sig = Util.GetSignature(aps);
                    // using reflection find all classes that extend EAtomic
                    var types =
                        Assembly.GetAssembly(typeof(EAtomic.EAtomic)).GetTypes().Where(t => t.IsSubclassOf(typeof(EAtomic.EAtomic)));
                    foreach (var type in types)
                    {
                        var resolverInstance = Activator.CreateInstance(type) as EAtomic.EAtomic;
                        if (sig == resolverInstance?.Signature)
                        {
                            //TODO: validate input countx
                            foreach (var item in resolverInstance?.Generate(aps, state))
                            {
                                yield return(item);
                            }
                        }
                        // if we reached this point, rewrite  the apply suffix
                        foreach (var item in EvaluateTacnyExpression(state, aps.Lhs))
                        {
                            if (!(item is NameSegment))
                            {
                                //TODO: warning
                            }
                            else
                            {
                                var argList = new List <Expression>();
                                foreach (var arg in aps.Args)
                                {
                                    foreach (var result in EvaluateTacnyExpression(state, arg))
                                    {
                                        if (result is Expression)
                                        {
                                            argList.Add(result as Expression);
                                        }
                                        else
                                        {
                                            argList.Add(Util.VariableToExpression(result as IVariable));
                                        }
                                        break;
                                    }
                                }
                                yield return(new ApplySuffix(aps.tok, aps.Lhs, argList));
                            }
                        }
                    }
                }
            }
            else if (expr is ExprDotName)
            {
                var edn = (ExprDotName)expr;
                var ns  = edn.Lhs as NameSegment;
                if (ns != null && state.ContainsVariable(ns))
                {
                    var newLhs = state.GetLocalValue(ns);
                    var lhs    = newLhs as Expression;
                    if (lhs != null)
                    {
                        yield return(new ExprDotName(edn.tok, lhs, edn.SuffixName, edn.OptTypeArguments));
                    }
                }
                yield return(edn);
            }
            else if (expr is UnaryOpExpr)
            {
                var op = (UnaryOpExpr)expr;
                foreach (var result in EvaluateTacnyExpression(state, op.E))
                {
                    switch (op.Op)
                    {
                    case UnaryOpExpr.Opcode.Cardinality:
                        if (!(result is IEnumerable))
                        {
                            var resultExp = result is IVariable
                  ? Util.VariableToExpression(result as IVariable)
                  : result as Expression;

                            yield return(new UnaryOpExpr(op.tok, op.Op, resultExp));
                        }
                        else
                        {
                            var enumerator = result as IList;
                            if (enumerator != null)
                            {
                                yield return(new Dafny.LiteralExpr(op.tok, enumerator.Count));
                            }
                        }
                        yield break;

                    case UnaryOpExpr.Opcode.Not:
                        if (result is Dafny.LiteralExpr)
                        {
                            var lit = (Dafny.LiteralExpr)result;
                            if (lit.Value is bool)
                            {
                                // inverse the bool value
                                yield return(new Dafny.LiteralExpr(op.tok, !(bool)lit.Value));
                            }
                            else
                            {
                                Contract.Assert(false);
                                //TODO: error message
                            }
                        }
                        else
                        {
                            var resultExp = result is IVariable?Util.VariableToExpression(result as IVariable) : result as Expression;

                            yield return(new UnaryOpExpr(op.tok, op.Op, resultExp));
                        }
                        yield break;

                    default:
                        Contract.Assert(false, "Unsupported Unary Operator");
                        yield break;
                    }
                }
            }
            else if (expr is DisplayExpression)
            {
                var dexpr = (DisplayExpression)expr;
                if (dexpr.Elements.Count == 0)
                {
                    yield return(dexpr.Copy());
                }
                else
                {
                    foreach (var item in ResolveDisplayExpression(state, dexpr))
                    {
                        yield return(item);
                    }
                }
            }
            else
            {
                yield return(expr);
            }
        }