private void SafeUpdateThresholdsUpward(FeedbackLevel level, FeedbackLevel next, int input, Dictionary <FeedbackLevel, FeedbackLevelData> updatedLevels, float factor)
        {
            FeedbackLevel realLevel;

            this.GetExistingLevel(level, out realLevel);

            FeedbackLevelData values, hierLevelValues;

            if (!this.UpdateLevelValues(realLevel, input, factor, out values, out hierLevelValues, updatedLevels))
            {
                return;
            }

            if (level == next)
            {
                return;
            }


            var upDownDiff = hierLevelValues.UpperBound - values.UpperBound;

            if (MinimalLevelSize > upDownDiff)
            {
                this.UpdateThresholdsInt(values.UpperBound + MinimalLevelSize, next, 1.0f, ref updatedLevels);
            }
        }
 public DFAFeedback(FeedbackLevel level, HashSet<char> alphabet, double utility, CharSetSolver solver)
 {
     this.alphabet = alphabet;
     this.level = level;
     this.solver = solver;
     this.utility = Math.Round(Math.Max(1-utility,0)*100);
 }
Example #3
0
 public ServerBunch(byte priority, float reserveRatio, FeedbackLevel takeFromReserveLevel = FeedbackLevel.Highest)
 {
     this.reserveRatio             = reserveRatio;
     this.Priority                 = priority;
     this.takeFromReserveLoadLevel = (int)takeFromReserveLevel;
     this.serverList               = new SortedDictionary <TServer, ServerStateData <TServer> >();
 }
 public DFAFeedback(FeedbackLevel level, HashSet <char> alphabet, double utility, CharSetSolver solver)
 {
     this.alphabet = alphabet;
     this.level    = level;
     this.solver   = solver;
     this.utility  = Math.Round(Math.Max(1 - utility, 0) * 100);
 }
        private void UpdateServerState(FeedbackLevel workload, int peerCount, ServerState state)
        {
            Dictionary <byte, int[]> predictionData = null;

            if (this.loadStatsCollector != null)
            {
                this.loadStatsCollector.UpdatePrediction(peerCount, workload, out predictionData);
            }

            if (!this.IsRegistered)
            {
                return;
            }

            var contract = new UpdateServerEvent
            {
                LoadIndex       = (byte)workload,
                PeerCount       = peerCount,
                State           = (int)state,
                LoadLevelsCount = (int)FeedbackLevel.LEVELS_COUNT,
                PredictionData  = predictionData,
            };
            var eventData = new EventData((byte)ServerEventCode.UpdateServer, contract);

            this.SendEvent(eventData, new SendParameters());
        }
Example #6
0
        /// <summary>
        ///   Attempts to add a server instance.
        /// </summary>
        /// <param name = "server">The server instance to add.</param>
        /// <param name = "loadLevel">The current workload of the server instance.</param>
        /// <returns>
        ///   True if the server instance was added successfully. If the server instance already exists,
        ///   this method returns false.
        /// </returns>
        public bool TryAddServer(TServer server, FeedbackLevel loadLevel)
        {
            lock (this.serverList)
            {
                // check if the server instance was already added
                if (this.serverList.ContainsKey(server))
                {
                    log.WarnFormat("LoadBalancer already contains server {0}", server);
                    return(false);
                }

                var serverState = new ServerState(server)
                {
                    LoadLevel = loadLevel,
                    Weight    = this.GetLoadLevelWeight(loadLevel)
                };

                this.serverList.Add(server, serverState);

                if (serverState.Weight > 0)
                {
                    this.AddToAvailableServers(serverState);
                }

                this.UpdateTotalWorkload(FeedbackLevel.Lowest, loadLevel);

                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Added server: workload={0}", loadLevel);
                }

                return(true);
            }
        }
Example #7
0
        public ServerStateData <TServer> TryAddServer(TServer server, FeedbackLevel loadLevel, int loadLevelWeight)
        {
            // check if the server instance was already added
            if (this.serverList.ContainsKey(server))
            {
                log.WarnFormat("LoadBalancer already contains server {0}", server);
                return(null);
            }

            var serverState = new ServerStateData <TServer>(server)
            {
                LoadLevel = loadLevel,
                Weight    = loadLevelWeight,
                Priority  = this.Priority
            };

            this.serverList.Add(server, serverState);

            // we add new server to reserve only when it should be increased by 1
            // let's say we had 9 server and ratio is 0.2, then reserve will contain 1 server
            // we add new server. 10*0.2 == 2. 2 - resevedServersCount(1) == 1. and -1 will gives us almost 0. so we increase amount of reserved servers
            if (Math.Abs(this.reserveRatio * this.serverList.Count - this.reservedServersCount - 1) < 0.0001)
            {
                serverState.MarkReserved();
                ++this.reservedServersCount;
            }

            this.UpdateServerReturnThreshold();
            return(serverState);
        }
