예제 #1
0
        public static bool BoogieOnce(string baseFile, string moduleName, Bpl.Program boogieProgram, string programId,
            out PipelineStatistics stats, out PipelineOutcome oc)
        {
            if (programId == null)
              {
            programId = "main_program_id";
              }
              programId += "_" + moduleName;

              string bplFilename;
              if (CommandLineOptions.Clo.PrintFile != null)
              {
            bplFilename = CommandLineOptions.Clo.PrintFile;
              }
              else
              {
            string baseName = cce.NonNull(Path.GetFileName(baseFile));
            baseName = cce.NonNull(Path.ChangeExtension(baseName, "bpl"));
            bplFilename = Path.Combine(Path.GetTempPath(), baseName);
              }

              bplFilename = BoogieProgramSuffix(bplFilename, moduleName);
              stats = null;
              oc = BoogiePipelineWithRerun(boogieProgram, bplFilename, out stats, 1 < Dafny.DafnyOptions.Clo.VerifySnapshots ? programId : null);
              return (oc == PipelineOutcome.Done || oc == PipelineOutcome.VerificationCompleted) && stats.ErrorCount == 0 && stats.InconclusiveCount == 0 && stats.TimeoutCount == 0 && stats.OutOfMemoryCount == 0;
        }
예제 #2
0
파일: Pipeline.cs 프로젝트: ggrov/tacny
        /// <summary>
        /// Translates Dafny program to Boogie program
        /// </summary>
        /// <returns>Exit value</returns>
        public static void Translate(Dafny.Program dafnyProgram, string uniqueIdPrefix, out Bpl.Program boogieProgram) {

            Translator translator = new Translator(dafnyProgram.reporter);
            translator.InsertChecksums = true;
            translator.UniqueIdPrefix = uniqueIdPrefix;
            boogieProgram = translator.Translate(dafnyProgram);
        }
 public static Bpl.AssignCmd BuildAssignCmd(Bpl.IdentifierExpr lhs, Bpl.Expr rhs)
 {
   List<Bpl.AssignLhs> lhss = new List<Bpl.AssignLhs>();
   lhss.Add(new Bpl.SimpleAssignLhs(lhs.tok, lhs));
   List<Bpl.Expr> rhss = new List<Bpl.Expr>();
   rhss.Add(rhs);
   return new Bpl.AssignCmd(lhs.tok, lhss, rhss);
 }
예제 #4
0
 public override Bpl.CmdSeq VisitCmdSeq(Bpl.CmdSeq cmdSeq) {
   Bpl.CmdSeq newCmdSeq = new Bpl.CmdSeq();
   for (int i = 0; i < cmdSeq.Length; i++) {
     Bpl.Cmd cmd = cmdSeq[i];
     if (IsRelevant(cmd))
       newCmdSeq.Add(new Bpl.AssertCmd(cmd.tok, Bpl.Expr.False));
     newCmdSeq.Add(cmd);
   }
   return newCmdSeq;
 }
예제 #5
0
 public override bool MakeHeap(Sink sink, out Heap heap, out Bpl.Program/*?*/ program) {
   heap = this;
   program = null;
   this.sink = sink;
   string prelude = this.InitialPreludeText + this.CommonText;
   var b = RepresentationFor.ParsePrelude(prelude, this, out program);
   if (b) {
     this.FieldType = new Bpl.CtorType(this.FieldTypeDecl.tok, this.FieldTypeDecl, new List<Bpl.Type>());
     this.RefType = new Bpl.CtorType(this.RefTypeDecl.tok, this.RefTypeDecl, new List<Bpl.Type>());
     this.RealType = new Bpl.CtorType(this.RealTypeDecl.tok, this.RealTypeDecl, new List<Bpl.Type>());
   } 
   return b;
 }
    public MethodParameter(IParameterDefinition parameterDefinition, Bpl.Type ptype) {
      this.underlyingParameter = parameterDefinition;

      var parameterToken = parameterDefinition.Token();
      var typeToken = parameterDefinition.Type.Token();
      var parameterName = TranslationHelper.TurnStringIntoValidIdentifier(parameterDefinition.Name.Value);
      if (String.IsNullOrWhiteSpace(parameterName)) parameterName = "P" + parameterDefinition.Index.ToString();

      this.inParameterCopy = new Bpl.Formal(parameterToken, new Bpl.TypedIdent(typeToken, parameterName + "$in", ptype), true);
      if (parameterDefinition.IsByReference) {
        this.outParameterCopy = new Bpl.Formal(parameterToken, new Bpl.TypedIdent(typeToken, parameterName + "$out", ptype), false);
      } else {
        this.outParameterCopy = new Bpl.LocalVariable(parameterToken, new Bpl.TypedIdent(typeToken, parameterName, ptype));
      }
    }
예제 #7
0
 protected override bool ParseOption(string name, Bpl.CommandLineOptionEngine.CommandLineParseState ps)
 {
     switch (name) {
         case "relational":
             relational = true;
             return true;
         case "x64":
             x64 = true;
             return true;
         case "useFramePointer":
             useFramePointer = true;
             return true;
         default:
             break;
     }
     return base.ParseOption(name, ps);
 }
