Ejemplo n.º 1
0
        internal ISatExpressionWrapper GetSolverExpressionFor(Instruction expression, List <List <Instruction> > listOfConjunctions = null)
        {
            Contract.Requires(expression != null);
            Contract.Ensures(Contract.Result <ISatExpressionWrapper>() != null);

            var wrapper = this.expressionMap[expression] as ISatExpressionWrapper;

            if (wrapper == null)
            {
                if (!this.mappings.IsRecursive(expression))
                {
                    expression = Simplifier.HoistPhiNodes(expression);
                }
                if (listOfConjunctions != null && expression.Type.TypeCode == PrimitiveTypeCode.Boolean && expression.Operation.OperationCode == OperationCode.Nop && expression.Operation.Value is INamedEntity)
                {
                    wrapper = this.GetSolverExpressionForBooleanPhiNode(expression, listOfConjunctions);
                }
                else
                {
                    var operand1 = expression.Operand1 as Instruction;
                    if (operand1 == null)
                    {
                        wrapper = this.satSolver.MakeExpression(expression.Operation, expression.Type);
                    }
                    else
                    {
                        var operand1wrapper = this.GetSolverExpressionFor(operand1, listOfConjunctions);
                        var operand2        = expression.Operand2 as Instruction;
                        if (operand2 == null)
                        {
                            wrapper = this.satSolver.MakeExpression(expression.Operation, expression.Type, operand1wrapper);
                        }
                        else
                        {
                            var operand2wrapper = this.GetSolverExpressionFor(operand2, listOfConjunctions);
                            wrapper = this.satSolver.MakeExpression(expression.Operation, expression.Type, operand1wrapper, operand2wrapper);
                        }
                    }
                }
                if (wrapper == null)
                {
                    wrapper = this.satSolver.Dummy;
                }
                Contract.Assume(wrapper != null);
                this.expressionMap[expression] = wrapper;
            }
            return(wrapper);
        }
Ejemplo n.º 2
0
        internal Instruction GetCanonicalExpression(Instruction naryInstruction, Instruction operand1, Instruction /*?*/ operand2, Instruction[] /*?*/ operands2andBeyond)
        {
            Contract.Requires(naryInstruction != null);
            Contract.Requires(operand1 != null);

            var expression = this.dummyInstruction;

            expression.Operation = naryInstruction.Operation;
            expression.Operand1  = this.GetCanonicalExpression(Simplifier.Simplify(operand1, this.mappings, this));
            if (operand2 != null)
            {
                expression.Operand2 = this.GetCanonicalExpression(Simplifier.Simplify(operand2, this.mappings, this));
            }
            else if (operands2andBeyond != null)
            {
                var n        = operands2andBeyond.Length;
                var canonOps = new Instruction[n];
                for (int i = 0; i < n; i++)
                {
                    Contract.Assume(operands2andBeyond[i] != null);
                    canonOps[i] = this.GetCanonicalExpression(Simplifier.Simplify(operands2andBeyond[i], this.mappings, this));
                }
                expression.Operand2 = canonOps;
            }
            expression.Type = naryInstruction.Type;

            Instruction result;

            if (!this.cache.TryGetValue(expression, out result))
            {
                this.cache[expression] = result = expression;
                this.dummyInstruction  = new Instruction();
            }
            Contract.Assume(result != null);
            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// If the cache contains an expression with an Operation structurally equivalent to unaryInstruction.Operation and Operand1 structurally equivalent to
        /// operand1, then return that expression. Otherwise construct such an expression, add it to the cache and return it.
        /// </summary>
        /// <param name="unaryInstruction">An instruction with a single operand.</param>
        /// <param name="operand1">The already canonicalized version of unaryInstruction.Operand1, if available, otherwise unaryInstruction.Operand1.</param>
        internal Instruction GetCanonicalExpression(Instruction unaryInstruction, Instruction operand1)
        {
            Contract.Requires(unaryInstruction != null);
            Contract.Requires(operand1 != null);
            Contract.Ensures(Contract.Result <Instruction>() != null);

            var expression = this.dummyInstruction;

            expression.Operation = unaryInstruction.Operation;
            expression.Operand1  = operand1;
            expression.Operand2  = null;
            expression.Type      = unaryInstruction.Type;

            Instruction result;

            if (!this.cache.TryGetValue(expression, out result))
            {
                result = this.GetCanonicalExpression(Simplifier.SimplifyUnary(expression, this.mappings, this));
                this.cache[expression] = result;
                this.dummyInstruction  = new Instruction();
            }
            Contract.Assume(result != null);
            return(result);
        }