Example #8
0
        public FeedbackLevel SetInput(FeedbackName key, int input, out FeedbackLevel level)
        {
            level = this.Output;

            // Controllers are optional, we don't need to configure them all.
            FeedbackController controller;

            if (this.values.TryGetValue(key, out controller))
            {
                if (controller.SetInput(input))
                {
                    level = controller.Output;
                    if (controller.Output > this.Output)
                    {
                        return(this.Output = controller.Output);
                    }

                    if (controller.Output < this.Output)
                    {
                        return(this.CalculateOutput());
                    }
                }

                level = controller.Output;
            }

            return(this.Output);
        }
 public FeedbackController(
     FeedbackName feedbackName, Dictionary <FeedbackLevel, int> thresholdValues, int initialInput, FeedbackLevel initalFeedbackLevel)
 {
     this.thresholdValues      = thresholdValues;
     this.feedbackName         = feedbackName;
     this.currentFeedbackLevel = initalFeedbackLevel;
     this.currentInput         = initialInput;
 }
 public FeedbackController(
     FeedbackName feedbackName, Dictionary<FeedbackLevel, int> thresholdValues, int initialInput, FeedbackLevel initalFeedbackLevel)
 {
     this.thresholdValues = thresholdValues;
     this.feedbackName = feedbackName;
     this.currentFeedbackLevel = initalFeedbackLevel;
     this.currentInput = initialInput;
 }
Example #11
0
 /// <summary>
 ///   Initializes a new instance of the <see cref = "LoadBalancer{TServer}" /> class.
 /// </summary>
 /// <remarks>
 /// This overload is used for unit testing to provide a fixed seed for the
 /// random number generator.
 /// </remarks>
 public LoadBalancer(int[] loadLevelWeights, int seed,
                     FeedbackLevel priorityUpThreshold = FeedbackLevel.Highest, FeedbackLevel priorityDownThreshold = FeedbackLevel.Highest)
     : this(loadLevelWeights)
 {
     this.PriorityUpThreshold   = priorityUpThreshold;
     this.priorityDownThreshold = priorityDownThreshold;
     this.random = new Random(seed);
 }
 /// <summary>
 /// Gets either 'level' if it is exist or first existing level below 'level'
 /// </summary>
 /// <param name="level"></param>
 /// <param name="realLevel"></param>
 private void GetExistingLevel(FeedbackLevel level, out FeedbackLevel realLevel)
 {
     while (!this.DoesLevelExists(level))
     {
         level = this.GetNextExistingLowerLevel(level);
     }
     realLevel = level;
 }
Example #13
0
        private void InitializeFromConfig(string configFilePath)
        {
            string message;
            LoadBalancerSection section;

            int[] weights = null;

            if (!ConfigurationLoader.TryLoadFromFile(configFilePath, out section, out message))
            {
                log.WarnFormat(
                    "Could not initialize LoadBalancer from configuration: Invalid configuration file {0}. Using default settings... ({1})",
                    configFilePath,
                    message);
            }

            if (section != null)
            {
                this.ReserveRatio = section.ReserveRatio;

                this.priorityDownThreshold = section.ValueDown;
                if (section.ValueDown == FeedbackLevel.Highest)
                {
                    this.priorityDownThreshold = section.ValueUp == 0 ? section.ValueUp : section.ValueUp - 1;
                }
                this.PriorityUpThreshold = section.ValueUp;

                // load weights from config file & sort:
                var dict = new SortedDictionary <int, int>();
                foreach (LoadBalancerWeight weight in section.LoadBalancerWeights)
                {
                    dict.Add((int)weight.Level, weight.Value);
                }

                if (dict.Count == (int)FeedbackLevel.Highest + 1)
                {
                    weights = new int[dict.Count];
                    dict.Values.CopyTo(weights, 0);

                    log.InfoFormat("Initialized Load Balancer from configuration file: {0}", configFilePath);
                }
                else
                {
                    log.WarnFormat(
                        "Could not initialize LoadBalancer from configuration: {0} is invalid - expected {1} entries, but found {2}. Using default settings...",
                        configFilePath,
                        (int)FeedbackLevel.Highest + 1,
                        dict.Count);
                }
            }

            if (weights == null)
            {
                weights = DefaultConfiguration.GetDefaultWeights();
            }

            this.loadLevelWeights = weights;
        }
        private bool UpdateLevelValues(FeedbackLevel level, int input, float factor, out FeedbackLevelData upDownValues, out FeedbackLevelData higherLevelValues, Dictionary <FeedbackLevel, FeedbackLevelData> updatedLevels)
        {
            higherLevelValues = new FeedbackLevelData(-1, -1);
            if (!this.thresholdValues.TryGetValue(level, out upDownValues))
            {
                log.WarnFormat("Can not find values for level {0}", level);
                return(false);
            }

            if (input < 0)
            {
                input = 0;
            }

            if (level == FeedbackLevel.Highest)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("We do not update upper bound for 'Highest' level");
                }
                //upDownValues.UpperBound = (int)(factor * (input - upDownValues.UpperBound)) + upDownValues.UpperBound;
                //this.thresholdValues[level] = upDownValues;
                //updatedLevels[level] = upDownValues;
                return(true);
            }

            var nextLevel = this.GetNextExistingHigherLevel(level);

            if (!this.thresholdValues.TryGetValue(nextLevel, out higherLevelValues))
            {
                log.WarnFormat("Can not find values for level {0}", nextLevel);
                return(false);
            }

            var upDownDiff = upDownValues.UpperBound - higherLevelValues.LowerBound;

            upDownValues.UpperBound      = (int)(factor * (input - upDownValues.UpperBound)) + upDownValues.UpperBound;
            higherLevelValues.LowerBound = upDownValues.UpperBound - upDownDiff;
            if (higherLevelValues.LowerBound > upDownValues.UpperBound)
            {
                higherLevelValues.LowerBound = upDownValues.UpperBound;
            }

            this.thresholdValues[level]     = upDownValues;
            this.thresholdValues[nextLevel] = higherLevelValues;
            updatedLevels[level]            = upDownValues;
            updatedLevels[nextLevel]        = higherLevelValues;

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("Level updated. Input:{0}, level:{1}, next:{2}, {1}'s data:{3}, {2}'s data:{4}",
                                input, level, nextLevel, upDownValues, higherLevelValues);
            }

            return(true);
        }
        public DFAEDFeedback(Automaton <BDD> dfaGoal, Automaton <BDD> dfaAttempt, FeedbackLevel level, HashSet <char> alphabet, DFAEditScript script, double utility, CharSetSolver solver)
            : base(level, alphabet, utility, solver)
        {
            var positiveDifference = dfaGoal.Minus(dfaAttempt, solver).Determinize(solver).Minimize(solver);
            var negativeDifference = dfaAttempt.Minus(dfaGoal, solver).Determinize(solver).Minimize(solver);

            this.counterexample = DFAUtilities.GenerateShortTerm(positiveDifference.IsEmpty ? negativeDifference : positiveDifference, solver);
            this.type           = FeedbackType.DFAED;
            this.script         = script;
        }
 public NFANotMinimalFeedback (
     FeedbackLevel level, HashSet<char> alphabet,
     int stateDiff, int transitionDiff,
     NFAEditScript script,
     CharSetSolver solver)
     : base(level, alphabet, solver)
 {
     this.transitionDiff = transitionDiff;
     this.stateDiff = stateDiff;
     this.script = script;
 }