예제 #8
0
 protected override bool ParseOption(string name, Bpl.CommandLineOptionEngine.CommandLineParseState ps)
 {
     switch (name) {
         case "outdir":
             if (ps.ConfirmArgumentCount(1))
             {
                 outDir = ps.args[ps.i];
             }
             return true;
         case "minVerify":
             minVerify = true;
             return true;
         default:
             break;
     }
     return base.ParseOption(name, ps);
 }
예제 #9
0
        private bool BoogieOnce(Bpl.Program boogieProgram)
        {
            if (boogieProgram.Resolve() == 0 && boogieProgram.Typecheck() == 0) { //FIXME ResolveAndTypecheck?
            ExecutionEngine.EliminateDeadVariables(boogieProgram);
            ExecutionEngine.CollectModSets(boogieProgram);
            ExecutionEngine.CoalesceBlocks(boogieProgram);
            ExecutionEngine.Inline(boogieProgram);

            //NOTE: We could capture errors instead of printing them (pass a delegate instead of null)
            switch (ExecutionEngine.InferAndVerify(boogieProgram, new PipelineStatistics(), "ServerProgram", null, DateTime.UtcNow.Ticks.ToString())) {
              case PipelineOutcome.Done:
              case PipelineOutcome.VerificationCompleted:
            return true;
            }
              }

              return false;
        }
