public void DileepTest1() { PDLEnumerator pdlEnumerator = new PDLEnumerator(); var solver = new CharSetSolver(BitWidth.BV64); List<char> alph = new List<char> { 'a', 'b' }; HashSet<char> al = new HashSet<char>(alph); PDLPred phi = new PDLModSetEq(new PDLIndicesOf("a"), 2, 1); phi = new PDLAnd(new PDLStartsWith("a"), phi); var dfa1 = phi.GetDFA(al, solver); var a = solver.MkCharConstraint(false, 'a'); var b = solver.MkCharConstraint(false, 'b'); var moves = new List<Move<BDD>>(); moves.Add(new Move<BDD>(0, 0, a)); moves.Add(new Move<BDD>(0, 5, a)); moves.Add(new Move<BDD>(5, 0, a)); moves.Add(new Move<BDD>(5, 5, b)); var dfa2 = Automaton<BDD>.Create(0, new int[] { 5 }, moves); var feedbackGrade = DFAGrading.GetGrade(dfa1, dfa2, al, solver, timeout, 10, FeedbackLevel.Solution, true, false, false); var feedString = "<ul>"; foreach (var feed in feedbackGrade.Second) feedString += string.Format("<li>{0}</li>", feed); feedString += "</ul>"; Console.Write( string.Format("<div>Grade: {0} <br /> Feedback: {1}</div>", feedbackGrade.First, feedString)); }
public void MyTest() { PDLEnumerator pdlEnumerator = new PDLEnumerator(); var solver = new CharSetSolver(BitWidth.BV64); List<char> alph = new List<char> { 'a', 'b' }; HashSet<char> al = new HashSet<char>(alph); var a = solver.MkCharConstraint(false, 'a'); var b = solver.MkCharConstraint(false, 'b'); var moves = new List<Move<BDD>>(); moves.Add(new Move<BDD>(0, 1, a)); moves.Add(new Move<BDD>(0, 3, b)); moves.Add(new Move<BDD>(1,2, b)); moves.Add(new Move<BDD>(2, 1, a)); moves.Add(new Move<BDD>(1, 1, a)); moves.Add(new Move<BDD>(2, 2, b)); moves.Add(new Move<BDD>(3, 4, a)); moves.Add(new Move<BDD>(4, 3, b)); moves.Add(new Move<BDD>(3, 3, b)); moves.Add(new Move<BDD>(4, 4, a)); var dfa1 = Automaton<BDD>.Create(0, new int[] { 0,1,3 }, moves).Determinize(solver).Minimize(solver); foreach (var v in pdlEnumerator.SynthesizePDL(al, dfa1, solver, new StringBuilder(), 5000)) { Console.WriteLine(PDLUtil.ToEnglishString(v)); break; } }
/// <summary> /// Returns the minimum PDL edit distance ratio between all the PDL A1 and A2 inferred for dfa1 and dfa2 /// in less than timeout. For every min_ij(d(A1i,A2j)/|A1i) /// </summary> /// <param name="dfa1"></param> /// <param name="dfa2"></param> /// <param name="al"></param> /// <param name="solver"></param> /// <param name="timeout"></param> /// <returns></returns> public static double GetMinimalFormulaEditDistanceRatio(Automaton<BDD> dfa1, Automaton<BDD> dfa2, HashSet<char> al, CharSetSolver solver, long timeout, PDLEnumerator pdlEnumerator) { var v = GetMinimalFormulaEditDistanceTransformation(dfa1, dfa2, al, solver, timeout, pdlEnumerator); if(v!=null){ var transformation = v.First; var scaling = 1.0; return transformation.totalCost / (transformation.minSizeForTreeA * scaling); } return 10; }
private void runTest(string testName) { PDLEnumerator pdlEnumerator = new PDLEnumerator(); CharSetSolver solver = new CharSetSolver(BitWidth.BV64); var dfa_al = ReadDFA(testName, solver); PDLPred synthPhi = null; StringBuilder sb = new StringBuilder(); sb.AppendLine("*------------------------------------"); sb.AppendLine("| " + testName); sb.AppendLine("|------------------------------------"); foreach (var phi in pdlEnumerator.SynthesizePDL(dfa_al.First, dfa_al.Second, solver, sb, timeout)) { synthPhi = phi; break; } sb.AppendLine("*------------------------------------"); sb.AppendLine(); System.Console.WriteLine(sb); }
/// <summary> /// Find the min formula edit distance between two dfas /// </summary> /// <param name="dfa1"></param> /// <param name="dfa2"></param> /// <param name="al"></param> /// <param name="solver"></param> /// <param name="timeout"></param> /// <returns>transformation of smallest cost, transf of feeedback (first one)</returns> public static Pair<Transformation, Transformation> GetMinimalFormulaEditDistanceTransformation(Automaton<BDD> dfa1, Automaton<BDD> dfa2, HashSet<char> al, CharSetSolver solver, long timeout, PDLEnumerator pdlEnumerator) { int maxFormulas = 30; //Find all the formulas describing dfa1 and dfa2 var v = new StringBuilder(); List<PDLPred> pdlFormulae1 = new List<PDLPred>(); foreach (var phi in pdlEnumerator.SynthesizePDL(al, dfa1, solver, v, timeout, maxFormulas)) { //Console.WriteLine(phi); pdlFormulae1.Add(phi); } if (pdlFormulae1.Count == 0) return null; List<PDLPred> pdlFormulae2 = new List<PDLPred>(); //Console.WriteLine(); foreach (var phi in pdlEnumerator.SynthesizePDL(al, dfa2, solver, v, timeout, maxFormulas)) { //Console.WriteLine(phi); pdlFormulae2.Add(phi); } if (pdlFormulae2.Count == 0) return null; // Initialize parameters for feedback search double minSizePhi1 = 20; PDLPred smallestPhi1 = null; PDLPred closestPhi2toSmallerPhi1 = null; //This first enumerations find the smallest phi1 describing the solution and the closest phi2 describing the solution for feedback foreach (var phi1 in pdlFormulae1) { var sizePhi1 = phi1.GetFormulaSize(); if (sizePhi1 < minSizePhi1) { minSizePhi1 = (double)sizePhi1; smallestPhi1 = phi1; } } // Look for the closest formula to the smallest one describing phi1 // The formula can be at most distance 2 from the smallest phi1 double minEd = 3; foreach (var phi2 in pdlFormulae2) { if (!phi2.IsComplex()) { if (minEd != 1 && ((int)Math.Abs(smallestPhi1.GetFormulaSize() - phi2.GetFormulaSize())) <= minEd) { var tr = GetFormulaEditDistance(smallestPhi1, phi2); var fed = tr.totalCost; if (fed < minEd) { minEd = fed; closestPhi2toSmallerPhi1 = phi2; } //if (closestPhi2toSmallerPhi1 == null || closestPhi2toSmallerPhi1.GetFormulaSize() > phi2.GetFormulaSize()) // closestPhi2toSmallerPhi1 = phi2; if (minEd == 0) throw new PDLException("cannot be 0"); } } } //Initialize parameters for grading search //This second enumerations are for grading minEd = 100; minSizePhi1 = 100; PDLPred phiMin1 = null; PDLPred phiMin2 = null; foreach (var phi1 in pdlFormulae1) { var sizePhi1 = phi1.GetFormulaSize(); if (sizePhi1 < minSizePhi1) minSizePhi1 = (double)sizePhi1; foreach (var phi2 in pdlFormulae2) { if (minEd != 1 && ((int)Math.Abs(phi1.GetFormulaSize() - phi2.GetFormulaSize())) <= minEd) { var tr = GetFormulaEditDistance(phi1, phi2); var fed = tr.totalCost; if (fed < minEd) { minEd = fed; phiMin1 = phi1; phiMin2 = phi2; } if (minEd == 0) throw new PDLException("cannot be 0"); } } } Transformation tgrade = GetFormulaEditDistance(phiMin1, phiMin2); tgrade.minSizeForTreeA = minSizePhi1; Transformation tfeed = null; if (closestPhi2toSmallerPhi1 != null) { tfeed = GetFormulaEditDistance(smallestPhi1, closestPhi2toSmallerPhi1); tfeed.minSizeForTreeA = minSizePhi1; } return new Pair<Transformation, Transformation>(tgrade, tfeed); }
public override string ToString() { long enumTimeout = 1500L; #region feedback components PDLEnumerator pdlEnumerator = new PDLEnumerator(); PDLPred symmPhi = null; PDLPred underPhi = null; string posWitness = null; string negWitness = null; //If hint or solution try computing the description of the symmdiff if (level == FeedbackLevel.Hint || level == FeedbackLevel.Solution) { //Avoid formulas that are too complex var maxSize = 7; foreach (var phi1 in pdlEnumerator.SynthesizePDL(alphabet, symmetricDifference, solver, new StringBuilder(), enumTimeout)) { var sizePhi1 = phi1.GetFormulaSize(); if (sizePhi1 < maxSize && !phi1.IsComplex()) { maxSize = sizePhi1; symmPhi = phi1; } } } //Avoid empty string case and particular string if (symmPhi is PDLEmptyString || symmPhi is PDLIsString) symmPhi = null; //If not minimal try computing and underapprox of symmdiff if (symmPhi == null && level != FeedbackLevel.Minimal) { //Avoid formulas that are too complex var minSize = 9; foreach (var phi2 in pdlEnumerator.SynthesizeUnderapproximationPDL(alphabet, symmetricDifference, solver, new StringBuilder(), enumTimeout)) { var formula = phi2.First; var sizeForm = formula.GetFormulaSize(); if (sizeForm < minSize && !formula.IsComplex()) { minSize = sizeForm; underPhi = formula; } break; } } //Avoid empty string case and particular string if (underPhi is PDLEmptyString || underPhi is PDLIsString) underPhi = null; if (!positiveDifference.IsEmpty) posWitness = DFAUtilities.GenerateShortTerm(positiveDifference, solver); else negWitness = DFAUtilities.GenerateShortTerm(negativeDifference, solver); #endregion string result = ""; //string.Format("U: {0}%. ", utility); if (symmPhi != null) { if (symmPhi is PDLEmptyString) result += "Your solution does not behave correctly on the empty string"; else result += string.Format("Your solution is not correct on this set of strings: <br /> <div align='center'>{0}</div>", PDLUtil.ToEnglishString(symmPhi)); } else if (underPhi != null) { if (underPhi is PDLEmptyString) result += "Your solution does not behave correctly on the empty string"; else result += string.Format("Your solution is not correct on this set of strings: <br /> <div align='center'>{0}</div>", PDLUtil.ToEnglishString(underPhi)); } else { if (posWitness != null) result += string.Format("Your solution does not accept the {0} while the correct solution does.", posWitness != "" ? "string '<i>" + posWitness + "</i>'" : "empty string"); else result += string.Format("Your solution accepts the {0} while the correct solution doesn't.", negWitness != "" ? "string '<i>" + negWitness + "</i>'" : "empty string"); } return result; }
public void DileepTest1() { PDLEnumerator pdlEnumerator = new PDLEnumerator(); PDLPred phi = new PDLAtSet('a', new PDLPredSet("x", new PDLModSetEq(new PDLAllPosBefore(new PDLPosVar("x")), 2, 1))); var solver = new CharSetSolver(BitWidth.BV64); var alph = new List<char> { 'a', 'b' }; var al = new HashSet<char>(alph); var dfa = phi.GetDFA(al, solver); //solver.SaveAsDot(dfa, "C:/Users/Dileep/Desktop/oddPos.dot"); PDLPred synthPhi = null; StringBuilder sb = new StringBuilder(); foreach (var phi1 in pdlEnumerator.SynthesizePDL(al, dfa, solver, sb, 10000)) { synthPhi = phi1; break; } Console.WriteLine(sb); }
public void DileepTest() { PDLEnumerator pdlEnumerator = new PDLEnumerator(); PDLPred phi = new PDLIntGeq(new PDLIndicesOf("ab"), 2); var solver = new CharSetSolver(BitWidth.BV64); var alph = new List<char> { 'a', 'b' }; var al = new HashSet<char>(alph); var dfa = phi.GetDFA(al, solver); PDLPred synthPhi = null; StringBuilder sb = new StringBuilder(); foreach (var phi1 in pdlEnumerator.SynthesizePDL(al, dfa, solver, sb, 10000)) { synthPhi = phi1; break; } Console.WriteLine(sb); }
// private void runUnderapproxTest(string testName) { PDLEnumerator pdlEnumerator = new PDLEnumerator(); int printLimit = 10; CharSetSolver solver = new CharSetSolver(BitWidth.BV64); var dfa_al = ReadDFA(testName, solver); //PrintDFA(dfa_al.Second, "A", dfa_al.First); StringBuilder sb = new StringBuilder(); int i = 0; foreach (var pair in pdlEnumerator.SynthesizeUnderapproximationPDL(dfa_al.First, dfa_al.Second, solver, sb, timeout)) { i++; pair.First.ToString(sb); sb.AppendLine(" ### +"+pair.Second.ToString()+" ### +"+pair.First.GetFormulaSize()); sb.AppendLine(); if (i == printLimit) break; } System.Console.WriteLine(sb); }
/// <summary> /// Computes the grade for attempt using all the possible metrics /// </summary> /// <param name="dfaGoal">minimal correct dfa</param> /// <param name="dfaAttempt">dfa to be graded</param> /// <param name="al">input alphabet</param> /// <param name="solver">SMT solver for char set</param> /// <param name="timeout">timeout for the PDL enumeration (suggested > 1000)</param> /// <param name="maxGrade">Max grade for the homework</param> /// <param name="enableDFAED">true to enable DFA edit distance</param> /// <param name="enablePDLED">true to enable PDL edit distance</param> /// <param name="enableDensity">true to enable density distance</param> /// <returns>Grade for dfa2</returns> public static Pair<int, IEnumerable<DFAFeedback>> GetGrade( Automaton<BDD> dfaGoal, Automaton<BDD> dfaAttempt, HashSet<char> al, CharSetSolver solver, long timeout, int maxGrade, FeedbackLevel level, bool enableDFAED, bool enablePDLED, bool enableDensity) { PDLEnumerator pdlEnumerator = new PDLEnumerator(); var feedList = new List<DFAFeedback>(); DFAFeedback defaultFeedback = new StringFeedback(level, StringFeedbackType.Wrong, al, solver); #region Accessory and initial vars //Compute minimized version of DFAs var dfaGoalMin = dfaGoal.Determinize(solver).Minimize(solver); var dfaAttemptMin = dfaAttempt.Determinize(solver).Minimize(solver); //Initialize distances at high values in case they are not used // they only produce positive grade if between 0 and 1 double pdlEditDistanceScaled = 2; double densityRatio = 2; double dfaED = 2; #endregion #region deductions on the grade based on the size of the dfa //Deduction if DFA is smaller than it should be: used only for PDL ed and for density var smallerDFADeduction = 0.2 * Math.Sqrt( Math.Max(0.0, dfaGoalMin.StateCount - dfaAttemptMin.StateCount) / ((double)dfaGoalMin.StateCount)); #endregion #region check whether the attempt is equivalent to the solution if (dfaGoal.IsEquivalentWith(dfaAttempt, solver)) { Console.WriteLine("Correct"); feedList.Add(new StringFeedback(level, StringFeedbackType.Correct, al, solver)); return new Pair<int, IEnumerable<DFAFeedback>>(maxGrade, feedList); } #endregion #region metrics computation Stopwatch swPDLed = new Stopwatch(); swPDLed.Start(); #region PDL edit distance Transformation feedbackTransformation = null; if (enablePDLED) { var trpair = PDLEditDistance.GetMinimalFormulaEditDistanceTransformation(dfaGoalMin, dfaAttemptMin, al, solver, timeout, pdlEnumerator); if (trpair != null) { var transformationGrade = trpair.First; feedbackTransformation = trpair.Second; var scaling = 1.0; pdlEditDistanceScaled = transformationGrade.totalCost / (transformationGrade.minSizeForTreeA * scaling) + smallerDFADeduction; } } #endregion swPDLed.Stop(); Stopwatch swDensity = new Stopwatch(); swDensity.Start(); #region density distance if (enableDensity) { densityRatio = DFADensity.GetDFADifferenceRatio(dfaGoalMin, dfaAttemptMin, al, solver); densityRatio += smallerDFADeduction; } #endregion swDensity.Stop(); Stopwatch swDFAed = new Stopwatch(); swDFAed.Start(); #region DFA edit distance DFAEditScript dfaEditScript = null; if (enableDFAED) { //limit the depth of the DFA edit distance search var maxMoves = Math.Max(1, 6 - (int)Math.Sqrt(dfaAttempt.MoveCount + dfaAttempt.StateCount)); dfaEditScript = DFAEditDistance.GetDFAOptimalEdit(dfaGoal, dfaAttempt, al, solver, timeout, new StringBuilder()); if (dfaEditScript != null) dfaED = ((double)(dfaEditScript.GetCost())) / ((double)((dfaGoalMin.StateCount + 1) * al.Count)); } #endregion swDFAed.Stop(); #endregion #region metrics scaling var scalingSquarePDLED = 1.005; var scalingSquareDensity = 1; var multv2 = 0.5; var scalingSquareDFAED = 1.03; var scaledPdlED = (0.9 * (scalingSquarePDLED + pdlEditDistanceScaled) * (scalingSquarePDLED + pdlEditDistanceScaled)) - scalingSquarePDLED * scalingSquarePDLED; var scaledDensityRatio = (scalingSquareDensity + (multv2 * densityRatio)) * (scalingSquareDensity + (multv2 * densityRatio)) - scalingSquareDensity * scalingSquareDensity; var scaledDfaED = (scalingSquareDFAED + dfaED) * (scalingSquareDFAED + dfaED) - scalingSquareDFAED * scalingSquareDFAED; //Select dominating Feedback based on grade double unscaledGrade = Math.Min(Math.Min(scaledPdlED, scaledDensityRatio), scaledDfaED); var pdledwins = scaledPdlED <= Math.Min(scaledDensityRatio, scaledDfaED); var dfaedwins = scaledDfaED <= Math.Min(scaledDensityRatio, scaledPdlED); var densitywins = scaledDensityRatio <= Math.Min(scaledDfaED, scaledPdlED); #endregion #region Feedback Selection if (pdledwins && feedbackTransformation != null && feedbackTransformation.pdlB.GetFormulaSize()<10) feedList.Add(new PDLEDFeedback(level, al, feedbackTransformation, scaledPdlED, solver)); if ((dfaedwins || feedList.Count == 0) && dfaEditScript != null && !dfaEditScript.IsComplex()) { feedList = new List<DFAFeedback>(); feedList.Add(new DFAEDFeedback(dfaGoal, dfaAttempt, level, al, dfaEditScript, scaledDfaED, solver)); } if (densitywins || feedList.Count == 0) { feedList = new List<DFAFeedback>(); feedList.Add(new DensityFeedback(level, al, dfaGoal, dfaAttempt, scaledDensityRatio, solver)); } if (feedList.Count == 0) { Console.WriteLine("Why no feedback!!"); feedList.Add(defaultFeedback); } #endregion #region normalize grade var scaledGrade = maxGrade - (int)Math.Round(unscaledGrade * (double)(maxGrade)); //If rounding yields maxgrade deduct 1 point by default if (scaledGrade == maxGrade) scaledGrade = maxGrade - 1; //Remove possible deduction scaledGrade = scaledGrade < 0 ? 0 : scaledGrade; return new Pair<int, IEnumerable<DFAFeedback>>(scaledGrade, feedList); #endregion }