Example #17
0
        public void UpdateTotalWorkload(ServerStateData <TServer> server, FeedbackLevel oldLoadLevel, FeedbackLevel newLoadLevel)
        {
            this.totalWorkload -= (int)oldLoadLevel;
            this.totalWorkload += (int)newLoadLevel;

            if (!server.IsInReserve)
            {
                this.serversInUseWorkload -= (int)oldLoadLevel;
                this.serversInUseWorkload += (int)newLoadLevel;
            }
        }
 public NFANotMinimalFeedback(
     FeedbackLevel level, HashSet <char> alphabet,
     int stateDiff, int transitionDiff,
     NFAEditScript script,
     CharSetSolver solver)
     : base(level, alphabet, solver)
 {
     this.transitionDiff = transitionDiff;
     this.stateDiff      = stateDiff;
     this.script         = script;
 }
        public void UpdateServerState(FeedbackLevel workload, int peerCount, ServerState state)
        {
            if (!this.IsRegistered)
            {
                return;
            }

            var contract = new UpdateServerEvent { LoadIndex = (byte)workload, PeerCount = peerCount, State = (int)state };
            var eventData = new EventData((byte)ServerEventCode.UpdateServer, contract);
            this.SendEvent(eventData, new SendParameters());
        }
        private bool GetLowerThreshold(FeedbackLevel level, out int result)
        {
            FeedbackLevelData values;

            if (this.thresholdValues.TryGetValue(level, out values))
            {
                result = values.LowerBound;
                return(true);
            }
            result = 0;
            return(false);
        }
        internal void UpdateThresholds(SortedDictionary <FeedbackLevel, FeedbackLevelData> dict)
        {
            foreach (var feedbackLevelData in dict)
            {
                this.thresholdValues[feedbackLevelData.Key] = feedbackLevelData.Value;
            }
            var t = this.currentInput;

            this.currentInput         = 0;
            this.currentFeedbackLevel = FeedbackLevel.Lowest;
            this.SetInput(t);
        }
        public NFAEDFeedback(Automaton <BDD> nfaGoal, Automaton <BDD> nfaAttempt,
                             FeedbackLevel level, HashSet <char> alphabet,
                             NFAEditScript script, CharSetSolver solver)
            : base(level, alphabet, solver)
        {
            //TODO might have to determinize to do this operations
            var positiveDifference = nfaGoal.Minus(nfaAttempt, solver).Determinize(solver).Minimize(solver);
            var negativeDifference = nfaAttempt.Minus(nfaGoal, solver).Determinize(solver).Minimize(solver);

            this.counterexample = DFAUtilities.GenerateShortTerm(positiveDifference.IsEmpty ? negativeDifference : positiveDifference, solver);
            this.script         = script;
        }
