Beispiel #1
0
    public RtlVar TempVar(Type t, bool declare = true)
    {
        string name = "$ghost__" + TempName();
        RtlVar ret  = new RtlVar(name, false, AppType(t));

        if (declare)
        {
            allVars.Add(name, ret);
        }
        return(ret);
    }
Beispiel #2
0
    public RtlVar AsVar(Expression exp)
    {
        exp = GetExp(exp);
        IdentifierExpr id = exp as IdentifierExpr;

        if (id != null)
        {
            //- We're assuming this is a local variable for the moment; otherwise we shouldn't call AppType
            string name = GhostVar(id.Name);
            RtlVar ret  = new RtlVar(name, id.Var.IsGhost, AppType(id.Type));

            return(ret);
        }
        else
        {
            return(null);
        }
    }
Beispiel #3
0
    public virtual void AddResolvedGhostStatement(Statement stmt)
    {
        BlockStmt          block      = stmt as BlockStmt;
        IfStmt             ifStmt     = stmt as IfStmt;
        AssertStmt         assertStmt = stmt as AssertStmt;
        AssignStmt         assignStmt = stmt as AssignStmt;
        CallStmt           callStmt   = stmt as CallStmt;
        VarDecl            varDecl    = stmt as VarDecl;
        CalcStmt           calcStmt   = stmt as CalcStmt;
        ForallStmt         forallStmt = stmt as ForallStmt;
        AssignSuchThatStmt existsStmt = stmt as AssignSuchThatStmt;

        if (block != null)
        {
            var oldRenamer = PushRename();
            block.Body.ForEach(AddGhostStatement);
            PopRename(oldRenamer);
        }
        else if (varDecl != null)
        {
            AddGhostVarDecl(varDecl.Name, varDecl.Type, varDecl.IsGhost);
        }
        else if (minVerify)
        {
            return;
        }
        else if (assignStmt != null)
        {
            ExprRhs expRhs = assignStmt.Rhs as ExprRhs;
            if (expRhs != null)
            {
                FieldSelectExpr fieldSelect = assignStmt.Lhs as FieldSelectExpr;
                RtlVar          destVar;
                if (fieldSelect != null)
                {
                    destVar = new RtlVar(GhostVar(fieldSelect.FieldName), true, fieldSelect.Type);
                }
                else
                {
                    destVar = AsVar(assignStmt.Lhs);
                    Util.Assert(destVar != null);
                }
                stmts.Add(new RtlGhostMove(new RtlVar[] { destVar },
                                           new RtlExp[] { GhostExpression(expRhs.Expr) }));
            }
            else
            {
                throw new Exception("not implemented: " + assignStmt.Rhs);
            }
        }
        else if (callStmt != null)
        {
            AddGhostCall(callStmt.Lhs.ConvertAll(AsVar), callStmt.Args,
                         dafnySpec.Compile_Method(callStmt.Method,
                                                  callStmt.TypeArgumentSubstitutions.ToDictionary(p => p.Key, p => AppType(p.Value))),
                         DafnySpec.IsHeapMethod(callStmt.Method));
            SymdiffLinearityPoint();
        }
        else if (ifStmt != null)
        {
            stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ") {",
                                               new RtlExp[] { GhostExpression(ifStmt.Guard) }));
            Indent();
            AddGhostStatement(ifStmt.Thn);
            Unindent();
            stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0]));
            if (ifStmt.Els != null)
            {
                stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ") {",
                                                   new RtlExp[] {
                    GhostExpression(new UnaryExpr(Bpl.Token.NoToken, UnaryExpr.Opcode.Not, ifStmt.Guard))
                }));
                Indent();
                AddGhostStatement(ifStmt.Els);
                Unindent();
                stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0]));
            }
        }
        else if (assertStmt != null)
        {
            stmts.Add(new RtlAssert(GhostExpression(assertStmt.Expr)));
        }
        else if (forallStmt != null)
        {
            var    oldRenamer = PushRename(forallStmt.BoundVars.Select(v => v.Name));
            RtlExp ens        = new RtlLiteral("true");
            foreach (var e in forallStmt.Ens)
            {
                ens = new RtlBinary("&&", ens, GhostExpression(e.E));
            }
            RtlExp range = (forallStmt.Range == null) ? new RtlLiteral("true")
                : GhostExpression(forallStmt.Range);
            List <RtlExp> wellFormed = GetTypeWellFormed(forallStmt.BoundVars.
                                                         Select(x => Tuple.Create(GhostVar(x.Name), x.IsGhost, x.Type)).ToList());
            wellFormed.ForEach(e => range = new RtlBinary("&&", e, range));
            ens = new RtlBinary("==>", range, ens);
            string vars = String.Join(", ", forallStmt.BoundVars.Select(x => GhostVar(x.Name) + ":" +
                                                                        TypeString(AppType(x.Type))));
            stmts.Add(new RtlGhostStmtComputed(s => "forall " + vars + "::(" + s.args[0] + ")",
                                               new List <RtlExp> {
                ens
            }));
            stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0]));
            Indent();
            stmts.Add(PushForall());
            stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ")",
                                               new List <RtlExp> {
                range
            }));
            stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0]));
            Indent();
            AddGhostStatement(forallStmt.Body);
            foreach (var e in forallStmt.Ens)
            {
                stmts.Add(new RtlAssert(GhostExpression(e.E)));
            }
            PopForall();
            Unindent();
            stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0]));
            Unindent();
            stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0]));
            PopRename(oldRenamer);
        }
        else if (existsStmt != null)
        {
            List <RtlStmt> assigns = new List <RtlStmt>();
            List <RtlVar>  tmps    = new List <RtlVar>();
            List <Tuple <string, bool, Type> > varTuples = new List <Tuple <string, bool, Type> >();
            var oldRenamer = PushRename();
            foreach (var lhs in existsStmt.Lhss)
            {
                IdentifierExpr idExp   = lhs.Resolved as IdentifierExpr;
                RtlVar         origVar = AsVar(lhs);
                AddRename(idExp.Name);
                RtlVar renameVar = AsVar(lhs);
                tmps.Add(renameVar);
                varTuples.Add(Tuple.Create(renameVar.ToString(), true, idExp.Type));
                assigns.Add(new RtlGhostMove(new RtlVar[] { origVar },
                                             new RtlExp[] { renameVar }));
            }
            string vars = String.Join(", ", tmps.Select(x => x.getName() + ":" + TypeString(AppType(x.type))));
            stmts.Add(new RtlGhostStmtComputed(s => "exists " + vars + "::(" + s.args[0] + ");",
                                               new List <RtlExp> {
                GetTypeWellFormedExp(varTuples.ToList(), "&&", GhostExpression(existsStmt.Expr))
            }));
            stmts.AddRange(assigns);
            PopRename(oldRenamer);
        }
        else if (calcStmt != null)
        {
            Util.Assert(calcStmt.Steps.Count == calcStmt.Hints.Count);
            CalcStmt.BinaryCalcOp binOp = calcStmt.Op as CalcStmt.BinaryCalcOp;
            bool isImply = binOp != null && binOp.Op == BinaryExpr.Opcode.Imp && calcStmt.Steps.Count > 0;
            if (isImply)
            {
                stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ")",
                                                   new RtlExp[] { GhostExpression(CalcStmt.Lhs(calcStmt.Steps[0])) }));
                stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0]));
                Indent();
            }
            var stepCount = calcStmt.Hints.Last().Body.Count == 0 ? calcStmt.Steps.Count - 1 : calcStmt.Steps.Count;
            for (int i = 0; i < stepCount; i++)
            {
                if (calcStmt.Hints[i] == null)
                {
                    stmts.Add(new RtlAssert(GhostExpression(calcStmt.Steps[i])));
                }
                else
                {
                    stmts.Add(new RtlGhostStmtComputed(s => "forall::(" + s.args[0] + ")",
                                                       new List <RtlExp> {
                        GhostExpression(calcStmt.Steps[i])
                    }));
                    stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0]));
                    Indent();
                    var dict = new Dictionary <string, RtlVar>();
                    stmts.Add(new RtlGhostStmtComputed(s => String.Concat(dict.Values.Select(
                                                                              x => "var " + x.x + ":" + TypeString(x.type) + ";")),
                                                       new RtlExp[0]));
                    forallVars.Add(dict);
                    AddGhostStatement(calcStmt.Hints[i]);
                    forallVars.RemoveAt(forallVars.Count - 1);
                    Unindent();
                    stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0]));
                }
            }
            if (isImply)
            {
                Unindent();
                stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0]));
            }
        }
        else
        {
            throw new Exception("not implemented in ghost methods: " + stmt);
        }
    }