예제 #10
0
파일: Pipeline.cs 프로젝트: ggrov/tacny
        /// <summary>
        /// Pipeline the boogie program to Dafny where it is valid
        /// </summary>
        /// <returns>Exit value</returns>
        public PipelineOutcome BoogiePipeline(Bpl.Program program, IList<string> fileNames, string programId, out PipelineStatistics stats, out List<ErrorInformation> errorList) {
            Contract.Requires(program != null);
            Contract.Ensures(0 <= Contract.ValueAtReturn(out stats).InconclusiveCount && 0 <= Contract.ValueAtReturn(out stats).TimeoutCount);

            LinearTypeChecker ltc;
            CivlTypeChecker ctc;
            string baseName = cce.NonNull(Path.GetFileName(fileNames[fileNames.Count - 1]));
            baseName = cce.NonNull(Path.ChangeExtension(baseName, "bpl"));
            string bplFileName = Path.Combine(Path.GetTempPath(), baseName);

            errorList = new List<ErrorInformation>();
            stats = new PipelineStatistics();

            if (TacnyOptions.O.ParallelExecution)
                mut.WaitOne();

            PipelineOutcome oc = ExecutionEngine.ResolveAndTypecheck(program, bplFileName, out ltc, out ctc);
            switch (oc) {
                case PipelineOutcome.ResolvedAndTypeChecked:
                    ExecutionEngine.EliminateDeadVariables(program);
                    ExecutionEngine.CollectModSets(program);
                    ExecutionEngine.CoalesceBlocks(program);
                    ExecutionEngine.Inline(program);
                    errorList = new List<ErrorInformation>();
                    var tmp = new List<ErrorInformation>();

                    oc = ExecutionEngine.InferAndVerify(program, stats, programId, errorInfo => {
                        tmp.Add(errorInfo);
                    });
                    errorList.AddRange(tmp);
                    if (TacnyOptions.O.ParallelExecution)
                        mut.ReleaseMutex();
                    return oc;
                default:
                    if (TacnyOptions.O.ParallelExecution)
                        mut.ReleaseMutex();
                    return oc;
                    //Contract.Assert(false); throw new cce.UnreachableException();  // unexpected outcome
            }
        }
    /// <summary>
    /// Handles "instance.container := source".
    /// Note that instance can be null in which case the container better be
    /// a local, parameter, static field, or address dereference.
    /// </summary>
    private void TranslateAssignment(Bpl.IToken tok, object container, IExpression/*?*/ instance, IExpression source) {
      Contract.Assert(TranslatedExpressions.Count == 0);

      var typ = source.Type;
      var structCopy = TranslationHelper.IsStruct(typ) && !(source is IDefaultValue);
      // then a struct value of type S is being assigned: "lhs := s"
      // model this as the statement "call lhs := S..#copy_ctor(s)" that does the bit-wise copying
      Bpl.DeclWithFormals proc = null;
      if (structCopy) {
        proc = this.sink.FindOrCreateProcedureForStructCopy(typ);
      }
      Bpl.Cmd cmd;

      EmitLineDirective(tok);

      var/*?*/ local = container as ILocalDefinition;
      if (local != null) {
        Contract.Assume(instance == null);
        this.Traverse(source);
        var e = this.TranslatedExpressions.Pop();
        var bplLocal = Bpl.Expr.Ident(this.sink.FindOrCreateLocalVariable(local));
        if (structCopy) {
          cmd = new Bpl.CallCmd(tok, proc.Name, new List<Bpl.Expr>{ e, }, new List<Bpl.IdentifierExpr>{ bplLocal, });
        } else {
          cmd = Bpl.Cmd.SimpleAssign(tok, bplLocal, e);
        }
        StmtTraverser.StmtBuilder.Add(cmd);
        this.TranslatedExpressions.Push(e); // value of assignment might be needed for an enclosing expression
        return;
      }

      var/*?*/ parameter = container as IParameterDefinition;
      if (parameter != null) {
        Contract.Assume(instance == null);
        this.Traverse(source);
        var e = this.TranslatedExpressions.Pop();
        var bplParam = Bpl.Expr.Ident(this.sink.FindParameterVariable(parameter, this.contractContext));
        if (structCopy) {
          cmd = new Bpl.CallCmd(tok, proc.Name, new List<Bpl.Expr> { e, }, new List<Bpl.IdentifierExpr>{ bplParam });
        } else {
          cmd = Bpl.Cmd.SimpleAssign(tok, bplParam, e);
        }
        StmtTraverser.StmtBuilder.Add(cmd);
        this.TranslatedExpressions.Push(e); // value of assignment might be needed for an enclosing expression
        return;
      }

      var/*?*/ field = container as IFieldReference;
      if (field != null) {
        this.Traverse(source);
        var e = this.TranslatedExpressions.Pop();
        var f = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(field));
        if (instance == null) {
          // static fields are not kept in the heap
          StmtTraverser.StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok, f, e));
        }
        else {
          this.Traverse(instance);
          var x = this.TranslatedExpressions.Pop();
          var boogieType = sink.CciTypeToBoogie(field.Type);
          this.sink.Heap.WriteHeap(tok, x, f, e,
            field.ResolvedField.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap,
            boogieType, StmtTraverser.StmtBuilder);
          this.TranslatedExpressions.Push(e); // value of assignment might be needed for an enclosing expression
        }
        return;
      }

      var/*?*/ arrayIndexer = container as IArrayIndexer;
      if (arrayIndexer != null) {
        this.Traverse(instance);
        var x = this.TranslatedExpressions.Pop();
        this.Traverse(arrayIndexer.Indices);
        var indices_prime = this.TranslatedExpressions.Pop();
        this.Traverse(source);
        var e = this.TranslatedExpressions.Pop();
        sink.Heap.WriteHeap(Bpl.Token.NoToken, x, indices_prime, e, AccessType.Array, sink.CciTypeToBoogie(arrayIndexer.Type), StmtTraverser.StmtBuilder);
        this.TranslatedExpressions.Push(e); // value of assignment might be needed for an enclosing expression
        return;
      }

      var/*?*/ addressDereference = container as IAddressDereference;
      if (addressDereference != null) {
        var addressOf = addressDereference.Address as IAddressOf;
        if (addressOf != null) {
          var ae = addressOf.Expression;
          TranslateAssignment(tok, ae.Definition, ae.Instance, source);
          return;
        }
        var pop = addressDereference.Address as IPopValue;
        if (pop != null) {
          var popValue = this.sink.operandStack.Pop();
          var identifierExpr = popValue as Bpl.IdentifierExpr;
          if (identifierExpr != null) {
            Contract.Assume(instance == null);
            this.Traverse(source);
            var e = this.TranslatedExpressions.Pop();
            cmd = Bpl.Cmd.SimpleAssign(tok, identifierExpr, e);
            StmtTraverser.StmtBuilder.Add(cmd);
            this.TranslatedExpressions.Push(e); // value of assignment might be needed for an enclosing expression
            return;
          }
        }
        var be2 = addressDereference.Address as IBoundExpression;
        if (be2 != null) {
          TranslateAssignment(tok, be2.Definition, be2.Instance, source);
          return;
        }
        var thisExp = addressDereference.Address as IThisReference;
        if (thisExp != null) {
          // I believe this happens only when a struct calls the default
          // ctor (probably only ever done in a different ctor for the
          // struct). The assignment actually looks like "*this := DefaultValue(S)"
          Contract.Assume(instance == null);
          this.Traverse(source);
          var e = this.TranslatedExpressions.Pop();
          var bplLocal = Bpl.Expr.Ident(this.sink.ThisVariable);
          cmd = Bpl.Cmd.SimpleAssign(tok, bplLocal, e);
          StmtTraverser.StmtBuilder.Add(cmd);
          this.TranslatedExpressions.Push(e); // value of assignment might be needed for an enclosing expression
          return;
        }
      }
      throw new TranslationException("Untranslatable assignment statement.");
    }
예제 #12
0
파일: Parser.cs 프로젝트: qunyanm/boogie
	void MapType(out Bpl.Type/*!*/ ty) {
		Contract.Ensures(Contract.ValueAtReturn(out ty) != null); IToken tok = null;
		IToken/*!*/ nnTok;
		List<Bpl.Type>/*!*/ arguments = new List<Bpl.Type>();
		Bpl.Type/*!*/ result;
		List<TypeVariable>/*!*/ typeParameters = new List<TypeVariable>();
		
		if (la.kind == 20) {
			TypeParams(out nnTok, out typeParameters);
			tok = nnTok; 
		}
		Expect(18);
		if (tok == null) tok = t;  
		if (StartOf(6)) {
			Types(arguments);
		}
		Expect(19);
		Type(out result);
		ty = new MapType(tok, typeParameters, arguments, result);
		
	}