Example #23
0
        public void UpdateServerState(FeedbackLevel workload, int peerCount, ServerState state)
        {
            if (!this.IsRegistered)
            {
                return;
            }

            var contract = new UpdateServerEvent {
                LoadIndex = (byte)workload, PeerCount = peerCount, State = (int)state
            };
            var eventData = new EventData((byte)ServerEventCode.UpdateServer, contract);

            this.SendEvent(eventData, new SendParameters());
        }
        private bool UpdateThresholdsInt(int input, FeedbackLevel level, float factor,
                                         ref Dictionary <FeedbackLevel, FeedbackLevelData> updatedLevels)
        {
            var expectedLevel = FeedbackLevel.Lowest;

            foreach (var thresholdValue in this.thresholdValues)
            {
                if (thresholdValue.Value.UpperBound >= input)
                {
                    expectedLevel = thresholdValue.Key;
                    break;
                }

                if (thresholdValue.Key == FeedbackLevel.Highest)
                {
                    expectedLevel = FeedbackLevel.Highest;
                    break;
                }
            }

            if (expectedLevel == level)
            {
                return(false);
            }

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("Level updating. input:{0}, level:{1}, factor:{2}", input, level, factor);
            }

            if (updatedLevels == null)
            {
                updatedLevels = new Dictionary <FeedbackLevel, FeedbackLevelData>();
            }

            if (expectedLevel < level)
            {
                var next = this.GetNextExistingLowerLevel(level);

                this.SafeUpdateThresholdsDownward(level, next, input, factor, ref updatedLevels);
            }
            else
            {
                var next = this.GetNextExistingHigherLevel(level);

                this.SafeUpdateThresholdsUpward(level, next, input, updatedLevels, factor);
            }
            return(true);
        }
 public void SendMessage(FeedbackLevel level, LocalizedString message)
 {
     switch (level)
     {
         case FeedbackLevel.Info:
             Logger.Information(message.ToString());
             return;
         case FeedbackLevel.Warn:
             Logger.Information(message.ToString());
             return;
         case FeedbackLevel.Error:
             Logger.Information(message.ToString());
             return;
     }
 }
        private FeedbackLevel GetNextExistingLowerLevel(FeedbackLevel level)
        {
            var next = level;

            while (next != FeedbackLevel.Lowest)
            {
                next = GetNextLower(next);
                if (this.DoesLevelExists(next))
                {
                    return(next);
                }
            }

            return(FeedbackLevel.Lowest);
        }
        public FeedbackLevel GetNextLowerThreshold(FeedbackLevel level, out int result)
        {
            FeedbackLevel next = level;
            while (next != FeedbackLevel.Lowest)
            {
                next = FeedbackLevelOrder.GetNextLower(next);
                if (this.thresholdValues.TryGetValue(next, out result))
                {
                    return next;
                }
            }

            this.thresholdValues.TryGetValue(level, out result);
            return level;
        }
        private bool DoesLevelExists(FeedbackLevel level)
        {
            FeedbackLevelData values;

            if (this.thresholdValues.TryGetValue(level, out values))
            {
                return(true);
            }

            if (level == FeedbackLevel.Highest)
            {
                return(true);
            }

            return(false);
        }
        private FeedbackLevel GetNextLowerThreshold(FeedbackLevel level, out int result)
        {
            var next = level;

            while (next != FeedbackLevel.Lowest)
            {
                next = this.GetNextLower(next);
                if (this.GetLowerThreshold(next, out result))
                {
                    return(next);
                }
            }

            this.GetLowerThreshold(next, out result);
            return(level);
        }
Example #30
0
        public FeedbackLevel GetNextLowerThreshold(FeedbackLevel level, out int result)
        {
            FeedbackLevel next = level;

            while (next != FeedbackLevel.Lowest)
            {
                next = FeedbackLevelOrder.GetNextLower(next);
                if (this.thresholdValues.TryGetValue(next, out result))
                {
                    return(next);
                }
            }

            this.thresholdValues.TryGetValue(level, out result);
            return(level);
        }
        private FeedbackLevel GetNextExistingHigherLevel(FeedbackLevel level)
        {
            var next = level;

            while (next != FeedbackLevel.Highest)
            {
                next = GetNextHigher(next);
                if (this.DoesLevelExists(next))
                {
                    return(next);
                }
            }

            this.DoesLevelExists(level);

            return(level);
        }
Example #32
0
        public void SendMessage(FeedbackLevel level, LocalizedString message)
        {
            switch (level)
            {
            case FeedbackLevel.Info:
                Logger.Information(message.ToString());
                return;

            case FeedbackLevel.Warn:
                Logger.Information(message.ToString());
                return;

            case FeedbackLevel.Error:
                Logger.Information(message.ToString());
                return;
            }
        }
        private void SafeUpdateThresholdsDownward(FeedbackLevel level, FeedbackLevel next, int input,
                                                  float factor, ref Dictionary <FeedbackLevel, FeedbackLevelData> updatedLevels)
        {
            FeedbackLevelData values, higherLevelValues;

            if (!this.UpdateLevelValues(next, input - 1, factor, out values, out higherLevelValues, updatedLevels))
            {
                return;
            }

            var upDownDiff = values.UpperBound - values.LowerBound;

            if (upDownDiff < MinimalLevelSize)
            {
                this.UpdateThresholdsInt(values.UpperBound - MinimalLevelSize, next, 1.0f, ref updatedLevels);
            }
        }