Beispiel #4
0
 public void MoveGhost(RtlVar destVar, RtlExp rhs)
 {
     stmts.Add(new RtlGhostMove(new RtlVar[] { destVar }, new RtlExp[] { rhs }));
 }
Beispiel #5
0
    public virtual void AddResolvedGhostStatement(Statement stmt, Attributes attrs)
    {
        BlockStmt block = stmt as BlockStmt;
        IfStmt ifStmt = stmt as IfStmt;
        AssertStmt assertStmt = stmt as AssertStmt;
        AssignStmt assignStmt = stmt as AssignStmt;
        CallStmt callStmt = stmt as CallStmt;
        VarDeclStmt varDecl = stmt as VarDeclStmt;
        CalcStmt calcStmt = stmt as CalcStmt;
        ForallStmt forallStmt = stmt as ForallStmt;
        AssignSuchThatStmt existsStmt = stmt as AssignSuchThatStmt;

        if (block != null)
        {
            var oldRenamer = PushRename();
            block.Body.ForEach(s => AddGhostStatement(s, attrs));
            PopRename(oldRenamer);
        }
        else if (varDecl != null)
        {
            foreach (var varLocal in varDecl.Locals) { 
                AddGhostVarDecl(varLocal.Name, varLocal.Type, varLocal.IsGhost);
            }

            if (varDecl.Update != null) {                
                Util.Assert(varDecl.Update is UpdateStmt || varDecl.Update is AssignSuchThatStmt);
                AddGhostStatement((Statement)varDecl.Update, attrs);
                //Util.Assert(varDecl.Update.Lhss.Count() == 1);
                //var destVar = AsVar(varDecl.Update.Lhss[0]);
                //Util.Assert(destVar != null);
                //ExprRhs expRhs = ((UpdateStmt)varDecl.Update).Rhss[0] as ExprRhs;
                //if (expRhs != null) { 
                //    stmts.Add(new RtlGhostMove(new RtlVar[] { destVar },
                //        new RtlExp[] { GhostExpression(expRhs.Expr) }));
                //} else {
                //    throw new Exception("not implemented: " + ((UpdateStmt)varDecl.Update).Rhss[0]);
                //}
            }
        }
        else if (minVerify)
        {
            return;
        }
        else if (assignStmt != null)
        {
            ExprRhs expRhs = assignStmt.Rhs as ExprRhs;
            if (expRhs != null)
            {
              MemberSelectExpr memberSelect = assignStmt.Lhs as MemberSelectExpr;
                RtlVar destVar;
                if (memberSelect != null && memberSelect.Member is Field)
                {
                    // assume that this is a global variable; we don't support objects yet
                    destVar = new RtlVar(GhostVar(memberSelect.MemberName), true, memberSelect.Type);
                }
                else
                {
                    destVar = AsVar(assignStmt.Lhs);
                    Util.Assert(destVar != null);
                }
                stmts.Add(new RtlGhostMove(new RtlVar[] { destVar },
                    new RtlExp[] { GhostExpression(expRhs.Expr) }));
            }
            else
            {
                throw new Exception("not implemented: " + assignStmt.Rhs);
            }
        }
        else if (callStmt != null)
        {
            var extraTypeargs = GetTypeArgs(attrs);
            var extraTypeargsDict = extraTypeargs.Select((t,index) => Tuple.Create(new TypeParameter(callStmt.Tok, "Fake" + index),t)).ToDictionary(tuple => tuple.Item1, tuple => tuple.Item2);
            var subst = callStmt.MethodSelect.TypeArgumentSubstitutions().Concat(extraTypeargsDict);

            AddGhostCall(callStmt.Lhs.ConvertAll(AsVar), callStmt.Args,
                dafnySpec.Compile_Method((Method)callStmt.MethodSelect.Member,
                    subst.ToDictionary(p => p.Key, p => AppType(p.Value)),
                    extraTypeargsDict.Keys.ToList()),
                DafnySpec.IsHeapMethod((Method)callStmt.MethodSelect.Member));
            SymdiffLinearityPoint();
        }
        else if (ifStmt != null)
        {
            stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ") {",
                new RtlExp[] { GhostExpression(ifStmt.Guard) }));
            Indent();
            AddGhostStatement(ifStmt.Thn, attrs);
            Unindent();
            stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0]));
            if (ifStmt.Els != null)
            {
                stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ") {",
                    new RtlExp[] {
                        GhostExpression(new UnaryOpExpr(Bpl.Token.NoToken, UnaryOpExpr.Opcode.Not, ifStmt.Guard)) }));
                Indent();
                AddGhostStatement(ifStmt.Els, attrs);
                Unindent();
                stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0]));
            }
        }
        else if (assertStmt != null)
        {
            stmts.Add(new RtlAssert(GhostExpression(assertStmt.Expr)));
        }
        else if (forallStmt != null)
        {
            var oldRenamer = PushRename(forallStmt.BoundVars.Select(v => v.Name));
            RtlExp ens = new RtlLiteral("true");
            foreach (var e in forallStmt.Ens)
            {
                ens = new RtlBinary("&&", ens, GhostExpression(e.E));
            }
            RtlExp range = (forallStmt.Range == null) ? new RtlLiteral("true")
                : GhostExpression(forallStmt.Range);
            List<RtlExp> wellFormed = GetTypeWellFormed(forallStmt.BoundVars.
                Select(x => Tuple.Create(GhostVar(x.Name), x.IsGhost, x.Type)).ToList());
            wellFormed.ForEach(e => range = new RtlBinary("&&", e, range));
            ens = new RtlBinary("==>", range, ens);
            string vars = String.Join(", ", forallStmt.BoundVars.Select(x => GhostVar(x.Name) + ":" +
                TypeString(AppType(x.Type))));
            stmts.Add(new RtlGhostStmtComputed(s => "forall " + vars + "::(" + s.args[0] + ")",
                new List<RtlExp> { ens }));
            stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0]));
            Indent();
            stmts.Add(PushForall());
            stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ")",
                new List<RtlExp> { range }));
            stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0]));
            Indent();
            AddGhostStatement(forallStmt.Body, attrs);
            foreach (var e in forallStmt.Ens)
            {
                stmts.Add(new RtlAssert(GhostExpression(e.E)));
            }
            PopForall();
            Unindent();
            stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0]));
            Unindent();
            stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0]));
            PopRename(oldRenamer);
        }
        else if (existsStmt != null)
        {
            List<RtlStmt> assigns = new List<RtlStmt>();
            List<RtlVar> tmps = new List<RtlVar>();
            List<Tuple<string,bool,Type>> varTuples = new List<Tuple<string,bool,Type>>();
            var oldRenamer = PushRename();
            foreach (var lhs in existsStmt.Lhss)
            {
                IdentifierExpr idExp = lhs.Resolved as IdentifierExpr;
                RtlVar origVar = AsVar(lhs);
                AddRename(idExp.Name);
                RtlVar renameVar = AsVar(lhs);
                tmps.Add(renameVar);
                varTuples.Add(Tuple.Create(renameVar.ToString(), true, idExp.Type));
                assigns.Add(new RtlGhostMove(new RtlVar[] { origVar },
                    new RtlExp[] { renameVar }));
            }
            string vars = String.Join(", ", tmps.Select(x => x.getName() + ":" + TypeString(AppType(x.type))));
            stmts.Add(new RtlGhostStmtComputed(s => "exists " + vars + "::(" + s.args[0] + ");",
                new List<RtlExp> {
                    GetTypeWellFormedExp(varTuples.ToList(), "&&", GhostExpression(existsStmt.Expr)) }));
            stmts.AddRange(assigns);
            PopRename(oldRenamer);
        }
        else if (calcStmt != null)
        {
            Util.Assert(calcStmt.Steps.Count == calcStmt.Hints.Count);
            CalcStmt.BinaryCalcOp binOp = calcStmt.Op as CalcStmt.BinaryCalcOp;
            bool isImply = binOp != null && binOp.Op == BinaryExpr.Opcode.Imp && calcStmt.Steps.Count > 0;
            if (isImply)
            {
                stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ")",
                    new RtlExp[] { GhostExpression(CalcStmt.Lhs(calcStmt.Steps[0])) }));
                stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0]));
                Indent();
            }
            var stepCount = calcStmt.Hints.Last().Body.Count == 0 ? calcStmt.Steps.Count - 1 : calcStmt.Steps.Count;
            for (int i = 0; i < stepCount; i++)
            {
                if (calcStmt.Hints[i] == null)
                {
                    stmts.Add(new RtlAssert(GhostExpression(calcStmt.Steps[i])));
                }
                else
                {
                    stmts.Add(new RtlGhostStmtComputed(s => "forall::(" + s.args[0] + ")",
                        new List<RtlExp> { GhostExpression(calcStmt.Steps[i]) }));
                    stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0]));
                    Indent();
                    var dict = new Dictionary<string,RtlVar>();
                    stmts.Add(new RtlGhostStmtComputed(s => String.Concat(dict.Values.Select(
                        x => "var " + x.x + ":" + TypeString(x.type) + ";")),
                        new RtlExp[0]));
                    forallVars.Add(dict);
                    AddGhostStatement(calcStmt.Hints[i], attrs);
                    forallVars.RemoveAt(forallVars.Count - 1);
                    Unindent();
                    stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0]));
                }
            }
            if (isImply)
            {
                Unindent();
                stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0]));
            }
        }
        else
        {
            throw new Exception("not implemented in ghost methods: " + stmt);
        }
    }
Beispiel #6
0
 public void MoveGhost(RtlVar destVar, RtlExp rhs)
 {
     stmts.Add(new RtlGhostMove(new RtlVar[] { destVar }, new RtlExp[] { rhs }));
 }
Beispiel #7
0
 public RtlVar AsVar(Expression exp)
 {
     exp = GetExp(exp);
     IdentifierExpr id = exp as IdentifierExpr;
     if (id != null)
     {
         //- We're assuming this is a local variable for the moment; otherwise we shouldn't call AppType
         string name = GhostVar(id.Name);
         RtlVar ret = new RtlVar(name, id.Var.IsGhost, AppType(id.Type));
         
         return ret;
     }
     else
     {
         return null;
     }
 }
Beispiel #8
0
 public RtlVar TempVar(Type t, bool declare = true)
 {
     string name = "$ghost__" + TempName();
     RtlVar ret = new RtlVar(name, false, AppType(t));
     if (declare)
     {
         allVars.Add(name, ret);
     }
     return ret;
 }