예제 #13
0
    public Bpl.Expr ToUnion(Bpl.IToken tok, Bpl.Type boogieType, Bpl.Expr expr, bool isStruct, Bpl.StmtListBuilder builder)
    {
        if (boogieType == UnionType || boogieType == RefType)
            return expr;

        Bpl.Expr callConversion;
        if (boogieType == Bpl.Type.Bool)
        {
            callConversion = new Bpl.NAryExpr(tok, new Bpl.FunctionCall(this.Bool2Union), new List<Bpl.Expr>(new Bpl.Expr[] {expr}));
            builder.Add(
                new Bpl.AssumeCmd(tok,
                Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq,
                                new Bpl.NAryExpr(tok, new Bpl.FunctionCall(this.Union2Bool), new List<Bpl.Expr>(new Bpl.Expr[] { callConversion })),
                                expr)));
        }
        else if (boogieType == Bpl.Type.Int)
        {
            callConversion = new Bpl.NAryExpr(tok, new Bpl.FunctionCall(this.Int2Union), new List<Bpl.Expr>(new Bpl.Expr[] { expr }));
            builder.Add(
                new Bpl.AssumeCmd(tok,
                Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq,
                                new Bpl.NAryExpr(tok, new Bpl.FunctionCall(this.Union2Int), new List<Bpl.Expr>(new Bpl.Expr[] {callConversion})),
                                expr)));
        }
        else if (boogieType == RealType)
        {
            callConversion = new Bpl.NAryExpr(tok, new Bpl.FunctionCall(this.Real2Union), new List<Bpl.Expr>(new Bpl.Expr[] { expr }));
            builder.Add(
                new Bpl.AssumeCmd(tok,
                Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq,
                                new Bpl.NAryExpr(tok, new Bpl.FunctionCall(this.Union2Real), new List<Bpl.Expr>(new Bpl.Expr[] { callConversion })),
                                expr)));
        }
        else
        {
            throw new InvalidOperationException(String.Format("Unknown Boogie type: '{0}'", boogieType.ToString()));
        }
        return callConversion;
    }
예제 #14
0
파일: Parser.cs 프로젝트: qunyanm/boogie
	void Type(out Bpl.Type/*!*/ ty) {
		Contract.Ensures(Contract.ValueAtReturn(out ty) != null); IToken/*!*/ tok; ty = dummyType; 
		if (StartOf(5)) {
			TypeAtom(out ty);
		} else if (la.kind == 1) {
			Ident(out tok);
			List<Bpl.Type>/*!*/ args = new List<Bpl.Type> (); 
			if (StartOf(6)) {
				TypeArgs(args);
			}
			ty = new UnresolvedTypeIdentifier (tok, tok.val, args); 
		} else if (la.kind == 18 || la.kind == 20) {
			MapType(out ty);
		} else SynErr(101);
	}
