/// <summary> /// Model check an expression to find inputs that lead to it being false. /// </summary> /// <param name="expression">The expression.</param> /// <returns> /// Assignment to zen arbitrary variables that make the expression false. /// Null if no such assignment exists. /// </returns> public Dictionary <object, object> ModelCheck(Zen <bool> expression) { var symbolicEvaluator = new SymbolicEvaluationVisitor <TModel, TVar, TBool, TInt>(solver); var env = new SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt>(); var symbolicResult = (SymbolicBool <TModel, TVar, TBool, TInt>)expression.Accept(symbolicEvaluator, env); // Console.WriteLine($"[time] model checking: {watch.ElapsedMilliseconds}ms"); // watch.Restart(); var possibleModel = solver.Satisfiable(symbolicResult.Value); // Console.WriteLine($"[time] get sat: {watch.ElapsedMilliseconds}ms"); if (!possibleModel.HasValue) { return(null); } var model = possibleModel.Value; // compute the input given the assignment var arbitraryAssignment = new Dictionary <object, object>(); foreach (var kv in symbolicEvaluator.ArbitraryVariables) { var expr = kv.Key; var variable = kv.Value; arbitraryAssignment.Add(expr, this.solver.Get(model, variable)); } return(arbitraryAssignment); }
/// <summary> /// Model check an expression to find inputs that lead to it being false. /// </summary> /// <param name="expression">The expression.</param> /// <returns> /// Assignment to zen arbitrary variables that make the expression false. /// Null if no such assignment exists. /// </returns> public Dictionary <object, object> ModelCheck(Zen <bool> expression) { var symbolicEvaluator = new SymbolicEvaluationVisitor <TModel, TVar, TBool, TBitvec, TInt, TString>(solver); var env = new SymbolicEvaluationEnvironment <TModel, TVar, TBool, TBitvec, TInt, TString>(); var symbolicResult = (SymbolicBool <TModel, TVar, TBool, TBitvec, TInt, TString>)expression.Accept(symbolicEvaluator, env); var possibleModel = solver.Satisfiable(symbolicResult.Value); if (!possibleModel.HasValue) { return(null); } var model = possibleModel.Value; // compute the input given the assignment var arbitraryAssignment = new Dictionary <object, object>(); foreach (var kv in symbolicEvaluator.ArbitraryVariables) { var expr = kv.Key; var variable = kv.Value; var type = expr.GetType().GetGenericArguments()[0]; var obj = this.solver.Get(model, variable); if (ReflectionUtilities.IsFixedIntegerType(type)) { obj = type.GetConstructor(new Type[] { typeof(byte[]) }).Invoke(new object[] { obj }); } arbitraryAssignment.Add(expr, obj); } return(arbitraryAssignment); }
public SymbolicValue <TModel, TVar, TBool, TInt, TString> VisitZenAdapterExpr <TTo, TFrom>(ZenAdapterExpr <TTo, TFrom> expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt, TString> parameter) { return(LookupOrCompute(expression, () => { return expression.Expr.Accept(this, parameter); })); }
public SymbolicValue <TModel, TVar, TBool, TInt, TString> VisitZenComparisonExpr <T1>(ZenComparisonExpr <T1> expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt, TString> parameter) { return(LookupOrCompute(expression, () => { switch (expression.ComparisonType) { case ComparisonType.Geq: case ComparisonType.Leq: var v1 = (SymbolicInteger <TModel, TVar, TBool, TInt, TString>)expression.Expr1.Accept(this, parameter); var v2 = (SymbolicInteger <TModel, TVar, TBool, TInt, TString>)expression.Expr2.Accept(this, parameter); var result = ReflectionUtilities.IsUnsignedIntegerType(typeof(T1)) ? (expression.ComparisonType == ComparisonType.Geq ? this.Solver.GreaterThanOrEqual(v1.Value, v2.Value) : this.Solver.LessThanOrEqual(v1.Value, v2.Value)) : (expression.ComparisonType == ComparisonType.Geq ? this.Solver.GreaterThanOrEqualSigned(v1.Value, v2.Value) : this.Solver.LessThanOrEqualSigned(v1.Value, v2.Value)); return new SymbolicBool <TModel, TVar, TBool, TInt, TString>(this.Solver, result); default: var e1 = expression.Expr1.Accept(this, parameter); var e2 = expression.Expr2.Accept(this, parameter); if (e1 is SymbolicBool <TModel, TVar, TBool, TInt, TString> b1 && e2 is SymbolicBool <TModel, TVar, TBool, TInt, TString> b2) { return new SymbolicBool <TModel, TVar, TBool, TInt, TString>(this.Solver, this.Solver.Iff(b1.Value, b2.Value)); } if (e1 is SymbolicString <TModel, TVar, TBool, TInt, TString> s1 && e2 is SymbolicString <TModel, TVar, TBool, TInt, TString> s2) { return new SymbolicBool <TModel, TVar, TBool, TInt, TString>(this.Solver, this.Solver.Eq(s1.Value, s2.Value)); } var i1 = (SymbolicInteger <TModel, TVar, TBool, TInt, TString>)e1; var i2 = (SymbolicInteger <TModel, TVar, TBool, TInt, TString>)e2; return new SymbolicBool <TModel, TVar, TBool, TInt, TString>(this.Solver, this.Solver.Eq(i1.Value, i2.Value)); }
public SymbolicValue <TModel, TVar, TBool, TInt, TString> VisitZenIfExpr <T1>(ZenIfExpr <T1> expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt, TString> parameter) { return(LookupOrCompute(expression, () => { var v = (SymbolicBool <TModel, TVar, TBool, TInt, TString>)expression.GuardExpr.Accept(this, parameter); var vtrue = expression.TrueExpr.Accept(this, parameter); var vfalse = expression.FalseExpr.Accept(this, parameter); return vtrue.Merge(v.Value, vfalse); })); }
public SymbolicValue <TModel, TVar, TBool, TInt, TString> VisitZenGetFieldExpr <T1, T2>(ZenGetFieldExpr <T1, T2> expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt, TString> parameter) { return(LookupOrCompute(expression, () => { var v = (SymbolicClass <TModel, TVar, TBool, TInt, TString>)expression.Expr.Accept(this, parameter); return v.Fields[expression.FieldName]; })); }
public SymbolicValue <TModel, TVar, TBool, TInt, TString> VisitZenCreateObjectExpr <TObject>(ZenCreateObjectExpr <TObject> expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt, TString> parameter) { return(LookupOrCompute(expression, () => { var fields = ImmutableDictionary <string, SymbolicValue <TModel, TVar, TBool, TInt, TString> > .Empty; foreach (var fieldValuePair in expression.Fields) { var field = fieldValuePair.Key; dynamic fieldValue = fieldValuePair.Value; fields = fields.Add(field, fieldValue.Accept(this, parameter)); } return new SymbolicClass <TModel, TVar, TBool, TInt, TString>(this.Solver, fields); })); }
public SymbolicValue <TModel, TVar, TBool, TInt, TString> VisitZenConstantStringExpr(ZenConstantStringExpr expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt, TString> parameter) { return(LookupOrCompute(expression, () => { var v = this.Solver.CreateStringConst(expression.EscapedValue); return new SymbolicString <TModel, TVar, TBool, TInt, TString>(this.Solver, v); })); }
/// <summary> /// Visit an EqExpr. /// </summary> /// <param name="expression">The expression.</param> /// <param name="parameter">The parameter.</param> /// <returns>The resulting symbolic value.</returns> public SymbolicValue <TModel, TVar, TBool, TInt> VisitZenEqExpr <T1>(ZenEqExpr <T1> expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt> parameter) { return(LookupOrCompute(expression, () => { var v1 = expression.Expr1.Accept(this, parameter); var v2 = expression.Expr2.Accept(this, parameter); if (v1 is SymbolicBool <TModel, TVar, TBool, TInt> b1 && v2 is SymbolicBool <TModel, TVar, TBool, TInt> b2) { return new SymbolicBool <TModel, TVar, TBool, TInt>(this.Solver, this.Solver.Iff(b1.Value, b2.Value)); } var i1 = (SymbolicInteger <TModel, TVar, TBool, TInt>)v1; var i2 = (SymbolicInteger <TModel, TVar, TBool, TInt>)v2; return new SymbolicBool <TModel, TVar, TBool, TInt>(this.Solver, this.Solver.Eq(i1.Value, i2.Value)); }));
public SymbolicValue <TModel, TVar, TBool, TInt, TString> VisitZenConstantBoolExpr(ZenConstantBoolExpr expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt, TString> parameter) { return(LookupOrCompute(expression, () => { var b = expression.Value ? this.Solver.True() : this.Solver.False(); return new SymbolicBool <TModel, TVar, TBool, TInt, TString>(this.Solver, b); })); }
public SymbolicValue <TModel, TVar, TBool, TInt, TString> VisitZenBitwiseNotExpr <T1>(ZenBitwiseNotExpr <T1> expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt, TString> parameter) { return(LookupOrCompute(expression, () => { var v = (SymbolicInteger <TModel, TVar, TBool, TInt, TString>)expression.Expr.Accept(this, parameter); return new SymbolicInteger <TModel, TVar, TBool, TInt, TString>(this.Solver, this.Solver.BitwiseNot(v.Value)); })); }
public SymbolicValue <TModel, TVar, TBool, TInt, TString> VisitZenIntegerBinopExpr <T1>(ZenIntegerBinopExpr <T1> expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt, TString> parameter) { return(LookupOrCompute(expression, () => { var v1 = (SymbolicInteger <TModel, TVar, TBool, TInt, TString>)expression.Expr1.Accept(this, parameter); var v2 = (SymbolicInteger <TModel, TVar, TBool, TInt, TString>)expression.Expr2.Accept(this, parameter); switch (expression.Operation) { case Op.BitwiseAnd: return new SymbolicInteger <TModel, TVar, TBool, TInt, TString>(this.Solver, this.Solver.BitwiseAnd(v1.Value, v2.Value)); case Op.BitwiseOr: return new SymbolicInteger <TModel, TVar, TBool, TInt, TString>(this.Solver, this.Solver.BitwiseOr(v1.Value, v2.Value)); case Op.BitwiseXor: return new SymbolicInteger <TModel, TVar, TBool, TInt, TString>(this.Solver, this.Solver.BitwiseXor(v1.Value, v2.Value)); case Op.Addition: return new SymbolicInteger <TModel, TVar, TBool, TInt, TString>(this.Solver, this.Solver.Add(v1.Value, v2.Value)); case Op.Subtraction: return new SymbolicInteger <TModel, TVar, TBool, TInt, TString>(this.Solver, this.Solver.Subtract(v1.Value, v2.Value)); default: return new SymbolicInteger <TModel, TVar, TBool, TInt, TString>(this.Solver, this.Solver.Multiply(v1.Value, v2.Value)); } })); }
public SymbolicValue <TModel, TVar, TBool, TInt, TString> VisitZenArgumentExpr <T1>(ZenArgumentExpr <T1> expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt, TString> parameter) { return(LookupOrCompute(expression, () => { return parameter.ArgumentAssignment[expression.Id]; })); }
public SymbolicValue <TModel, TVar, TBool, TBitvec, TInt, TString> VisitZenConstantExpr <T>(ZenConstantExpr <T> expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TBitvec, TInt, TString> parameter) { return(LookupOrCompute(expression, () => { var type = typeof(T); if (type == ReflectionUtilities.BigIntType) { var bi = this.Solver.CreateBigIntegerConst((BigInteger)(object)expression.Value); return new SymbolicInteger <TModel, TVar, TBool, TBitvec, TInt, TString>(this.Solver, bi); } if (type == ReflectionUtilities.BoolType) { var b = (bool)(object)expression.Value ? this.Solver.True() : this.Solver.False(); return new SymbolicBool <TModel, TVar, TBool, TBitvec, TInt, TString>(this.Solver, b); } if (type == ReflectionUtilities.ByteType) { var bv = this.Solver.CreateByteConst((byte)(object)expression.Value); return new SymbolicBitvec <TModel, TVar, TBool, TBitvec, TInt, TString>(this.Solver, bv); } if (type == ReflectionUtilities.ShortType) { var bv = this.Solver.CreateShortConst((short)(object)expression.Value); return new SymbolicBitvec <TModel, TVar, TBool, TBitvec, TInt, TString>(this.Solver, bv); } if (type == ReflectionUtilities.UshortType) { var bv = this.Solver.CreateShortConst((short)(ushort)(object)expression.Value); return new SymbolicBitvec <TModel, TVar, TBool, TBitvec, TInt, TString>(this.Solver, bv); } if (type == ReflectionUtilities.IntType) { var bv = this.Solver.CreateIntConst((int)(object)expression.Value); return new SymbolicBitvec <TModel, TVar, TBool, TBitvec, TInt, TString>(this.Solver, bv); } if (type == ReflectionUtilities.UintType) { var bv = this.Solver.CreateIntConst((int)(uint)(object)expression.Value); return new SymbolicBitvec <TModel, TVar, TBool, TBitvec, TInt, TString>(this.Solver, bv); } if (type == ReflectionUtilities.LongType) { var bv = this.Solver.CreateLongConst((long)(object)expression.Value); return new SymbolicBitvec <TModel, TVar, TBool, TBitvec, TInt, TString>(this.Solver, bv); } if (type == ReflectionUtilities.UlongType) { var bv = this.Solver.CreateLongConst((long)(ulong)(object)expression.Value); return new SymbolicBitvec <TModel, TVar, TBool, TBitvec, TInt, TString>(this.Solver, bv); } if (ReflectionUtilities.IsFixedIntegerType(type)) { var bv = this.Solver.CreateBitvecConst(((dynamic)expression.Value).GetBits()); return new SymbolicBitvec <TModel, TVar, TBool, TBitvec, TInt, TString>(this.Solver, bv); } // string type. var s = CommonUtilities.ConvertCSharpStringToZ3((string)(object)expression.Value); var v = this.Solver.CreateStringConst(s); return new SymbolicString <TModel, TVar, TBool, TBitvec, TInt, TString>(this.Solver, v); })); }
public SymbolicValue <TModel, TVar, TBool, TInt, TString> VisitZenAndExpr(ZenAndExpr expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt, TString> parameter) { return(LookupOrCompute(expression, () => { var v1 = (SymbolicBool <TModel, TVar, TBool, TInt, TString>)expression.Expr1.Accept(this, parameter); var v2 = (SymbolicBool <TModel, TVar, TBool, TInt, TString>)expression.Expr2.Accept(this, parameter); return new SymbolicBool <TModel, TVar, TBool, TInt, TString>(this.Solver, this.Solver.And(v1.Value, v2.Value)); })); }
public SymbolicValue <TModel, TVar, TBool, TInt, TString> VisitZenConstantUshortExpr(ZenConstantUshortExpr expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt, TString> parameter) { return(LookupOrCompute(expression, () => { var bv = this.Solver.CreateShortConst((short)expression.Value); return new SymbolicInteger <TModel, TVar, TBool, TInt, TString>(this.Solver, bv); })); }
public SymbolicValue <TModel, TVar, TBool, TInt, TString> VisitZenArbitraryExpr <T1>(ZenArbitraryExpr <T1> expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt, TString> parameter) { return(LookupOrCompute(expression, () => { var type = typeof(T1); if (type == ReflectionUtilities.BoolType) { var(variable, expr) = this.Solver.CreateBoolVar(expression); this.Variables.Add(variable); var result = new SymbolicBool <TModel, TVar, TBool, TInt, TString>(this.Solver, expr); this.ArbitraryVariables[expression] = variable; return result; } if (type == ReflectionUtilities.ByteType) { var(variable, expr) = this.Solver.CreateByteVar(expression); this.Variables.Add(variable); var result = new SymbolicInteger <TModel, TVar, TBool, TInt, TString>(this.Solver, expr); this.ArbitraryVariables[expression] = variable; return result; } if (type == ReflectionUtilities.ShortType || type == ReflectionUtilities.UshortType) { var(variable, expr) = this.Solver.CreateShortVar(expression); this.Variables.Add(variable); var result = new SymbolicInteger <TModel, TVar, TBool, TInt, TString>(this.Solver, expr); this.ArbitraryVariables[expression] = variable; return result; } if (type == ReflectionUtilities.IntType || type == ReflectionUtilities.UintType) { var(variable, expr) = this.Solver.CreateIntVar(expression); this.Variables.Add(variable); var result = new SymbolicInteger <TModel, TVar, TBool, TInt, TString>(this.Solver, expr); this.ArbitraryVariables[expression] = variable; return result; } if (type == ReflectionUtilities.StringType) { var(variable, expr) = this.Solver.CreateStringVar(expression); this.Variables.Add(variable); var result = new SymbolicString <TModel, TVar, TBool, TInt, TString>(this.Solver, expr); this.ArbitraryVariables[expression] = variable; return result; } // long or ulong var(v, e) = this.Solver.CreateLongVar(expression); this.Variables.Add(v); var r = new SymbolicInteger <TModel, TVar, TBool, TInt, TString>(this.Solver, e); this.ArbitraryVariables[expression] = v; return r; })); }
/// <summary> /// Visit a BitwiseXorExpr. /// </summary> /// <param name="expression">The expression.</param> /// <param name="parameter">The parameter.</param> /// <returns>The resulting symbolic value.</returns> public SymbolicValue <TModel, TVar, TBool, TInt> VisitZenBitwiseXorExpr <T1>(ZenBitwiseXorExpr <T1> expression, SymbolicEvaluationEnvironment <TModel, TVar, TBool, TInt> parameter) { return(LookupOrCompute(expression, () => { var v1 = (SymbolicInteger <TModel, TVar, TBool, TInt>)expression.Expr1.Accept(this, parameter); var v2 = (SymbolicInteger <TModel, TVar, TBool, TInt>)expression.Expr2.Accept(this, parameter); return new SymbolicInteger <TModel, TVar, TBool, TInt>(this.Solver, this.Solver.BitwiseXor(v1.Value, v2.Value)); })); }