Exemple #1
0
 public static ISymbolIdWithType[] Collect(TermManager termManager, Term term,
                                           SafeDictionary <Field, FieldValueHolder> fieldValues, SafeList <Field> fields, SafeList <TypeEx> allFieldTypes)
 {
     using (var collector = new VariablesCollector(termManager, fieldValues, fields, allFieldTypes))
     {
         collector.VisitTerm(default(TVoid), term);
         return(collector.variables.ToArray());
     }
 }
Exemple #2
0
        /// <summary>
        /// simplifies the term based on the contents of the term. all
        /// </summary>
        /// <param name="host"></param>
        /// <param name="termManager"></param>
        /// <param name="condition"></param>
        /// <param name="binOp"></param>
        private static Term SimplifyTerm(IPexExplorationComponent host, TermManager termManager, Term condition)
        {
            Term           left, right;
            BinaryOperator binOp;

            if (!termManager.TryGetBinary(condition, out binOp, out left, out right))
            {
                return(condition);
            }

            if (!IsInteger(termManager, left) || !IsInteger(termManager, right))
            {
                return(condition);
            }

            //Check whether the term is of the form x > 20, where one side is a constant. then no simplification needs to be done
            if (termManager.IsValue(left))
            {
                //one side is constant. so just return over here
                return(condition);
            }

            if (termManager.IsValue(right))
            {
                //one side is constant. so just return over here
                return(condition);
            }


            //none of the sides are concrete. both sides are symbolic.
            //find out which side can be more controlled based on the variables
            //contained on that side
            SafeList <Field>  allFieldsInLeftCondition          = new SafeList <Field>();
            SafeList <TypeEx> allFieldTypes                     = new SafeList <TypeEx>();
            SafeDictionary <Field, FieldValueHolder> leftfields = new SafeDictionary <Field, FieldValueHolder>();

            VariablesCollector.Collect(termManager, left, leftfields, allFieldsInLeftCondition, allFieldTypes);

            //TODO: How to get the concrete value of the other side, could be either left
            //or right. and make a term out of the concrete value
            int lvalue;

            if (termManager.TryGetI4Constant(left, out lvalue))
            {
            }

            int rvalue;

            if (termManager.TryGetI4Constant(right, out rvalue))
            {
            }

            return(condition);
        }
Exemple #3
0
        /// <summary>
        /// Solves a term and computes the actual and expected values of fields. There are various possibilites of the term. The actual
        /// fiels in a condition, returned by this function should be only from one side.
        ///
        /// a. One side of the term is concrete and not symbolic. It is easy to handle this case as one side is concrete
        /// b. Both the sides are symbolic. Pex assigns different values to both the sides, since both are symbolic, but this is not possible
        ///     in the context of ours. So, we treat one side as a concrete and other side as symbolic. We use heuristics in deciding which
        ///     side is concrete and which side is symbolic.
        /// </summary>
        /// <param name="host"></param>
        /// <param name="condition"></param>
        /// <param name="binOp"></param>
        /// <param name="actualFieldValues"></param>
        /// <param name="expectedFieldValues"></param>
        /// <param name="allFieldsInCondition"></param>
        /// <returns></returns>
        public static bool SolveTerm(IPexExplorationComponent host, Term condition, BinaryOperator binOp,
                                     out SafeDictionary <Field, FieldValueHolder> actualFieldValues,
                                     out SafeDictionary <Field, FieldValueHolder> expectedFieldValues,
                                     out SafeList <Field> allFieldsInCondition, out SafeList <TypeEx> allFieldTypes)
        {
            var termManager      = host.ExplorationServices.TermManager;
            var solverFactory    = host.ExplorationServices.SolverFactory;
            var solverStatistics = solverFactory.CreateStatistics();

            actualFieldValues   = new SafeDictionary <Field, FieldValueHolder>();
            expectedFieldValues = new SafeDictionary <Field, FieldValueHolder>();
            allFieldTypes       = new SafeList <TypeEx>();

            //Simplifies term based on the contents within the term. gathering a simplied form of condition
            condition = SimplifyTerm(host, termManager, condition);

            allFieldsInCondition = new SafeList <Field>();
            var variables = VariablesCollector.Collect(termManager, condition,
                                                       actualFieldValues, allFieldsInCondition, allFieldTypes);

            using (var solver = solverFactory.CreateSolver(solverStatistics))
            {
                var writer = new SafeStringWriter();
                foreach (var symbolIdWithType in variables)
                {
                    writer.WriteLine("variable: {0}", symbolIdWithType.Description);
                    solver.AddDomainVariable(0, symbolIdWithType);
                }
                writer.WriteLine("condition: {0}", prettyPrintTerm(host, condition, SystemTypes.Bool));

                solver.Assert("is satisfiable check", condition);
                IModel model;
                var    result = solver.TryGetModel(null, out model);
                writer.WriteLine("TryGetModel => {0}", result);
                if (result == TryGetModelResult.Success)
                {
                    foreach (var symbolIdWithType in variables)
                    {
                        writer.Write("{0} => ", symbolIdWithType.Description);
                        var variable = termManager.Symbol(symbolIdWithType);
                        var value    = model.GetValue(variable);
                        writer.WriteLine(prettyPrintTerm(host, value, symbolIdWithType.Type));

                        TypeEx type;

                        if (symbolIdWithType.Layout.Kind == LayoutKind.Ref &&
                            termManager.TryGetObjectType(value, out type) &&
                            type != SystemTypes.Null)
                        {
                            foreach (var field in type.InstanceFields)
                            {
                                var fieldVariable = termManager.SelectInstanceFieldInInitialState(variable, field);
                                var fieldValue    = model.GetValue(fieldVariable);

                                writer.Write("{0}.{1} => ", symbolIdWithType.Description, field.ShortName);
                                writer.WriteLine(prettyPrintTerm(host, fieldValue, field.Type));

                                TypeEx fieldValueType;
                                if (termManager.TryGetObjectType(fieldValue, out fieldValueType)) // is this an object, and if so, what’s its type?
                                {
                                    // do the same thing are before for the nested fields
                                    foreach (var nestedField in field.Type.InstanceFields)
                                    {
                                        var nestedFieldVariable = termManager.SelectInstanceFieldInInitialState(fieldValue, nestedField);
                                        var nestedFieldValue    = model.GetValue(nestedFieldVariable);
                                        writer.Write("{0}.{1}.{2} => ", symbolIdWithType.Description, field.ShortName, nestedField.ShortName);
                                        writer.WriteLine(prettyPrintTerm(host, nestedFieldValue, nestedField.Type));
                                    }
                                }

                                //stores the field value into expected field values
                                StoreFieldValue(termManager, field, fieldValue, expectedFieldValues, actualFieldValues, allFieldsInCondition, host, condition, binOp);
                            }
                        }
                    }
                }
                if (model != null)
                {
                    model.Dispose();
                }

                host.Log.Dump("Satisfiable Checker", "TermSolver", writer.ToString());
            }

            return(true);
        }