예제 #15
0
파일: Parser.cs 프로젝트: qunyanm/boogie
	void TypeAtom(out Bpl.Type/*!*/ ty) {
		Contract.Ensures(Contract.ValueAtReturn(out ty) != null); ty = dummyType; 
		if (la.kind == 15) {
			Get();
			ty = new BasicType(t, SimpleType.Int); 
		} else if (la.kind == 16) {
			Get();
			ty = new BasicType(t, SimpleType.Real); 
		} else if (la.kind == 17) {
			Get();
			ty = new BasicType(t, SimpleType.Bool); 
		} else if (la.kind == 10) {
			Get();
			Type(out ty);
			Expect(11);
		} else SynErr(102);
	}
    // REVIEW: Does "thisExpr" really need to come back as an identifier? Can't it be a general expression?
    protected Bpl.DeclWithFormals TranslateArgumentsAndReturnProcedure(Bpl.IToken token, IMethodReference methodToCall, IMethodDefinition resolvedMethod, IExpression/*?*/ thisArg, IEnumerable<IExpression> arguments, out List<Bpl.Expr> inexpr, out List<Bpl.IdentifierExpr> outvars, out Bpl.IdentifierExpr thisExpr, out Dictionary<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>> toUnioned) {
      inexpr = new List<Bpl.Expr>();
      outvars = new List<Bpl.IdentifierExpr>();

      #region Create the 'this' argument for the function call
      thisExpr = null;
      if (thisArg != null) {

        // Special case! thisArg is going to be an AddressOf expression if the receiver is a value-type
        // But if the method's containing type is something that doesn't get translated as a Ref, then
        // the AddressOf node should be ignored.
        var addrOf = thisArg as IAddressOf;
        var boogieType = this.sink.CciTypeToBoogie(methodToCall.ContainingType);
        if (false && addrOf != null && boogieType != this.sink.Heap.RefType) {
          thisArg = addrOf.Expression;
        }

        this.Traverse(thisArg);

        var e = this.TranslatedExpressions.Pop();
        var identifierExpr = e as Bpl.IdentifierExpr;
        if (identifierExpr == null) {
          var newLocal = Bpl.Expr.Ident(this.sink.CreateFreshLocal(methodToCall.ContainingType));
          var cmd = Bpl.Cmd.SimpleAssign(token, newLocal, e);
          this.StmtTraverser.StmtBuilder.Add(cmd);
          e = newLocal;
        } else {

        }
        inexpr.Add(e);
        thisExpr = (Bpl.IdentifierExpr) e;
      }
      #endregion

      toUnioned = new Dictionary<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>>();
      IEnumerator<IParameterDefinition> penum = resolvedMethod.Parameters.GetEnumerator();
      penum.MoveNext();
      foreach (IExpression exp in arguments) {
        if (penum.Current == null) {
          throw new TranslationException("More arguments than parameters in method call");
        }

        var expressionToTraverse = exp;
        //Bpl.Type boogieTypeOfExpression;

        //// Special case! exp can be an AddressOf expression if it is a value type being passed by reference.
        //// But since we pass reference parameters by in-out value passing, need to short-circuit the
        //// AddressOf node if the underlying type is not a Ref.
        //var addrOf = exp as IAddressOf;
        //if (addrOf != null) {
        //  boogieTypeOfExpression = this.sink.CciTypeToBoogie(addrOf.Expression.Type);
        //  if (boogieTypeOfExpression != this.sink.Heap.RefType) {
        //    expressionToTraverse = addrOf.Expression;
        //  }
        //}

        //boogieTypeOfExpression = this.sink.CciTypeToBoogie(expressionToTraverse.Type);
        this.Traverse(expressionToTraverse);

        Bpl.Expr e = this.TranslatedExpressions.Pop();
        var currentType = penum.Current.Type;

        // If the argument is a struct, then make a copy of it to pass to the procedure.
        if (TranslationHelper.IsStruct(exp.Type)) {
          var proc = this.sink.FindOrCreateProcedureForStructCopy(exp.Type);
          var bplLocal = Bpl.Expr.Ident(this.sink.CreateFreshLocal(exp.Type));
          var cmd = new Bpl.CallCmd(token, proc.Name, new List<Bpl.Expr> { e, }, new List<Bpl.IdentifierExpr> { bplLocal, });
          this.StmtTraverser.StmtBuilder.Add(cmd);
          e = bplLocal;
        }

        if (currentType is IGenericParameterReference && this.sink.CciTypeToBoogie(currentType) == this.sink.Heap.UnionType) {
            inexpr.Add(sink.Heap.ToUnion(token, this.sink.CciTypeToBoogie(expressionToTraverse.Type), e, TranslationHelper.IsStruct(expressionToTraverse.Type), StmtTraverser.StmtBuilder));
        } else {
            inexpr.Add(e);
        }
        if (penum.Current.IsByReference) {
          Bpl.IdentifierExpr unboxed = e as Bpl.IdentifierExpr;
          if (unboxed == null) {
            throw new TranslationException("Trying to pass a complex expression for an out or ref parameter");
          }
          if (penum.Current.Type is IGenericParameterReference) {
            var boogieType = this.sink.CciTypeToBoogie(penum.Current.Type);
            if (boogieType == this.sink.Heap.UnionType) {
              Bpl.IdentifierExpr boxed = Bpl.Expr.Ident(sink.CreateFreshLocal(this.sink.Heap.UnionType));
              toUnioned[unboxed] = Tuple.Create(boxed,false);
              outvars.Add(boxed);
            } else {
              outvars.Add(unboxed);
            }
          } else {
            outvars.Add(unboxed);
          }
        }
        penum.MoveNext();
      }

      if (resolvedMethod.IsStatic) {
        List<ITypeReference> consolidatedTypeArguments = new List<ITypeReference>();
        Sink.GetConsolidatedTypeArguments(consolidatedTypeArguments, methodToCall.ContainingType);
        foreach (ITypeReference typeReference in consolidatedTypeArguments) {
          inexpr.Add(this.sink.FindOrCreateTypeReferenceInCodeContext(typeReference));
        }
      }
      IGenericMethodInstanceReference methodInstanceReference = methodToCall as IGenericMethodInstanceReference;
      if (methodInstanceReference != null) {
        foreach (ITypeReference typeReference in methodInstanceReference.GenericArguments) {
          inexpr.Add(this.sink.FindOrCreateTypeReferenceInCodeContext(typeReference));
        }
      }

      var procInfo = this.sink.FindOrCreateProcedure(resolvedMethod);
      var translateAsFunctionCall = procInfo.Decl is Bpl.Function;
      if (!translateAsFunctionCall) {
        if (resolvedMethod.Type.ResolvedType.TypeCode != PrimitiveTypeCode.Void) {
          Bpl.Variable v = this.sink.CreateFreshLocal(methodToCall.ResolvedMethod.Type.ResolvedType);
          Bpl.IdentifierExpr unUnioned = new Bpl.IdentifierExpr(token, v);
          if (resolvedMethod.Type is IGenericParameterReference) {
            var boogieType = this.sink.CciTypeToBoogie(resolvedMethod.Type);
            if (boogieType == this.sink.Heap.UnionType) {
              Bpl.IdentifierExpr unioned = Bpl.Expr.Ident(this.sink.CreateFreshLocal(this.sink.Heap.UnionType));
              toUnioned[unUnioned] = Tuple.Create(unioned, TranslationHelper.IsStruct(methodToCall.ResolvedMethod.Type.ResolvedType));
              outvars.Add(unioned);
            } else {
              outvars.Add(unUnioned);
            }
          } else {
            outvars.Add(unUnioned);
          }
          TranslatedExpressions.Push(unUnioned);
        }
      }

      return procInfo.Decl;
    }
