Пример #1
0
        public SetDomain <T> Join(SetDomain <T> newState, out bool weaker, bool widen)
        {
            if (set == newState.set)
            {
                weaker = false; return(this);
            }
            if (this.IsBottom)
            {
                weaker = !newState.IsBottom; return(newState);
            }
            if (newState.IsBottom || this.IsTop)
            {
                weaker = false; return(this);
            }
            if (newState.IsTop)
            {
                weaker = !this.IsTop; return(newState);
            }

            Contract.Assert(set != null);

            IFunctionalSet <T> result = set.Intersect(newState.set);

            weaker = result.Count < set.Count;
            return(new SetDomain <T>(result));
        }
Пример #2
0
        public bool LessEqual(SetDomain <T> that)
        {
            if (this.IsBottom)
            {
                return(true);
            }
            if (that.IsBottom)
            {
                return(false);
            }

            Contract.Assert(set != null);

            return(that.set.Contained(set));
        }
                    /// <summary>
                    /// Here we actually add constraints to our state.
                    /// </summary>
                    private Domain ConstrainLessThan(Expression var, Expression bound, Domain domain)
                    {
                        // First, skip unary coercions on var and bound
                        SkipConversionDecoder skipper = new SkipConversionDecoder();

                        var   = this.context.Decode <Unit, Expression, SkipConversionDecoder>(var, skipper, Unit.Value);
                        bound = this.context.Decode <Unit, Expression, SkipConversionDecoder>(bound, skipper, Unit.Value);

                        Variable left  = this.context.Unrefine(var);
                        Variable right = this.context.Unrefine(bound);
                        // add the bound to the set of bounds known
                        SetDomain <Variable> currentBounds =
                            (domain.Value.Contains(left)) ? domain.Value[left] : SetDomain <Variable> .TopValue;

                        return(new Domain(domain.Value.Add(left, currentBounds.Add(right))));
                    }
                /// <summary>
                /// Here's where the actual work is. We get passed a list of pairs (source,targets) representing
                /// the assignments t = source for each t in targets.
                ///
                /// For our domain, we thus add new mappings for all targets by looking up the bounds of the source and map the source bounds to new target bounds.
                /// </summary>
                public Domain ParallelAssign(Pair <Label, Label> edge, IFunctionalMap <Variable, FList <Variable> > sourceTargetMap, Domain state)
                {
                    EnvironmentDomain <Variable, SetDomain <Variable> > originalState = state.Value;
                    EnvironmentDomain <Variable, SetDomain <Variable> > newState      = originalState;

                    foreach (Variable source in sourceTargetMap.Keys)
                    {
                        FList <Variable> targets = sourceTargetMap[source];

                        // 1) for each target in this assignment, assign it the same bounds as source.
                        // 2) since we also have to map the source bounds, we assign it actually the union of all targets of all bounds of the source.
                        SetDomain <Variable> targetBounds = SetDomain <Variable> .TopValue;
                        if (originalState.Contains(source))
                        {
                            SetDomain <Variable> originalBounds = originalState[source];
                            foreach (Variable origBound in originalBounds.Elements)
                            {
                                FList <Variable> targetBoundNames = sourceTargetMap[origBound];
                                while (targetBoundNames != null)
                                {
                                    targetBounds     = targetBounds.Add(targetBoundNames.Head);
                                    targetBoundNames = targetBoundNames.Tail;
                                }
                            }
                        }
                        if (targetBounds.IsTop)
                        {
                            // have no bounds, so havoc all targets
                            while (targets != null)
                            {
                                newState = newState.Remove(targets.Head);
                                targets  = targets.Tail;
                            }
                        }
                        else
                        {
                            while (targets != null)
                            {
                                newState = newState.Add(targets.Head, targetBounds);
                                targets  = targets.Tail;
                            }
                        }
                    }
                    return(new Domain(newState));
                }
Пример #5
0
        public SetDomain <T> Meet(SetDomain <T> that)
        {
            if (set == that.set)
            {
                return(this);
            }
            if (this.IsBottom || that.IsTop)
            {
                return(this);
            }
            if (that.IsBottom || this.IsTop)
            {
                return(that);
            }

            Contract.Assert(set != null);

            IFunctionalSet <T> result = set.Union(that.set);

            return(new SetDomain <T>(result));
        }
                /// <summary>
                /// Here's one place where we want to check the bound. In principle, we want to only record the position and relevant
                /// parameters for a proof obligation and check it only after the fixpoint is computed.
                /// I'm lazy and checking it right away.
                /// </summary>
                public override Domain Ldelem(Label pc, Type type, Variable dest, Variable array, Variable index, Domain data)
                {
                    if (data.Value.Contains(index))
                    {
                        SetDomain <Variable> bounds = data.Value[index];
                        // lookup upper bound of index and array bound
                        Variable bound;
                        if (this.context.TryGetArrayLength(pc, array, out bound))
                        {
                            if (Debug)
                            {
                                Console.WriteLine("bound for array {0} is {1}", array.ToString(), bound.ToString());
                            }
                            // check that bound is in bounds of index
                            if (!bounds.Contains(bound))
                            {
                                Console.WriteLine("{0}: WARNING: Can't prove that array index is okay", this.context.SourceContext(pc));
                            }
                            else
                            {
                                Console.WriteLine("{0}: INFO: Array index looks good.", this.context.SourceContext(pc));
                            }
                        }
                        else
                        {
                            Console.WriteLine("{0}: WARNING: Can't prove that array index is okay", this.context.SourceContext(pc));
                        }
                    }
                    else
                    {
                        Console.WriteLine("{0}: WARNING: Can't prove that array index is okay", this.context.SourceContext(pc));
                    }

                    // TODO: might want to constrain index by bound of array to eliminate subsequent errors

                    return(data);
                }