/// <summary> /// Produces a witness body given input restrictions, output /// restrictions and a transform. /// </summary> /// <param name="inputBodyRestriction"></param> /// <param name="bodyTransform"></param> /// <param name="outputBodyRestriction"></param> /// <returns></returns> public static Z3Body GenerateWitness( CompositeBodyRestriction inputBodyRestriction, BodyTransform bodyTransform, CompositeBodyRestriction outputBodyRestriction) { var body = Z3Body.MkZ3Const(); var transformedBody = bodyTransform.Transform(body); var expr1 = inputBodyRestriction.Evaluate(body); var expr2 = outputBodyRestriction.Evaluate(transformedBody); var expr = Z3.Context.MkAnd(expr1, expr2); var evaluatedJoints = JointTypeHelper.MergeJointTypeLists( inputBodyRestriction.GetJointTypes(), bodyTransform.GetJointTypes(), outputBodyRestriction.GetJointTypes()); var checkResult = CheckStatus(expr); if (checkResult.Status == Status.SATISFIABLE) { var witness = CreateBodyWitness( body, checkResult.Model, evaluatedJoints, JointTypeHelper.CreateDefaultZ3Body()); return(witness); } else { return(null); } }
public static bool IsWithinDefaultSafetyRestrictions(Pose pose, out string firstBadStatement) { bool result = true; firstBadStatement = ""; Z3Body input = Z3Body.MkZ3Const(); Z3Body transformed = pose.Transform.Transform(input); BoolExpr transformedRestricted = pose.Restriction.Evaluate(transformed); var restrictions = Safety.DefaultSafetyRestriction().Restrictions; var composite = new CompositeBodyRestriction(); foreach (var restriction in restrictions) { composite.And(restriction); BoolExpr inputSafe = composite.Evaluate(transformed); BoolExpr expr = Z3.Context.MkAnd(transformedRestricted, inputSafe); SolverCheckResult solverResult = Z3AnalysisInterface.CheckStatus(expr); if (solverResult.Status == Status.UNSATISFIABLE) { firstBadStatement = ((SimpleBodyRestriction)restriction).Message; result = false; break; } } return(result); }
public static bool IsInternallyValid(Pose pose, out string firstBadStatement) { bool result = true; firstBadStatement = ""; Z3Body input = Z3Body.MkZ3Const(); Z3Body transformed = pose.Transform.Transform(input); var restrictions = pose.Restriction.Restrictions; var composite = new CompositeBodyRestriction(); foreach (var restriction in restrictions) { composite.And(restriction); BoolExpr transformedRestricted = composite.Evaluate(transformed); SolverCheckResult solverResult = Z3AnalysisInterface.CheckStatus(transformedRestricted); if (solverResult.Status == Status.UNSATISFIABLE) { firstBadStatement = restriction.ToString(); result = false; break; } } return(result); }
public bool IsTransformAcceptedByRestriction() { Z3Body body = Z3Body.MkZ3Const(); Z3Body transformedBody = this.Transform.Transform(body); BoolExpr expr = this.Restriction.Evaluate(transformedBody); SolverCheckResult checkResult = Z3AnalysisInterface.CheckStatus(expr); return(checkResult.Status != Status.UNSATISFIABLE); }
private static BoolExpr ExpressionFromCurrentStep(Gesture gesture1, int gesture1CurrentStep) { var input1 = Z3Body.MkZ3Const(); var step1 = gesture1.Steps[gesture1CurrentStep]; var pose1 = step1.Pose; input1 = pose1.Transform.Transform(input1); var expr1 = pose1.Restriction.Evaluate(input1); return(expr1); }
/// <summary> /// Generates a witness body tha matches the restrictions that /// are passed in. /// </summary> /// <param name="bodyRestriction"></param> /// <returns></returns> public static Z3Body GenerateWitness(IBodyRestriction bodyRestriction) { var body = Z3Body.MkZ3Const(); var expr = bodyRestriction.Evaluate(body); var checkResult = CheckStatus(expr); var witness = CreateBodyWitness( body, checkResult.Model, bodyRestriction.GetJointTypes(), JointTypeHelper.CreateDefaultZ3Body()); return(witness); }
// Generates a body witness which satisfies two conditions // 1. It is within a range (angle threshold) of a transform from a start body // 2. It is within the considered restrictions public static Z3Target GenerateTarget( BodyTransform transform, CompositeBodyRestriction restriction, Z3Body startBody, int angleThreshold) { var z3ConstBody = Z3Body.MkZ3Const(); z3ConstBody.Norms = startBody.Norms; var transformedBody = transform.Transform(startBody); var joints = transform.GetJointTypes().Union(restriction.GetJointTypes()).ToList(); var isNearExpr = z3ConstBody.IsAngleBetweenLessThan(transformedBody, joints, angleThreshold); var evaluateExpr = restriction.Evaluate(z3ConstBody); //var normsExpr = BodyRestrictionBuilder.EvaluateNorms(startBody, z3ConstBody); //var expr = Z3.Context.MkAnd(isNearExpr, evaluateExpr, normsExpr); //var expr = Z3.Context.MkAnd(evaluateExpr, normsExpr); var expr = Z3.Context.MkAnd(evaluateExpr, isNearExpr); var checkResult = CheckStatus(expr); if (checkResult.Status == Status.SATISFIABLE) { var witness = CreateBodyWitness( z3ConstBody, checkResult.Model, restriction.GetJointTypes(), startBody); var target = new Z3Target(); target.Body = witness; target.RestrictedJoints = restriction.GetJointTypes(); target.TransformedJoints = transform.GetJointTypes(); foreach (var jointType in transform.GetJointTypes()) { target.Body.Joints[jointType] = transformedBody.Joints[jointType]; } return(target); } else { return(null); } }
/// <summary> /// Checks if the pose is within default safety /// restrictions when the transform and restrictions /// are applied. /// </summary> /// <returns>True if it's safe</returns> public static bool IsWithinSafetyRestrictions(Pose pose, out Z3Body witness) { Z3Body input = Z3Body.MkZ3Const(); Z3Body transformed = pose.Transform.Transform(input); IBodyRestriction safe = Safety.DefaultSafetyRestriction(); BoolExpr inputSafe = safe.Evaluate(input); BoolExpr transformedRestricted = pose.Restriction.Evaluate(transformed); // Try to generate a unsafe witness using the transform BoolExpr outputUnsafe = Z3.Context.MkNot(safe.Evaluate(transformed)); // Put together all expressions and search for unsat BoolExpr expr = Z3.Context.MkAnd(inputSafe, transformedRestricted, outputUnsafe); SolverCheckResult solverResult = Z3AnalysisInterface.CheckStatus(expr); if (solverResult.Status == Status.SATISFIABLE) { //Z3Body witness = Z3AnalysisInterface.CreateBodyWitness( transformed, solverResult.Model, pose.GetAllJointTypes(), JointTypeHelper.CreateDefaultZ3Body()); return(false); } else if (solverResult.Status == Status.UNKNOWN) { //Z3Body witness = JointTypeHelper.CreateDefaultZ3Body(); return(false); } else { Contract.Assert(solverResult.Status == Status.UNSATISFIABLE); witness = null; return(true); } }
public override bool Equals(object obj) { var that = obj as SimpleBodyRestriction; Solver solver = Z3.Context.MkSolver(); Z3Body body = Z3Body.MkZ3Const(); var jointTypes = EnumUtil.GetValues <JointType>(); BoolExpr thisResult = this.Evaluate(body); BoolExpr thatResult = that.Evaluate(body); BoolExpr equalsExpr = Z3.Context.MkEq(thisResult, thatResult); solver.Assert(Z3.Context.MkNot(equalsExpr)); Status status = solver.Check(); Statistics stats = solver.Statistics; //Console.WriteLine("EqualsExpr: " + equalsExpr); //Console.WriteLine("Proving: " + equalsExpr); //switch (status) //{ // case Status.UNKNOWN: // Console.WriteLine("Unknown because:\n" + solver.ReasonUnknown); // break; // case Status.SATISFIABLE: // throw new ArgumentException("Test Failed Expception"); // case Status.UNSATISFIABLE: // Console.WriteLine("OK, proof:\n" + solver.Proof); // break; //} bool result = false; if (status == Status.UNSATISFIABLE) { result = true; } return(result); }
public static bool IsInternallyValid(Pose pose) { Z3Body input = Z3Body.MkZ3Const(); Z3Body transformed = pose.Transform.Transform(input); // We have to check that the pose is within the default safety restriction IBodyRestriction safe = Safety.DefaultSafetyRestriction(); BoolExpr inputSafe = safe.Evaluate(input); BoolExpr transformedRestricted = pose.Restriction.Evaluate(transformed); // Try to generate a safe witness using the transform BoolExpr outputSafe = safe.Evaluate(transformed); // Check to see if the transform is not satisfiable -- if so, then it is not internally valid BoolExpr expr = Z3.Context.MkAnd(inputSafe, transformedRestricted, outputSafe); SolverCheckResult solverResult = Z3AnalysisInterface.CheckStatus(expr); if (solverResult.Status == Status.SATISFIABLE) { // We can create a witness - therefore the pose must be valid return(true); } else if (solverResult.Status == Status.UNKNOWN) { return(false); } else { Contract.Assert(solverResult.Status == Status.UNSATISFIABLE); // Pose is not internally valid and as a result there can be no witness created return(false); } }
/// <summary> /// Check for pairwise ambiguity /// </summary> /// <returns></returns> public static bool HasPairwiseConflicts(App app, out List <PairwiseConflictException> allExceptions, out List <AmbiguityTime> ambiguityTimes, int precision = 15) { List <Gesture> conflictGestures = (List <Gesture>)app.Gestures; bool result = false; allExceptions = new List <PairwiseConflictException>(); ambiguityTimes = new List <AmbiguityTime>(); for (int i = 0; i < conflictGestures.Count - 1; i++) { for (int j = i + 1; j < conflictGestures.Count; j++) { var gesture1 = conflictGestures[i]; var gesture2 = conflictGestures[j]; // Create const input body var input = Z3Body.MkZ3Const(); var allJoints = EnumUtil.GetValues <JointType>().ToList(); Z3Body transformed1 = null; Z3Body transformed2 = null; BoolExpr evaluation1 = Z3Math.True; BoolExpr evaluation2 = Z3Math.True; // Pass input through both gestures gesture1.FinalResult(input, out transformed1, out evaluation1); gesture2.FinalResult(input, out transformed2, out evaluation2); // Check if it is possible that both outputs are equals // This is performed by checking if is possible that all expressions are true var isNearExpr = transformed1.IsNearerThan( transformed2, precision); var expr = Z3.Context.MkAnd(isNearExpr, evaluation1, evaluation2); // If we are dumping Z3 constraints, then convert the expression to a SMTLIB formatted string // and dump it to disk. Note this is not included in the timing for the individual pair of gestures, // but it _is_ included in the timing for the app overall. if (DumpZ3Constraints) { string exprName = String.Join("X", gesture1.Name, gesture2.Name); string exprPath = exprName + ".smt2"; Z3AnalysisInterface.WriteExprToDisk(expr, exprName, exprPath); } // Check if we have an ambiguity conflict. Record the time it takes. var stopwatch = new Stopwatch(); stopwatch.Start(); var checkResult = Z3AnalysisInterface.CheckStatus(expr); stopwatch.Stop(); if (checkResult.Status == Status.SATISFIABLE) { var witness = Z3AnalysisInterface.CreateBodyWitness( input, checkResult.Model, allJoints, JointTypeHelper.CreateDefaultZ3Body()); var exception = new PairwiseConflictException( "Conflict detected between pair of gestures", gesture1, gesture2, witness); allExceptions.Add(exception); result = true; } // TODO the witness here should exist, this case shouldn't be needed else if (checkResult.Status == Status.UNKNOWN) { var witness = JointTypeHelper.CreateDefaultZ3Body(); var exception = new PairwiseConflictException( "Conflict detected between pair of gestures, the reason is unknown", gesture1, gesture2, witness); allExceptions.Add(exception); result = true; } ambiguityTimes.Add(new AmbiguityTime { Gesture1 = gesture1, Gesture2 = gesture2, Time = stopwatch.ElapsedMilliseconds, Conflict = result, CheckResult = checkResult }); } } return(result); }