예제 #17
0
파일: Printer.cs 프로젝트: ggrov/tacny
 private bool PrintModeSkipGeneral(Bpl.IToken tok, string fileBeingPrinted)
 {
     return (printMode == DafnyOptions.PrintModes.NoIncludes || printMode == DafnyOptions.PrintModes.NoGhost)
            && (tok.filename != null && fileBeingPrinted != null && Path.GetFullPath(tok.filename) != fileBeingPrinted);
 }
    private Bpl.CallCmd translateAddRemoveCall(IMethodCall methodCall, IMethodDefinition resolvedMethod, Bpl.IToken methodCallToken, List<Bpl.Expr> inexpr, List<Bpl.IdentifierExpr> outvars, Bpl.IdentifierExpr thisExpr, bool isEventAdd) {
      Bpl.CallCmd call;
      var mName = resolvedMethod.Name.Value;
      var eventName = mName.Substring(mName.IndexOf('_') + 1);
      var eventDef = TypeHelper.GetEvent(resolvedMethod.ContainingTypeDefinition, this.sink.host.NameTable.GetNameFor(eventName));
      Contract.Assert(eventDef != Dummy.Event);
      Bpl.Variable eventVar = this.sink.FindOrCreateEventVariable(eventDef);
      Bpl.Variable local = this.sink.CreateFreshLocal(eventDef.Type);

      if (methodCall.IsStaticCall) {
        this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(local), Bpl.Expr.Ident(eventVar)));
        inexpr.Insert(0, Bpl.Expr.Ident(local));
      } else {
        AssertOrAssumeNonNull(methodCallToken, thisExpr);
        this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(local), this.sink.Heap.ReadHeap(thisExpr, Bpl.Expr.Ident(eventVar), resolvedMethod.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, local.TypedIdent.Type)));
        inexpr[0] = Bpl.Expr.Ident(local);
      }

      System.Diagnostics.Debug.Assert(outvars.Count == 0);
      outvars.Insert(0, Bpl.Expr.Ident(local));
      string methodName = isEventAdd ? this.sink.DelegateAdd(eventDef.Type.ResolvedType) : this.sink.DelegateRemove(eventDef.Type.ResolvedType);
      call = new Bpl.CallCmd(methodCallToken, methodName, inexpr, outvars);
      this.StmtTraverser.StmtBuilder.Add(call);
      if (methodCall.IsStaticCall) {
        this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(eventVar), Bpl.Expr.Ident(local)));
      } else {
        this.sink.Heap.WriteHeap(methodCallToken, thisExpr, Bpl.Expr.Ident(eventVar), Bpl.Expr.Ident(local), resolvedMethod.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, local.TypedIdent.Type, this.StmtTraverser.StmtBuilder);
      }
      return call;
    }
    private void handleStructConstructorCall(IMethodCall methodCall, Bpl.IToken methodCallToken, List<Bpl.Expr> inexpr, List<Bpl.IdentifierExpr> outvars, Bpl.IdentifierExpr thisExpr, Bpl.DeclWithFormals proc) {
      // then the method call looks like "&s.S.ctor(...)" for some variable s of struct type S
      // treat it as if it was "s := new S(...)"
      // So this code is the same as Visit(ICreateObjectInstance)
      // TODO: factor the code into a single method?

      // First generate an Alloc() call
      this.StmtTraverser.StmtBuilder.Add(new Bpl.CallCmd(methodCallToken, this.sink.AllocationMethodName, new List<Bpl.Expr>(), new List<Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] {thisExpr})));

      // Second, generate the call to the appropriate ctor
      EmitLineDirective(methodCallToken);
      this.StmtTraverser.StmtBuilder.Add(new Bpl.CallCmd(methodCallToken, proc.Name, inexpr, outvars));

      // Generate an assumption about the dynamic type of the just allocated object
      this.sink.GenerateDynamicTypeAssume(this.StmtTraverser.StmtBuilder, methodCallToken, thisExpr, methodCall.MethodToCall.ResolvedMethod.ContainingTypeDefinition);
    }