Example #34
0
        /// <summary>
        ///   Tries to update a server instance.
        /// </summary>
        /// <param name = "server">The server to update.</param>
        /// <param name = "newLoadLevel">The current workload of the server instance.</param>
        /// <returns>
        ///   True if the server instance was updated successfully.
        ///   If the server instance does not exists, this method returns false.
        /// </returns>
        public bool TryUpdateServer(TServer server, FeedbackLevel newLoadLevel)
        {
            lock (this.serverList)
            {
                // check if server instance exits
                ServerState serverState;
                if (this.serverList.TryGetValue(server, out serverState) == false)
                {
                    return(false);
                }

                // check if load level has changed
                if (serverState.LoadLevel == newLoadLevel)
                {
                    return(true);
                }

                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Updating server: oldWorkload={0}, newWorkload={1}", serverState.LoadLevel, newLoadLevel);
                }

                // apply new state
                this.UpdateTotalWorkload(serverState.LoadLevel, newLoadLevel);

                serverState.LoadLevel = newLoadLevel;
                var newWeight = this.GetLoadLevelWeight(newLoadLevel);

                // check if the weight for the server instance has changes
                // if it has not changed we don't have to update the list of available servers
                if (newWeight == serverState.Weight)
                {
                    return(true);
                }

                this.RemoveFromAvailableServers(serverState);
                serverState.Weight = newWeight;

                if (serverState.Weight > 0)
                {
                    this.AddToAvailableServers(serverState);
                }

                return(true);
            }
        }
        public DensityFeedback(FeedbackLevel level, HashSet <char> alphabet, Automaton <BDD> dfaGoal, Automaton <BDD> dfaAttempt, double utility, CharSetSolver solver)
            : base(level, alphabet, utility, solver)
        {
            BDD pred = solver.False;

            foreach (var el in alphabet)
            {
                pred = solver.MkOr(pred, solver.MkCharConstraint(false, el));
            }

            var dfaAll = Automaton <BDD> .Create(0, new int[] { 0 }, new Move <BDD>[] { new Move <BDD>(0, 0, pred) });

            this.type = FeedbackType.Density;
            this.positiveDifference  = dfaGoal.Minus(dfaAttempt, solver).Determinize(solver).Minimize(solver);
            this.negativeDifference  = dfaAttempt.Minus(dfaGoal, solver).Determinize(solver).Minimize(solver);
            this.symmetricDifference = dfaAll.Minus(dfaAll.Minus(positiveDifference, solver).Intersect(dfaAll.Minus(negativeDifference, solver), solver), solver).Determinize(solver).Minimize(solver);
            this.solver = solver;
        }
        // automata come already determinized
        public NFACounterexampleFeedback(
            FeedbackLevel level, HashSet <char> alphabet,
            Automaton <BDD> solutionDFA, Automaton <BDD> attemptDFA,
            CharSetSolver solver)
            : base(level, alphabet, solver)
        {
            BDD pred = solver.False;

            foreach (var el in alphabet)
            {
                pred = solver.MkOr(pred, solver.MkCharConstraint(false, el));
            }

            var dfaAll = Automaton <BDD> .Create(0, new int[] { 0 }, new Move <BDD>[] { new Move <BDD>(0, 0, pred) });

            this.positiveDifference = solutionDFA.Minus(attemptDFA, solver).Determinize(solver).Minimize(solver);
            this.negativeDifference = attemptDFA.Minus(solutionDFA, solver).Determinize(solver).Minimize(solver);
            this.solver             = solver;
        }
        public FeedbackLevel SetInput(FeedbackName key, int input)
        {
            // Controllers are optional, we don't need to configure them all. 
            FeedbackController controller;
            if (this.values.TryGetValue(key, out controller))
            {
                if (controller.SetInput(input))
                {
                    if (controller.Output > this.Output)
                    {
                        return this.Output = controller.Output;
                    }

                    if (controller.Output < this.Output)
                    {
                        return this.CalculateOutput();
                    }
                }
            }

            return this.Output;
        }
        /// <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
        }
 public NFAEDFeedback(Automaton<BDD> nfaGoal, Automaton<BDD> nfaAttempt, 
     FeedbackLevel level, HashSet<char> alphabet, 
     NFAEditScript script, CharSetSolver solver)
     : base(level, alphabet, solver)
 {
     //TODO might have to determinize to do this operations
     var positiveDifference = nfaGoal.Minus(nfaAttempt, solver).Determinize(solver).Minimize(solver);
     var negativeDifference = nfaAttempt.Minus(nfaGoal, solver).Determinize(solver).Minimize(solver);
     this.counterexample = DFAUtilities.GenerateShortTerm(positiveDifference.IsEmpty ? negativeDifference : positiveDifference, solver);            
     this.script = script;
 }
 private void TryAddServer(Server server, FeedbackLevel loadLevel, bool expectedResult = true)
 {
     var result = this.balancer.TryAddServer(server, loadLevel);
     Assert.AreEqual(result, expectedResult);
 }
 public DFAEDFeedback(Automaton<BDD> dfaGoal, Automaton<BDD> dfaAttempt, FeedbackLevel level, HashSet<char> alphabet, DFAEditScript script, double utility, CharSetSolver solver)
     : base(level, alphabet, utility, solver)
 {
     var positiveDifference = dfaGoal.Minus(dfaAttempt, solver).Determinize(solver).Minimize(solver);
     var negativeDifference = dfaAttempt.Minus(dfaGoal, solver).Determinize(solver).Minimize(solver);
     this.counterexample = DFAUtilities.GenerateShortTerm(positiveDifference.IsEmpty ? negativeDifference : positiveDifference, solver);
     this.type = FeedbackType.DFAED;
     this.script = script;
 }
 public StringFeedback(FeedbackLevel level, StringFeedbackType sfType, HashSet<char> alphabet, CharSetSolver solver)
     : base(level, alphabet, 1, solver)
 {
     this.type = FeedbackType.String;
     this.sfType = sfType;
 }
 public NFAFeedback(FeedbackLevel level, HashSet<char> alphabet, CharSetSolver solver)
 {
     this.alphabet = alphabet;
     this.level = level;
     this.solver = solver;
 }
 private DFAFeedback() {
     this.level = FeedbackLevel.Minimal;
 }
        public DensityFeedback(FeedbackLevel level, HashSet<char> alphabet, Automaton<BDD> dfaGoal, Automaton<BDD> dfaAttempt, double utility, CharSetSolver solver)
            : base(level, alphabet, utility,solver)
        {
            BDD pred = solver.False;
            foreach (var el in alphabet)
                pred=solver.MkOr(pred,solver.MkCharConstraint(false,el));

            var dfaAll = Automaton<BDD>.Create(0,new int[]{0},new Move<BDD>[]{new Move<BDD>(0,0,pred)});
            this.type = FeedbackType.Density;
            this.positiveDifference = dfaGoal.Minus(dfaAttempt, solver).Determinize(solver).Minimize(solver);
            this.negativeDifference = dfaAttempt.Minus(dfaGoal, solver).Determinize(solver).Minimize(solver);
            this.symmetricDifference = dfaAll.Minus(dfaAll.Minus(positiveDifference,solver).Intersect(dfaAll.Minus(negativeDifference,solver),solver),solver).Determinize(solver).Minimize(solver);                
            this.solver = solver;
        }
 public PDLEDFeedback(FeedbackLevel level, HashSet<char> alphabet, Transformation transformation, double utility, CharSetSolver solver)
     : base(level, alphabet, utility,solver)
 {
     this.transformation = transformation;
     this.type = FeedbackType.PDLED;
 }
 public static FeedbackLevel GetNextHigher(FeedbackLevel level)
 {
     return ascending[level];
 }
 public static FeedbackLevel GetNextLower(FeedbackLevel level)
 {
     return descending[level];
 }
 public FeedbackLevel CalculateOutput()
 {
     return this.Output = this.values.Values.Max(controller => controller.Output);
 }
        // automata come already determinized
        public NFACounterexampleFeedback(
            FeedbackLevel level, HashSet<char> alphabet, 
            Automaton<BDD> solutionDFA, Automaton<BDD> attemptDFA, 
            CharSetSolver solver)
            : base(level, alphabet, solver)
        {
            BDD pred = solver.False;
            foreach (var el in alphabet)
                pred = solver.MkOr(pred, solver.MkCharConstraint(false, el));

            var dfaAll = Automaton<BDD>.Create(0, new int[] { 0 }, new Move<BDD>[] { new Move<BDD>(0, 0, pred) });
            this.positiveDifference = solutionDFA.Minus(attemptDFA, solver).Determinize(solver).Minimize(solver);
            this.negativeDifference = attemptDFA.Minus(solutionDFA, solver).Determinize(solver).Minimize(solver);
            this.solver = solver;
        }
