Ejemplo n.º 1
0
    public static IEnumerable<object> EvalTacnyExpression(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.ContainTacnyVal(ns.Name)) {
          yield return state.GetTacnyVarValue(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;
          }
          */
        } else if(aps.Lhs is ExprDotName) {
          foreach(var item in EvalTacnyExpression(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 {
          // get the keyword of this application
          string sig = Util.GetSignature(aps);
          // Try to evaluate as tacny expression
          // 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 eType in types) {
            var eatomInst = Activator.CreateInstance(eType) as EAtomic.EAtomic;
            if(sig == eatomInst?.Signature) {
              //TODO: validate input countx
              var enumerable = eatomInst?.Generate(aps, state);
              if(enumerable != null)
                foreach(var item in enumerable) {
                  yield return item;
                  yield break;
                }
            }
          }

          // if we reached this point, rewrite  the apply suffix
          foreach(var item in EvalTacnyExpression(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 EvalTacnyExpression(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.ContainDafnyVar(ns)) {
          var newLhs = state.GetTacnyVarValue(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 EvalTacnyExpression(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 EvalDisplayExpression(state, dexpr)) {
            yield return item;
          }

        }
      } else { yield return expr; }
    }
Ejemplo n.º 2
0
        public static IEnumerable <object> EvalTacnyExpression(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.ContainTacnyVal(ns.Name))
                {
                    yield return(state.GetTacnyVarValue(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;
                     * }
                     */
                }
                else if (aps.Lhs is ExprDotName)
                {
                    foreach (var item in EvalTacnyExpression(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
                {
                    // get the keyword of this application
                    string sig = Util.GetSignature(aps);
                    // Try to evaluate as tacny expression
                    // 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 eType in types)
                    {
                        var eatomInst = Activator.CreateInstance(eType) as EAtomic.EAtomic;
                        if (sig == eatomInst?.Signature)
                        {
                            //TODO: validate input countx
                            var enumerable = eatomInst?.Generate(aps, state);
                            if (enumerable != null)
                            {
                                foreach (var item in enumerable)
                                {
                                    yield return(item);

                                    yield break;
                                }
                            }
                        }
                    }

                    // if we reached this point, rewrite  the apply suffix
                    foreach (var item in EvalTacnyExpression(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 EvalTacnyExpression(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.ContainDafnyVar(ns))
                {
                    var newLhs = state.GetTacnyVarValue(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 EvalTacnyExpression(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 EvalDisplayExpression(state, dexpr))
                    {
                        yield return(item);
                    }
                }
            }
            else
            {
                yield return(expr);
            }
        }