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); }
//BoolExpr expr = Z3.Context.MkNot(Z3.Context.MkAnd( // Z3.Context.MkLt(body.Joints[JointType.ElbowRight].Z, body.Joints[JointType.ShoulderRight].Z), // Z3.Context.MkGt(body.Joints[JointType.ElbowRight].Y, body.Joints[JointType.ShoulderRight].Y))); // return expr; // }, body => { return 1.0; }, // "don't put your right elbow behind you and above your shoulders."); public static bool IsWithinDefaultSafetyRestrictions( App app, out string errorMessage, out List <long> elapsedTimes) { errorMessage = ""; elapsedTimes = new List <long>(); var result = true; foreach (var gesture in app.Gestures) { var stopwatch = new Stopwatch(); stopwatch.Start(); if (!Safety.IsWithinDefaultSafetyRestrictions(gesture, out errorMessage)) { errorMessage = "\tThe gesture " + gesture.Name + " is unsafe.\n" + errorMessage; result = false; break; } stopwatch.Stop(); elapsedTimes.Add(stopwatch.ElapsedMilliseconds); } return(result); }
/// <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 static bool IsWithinDefaultSafetyRestrictions(Gesture gesture, out string firstBadStep) { firstBadStep = ""; bool result = true; foreach (var pose in gesture.DeclaredPoses) { Z3Body witness = null; if (!Safety.IsWithinDefaultSafetyRestrictions(pose, out firstBadStep)) { firstBadStep = "\tOn the pose: " + pose.Name + ".\n\tBecause it inflicts the following statement:\n\t" + firstBadStep; result = false; break; } } return(result); }
/// <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 IsWithinDefaultSafetyRestrictions(Gesture gesture, out List <PoseSafetyException> exceptions) { bool result = true; exceptions = new List <PoseSafetyException>(); foreach (var step in gesture.Steps) { var pose = step.Pose; Z3Body witness = null; if (!Safety.IsWithinSafetyRestrictions(pose, out witness)) { var exception = new PoseSafetyException( "Default safety violation", pose, witness ); exceptions.Add(exception); result = false; } } 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); } }
private void ProcessFile(string file) { Console.WriteLine("Reading {0}", file); var rawApp = App.ReadApp(file); // var app = CreateNewAppWithInterpolatedGestures(rawApp); var app = rawApp; if (DoValidityChecking) { var stopwatch = new Stopwatch(); stopwatch.Start(); List <PoseSafetyException> validityExceptions = null; List <long> validityTimes = null; var isValid = Validity.IsInternallyValid(app, out validityExceptions, out validityTimes); stopwatch.Stop(); Console.WriteLine("validity\t{0}", stopwatch.ElapsedMilliseconds); Console.WriteLine("restrictions:\t{0}", app.Gestures.Sum(r => r.RestrictionCount)); int i = 0; foreach (var gesture in app.Gestures) { Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", gesture.Name, gesture.TransformCount, gesture.RestrictionCount, gesture.NegatedRestrictionCount, gesture.Steps.Count, validityTimes[i]); swValidity.WriteLine("{0},{1},{2},{3},{4},{5}", gesture.Name, gesture.TransformCount, gesture.RestrictionCount, gesture.NegatedRestrictionCount, gesture.Steps.Count, validityTimes[i]); i++; swValidity.Flush(); } } if (DoSafetyChecking) { var stopwatch = new Stopwatch(); stopwatch.Start(); // Test if app gestures are safe List <PoseSafetyException> safetyExceptions = null; List <long> safetyTimes = null; var isSafe = Safety.IsWithinDefaultSafetyRestrictions(app, out safetyExceptions, out safetyTimes); if (!isSafe) { Console.WriteLine("Safety exceptions:"); foreach (var ex in safetyExceptions) { Console.WriteLine("\t{0}", ex); } Console.WriteLine(); } stopwatch.Stop(); Console.WriteLine("safety\t{0}", stopwatch.ElapsedMilliseconds); Console.WriteLine("restrictions:\t{0}", app.Gestures.Sum(r => r.RestrictionCount)); int i = 0; foreach (var gesture in app.Gestures) { Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", gesture.Name, gesture.TransformCount, gesture.RestrictionCount, gesture.NegatedRestrictionCount, gesture.Steps.Count, safetyTimes[i]); swSafety.WriteLine("{0},{1},{2},{3},{4},{5}", gesture.Name, gesture.TransformCount, gesture.RestrictionCount, gesture.NegatedRestrictionCount, gesture.Steps.Count, safetyTimes[i]); i++; } } if (DoAmbiguityChecking) { var stopwatch = new Stopwatch(); stopwatch.Start(); uint numConflicts = 0; // Test if app gestures present conflicts List <PairwiseConflictException> conflictExceptions = null; List <PreposeGestures.Ambiguity.AmbiguityTime> ambiguityTimes; var hasConflicts = Ambiguity.HasPairwiseConflicts(app, out conflictExceptions, out ambiguityTimes); if (hasConflicts) { foreach (var ex in conflictExceptions) { numConflicts++; } } stopwatch.Stop(); long elapsedTime = stopwatch.ElapsedMilliseconds; var numGestures = app.Gestures.Count(); var numPoses = 0; var numTotalRestrictions = app.Gestures.Sum(r => r.RestrictionCount); var numTotalNegatedRestrictions = app.Gestures.Sum(r => r.NegatedRestrictionCount); var numTotalTransforms = app.Gestures.Sum(r => r.TransformCount); var numTotalTransformedJoints = app.Gestures.Sum(r => r.DistinctTransformedJointsCount); var numTotalSteps = app.Gestures.Sum(r => r.Steps.Count()); foreach (var ges in app.Gestures) { numPoses += ges.DeclaredPoses.Count(); } swConflict.WriteLine(); swConflict.WriteLine("Name,ElapsedTime,NumGestures,NumPoses,NumTotalRestrictions,NumTotalNegatedRestrictions,NumTotalTransforms, NumTotalTransformedJoints,NumSteps,NumConflicts"); swConflict.Flush(); swConflict.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}", app.Name, numGestures, numPoses, numTotalRestrictions, numTotalNegatedRestrictions, numTotalTransforms, numTotalTransformedJoints, numTotalSteps, numConflicts, elapsedTime ); swConflict.Flush(); swConflict.WriteLine(); swConflict.WriteLine("NameG1*NameG2,NumPosesG1,NumRestrictionsG1,NumNegatedRestrictionsG1,NumTransformsG1,NumStepsG1,NumDistinctJointsG1,NumPosesG2,NumRestrictionsG2,NumNegatedRestrictionsG2,NumTransformsG2,NumStepsG2,NumDistinctJointsG2,Conflict,NumPivots,ElapsedTime"); swConflict.Flush(); foreach (var timing in ambiguityTimes) { Console.WriteLine("Logging results for {0}X{1}", timing.Gesture1.Name, timing.Gesture2.Name); uint numPivots = 0; long time = timing.Time; if (timing.CheckResult.bTimedOut) { time = -1; // Timed out goes to -1 } if (timing.CheckResult.stats != null) { if (timing.CheckResult.stats["pivots"] != null) { numPivots = timing.CheckResult.stats["pivots"].UIntValue; } } var times = new object[] { string.Format("{0}*{1}", timing.Gesture1.Name, timing.Gesture2.Name), timing.Gesture1.DeclaredPoses.Count, timing.Gesture1.RestrictionCount, timing.Gesture1.NegatedRestrictionCount, timing.Gesture1.TransformCount, timing.Gesture1.Steps.Count, timing.Gesture1.DistinctTransformedJointsCount, timing.Gesture2.DeclaredPoses.Count, timing.Gesture2.RestrictionCount, timing.Gesture2.NegatedRestrictionCount, timing.Gesture2.TransformCount, timing.Gesture2.Steps.Count, timing.Gesture2.DistinctTransformedJointsCount, timing.Conflict, numPivots, time, }; Statistics stats = timing.CheckResult.stats; string output = string.Join(",", times); swConflict.WriteLine("{0}", output); swConflict.Flush(); } } }