Example #51
0
 /// <summary>
 /// Clears the data stored in the model.
 /// </summary>
 public void Clear()
 {
     Level = FeedbackLevel.None;
     Description = string.Empty;
 }
        /// <summary>
        /// Computes the grade for attempt using all the possible metrics
        /// </summary>
        /// <param name="solutionNFA">correct nfa</param>
        /// <param name="attemptNFA">nfa to be graded</param>
        /// <param name="alpahbet">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="level">Feedback level</param>
        /// <returns>Grade for nfa2</returns>
        public static Pair<int, IEnumerable<NFAFeedback>> GetGrade(
            Automaton<BDD> solutionNFA, Automaton<BDD> attemptNFA, HashSet<char> alphabet,
            CharSetSolver solver, long timeout, int maxGrade, FeedbackLevel level)
        {
            var feedbacks = new List<NFAFeedback>();
            int deadStateDeduction = 0;
            int tooBigDeduction = 0;
            int incorrectDeduction = 0;

            // Remove at most a percentage of max grade when NFA is big
            double maxDeductionForTooBig = ((double)maxGrade * 0.3);
            double maxDeductionForDeadStates = ((double)maxGrade * 0.1);


            double solutionStateCount = solutionNFA.StateCount;
            double attemptStateCount = attemptNFA.StateCount;
            double solutionTransCount = solutionNFA.MoveCount;
            double attemptTransCount = attemptNFA.MoveCount;
            NFAEditDistanceProvider nfaedp = new NFAEditDistanceProvider(solutionNFA, alphabet, solver, timeout);

            //Check if using epsilon and nondeterminism
            if (solutionNFA.IsEpsilonFree)
                solutionNFA.CheckDeterminism(solver);
            if (attemptNFA.IsEpsilonFree)
                attemptNFA.CheckDeterminism(solver);

            bool shouldUseEpsilon = !solutionNFA.IsEpsilonFree && attemptNFA.IsEpsilonFree;
            bool shouldUseNonDet = !shouldUseEpsilon && !solutionNFA.isDeterministic && attemptNFA.isDeterministic;

            //Check if solution has dead states and remove if it does
            var statesBeforeDeadStatesElimination = attemptNFA.StateCount;
            attemptNFA.EliminateDeadStates();
            var solutionHasDeadStates = attemptNFA.StateCount < statesBeforeDeadStatesElimination;

            //Start checking equiv
            bool areEquivalent = solutionNFA.IsEquivalentWith(attemptNFA, solver);

            if (areEquivalent)
            {
                // prompt nfa is correct
                feedbacks.Insert(0, new NFAStringFeedback(level, alphabet, solver, "Your NFA accepts the CORRECT language."));

                #region Check number of states and decrease grade if too big
                int stateDiff = (int)(attemptStateCount - solutionStateCount);
                int transDiff = (int)(attemptTransCount - solutionTransCount);

                //If is not minimal apply deduction and compute edit
                if (stateDiff > 0 || transDiff > 0)
                {
                    #region Try to collapse for feedback
                    // Try to find a way to collaps states or remove states and transitions to make the NFA smaller  
                    NFAEditScript collapseScript = null;
                    var edit = nfaedp.NFACollapseSearch(attemptNFA);
                    if (edit != null)
                    {
                        collapseScript = new NFAEditScript();
                        collapseScript.script.Insert(0, edit);
                    }
                    feedbacks.Add(new NFANotMinimalFeedback(level, alphabet, stateDiff, transDiff, collapseScript, solver));
                    #endregion

                    #region Compute tooBigDeduction
                    if (stateDiff > 0)
                    {
                        // ((att/sol)^2)-1
                        var stateRatio = attemptStateCount / solutionStateCount;
                        var stateRatioSqM1 = Math.Pow(stateRatio, 2) - 1;
                        var sclaedStateRatio = stateRatioSqM1 * maxDeductionForTooBig / 2;

                        tooBigDeduction = (int)Math.Round(Math.Min(sclaedStateRatio, maxDeductionForTooBig));
                    }
                    else
                    {
                        if (transDiff > 0)
                        {
                            // ((att/sol)^2)-1
                            var transRatio = attemptTransCount / solutionTransCount;
                            var transRatioSqM1 = Math.Pow(transRatio, 2) - 1;
                            var sclaedTransRatio = transRatioSqM1 * maxDeductionForTooBig / 2;

                            tooBigDeduction = (int)Math.Round(Math.Min(sclaedTransRatio, maxDeductionForTooBig));
                        }
                    }
                    //Make sure deduction is positive
                    tooBigDeduction = Math.Max(tooBigDeduction, 0);
                    #endregion
                }
                #endregion

            }
            else
            {
                // prompt nfa is incorrect
                feedbacks.Add(new NFAStringFeedback(level, alphabet, solver, "Your NFA does NOT accept the correct langauge."));

                //inequivalent, try using grading metrics and based on winning metric give feedback
                int remainingGrade = maxGrade - tooBigDeduction;

                #region metric computation
                //compute deterministic versions
                var solutionNFAdet = solutionNFA.RemoveEpsilons(solver.MkOr).Determinize(solver).MakeTotal(solver).Minimize(solver);
                var attemptNFAdet = attemptNFA.RemoveEpsilons(solver.MkOr).Determinize(solver).MakeTotal(solver).Minimize(solver);
                solutionNFAdet.EliminateDeadStates();
                attemptNFAdet.EliminateDeadStates();

                //compute density
                double densityRatio = DFADensity.GetDFADifferenceRatio(solutionNFAdet, attemptNFAdet, alphabet, solver);

                //compute edit distance
                double nfaED = 2;
                var editScript = nfaedp.GetNFAOptimalEdit(attemptNFA);

                if (editScript != null)
                    nfaED = ((double)(editScript.GetCost())) / ((double)((solutionNFA.StateCount + 1) * alphabet.Count));
                #endregion

                #region metrics scaling
                var scalingSquareDensity = 1; var multv2 = 0.5;
                var scalingSquareDFAED = 1.03;

                var scaledDensityRatio = (scalingSquareDensity + (multv2 * densityRatio)) * (scalingSquareDensity + (multv2 * densityRatio)) - scalingSquareDensity * scalingSquareDensity;
                var scaledNfaED = (scalingSquareDFAED + nfaED) * (scalingSquareDFAED + nfaED) - scalingSquareDFAED * scalingSquareDFAED;

                //If the edit script was not computed make sure it loses.
                if (editScript == null)
                    scaledNfaED = Double.MaxValue;

                //Select dominating Feedback based on grade
                double unscaledGrade = Math.Min(scaledDensityRatio, scaledNfaED);
                var dfaedwins = scaledNfaED <= scaledDensityRatio;
                var densitywins = scaledDensityRatio <= scaledNfaED;

                incorrectDeduction = (int)Math.Round(unscaledGrade * (double)(maxGrade));
                #endregion


                //If edit distance search works, provides feedback based upon result
                //Otherwise, gives counterexample feedback
                if (level != FeedbackLevel.Minimal)
                {
                    if (dfaedwins)
                        feedbacks.Add(new NFAEDFeedback(solutionNFA, attemptNFA, level, alphabet, editScript, solver));
                    else
                        feedbacks.Add(new NFACounterexampleFeedback(level, alphabet, solutionNFAdet, attemptNFAdet, solver));
                }

            }

            // Feedback related to nondeterminism and epislon
            if (shouldUseEpsilon)
                feedbacks.Add(new NFAStringFeedback(level, alphabet, solver, "You should try using epsilon transitions."));
            if (shouldUseNonDet)
                feedbacks.Add(new NFAStringFeedback(level, alphabet, solver, "You should try using nondeterminism."));

            // Deduct points and prompt feedback is solution has dead states
            if (solutionHasDeadStates)
            {
                deadStateDeduction = (int)maxDeductionForDeadStates;
                feedbacks.Add(new NFAStringFeedback(level, alphabet, solver, "Your NFA has some dead states."));
            }

            //Grade computation
            int grade = Math.Max(maxGrade - deadStateDeduction - tooBigDeduction - incorrectDeduction, 0);

            return new Pair<int, IEnumerable<NFAFeedback>>(grade, feedbacks);
        }
 private void TryUpdateServer(Server server, FeedbackLevel newLoadLevel, bool expectedResult = true)
 {
     var result = this.balancer.TryUpdateServer(server, newLoadLevel);
     Assert.AreEqual(expectedResult, result, "Unexpected update server result.");
 }
 /// <summary>
 /// Computes the grade for attempt using all the possible metrics
 /// </summary>
 /// <param name="solution">correct dfa</param>
 /// <param name="attempt">dfa to be graded</param>
 /// <param name="alpahbet">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="level">Feedback level</param>
 /// <returns>Grade for dfa2</returns>
 public static Pair<int, IEnumerable<DFAFeedback>> GetGrade(
     Automaton<BDD> solution, Automaton<BDD> attempt, HashSet<char> alpahbet,
     CharSetSolver solver, long timeout, int maxGrade, FeedbackLevel level)
 {
     return GetGrade(solution, attempt, alpahbet, solver, timeout, maxGrade, level, true, true, true);
 }
 public NFAStringFeedback(FeedbackLevel level, HashSet<char> alphabet, CharSetSolver solver, string message)
     : base(level, alphabet, solver)
 {
     this.message = message;
 }
 private void UpdateServer(Server server, FeedbackLevel newLoadLevel)
 {
     bool result = this.balancer.TryUpdateServer(server, newLoadLevel);
     Assert.IsTrue(result, "Failed to update {0} to the load level '{1}'", server.Name, newLoadLevel);
 }
        public bool SetInput(int input)
        {
            if (log.IsDebugEnabled)
            {
                log.DebugFormat("SetInput: {0} value {1}", this.FeedbackName, input);
            }

            if (input > this.currentInput)
            {
                int threshold;
                FeedbackLevel last = this.currentFeedbackLevel;
                FeedbackLevel next = this.GetNextHigherThreshold(last, out threshold);
                while (next != last)
                {
                    if (input >= threshold)
                    {
                        last = next;
                        next = this.GetNextHigherThreshold(last, out threshold);
                    }
                    else
                    {
                        next = last;
                    }
                }

                this.currentInput = input;
                if (next != this.currentFeedbackLevel)
                {
                    if (log.IsInfoEnabled)
                    {
                        log.InfoFormat("Transit {0} from {1} to {2} with input {3}", this.FeedbackName, this.currentFeedbackLevel, next, input);
                    }

                    this.currentFeedbackLevel = next;
                    return true;
                }
            }
            else if (input < this.currentInput)
            {
                int threshold;
                FeedbackLevel last = this.currentFeedbackLevel;
                FeedbackLevel next = this.GetNextLowerThreshold(last, out threshold);
                while (next != last)
                {
                    if (input <= threshold)
                    {
                        last = next;
                        next = this.GetNextLowerThreshold(last, out threshold);
                    }
                    else
                    {
                        next = last;
                    }
                }

                this.currentInput = input;
                if (next != this.currentFeedbackLevel)
                {
                    if (log.IsInfoEnabled)
                    {
                        log.InfoFormat("Transit {0} from {1} to {2} with input {3}", this.FeedbackName, this.currentFeedbackLevel, next, input);
                    }

                    this.currentFeedbackLevel = next;
                    return true;
                }
            }

            return false;
        }