예제 #20
0
    public Bpl.Expr FromUnion(Bpl.IToken tok, Bpl.Type boogieType, Bpl.Expr expr, bool isStruct) {
      if (boogieType == UnionType || boogieType == RefType)
          return expr;

      Bpl.Function conversion = null;
      if (boogieType == Bpl.Type.Bool)
        conversion = this.Union2Bool;
      else if (boogieType == Bpl.Type.Int)
        conversion = this.Union2Int;
      else if (boogieType == RealType)
          conversion = this.Union2Real;
      else
          throw new InvalidOperationException(String.Format("Unknown Boogie type: '{0}'", boogieType.ToString()));

      var callExpr = new Bpl.NAryExpr(
        tok,
        new Bpl.FunctionCall(conversion),
        new List<Bpl.Expr>(new Bpl.Expr[] {expr})
        );
      callExpr.Type = boogieType;
      return callExpr;
    }
 private void EmitLineDirective(Bpl.IToken methodCallToken) {
   var sloc = this.StmtTraverser.lastSourceLocation;
   if (sloc != null) {
     var fileName = sloc.Document.Location;
     var lineNumber = sloc.StartLine;
     var attrib = new Bpl.QKeyValue(methodCallToken, "sourceLine", new List<object> { Bpl.Expr.Literal((int)lineNumber) }, null);
     attrib = new Bpl.QKeyValue(methodCallToken, "sourceFile", new List<object> { fileName }, attrib);
     this.StmtTraverser.StmtBuilder.Add(new Bpl.AssertCmd(methodCallToken, Bpl.Expr.True, attrib));
   }
 }
예제 #22
0
 public abstract Bpl.Expr ReadHeap(Bpl.Expr o, Bpl.Expr f, AccessType accessType, Bpl.Type unboxType);
예제 #23
0
 public abstract void WriteHeap(Bpl.IToken tok, Bpl.Expr o, Bpl.Expr f, Bpl.Expr value, AccessType accessType, Bpl.Type boxType, Bpl.StmtListBuilder builder);
예제 #24
0
파일: DafnyOptions.cs 프로젝트: ggrov/tacny
    protected override bool ParseOption(string name, Bpl.CommandLineOptionEngine.CommandLineParseState ps) {
      var args = ps.args;  // convenient synonym

      switch (name) {
        case "dprelude":
          if (ps.ConfirmArgumentCount(1)) {
            DafnyPrelude = args[ps.i];
          }
          return true;

        case "dprint":
          if (ps.ConfirmArgumentCount(1)) {
            DafnyPrintFile = args[ps.i];
          }
          return true;

        case "printMode":
          if (ps.ConfirmArgumentCount(1)) {
            if (args[ps.i].Equals("Everything")) {
              PrintMode = PrintModes.Everything;
            }
            else if (args[ps.i].Equals("NoIncludes"))
            {
                PrintMode = PrintModes.NoIncludes;
            }
            else if (args[ps.i].Equals("NoGhost"))
            {
                PrintMode = PrintModes.NoGhost;
            }
            else
            {
                throw new Exception("Invalid value for printMode");
            }
          }
          return true;

        case "rprint":
          if (ps.ConfirmArgumentCount(1)) {
            DafnyPrintResolvedFile = args[ps.i];
          }
          return true;
        case "view":
          if (ps.ConfirmArgumentCount(1)) {
            DafnyPrintExportedViews = args[ps.i].Split(',').ToList();
          }
          return true;

        case "compile": {
            int compile = 0;
            if (ps.GetNumericArgument(ref compile, 4)) {
              // convert option to two booleans
              Compile = compile != 0;
              ForceCompile = compile == 2;
              RunAfterCompile = compile == 3;
            }
            return true;
          }

        case "dafnyVerify":
            {
                int verify = 0;
                if (ps.GetNumericArgument(ref verify, 2)) {
                    DafnyVerify = verify != 0; // convert to boolean
                }
                return true;
            }

        case "spillTargetCode": {
            int spill = 0;
            if (ps.GetNumericArgument(ref spill, 2)) {
              SpillTargetCode = spill != 0;  // convert to a boolean
            }
            return true;
          }
        case "out": {
            if (ps.ConfirmArgumentCount(1)) {
              DafnyPrintCompiledFile = args[ps.i];
            }
            return true;
          }

        case "dafnycc":
          Dafnycc = true;
          Induction = 0;
          Compile = false;
          UseAbstractInterpretation = false; // /noinfer
          return true;

        case "noCheating": {
            int cheat = 0; // 0 is default, allows cheating
            if (ps.GetNumericArgument(ref cheat, 2)) {
              DisallowSoundnessCheating = cheat == 1;
            }
            return true;
          }

        case "induction":
          ps.GetNumericArgument(ref Induction, 4);
          return true;

        case "inductionHeuristic":
          ps.GetNumericArgument(ref InductionHeuristic, 7);
          return true;

        case "noIncludes":
          DisallowIncludes = true;
          return true;

        case "noNLarith":
          DisableNLarith = true;
          this.AddZ3Option("smt.arith.nl=false");
          return true;

        case "autoReqPrint":
          if (ps.ConfirmArgumentCount(1)) {
              AutoReqPrintFile = args[ps.i];
          }
          return true;

        case "noAutoReq":
          ignoreAutoReq = true;
          return true;

        case "allowGlobals":
          AllowGlobals = true;
          return true;
        
        case "stats":
          PrintStats = true;
          return true;

        case "funcCallGraph":
          PrintFunctionCallGraph = true;
          return true;

        case "warnShadowing":
          WarnShadowing = true;
          return true;

        case "countVerificationErrors": {
          int countErrors = 1; // defaults to reporting verification errors
          if (ps.GetNumericArgument(ref countErrors, 2)) {
            CountVerificationErrors = countErrors == 1;
          }
          return true;
        }

        case "printTooltips":
          PrintTooltips = true;
          return true;

        case "autoTriggers": {
            int autoTriggers = 0;
            if (ps.GetNumericArgument(ref autoTriggers, 2)) {
              AutoTriggers = autoTriggers == 1;
            }
            return true;
          }

        case "rewriteFocalPredicates": {
            int rewriteFocalPredicates = 0;
            if (ps.GetNumericArgument(ref rewriteFocalPredicates, 2)) {
              RewriteFocalPredicates = rewriteFocalPredicates == 1;
            }
            return true;
          }

        case "optimize": {
            Optimize = true;
            return true;
        }

        case "noIronDafny": {
            IronDafny = false;
            return true;
        }

        case "ironDafny": {
            IronDafny = true;
            return true;
        }

        default:
          break;
      }
      // not a Dafny-specific option, so defer to superclass
      return base.ParseOption(name, ps);
    }
