public virtual ForallExpr VisitForallExpr(ForallExpr node) { Contract.Requires(node != null); Contract.Ensures(Contract.Result <ForallExpr>() != null); node = (ForallExpr)this.VisitQuantifierExpr(node); return(node); }
public static Expr Extract(Expr expr, Program program, List <Axiom> axioms) { Contract.Requires(expr != null && program != null && !program.TopLevelDeclarationsAreFrozen && axioms != null); if (expr is LiteralExpr) { return(expr); } var extractor = new FunctionExtractor(); var body = extractor.VisitExpr(expr); var name = program.FreshExtractedFunctionName(); var originalVars = extractor.Substitutions.Keys.ToList(); var formalInArgs = originalVars.Select(v => new Formal(Token.NoToken, new TypedIdent(Token.NoToken, extractor.Substitutions[v].Name, extractor.Substitutions[v].TypedIdent.Type), true)).ToList <Variable>(); var formalOutArg = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, name + "$result$", expr.Type), false); var func = new Function(Token.NoToken, name, formalInArgs, formalOutArg); func.AddAttribute("never_pattern"); var boundVars = originalVars.Select(k => extractor.Substitutions[k]); var axiomCall = new NAryExpr(Token.NoToken, new FunctionCall(func), boundVars.Select(b => new IdentifierExpr(Token.NoToken, b)).ToList <Expr>()); axiomCall.Type = expr.Type; axiomCall.TypeParameters = SimpleTypeParamInstantiation.EMPTY; var eq = LiteralExpr.Eq(axiomCall, body); eq.Type = body.Type; eq.TypeParameters = SimpleTypeParamInstantiation.EMPTY; if (0 < formalInArgs.Count) { var forallExpr = new ForallExpr(Token.NoToken, boundVars.ToList <Variable>(), new Trigger(Token.NoToken, true, new List <Expr> { axiomCall }), eq); body = forallExpr; forallExpr.Attributes = new QKeyValue(Token.NoToken, "weight", new List <object> { new LiteralExpr(Token.NoToken, Basetypes.BigNum.FromInt(30)) }, null); body.Type = Type.Bool; } else { body = eq; } var axiom = new Axiom(Token.NoToken, body); func.DefinitionAxiom = axiom; program.AddTopLevelDeclaration(func); program.AddTopLevelDeclaration(axiom); axioms.Add(axiom); var call = new NAryExpr(Token.NoToken, new FunctionCall(func), originalVars.Select(v => new IdentifierExpr(Token.NoToken, v)).ToList <Expr>()); call.Type = expr.Type; call.TypeParameters = SimpleTypeParamInstantiation.EMPTY; return(call); }
public static void AddCheckers(CivlTypeChecker ctc) { foreach (var action in ctc.AllAtomicActions.Where(a => a.HasPendingAsyncs)) { var requires = action.gate.Select(g => new Requires(false, g.Expr)).ToList(); var cmds = new List <Cmd> { CmdHelper.CallCmd( action.proc, action.impl.InParams.Select(Expr.Ident).ToList <Expr>(), action.impl.OutParams.Select(Expr.Ident).ToList()) }; var blocks = new List <Block>() { new Block(Token.NoToken, "init", cmds, CmdHelper.ReturnCmd) }; var PAs = Expr.Ident(action.impl.OutParams.Last(p => p.TypedIdent.Type.Equals(ctc.pendingAsyncMultisetType))); var paBound = VarHelper.BoundVariable("pa", ctc.pendingAsyncType); var pa = Expr.Ident(paBound); var nonnegativeExpr = new ForallExpr(Token.NoToken, new List <Variable> { paBound }, Expr.Ge(Expr.Select(PAs, pa), Expr.Literal(0))); var correctTypeExpr = new ForallExpr(Token.NoToken, new List <Variable> { paBound }, Expr.Imp( Expr.Gt(Expr.Select(PAs, pa), Expr.Literal(0)), Expr.Or(action.pendingAsyncs.Select(a => ExprHelper.FunctionCall(a.pendingAsyncCtor.membership, pa))))); var ensures = new List <Ensures> { new Ensures(false, nonnegativeExpr) { ErrorData = $"Action {action.proc.Name} might create negative pending asyncs" }, new Ensures(false, correctTypeExpr) { ErrorData = $"Action {action.proc.Name} might create undeclared pending asyncs" }, }; CivlUtil.ResolveAndTypecheck(ensures); var proc = new Procedure(Token.NoToken, $"PendingAsyncChecker_{action.proc.Name}", new List <TypeVariable>(), action.impl.InParams, action.impl.OutParams, requires, action.proc.Modifies, ensures); var impl = new Implementation(Token.NoToken, proc.Name, proc.TypeParameters, proc.InParams, proc.OutParams, new List <Variable>(), blocks) { Proc = proc }; ctc.program.AddTopLevelDeclaration(proc); ctc.program.AddTopLevelDeclaration(impl); } }
public void CachedHashCodeForAllExpr() { var x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int)); var y = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int)); var body = Expr.Gt (new IdentifierExpr (Token.NoToken, x, /*immutable=*/true), new IdentifierExpr(Token.NoToken, y, /*immutable=*/true)); var forAll = new ForallExpr(Token.NoToken, new List<Variable> () {x, y }, body, /*immutable=*/ true); Assert.AreEqual(forAll.ComputeHashCode(), forAll.GetHashCode()); }
public static Expr Extract(Expr expr, Program program, List<Axiom> axioms) { Contract.Requires(expr != null && program != null && !program.TopLevelDeclarationsAreFrozen && axioms != null); if (expr is LiteralExpr) { return expr; } var extractor = new FunctionExtractor(); var body = extractor.VisitExpr(expr); var name = program.FreshExtractedFunctionName(); var originalVars = extractor.Substitutions.Keys.ToList(); var formalInArgs = originalVars.Select(v => new Formal(Token.NoToken, new TypedIdent(Token.NoToken, extractor.Substitutions[v].Name, extractor.Substitutions[v].TypedIdent.Type), true)).ToList<Variable>(); var formalOutArg = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, name + "$result$", expr.Type), false); var func = new Function(Token.NoToken, name, formalInArgs, formalOutArg); func.AddAttribute("never_pattern"); var boundVars = originalVars.Select(k => extractor.Substitutions[k]); var axiomCall = new NAryExpr(Token.NoToken, new FunctionCall(func), boundVars.Select(b => new IdentifierExpr(Token.NoToken, b)).ToList<Expr>()); axiomCall.Type = expr.Type; axiomCall.TypeParameters = SimpleTypeParamInstantiation.EMPTY; var eq = LiteralExpr.Eq(axiomCall, body); eq.Type = body.Type; eq.TypeParameters = SimpleTypeParamInstantiation.EMPTY; if (0 < formalInArgs.Count) { var forallExpr = new ForallExpr(Token.NoToken, boundVars.ToList<Variable>(), new Trigger(Token.NoToken, true, new List<Expr> { axiomCall }), eq); body = forallExpr; forallExpr.Attributes = new QKeyValue(Token.NoToken, "weight", new List<object> { new LiteralExpr(Token.NoToken, Basetypes.BigNum.FromInt(30)) }, null); body.Type = Type.Bool; } else { body = eq; } var axiom = new Axiom(Token.NoToken, body); func.DefinitionAxiom = axiom; program.AddTopLevelDeclaration(func); program.AddTopLevelDeclaration(axiom); axioms.Add(axiom); var call = new NAryExpr(Token.NoToken, new FunctionCall(func), originalVars.Select(v => new IdentifierExpr(Token.NoToken, v)).ToList<Expr>()); call.Type = expr.Type; call.TypeParameters = SimpleTypeParamInstantiation.EMPTY; return call; }
public override Expr VisitForallExpr(ForallExpr node) { Contract.Ensures(Contract.Result<Expr>() == node); return (ForallExpr)this.VisitQuantifierExpr(node); }
public virtual Expr VisitForallExpr(ForallExpr node) { Contract.Requires(node != null); Contract.Ensures(Contract.Result<Expr>() != null); node = (ForallExpr)this.VisitQuantifierExpr(node); return node; }
void QuantifierGuts(out Expression q, bool allowSemi, bool allowLambda) { Contract.Ensures(Contract.ValueAtReturn(out q) != null); IToken/*!*/ x = Token.NoToken; bool univ = false; List<BoundVar/*!*/> bvars; Attributes attrs; Expression range; Expression/*!*/ body; if (la.kind == 103 || la.kind == 123) { Forall(); x = t; univ = true; } else if (la.kind == 124 || la.kind == 125) { Exists(); x = t; } else SynErr(238); QuantifierDomain(out bvars, out attrs, out range); QSep(); Expression(out body, allowSemi, allowLambda); if (univ) { q = new ForallExpr(x, bvars, range, body, attrs); } else { q = new ExistsExpr(x, bvars, range, body, attrs); } }
public Axiom CreateDefinitionAxiom(Expr definition, QKeyValue kv = null) { Contract.Requires(definition != null); List<Variable> dummies = new List<Variable>(); List<Expr> callArgs = new List<Expr>(); int i = 0; foreach (Formal/*!*/ f in InParams) { Contract.Assert(f != null); string nm = f.TypedIdent.HasName ? f.TypedIdent.Name : "_" + i; dummies.Add(new BoundVariable(f.tok, new TypedIdent(f.tok, nm, f.TypedIdent.Type))); callArgs.Add(new IdentifierExpr(f.tok, nm)); i++; } List<TypeVariable>/*!*/ quantifiedTypeVars = new List<TypeVariable>(); foreach (TypeVariable/*!*/ t in TypeParameters) { Contract.Assert(t != null); quantifiedTypeVars.Add(new TypeVariable(Token.NoToken, t.Name)); } Expr call = new NAryExpr(tok, new FunctionCall(new IdentifierExpr(tok, Name)), callArgs); // specify the type of the function, because it might be that // type parameters only occur in the output type call = Expr.CoerceType(tok, call, (Type)OutParams[0].TypedIdent.Type.Clone()); Expr def = Expr.Eq(call, definition); if (quantifiedTypeVars.Count != 0 || dummies.Count != 0) { def = new ForallExpr(tok, quantifiedTypeVars, dummies, kv, new Trigger(tok, true, new List<Expr> { call }, null), def); } DefinitionAxiom = new Axiom(tok, def); return DefinitionAxiom; }
public override ForallExpr VisitForallExpr(ForallExpr node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result <ForallExpr>() != null); return(base.VisitForallExpr((ForallExpr)node.Clone())); }
/// <summary> /// /// </summary> /// <param name="methodCall"></param> /// <remarks>Stub, This one really needs comments!</remarks> public override void TraverseChildren(IMethodCall methodCall) { var resolvedMethod = ResolveUnspecializedMethodOrThrow(methodCall.MethodToCall); Bpl.IToken methodCallToken = methodCall.Token(); if (this.sink.Options.getMeHere) { // TODO: Get a method reference so this isn't a string comparison? var methodName = MemberHelper.GetMethodSignature(methodCall.MethodToCall, NameFormattingOptions.None); if (methodName.Equals("GetMeHere.GetMeHere.Assert")) { // for now, just translate it as "assert e" this.Traverse(methodCall.Arguments.First()); Bpl.Expr e = this.TranslatedExpressions.Pop(); this.StmtTraverser.StmtBuilder.Add(new Bpl.AssertCmd(methodCallToken, e)); return; } } // Handle type equality specially when it is testing against a constant, i.e., o.GetType() == typeof(T) if (IsOperator(resolvedMethod) && !IsConversionOperator(resolvedMethod) && TypeHelper.TypesAreEquivalent(resolvedMethod.ContainingType, this.sink.host.PlatformType.SystemType)) { // REVIEW: Assume the only operators on System.Type are == and != var typeToTest = methodCall.Arguments.ElementAtOrDefault(0) as ITypeOf; IMethodCall callToGetType; if (typeToTest == null) { typeToTest = methodCall.Arguments.ElementAtOrDefault(1) as ITypeOf; callToGetType = methodCall.Arguments.ElementAtOrDefault(0) as IMethodCall; } else { callToGetType = methodCall.Arguments.ElementAtOrDefault(1) as IMethodCall; } if (typeToTest != null && callToGetType != null && TypeHelper.TypesAreEquivalent(callToGetType.MethodToCall.ContainingType, this.sink.host.PlatformType.SystemObject) && MemberHelper.GetMethodSignature(callToGetType.MethodToCall).Equals("System.Object.GetType")) { IExpression objectToTest = callToGetType.ThisArgument; // generate: $TypeConstructor($DynamicType(o)) == TypeConstructorId var typeConstructorId = this.sink.FindOrDefineType(typeToTest.TypeToGet.ResolvedType).ConstructorId; Contract.Assume(typeConstructorId != null); this.Traverse(objectToTest); var e = this.TranslatedExpressions.Pop(); var exprs = new List<Bpl.Expr>(new Bpl.Expr[] {this.sink.Heap.DynamicType(e)}); Bpl.Expr typeTestExpression = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.NAryExpr(methodCallToken, new Bpl.FunctionCall(sink.Heap.TypeConstructorFunction), exprs), Bpl.Expr.Ident(typeConstructorId)); if (MemberHelper.GetMethodSignature(resolvedMethod).Equals("System.Type.op_Inequality")) typeTestExpression = Bpl.Expr.Unary( methodCallToken, Bpl.UnaryOperator.Opcode.Not, typeTestExpression); this.TranslatedExpressions.Push(typeTestExpression); return; } } // Handle calls to Contract.ForAll and Contract.Exists specially (if they are to the overloads that take two ints and a predicate on ints) if (resolvedMethod.ContainingTypeDefinition.InternedKey == this.sink.host.PlatformType.SystemDiagnosticsContractsContract.InternedKey) { var methodName = resolvedMethod.Name.Value; if (methodCall.Arguments.Count() == 3 && (methodName == "ForAll" || methodName == "Exists")) { var noToken = Bpl.Token.NoToken; this.Traverse(methodCall.Arguments.ElementAt(0)); var lb = this.TranslatedExpressions.Pop(); this.Traverse(methodCall.Arguments.ElementAt(1)); var ub = this.TranslatedExpressions.Pop(); var delegateArgument = methodCall.Arguments.ElementAt(2); this.Traverse(delegateArgument); var del = this.TranslatedExpressions.Pop(); var boundVar = new Bpl.LocalVariable(noToken, new Bpl.TypedIdent(noToken, TranslationHelper.GenerateTempVarName(), Bpl.Type.Int)); var resultVar = new Bpl.LocalVariable(noToken, new Bpl.TypedIdent(noToken, TranslationHelper.GenerateTempVarName(), Bpl.Type.Bool)); var delegateType = delegateArgument.Type; var invokeMethod = delegateType.ResolvedType.GetMembersNamed(this.sink.host.NameTable.GetNameFor("Invoke"), false).First() as IMethodReference; var unspecializedInvokeMethod = Sink.Unspecialize(invokeMethod).ResolvedMethod; var invokeProcedureInfo = sink.FindOrCreateProcedure(unspecializedInvokeMethod); var ins = new List<Bpl.Expr>(); ins.Add(del); var localStmtTraverser = this.StmtTraverser.factory.MakeStatementTraverser(this.sink, this.StmtTraverser.PdbReader, this.contractContext); var secondArg = new Bpl.NAryExpr(noToken, new Bpl.FunctionCall(this.sink.Heap.Int2Union), new List<Bpl.Expr>(new Bpl.Expr[] {Bpl.Expr.Ident(boundVar)})); ins.Add(secondArg); var outs = new List<Bpl.IdentifierExpr>(); outs.Add(Bpl.Expr.Ident(resultVar)); var callCmd = new Bpl.CallCmd(noToken, invokeProcedureInfo.Decl.Name, ins, outs); var blockCmds = new List<Bpl.Cmd>(); blockCmds.Add( new Bpl.AssumeCmd(noToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.NAryExpr(noToken, new Bpl.FunctionCall(this.sink.Heap.Union2Int), new List<Bpl.Expr>(new Bpl.Expr[] {secondArg})), Bpl.Expr.Ident(boundVar)))); blockCmds.Add(callCmd); Bpl.Block block = new Bpl.Block(noToken, "A", blockCmds, new Bpl.ReturnExprCmd(noToken, Bpl.Expr.Ident(resultVar))); Bpl.Expr body = new Bpl.CodeExpr(new List<Bpl.Variable>(new Bpl.Variable[] {resultVar}), new List<Bpl.Block>{block}); Bpl.Expr antecedent = Bpl.Expr.And(Bpl.Expr.Le(lb, Bpl.Expr.Ident(boundVar)), Bpl.Expr.Lt(Bpl.Expr.Ident(boundVar), ub)); Bpl.Expr quantifier; if (methodName == "ForAll") { body = Bpl.Expr.Imp(antecedent, body); quantifier = new Bpl.ForallExpr(methodCallToken, new List<Bpl.Variable>(new Bpl.Variable[] {boundVar}), body); } else { body = Bpl.Expr.And(antecedent, body); quantifier = new Bpl.ExistsExpr(methodCallToken, new List<Bpl.Variable>(new Bpl.Variable[] {boundVar}), body); } this.TranslatedExpressions.Push(quantifier); return; } } List<Bpl.Expr> inexpr; List<Bpl.IdentifierExpr> outvars; Bpl.IdentifierExpr thisExpr; Dictionary<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>> toBoxed; var proc = TranslateArgumentsAndReturnProcedure(methodCallToken, methodCall.MethodToCall, resolvedMethod, methodCall.IsStaticCall ? null : methodCall.ThisArgument, methodCall.Arguments, out inexpr, out outvars, out thisExpr, out toBoxed); string methodname = proc.Name; var translateAsFunctionCall = proc is Bpl.Function; bool isAsync = false; // this code structure is quite chaotic, and some code needs to be evaluated regardless, hence the try-finally try { if (!translateAsFunctionCall) { foreach (var a in resolvedMethod.Attributes) { if (TypeHelper.GetTypeName(a.Type).EndsWith("AsyncAttribute")) { isAsync = true; } } } var deferringCtorCall = resolvedMethod.IsConstructor && methodCall.ThisArgument is IThisReference; // REVIEW!! Ask Herman: is the above test enough? The following test is used in FindCtorCall.IsDeferringCtor, // but it doesn't work when the type is a struct S because then "this" has a type of "&S". //&& TypeHelper.TypesAreEquivalent(resolvedMethod.ContainingType, methodCall.ThisArgument.Type); if (resolvedMethod.IsConstructor && resolvedMethod.ContainingTypeDefinition.IsStruct && !deferringCtorCall) { handleStructConstructorCall(methodCall, methodCallToken, inexpr, outvars, thisExpr, proc); return; } Bpl.CallCmd call; bool isEventAdd = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("add_"); bool isEventRemove = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("remove_"); if (isEventAdd || isEventRemove) { call = translateAddRemoveCall(methodCall, resolvedMethod, methodCallToken, inexpr, outvars, thisExpr, isEventAdd); } else { if (translateAsFunctionCall) { var func = proc as Bpl.Function; var exprSeq = new List<Bpl.Expr>(); foreach (var e in inexpr) { exprSeq.Add(e); } var callFunction = new Bpl.NAryExpr(methodCallToken, new Bpl.FunctionCall(func), exprSeq); this.TranslatedExpressions.Push(callFunction); return; } else { EmitLineDirective(methodCallToken); call = new Bpl.CallCmd(methodCallToken, methodname, inexpr, outvars); call.IsAsync = isAsync; this.StmtTraverser.StmtBuilder.Add(call); } } foreach (KeyValuePair<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>> kv in toBoxed) { var lhs = kv.Key; var tuple = kv.Value; var rhs = tuple.Item1; Bpl.Expr fromUnion = this.sink.Heap.FromUnion(Bpl.Token.NoToken, lhs.Type, rhs, tuple.Item2); this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(lhs, fromUnion)); } if (this.sink.Options.modelExceptions == 2 || (this.sink.Options.modelExceptions == 1 && this.sink.MethodThrowsExceptions(resolvedMethod))) { Bpl.Expr expr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef)); this.StmtTraverser.RaiseException(expr); } } finally { // TODO move away phone related code from the translation, it would be better to have 2 or more translation phases if (PhoneCodeHelper.instance().PhonePlugin != null) { if (PhoneCodeHelper.instance().PhoneNavigationToggled) { if (PhoneCodeHelper.instance().isNavigationCall(methodCall)) { Bpl.AssignCmd assignCmd = PhoneCodeHelper.instance().createBoogieNavigationUpdateCmd(sink); this.StmtTraverser.StmtBuilder.Add(assignCmd); } } if (PhoneCodeHelper.instance().PhoneFeedbackToggled) { if (PhoneCodeHelper.instance().isMethodKnownUIChanger(methodCall)) { Bpl.AssumeCmd assumeFalse = new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.LiteralExpr.False); this.StmtTraverser.StmtBuilder.Add(assumeFalse); } } } } }
public LinearDomain(Program program, string domainName, Type elementType) { this.elementType = elementType; this.axioms = new List <Axiom>(); MapType mapTypeBool = new MapType(Token.NoToken, new List <TypeVariable>(), new List <Type> { this.elementType }, Type.Bool); MapType mapTypeInt = new MapType(Token.NoToken, new List <TypeVariable>(), new List <Type> { this.elementType }, Type.Int); this.mapOrBool = new Function(Token.NoToken, "linear_" + domainName + "_MapOr", new List <Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool), true), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapOrBool.AddAttribute("builtin", "MapOr"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool)); IdentifierExpr aie = new IdentifierExpr(Token.NoToken, a); BoundVariable b = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool)); IdentifierExpr bie = new IdentifierExpr(Token.NoToken, b); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = new IdentifierExpr(Token.NoToken, x); var mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapOrBool), new List <Expr> { aie, bie }); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { mapApplTerm, xie }); var rhsTerm = Expr.Binary(BinaryOperator.Opcode.Or, new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { aie, xie }), new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { bie, xie })); var axiomExpr = new ForallExpr(Token.NoToken, new List <TypeVariable>(), new List <Variable> { a, b }, null, new Trigger(Token.NoToken, true, new List <Expr> { mapApplTerm }), new ForallExpr(Token.NoToken, new List <Variable> { x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm))); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } this.mapImpBool = new Function(Token.NoToken, "linear_" + domainName + "_MapImp", new List <Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool), true), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapImpBool.AddAttribute("builtin", "MapImp"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool)); IdentifierExpr aie = new IdentifierExpr(Token.NoToken, a); BoundVariable b = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool)); IdentifierExpr bie = new IdentifierExpr(Token.NoToken, b); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = new IdentifierExpr(Token.NoToken, x); var mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapImpBool), new List <Expr> { aie, bie }); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { mapApplTerm, xie }); var rhsTerm = Expr.Binary(BinaryOperator.Opcode.Imp, new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { aie, xie }), new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { bie, xie })); var axiomExpr = new ForallExpr(Token.NoToken, new List <TypeVariable>(), new List <Variable> { a, b }, null, new Trigger(Token.NoToken, true, new List <Expr> { mapApplTerm }), new ForallExpr(Token.NoToken, new List <Variable> { x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm))); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } this.mapConstBool = new Function(Token.NoToken, "linear_" + domainName + "_MapConstBool", new List <Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", Type.Bool), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapConstBool.AddAttribute("builtin", "MapConst"); } else { BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = new IdentifierExpr(Token.NoToken, x); var trueTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { new NAryExpr(Token.NoToken, new FunctionCall(mapConstBool), new List <Expr> { Expr.True }), xie }); var trueAxiomExpr = new ForallExpr(Token.NoToken, new List <Variable> { x }, trueTerm); trueAxiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, trueAxiomExpr)); var falseTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { new NAryExpr(Token.NoToken, new FunctionCall(mapConstBool), new List <Expr> { Expr.False }), xie }); var falseAxiomExpr = new ForallExpr(Token.NoToken, new List <Variable> { x }, Expr.Unary(Token.NoToken, UnaryOperator.Opcode.Not, falseTerm)); falseAxiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, falseAxiomExpr)); } this.mapEqInt = new Function(Token.NoToken, "linear_" + domainName + "_MapEq", new List <Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeInt), true), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeInt), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapEqInt.AddAttribute("builtin", "MapEq"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeInt)); IdentifierExpr aie = new IdentifierExpr(Token.NoToken, a); BoundVariable b = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeInt)); IdentifierExpr bie = new IdentifierExpr(Token.NoToken, b); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = new IdentifierExpr(Token.NoToken, x); var mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapEqInt), new List <Expr> { aie, bie }); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { mapApplTerm, xie }); var rhsTerm = Expr.Binary(BinaryOperator.Opcode.Eq, new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { aie, xie }), new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { bie, xie })); var axiomExpr = new ForallExpr(Token.NoToken, new List <TypeVariable>(), new List <Variable> { a, b }, null, new Trigger(Token.NoToken, true, new List <Expr> { mapApplTerm }), new ForallExpr(Token.NoToken, new List <Variable> { x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm))); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } this.mapConstInt = new Function(Token.NoToken, "linear_" + domainName + "_MapConstInt", new List <Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", Type.Int), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeInt), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapConstInt.AddAttribute("builtin", "MapConst"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", Type.Int)); IdentifierExpr aie = new IdentifierExpr(Token.NoToken, a); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = new IdentifierExpr(Token.NoToken, x); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { new NAryExpr(Token.NoToken, new FunctionCall(mapConstInt), new List <Expr> { aie }), xie }); var axiomExpr = new ForallExpr(Token.NoToken, new List <Variable> { a, x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, aie)); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } foreach (var axiom in axioms) { axiom.Expr.Resolve(new ResolutionContext(null)); axiom.Expr.Typecheck(new TypecheckingContext(null)); } }
private VCGenOutcome LearnInv(Dictionary<string, int> impl2Priority) { var worklist = new SortedSet<Tuple<int, string>>(); name2Impl.Keys.Iter(k => worklist.Add(Tuple.Create(impl2Priority[k], k))); while (worklist.Any()) { var impl = worklist.First().Item2; worklist.Remove(worklist.First()); #region vcgen var gen = prover.VCExprGen; var terms = new List<Expr>(); foreach (var tup in impl2FuncCalls[impl]) { var controlVar = tup.Item2; var exprVars = tup.Item3; var varList = new List<Expr>(); exprVars.Args.OfType<Expr>().Iter(v => varList.Add(v)); var args = new List<Expr>(); controlVar.InParams.Iter(v => args.Add(Expr.Ident(v))); Expr term = Expr.Eq(new NAryExpr(Token.NoToken, new FunctionCall(controlVar), args), function2Value[tup.Item1].Gamma(varList)); if (controlVar.InParams.Count != 0) { term = new ForallExpr(Token.NoToken, new List<Variable>(controlVar.InParams.ToArray()), new Trigger(Token.NoToken, true, new List<Expr> { new NAryExpr(Token.NoToken, new FunctionCall(controlVar), args) }), term); } terms.Add(term); /* foreach (var variable in varList) { terms.Add(Expr.Le(variable, Expr.Literal(10))); terms.Add(Expr.Ge(variable, Expr.Literal(-10))); } */ } var env = BinaryTreeAnd(terms, 0, terms.Count - 1); env.Typecheck(new TypecheckingContext((IErrorSink)null)); var envVC = prover.Context.BoogieExprTranslator.Translate(env); var vc = gen.Implies(envVC, impl2VC[impl]); if (CommandLineOptions.Clo.Trace) { Console.WriteLine("Verifying {0}: ", impl); //Console.WriteLine("env: {0}", envVC); var envFuncs = new HashSet<string>(); impl2FuncCalls[impl].Iter(tup => envFuncs.Add(tup.Item1)); envFuncs.Iter(f => PrintFunction(existentialFunctions[f])); } #endregion vcgen VCExpr finalVC; for (int i = 0; i <= bounds4cex.Count(); i++) { #region boundcexvalues /* Last iteration is when there are enforced no bounds on the cex values. */ if (i < bounds4cex.Count()) { int bound = bounds4cex.ElementAt(i); terms.Clear(); foreach (var tup in impl2FuncCalls[impl]) { var exprVars = tup.Item3; var varList = new List<Expr>(); exprVars.Args.OfType<Expr>().Where(v => v.Type.IsInt).Iter(v => varList.Add(v)); foreach (var variable in varList) { terms.Add(Expr.Le(variable, Expr.Literal(bound))); terms.Add(Expr.Ge(variable, Expr.Literal(-1 * bound))); //terms.Add(Expr.Ge(variable, Expr.Literal(0))); } } var boundcex = BinaryTreeAnd(terms, 0, terms.Count - 1); boundcex.Typecheck(new TypecheckingContext((IErrorSink)null)); var boundcexVC = prover.Context.BoogieExprTranslator.Translate(boundcex); finalVC = gen.Implies(boundcexVC, vc); } else { //finalVC = vc; int bound = 1000000; terms.Clear(); foreach (var tup in impl2FuncCalls[impl]) { var exprVars = tup.Item3; var varList = new List<Expr>(); exprVars.Args.OfType<Expr>().Where(v => v.Type.IsInt).Iter(v => varList.Add(v)); foreach (var variable in varList) { terms.Add(Expr.Le(variable, Expr.Literal(bound))); terms.Add(Expr.Ge(variable, Expr.Literal(-1 * bound))); //terms.Add(Expr.Ge(variable, Expr.Literal(0))); } } var boundcex = BinaryTreeAnd(terms, 0, terms.Count - 1); boundcex.Typecheck(new TypecheckingContext((IErrorSink)null)); var boundcexVC = prover.Context.BoogieExprTranslator.Translate(boundcex); finalVC = gen.Implies(boundcexVC, vc); } #endregion boundcexvalues var handler = impl2ErrorHandler[impl].Item1; var collector = impl2ErrorHandler[impl].Item2; collector.Reset(impl); implicationCounterExamples.Clear(); VCisValid = true; // set to false if control reaches HandleCounterExample //realErrorEncountered = false; //newSamplesAdded = false; //this.posNegCexAdded = false; var start = DateTime.Now; prover.Push(); prover.Assert(gen.Not(finalVC), true); prover.FlushAxiomsToTheoremProver(); prover.Check(); ProverInterface.Outcome proverOutcome = prover.CheckOutcomeCore(handler); var inc = (DateTime.Now - start); proverTime += inc; numProverQueries++; if (CommandLineOptions.Clo.Trace) Console.WriteLine("Prover Time taken = " + inc.TotalSeconds.ToString()); if (proverOutcome == ProverInterface.Outcome.TimeOut || proverOutcome == ProverInterface.Outcome.OutOfMemory) { Console.WriteLine("Z3 Prover for implementation {0} times out or runs out of memory !", impl); return new VCGenOutcome(proverOutcome, new List<Counterexample>()); } if (!VCisValid) { /* There was a counterexample found and acted upon while proving the method. */ if (collector.real_errors.Count > 0) { return new VCGenOutcome(ProverInterface.Outcome.Invalid, collector.real_errors); } if (collector.conjecture_errors.Count == 0) { // No positive or negative counter-example added. Need to add implication counter-examples Debug.Assert(collector.implication_errors.Count > 0); foreach (var cex in implicationCounterExamples) { AddCounterExample(cex); } } //Debug.Assert(newSamplesAdded); HashSet<string> funcsChanged; if (!learn(out funcsChanged)) { // learner timed out, ran into some errors, or if there is no consistent conjecture prover.Pop(); if(collector.conjecture_errors.Count > 0) return new VCGenOutcome(ProverInterface.Outcome.Invalid, collector.conjecture_errors); else return new VCGenOutcome(ProverInterface.Outcome.Invalid, collector.implication_errors); } // propagate dependent guys back into the worklist, including self var deps = new HashSet<string>(); deps.Add(impl); funcsChanged.Iter(f => deps.UnionWith(function2implAssumed[f])); funcsChanged.Iter(f => deps.UnionWith(function2implAsserted[f])); deps.Iter(s => worklist.Add(Tuple.Create(impl2Priority[s], s))); // break out of the loop that iterates over various bounds. prover.Pop(); break; } else { prover.Pop(); } } } // The program was verified return new VCGenOutcome(ProverInterface.Outcome.Valid, new List<Counterexample>()); }
public LinearDomain(Program program, string domainName, Dictionary<Type, Function> collectors) { this.axioms = new List<Axiom>(); this.collectors = collectors; MapType setType = (MapType)collectors.First().Value.OutParams[0].TypedIdent.Type; this.elementType = setType.Arguments[0]; MapType mapTypeBool = new MapType(Token.NoToken, new List<TypeVariable>(), new List<Type> { this.elementType }, Type.Bool); MapType mapTypeInt = new MapType(Token.NoToken, new List<TypeVariable>(), new List<Type> { this.elementType }, Type.Int); this.mapOrBool = new Function(Token.NoToken, "linear_" + domainName + "_MapOr", new List<Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool), true), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapOrBool.AddAttribute("builtin", "MapOr"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool)); IdentifierExpr aie = Expr.Ident(a); BoundVariable b = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool)); IdentifierExpr bie = Expr.Ident(b); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = Expr.Ident(x); var mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapOrBool), new List<Expr> { aie, bie } ); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { mapApplTerm, xie } ); var rhsTerm = Expr.Or(new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { aie, xie } ), new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { bie, xie} )); var axiomExpr = new ForallExpr(Token.NoToken, new List<TypeVariable>(), new List<Variable> { a, b }, null, new Trigger(Token.NoToken, true, new List<Expr> { mapApplTerm }), new ForallExpr(Token.NoToken, new List<Variable> { x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm))); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } this.mapImpBool = new Function(Token.NoToken, "linear_" + domainName + "_MapImp", new List<Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool), true), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapImpBool.AddAttribute("builtin", "MapImp"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool)); IdentifierExpr aie = Expr.Ident(a); BoundVariable b = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool)); IdentifierExpr bie = Expr.Ident(b); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = Expr.Ident(x); var mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapImpBool), new List<Expr> { aie, bie }); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { mapApplTerm, xie }); var rhsTerm = Expr.Imp(new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { aie, xie }), new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { bie, xie })); var axiomExpr = new ForallExpr(Token.NoToken, new List<TypeVariable>(), new List<Variable> { a, b }, null, new Trigger(Token.NoToken, true, new List<Expr> { mapApplTerm }), new ForallExpr(Token.NoToken, new List<Variable> { x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm))); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } this.mapConstBool = new Function(Token.NoToken, "linear_" + domainName + "_MapConstBool", new List<Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", Type.Bool), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapConstBool.AddAttribute("builtin", "MapConst"); } else { BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = Expr.Ident(x); var trueTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { new NAryExpr(Token.NoToken, new FunctionCall(mapConstBool), new List<Expr> { Expr.True }), xie }); var trueAxiomExpr = new ForallExpr(Token.NoToken, new List<Variable> { x }, trueTerm); trueAxiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, trueAxiomExpr)); var falseTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { new NAryExpr(Token.NoToken, new FunctionCall(mapConstBool), new List<Expr> { Expr.False }), xie }); var falseAxiomExpr = new ForallExpr(Token.NoToken, new List<Variable> { x }, Expr.Unary(Token.NoToken, UnaryOperator.Opcode.Not, falseTerm)); falseAxiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, falseAxiomExpr)); } this.mapEqInt = new Function(Token.NoToken, "linear_" + domainName + "_MapEq", new List<Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeInt), true), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeInt), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapEqInt.AddAttribute("builtin", "MapEq"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeInt)); IdentifierExpr aie = Expr.Ident(a); BoundVariable b = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeInt)); IdentifierExpr bie = Expr.Ident(b); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = Expr.Ident(x); var mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapEqInt), new List<Expr> { aie, bie }); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { mapApplTerm, xie }); var rhsTerm = Expr.Eq(new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { aie, xie }), new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { bie, xie })); var axiomExpr = new ForallExpr(Token.NoToken, new List<TypeVariable>(), new List<Variable> { a, b }, null, new Trigger(Token.NoToken, true, new List<Expr> { mapApplTerm }), new ForallExpr(Token.NoToken, new List<Variable> { x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm))); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } this.mapConstInt = new Function(Token.NoToken, "linear_" + domainName + "_MapConstInt", new List<Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", Type.Int), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeInt), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapConstInt.AddAttribute("builtin", "MapConst"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", Type.Int)); IdentifierExpr aie = Expr.Ident(a); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = Expr.Ident(x); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { new NAryExpr(Token.NoToken, new FunctionCall(mapConstInt), new List<Expr> { aie }), xie }); var axiomExpr = new ForallExpr(Token.NoToken, new List<Variable> { a, x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, aie)); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } foreach (var axiom in axioms) { axiom.Expr.Resolve(new ResolutionContext(null)); axiom.Expr.Typecheck(new TypecheckingContext(null)); } }
private ICEOutcome LearnInvFromTemplate(Dictionary<string, int> impl2Priority, Template t, int range, out VCGenOutcome overallOutcome) { overallOutcome = null; // create a new z3 context if (z3Context != null) { z3Context.context.Dispose(); z3Context.config.Dispose(); } z3Context = new Z3Context(); foreach (var func in existentialFunctions.Values) { // initialize function to an "Octagons" instance with the given template "t". function2Value[func.Name] = ICEDomainFactory.GetInstance("Octagons", t, ref z3Context, func.Name, range); } // add counterexamples into the z3Context. These are obtained from the earlier iterations of the template. foreach (var cex in counterExamples) { AddCounterExampleToZ3Context(cex); } var worklist = new SortedSet<Tuple<int, string>>(); name2Impl.Keys.Iter(k => worklist.Add(Tuple.Create(impl2Priority[k], k))); while (worklist.Any()) { var impl = worklist.First().Item2; worklist.Remove(worklist.First()); #region vcgen var gen = prover.VCExprGen; var terms = new List<Expr>(); foreach (var tup in impl2FuncCalls[impl]) { var controlVar = tup.Item2; var exprVars = tup.Item3; var varList = new List<Expr>(); exprVars.Args.OfType<Expr>().Iter(v => varList.Add(v)); var args = new List<Expr>(); controlVar.InParams.Iter(v => args.Add(Expr.Ident(v))); Expr term = Expr.Eq(new NAryExpr(Token.NoToken, new FunctionCall(controlVar), args), function2Value[tup.Item1].Gamma(varList)); if (controlVar.InParams.Count != 0) { term = new ForallExpr(Token.NoToken, new List<Variable>(controlVar.InParams.ToArray()), new Trigger(Token.NoToken, true, new List<Expr> { new NAryExpr(Token.NoToken, new FunctionCall(controlVar), args) }), term); } terms.Add(term); } var env = BinaryTreeAnd(terms, 0, terms.Count - 1); env.Typecheck(new TypecheckingContext((IErrorSink)null)); var envVC = prover.Context.BoogieExprTranslator.Translate(env); var vc = gen.Implies(envVC, impl2VC[impl]); if (CommandLineOptions.Clo.Trace) { Console.WriteLine("Verifying {0}: ", impl); //Console.WriteLine("env: {0}", envVC); var envFuncs = new HashSet<string>(); impl2FuncCalls[impl].Iter(tup => envFuncs.Add(tup.Item1)); envFuncs.Iter(f => PrintFunction(existentialFunctions[f])); } #endregion vcgen VCExpr finalVC; #region bound_value_of_cexs #if false finalVC = vc; #else int bound = 1000000; terms.Clear(); foreach (var tup in impl2FuncCalls[impl]) { var exprVars = tup.Item3; var varList = new List<Expr>(); exprVars.Args.OfType<Expr>().Where(v => v.Type.IsInt).Iter(v => varList.Add(v)); foreach (var variable in varList) { terms.Add(Expr.Le(variable, Expr.Literal(bound))); terms.Add(Expr.Ge(variable, Expr.Literal(-1 * bound))); //terms.Add(Expr.Ge(variable, Expr.Literal(0))); } } var boundcex = BinaryTreeAnd(terms, 0, terms.Count - 1); boundcex.Typecheck(new TypecheckingContext((IErrorSink)null)); var boundcexVC = prover.Context.BoogieExprTranslator.Translate(boundcex); finalVC = gen.Implies(boundcexVC, vc); #endif #endregion bound_value_of_cexs var handler = impl2ErrorHandler[impl].Item1; var collector = impl2ErrorHandler[impl].Item2; collector.Reset(impl); VCisValid = true; // set to false if control reaches HandleCounterExample realErrorEncountered = false; newSamplesAdded = false; var start = DateTime.Now; prover.Push(); prover.Assert(gen.Not(finalVC), true); prover.FlushAxiomsToTheoremProver(); prover.Check(); ProverInterface.Outcome proverOutcome = prover.CheckOutcomeCore(handler); //prover.BeginCheck(impl, vc, handler); //ProverInterface.Outcome proverOutcome = prover.CheckOutcomeCore(handler); var inc = (DateTime.Now - start); proverTime += inc; numProverQueries++; if (CommandLineOptions.Clo.Trace) Console.WriteLine("Prover Time taken = " + inc.TotalSeconds.ToString()); if (proverOutcome == ProverInterface.Outcome.TimeOut || proverOutcome == ProverInterface.Outcome.OutOfMemory) { Console.WriteLine("Z3 Prover for implementation {0} times out or runs out of memory !", impl); z3Context.context.Dispose(); z3Context.config.Dispose(); overallOutcome = new VCGenOutcome(proverOutcome, new List<Counterexample>()); return ICEOutcome.Timeout; } if (CommandLineOptions.Clo.Trace) Console.WriteLine(!VCisValid ? "SAT" : "UNSAT"); if (!VCisValid) { if (realErrorEncountered) { overallOutcome = new VCGenOutcome(ProverInterface.Outcome.Invalid, collector.real_errors); return ICEOutcome.ErrorFound; } Debug.Assert(newSamplesAdded); HashSet<string> funcsChanged; if (!learn(out funcsChanged)) { // learner timed out or there is no valid conjecture in the current given template overallOutcome = new VCGenOutcome(ProverInterface.Outcome.Invalid, collector.conjecture_errors); prover.Pop(); return ICEOutcome.InvariantNotFound; } // propagate dependent guys back into the worklist, including self var deps = new HashSet<string>(); deps.Add(impl); funcsChanged.Iter(f => deps.UnionWith(function2implAssumed[f])); funcsChanged.Iter(f => deps.UnionWith(function2implAsserted[f])); deps.Iter(s => worklist.Add(Tuple.Create(impl2Priority[s], s))); } prover.Pop(); } // The program was verified with the current template! overallOutcome = new VCGenOutcome(ProverInterface.Outcome.Valid, new List<Counterexample>()); return ICEOutcome.InvariantFound; }
public void ProtectedForAllExprBody() { var x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int)); var y = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int)); var xId = new IdentifierExpr(Token.NoToken, x, /*immutable=*/true); var yId = new IdentifierExpr(Token.NoToken, y, /*immutable=*/true); var body = Expr.Gt(xId, yId); var forAll = new ForallExpr(Token.NoToken, new List<Variable> () { x, y }, body, /*immutable=*/true); forAll.Body = Expr.Lt(xId, yId); // Changing the body of an immutable ForAllExpr should fail }
void AtomExpression(out Expr/*!*/ e) { Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; int n; BigNum bn; BigDec bd; BigFloat bf; List<Expr>/*!*/ es; List<Variable>/*!*/ ds; Trigger trig; List<TypeVariable>/*!*/ typeParams; IdentifierExpr/*!*/ id; QKeyValue kv; e = dummyExpr; List<Variable>/*!*/ locals; List<Block/*!*/>/*!*/ blocks; switch (la.kind) { case 83: { Get(); e = new LiteralExpr(t, false); break; } case 84: { Get(); e = new LiteralExpr(t, true); break; } case 3: { Nat(out bn); e = new LiteralExpr(t, bn); break; } case 5: case 6: { Dec(out bd); e = new LiteralExpr(t, bd); break; } case 7: { Float(out bf); e = new LiteralExpr(t, bf); break; } case 2: { BvLit(out bn, out n); e = new LiteralExpr(t, bn, n); break; } case 1: { Ident(out x); id = new IdentifierExpr(x, x.val); e = id; if (la.kind == 10) { Get(); if (StartOf(9)) { Expressions(out es); e = new NAryExpr(x, new FunctionCall(id), es); } else if (la.kind == 11) { e = new NAryExpr(x, new FunctionCall(id), new List<Expr>()); } else SynErr(124); Expect(11); } break; } case 85: { Get(); x = t; Expect(10); Expression(out e); Expect(11); e = new OldExpr(x, e); break; } case 15: { Get(); x = t; Expect(10); Expression(out e); Expect(11); e = new NAryExpr(x, new ArithmeticCoercion(x, ArithmeticCoercion.CoercionType.ToInt), new List<Expr>{ e }); break; } case 16: { Get(); x = t; Expect(10); Expression(out e); Expect(11); e = new NAryExpr(x, new ArithmeticCoercion(x, ArithmeticCoercion.CoercionType.ToReal), new List<Expr>{ e }); break; } case 10: { Get(); if (StartOf(9)) { Expression(out e); if (e is BvBounds) this.SemErr("parentheses around bitvector bounds " + "are not allowed"); } else if (la.kind == 89 || la.kind == 90) { Forall(); x = t; QuantifierBody(x, out typeParams, out ds, out kv, out trig, out e); if (typeParams.Count + ds.Count > 0) e = new ForallExpr(x, typeParams, ds, kv, trig, e); } else if (la.kind == 91 || la.kind == 92) { Exists(); x = t; QuantifierBody(x, out typeParams, out ds, out kv, out trig, out e); if (typeParams.Count + ds.Count > 0) e = new ExistsExpr(x, typeParams, ds, kv, trig, e); } else if (la.kind == 93 || la.kind == 94) { Lambda(); x = t; QuantifierBody(x, out typeParams, out ds, out kv, out trig, out e); if (trig != null) SemErr("triggers not allowed in lambda expressions"); if (typeParams.Count + ds.Count > 0) e = new LambdaExpr(x, typeParams, ds, kv, e); } else SynErr(125); Expect(11); break; } case 41: { IfThenElseExpression(out e); break; } case 86: { CodeExpression(out locals, out blocks); e = new CodeExpr(locals, blocks); break; } default: SynErr(126); break; } }
public override Expr VisitForallExpr(ForallExpr node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<Expr>() != null); return base.VisitForallExpr((ForallExpr)node.Clone()); }
public void SimpleForAll() { var boundVar = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken,"foo",Microsoft.Boogie.Type.Bool)); var id = new IdentifierExpr(Token.NoToken, boundVar); var forall = new ForallExpr(Token.NoToken, new List<Variable>() { boundVar }, id); var id2 = new IdentifierExpr(Token.NoToken, boundVar); var forall2 = new ForallExpr(Token.NoToken, new List<Variable>() { boundVar }, id2); Assert.AreNotSame(forall, forall2); // These are different references Assert.IsTrue(forall.Equals(forall2)); // These are "structurally equal" Assert.AreEqual(forall.GetHashCode(), forall2.GetHashCode()); // If the .Equals() is true then hash codes must be the same }