예제 #25
0
 /// <summary>
 /// Returns two things: an object that determines the heap representation,
 /// and (optionally) an initial program that contains declarations needed
 /// for the heap representation.
 /// </summary>
 /// <param name="sink">
 /// The heap might need to generate declarations so it needs access to the Sink.
 /// </param>
 /// <returns>
 /// false if and only if an error occurrs and the heap and/or program are not in a
 /// good state to be used.
 /// </returns>
 public abstract bool MakeHeap(Sink sink, out Heap heap, out Bpl.Program/*?*/ program);
예제 #26
0
 /// <summary>
 /// Returns the BPL expression that corresponds to the value of the dynamic type
 /// of the object represented by the expression <paramref name="o"/>.
 /// </summary>
 public Bpl.Expr DynamicType(Bpl.Expr o) {
   // $DymamicType(o)
   var callDynamicType = new Bpl.NAryExpr(
     o.tok,
     new Bpl.FunctionCall(this.DynamicTypeFunction),
     new List<Bpl.Expr>(new Bpl.Expr[] {o})
     );
   return callDynamicType;
 }
예제 #27
0
 public virtual Tuple<TextWriter,TextWriter,string,List<string>> ChooseWriter(
     Bpl.IToken tok, string name, TypeApply app = null)
 {
     string filename = Path.GetFullPath(tok.filename);
     if (app != null && !TrustedType(app.typeArgs.Values))
     {
         throw new Exception("specification cannot refer to untrusted type: " + name);
     }
     if (IsSeqFile(filename, true))
     {
         return Tuple.Create(trustedWriter,
             (name.StartsWith("lemma_Seq") ? trustedWriter : trustedIWriter),
             "Trusted",
             new List<string>());
     }
     else
     {
         return ChooseOutDirWriter(filename);
     }
 }
 /// <summary>
 /// Sometimes the decompiler doesn't recreate the expression "o != null" when the
 /// IL tests an object for being null by just branching on the object instead of
 /// doing a ceq operation on the constant null.
 /// </summary>
 /// <returns>
 /// If o is not of type Ref, then it just returns o, otherwise it returns
 /// the expression "o != null".
 /// </returns>
 private Bpl.Expr PossiblyCoerceRefToBool(Bpl.Expr o) {
   if (o.Type != this.sink.Heap.RefType) return o;
   return Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, o, Bpl.Expr.Ident(this.sink.Heap.NullRef));
 }
예제 #29
0
 public override Tuple<TextWriter,TextWriter,string,List<string>> ChooseWriter(
     Bpl.IToken tok, string name, TypeApply app = null)
 {
     string filename = Path.GetFullPath(tok.filename);
     bool trustedArg = (app != null && app.typeArgs.Count == 1 && TrustedType(app.typeArgs.Values));
     if (IsSeqFile(filename, true))
     {
         return Tuple.Create(trustedArg ? trustedWriter : checkedWriter,
             (name.StartsWith("lemma_Seq") ? (trustedArg ? trustedWriter : checkedWriter)
                 : (trustedArg ? trustedIWriter : checkedIWriter)),
             trustedArg ? "Trusted" : "Checked",
             trustedArg ? new List<string>() : new List<string> { "Trusted" });
     }
     else if (IsSeqFile(filename, false))
     {
         return Tuple.Create(seqWriter,
             (name.StartsWith("lemma_Seq") ? seqWriter : seqIWriter),
             "Seq",
             new List<string> { "Trusted", "Checked", "Heap" });
     }
     else
     {
         return ChooseOutDirWriter(filename);
     }
 }
 private void AssertOrAssumeNonNull(Bpl.IToken token, Bpl.Expr instance) {
   if (this.sink.Options.dereference != Options.Dereference.None) {
     Bpl.Cmd c;
     var n = Bpl.Expr.Ident(this.sink.Heap.NullRef);
     var neq = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, instance, n);
     if (this.sink.Options.dereference == Options.Dereference.Assume) {
       c = new Bpl.AssumeCmd(token, neq);
     } else {
       c = new Bpl.AssertCmd(token, neq);
     }
     this.StmtTraverser.StmtBuilder.Add(c);
   }
 }