Esempio n. 1
0
        // effects: Given a set of values in domain
        // Returns all possible values that are present in domain.
        static CellConstantSet DeterminePossibleValues(IEnumerable <Constant> domain)
        {
            // E.g., if we have 1, 2, NOT(1) --> Result = 1, 2
            // 1, NOT(1, 2) --> Result = 1, 2
            // 1, 2, NOT(NULL) --> Result = 1, 2, NULL
            // 1, 2, NOT(2), NOT(3, 4) --> Result = 1, 2, 3, 4

            CellConstantSet result = new CellConstantSet(Constant.EqualityComparer);

            foreach (Constant constant in domain)
            {
                NegatedConstant negated = constant as NegatedConstant;

                if (negated != null)
                {
                    // Go through all the constants in negated and add them to domain
                    // We add them to possible values also even if (say) Null is not allowed because we want the complete
                    // partitioning of the space, e.g., if the values specified by the caller are 1, NotNull -> we want 1, Null
                    foreach (Constant constElement in negated.Elements)
                    {
                        Debug.Assert(constElement as NegatedConstant == null, "Negated cell constant inside NegatedCellConstant");
                        result.Add(constElement);
                    }
                }
                else
                {
                    result.Add(constant);
                }
            }

            return(result);
        }
Esempio n. 2
0
 private void ExpandDomainsIfNeeded(Dictionary <MemberPath, CellConstantSet> domainMapForMembers)
 {
     // For the S-side, we always says that NOT(...) is
     // present. For example, if we are told "C", "P", we assume
     // that NOT(C, P) is possibly present in that column
     foreach (MemberPath path in domainMapForMembers.Keys)
     {
         CellConstantSet possibleValues = domainMapForMembers[path];
         if (path.IsScalarType() &&
             possibleValues.Any(c => c is NegatedConstant) == false)
         {
             if (MetadataHelper.HasDiscreteDomain(path.EdmType))
             {
                 // for a discrete domain, add all values that are not currently represented
                 // in the domain
                 Set <Constant> completeDomain = Domain.DeriveDomainFromMemberPath(path, m_edmItemCollection, true /* leaveDomainUnbounded */);
                 possibleValues.Unite(completeDomain);
             }
             else
             {
                 // for a non-discrete domain, add NOT("C", "P")
                 NegatedConstant negatedConstant = new NegatedConstant(possibleValues);
                 possibleValues.Add(negatedConstant);
             }
         }
     }
 }
Esempio n. 3
0
        // effects: Given a set of values in domain, "normalizes" it, i.e.,
        // all positive constants are seperated out and any negative constant
        // is changed s.t. it is the negative of all positive values
        // extraValues indicates more constants that domain could take, e.g.,
        // domain could be "1, 2, NOT(1, 2)", extraValues could be "3". In
        // this case, we return "1, 2, 3, NOT(1, 2, 3)"
        internal static CellConstantSet ExpandNegationsInDomain(IEnumerable <Constant> domain, IEnumerable <Constant> otherPossibleValues)
        {
            //Finds all constants referenced in (domain UNION extraValues) e.g: 1, NOT(2) =>  1, 2
            CellConstantSet possibleValues = DeterminePossibleValues(domain, otherPossibleValues);

            // For NOT --> Add all constants into d that are present in p but
            // not in the NOT
            // v = 1, NOT(1, 2); p = 1, 2, 3 => d = 1, NOT(1, 2, 3), 3
            // v = 1, 2, NOT(1); p = 1, 2, 4 => d = 1, 2, 4, NOT(1, 2, 4)
            // v = 1, 2, NOT(1, 2, 4), NOT(1, 2, 4, 5); p = 1, 2, 4, 5, 6 => d = 1, 2, 5, 6, NOT(1, 2, 4, 5, 6)

            // NotNull works naturally now. If possibleValues has (1, 2, NULL)
            // and values has NOT(NULL), add 1, 2 to m_domain
            CellConstantSet result = new Set <Constant>(Constant.EqualityComparer);

            foreach (Constant constant in domain)
            {
                NegatedConstant negated = constant as NegatedConstant;
                if (negated != null)
                {
                    result.Add(new NegatedConstant(possibleValues));
                    // Compute all elements in possibleValues that are not present in negated. E.g., if
                    // negated is NOT(1, 2, 3) and possibleValues is 1, 2, 3,
                    // 4, we need to add 4 to result
                    CellConstantSet remainingElements = possibleValues.Difference(negated.Elements);
                    result.AddRange(remainingElements);
                }
                else
                {
                    result.Add(constant);
                }
            }
            return(result);
        }
        protected override bool IsEqualTo(Constant right)
        {
            NegatedConstant rightNegatedConstant = right as NegatedConstant;

            if (rightNegatedConstant == null)
            {
                return(false);
            }

            return(m_negatedDomain.SetEquals(rightNegatedConstant.m_negatedDomain));
        }
Esempio n. 5
0
        // effects: Checks the invariants in "this"
        internal void AssertInvariant()
        {
            // Make sure m_domain has at most one negatedCellConstant
            //  m_possibleValues has none
            NegatedConstant negated = GetNegatedConstant(m_domain); // Can be null or not-null

            negated = GetNegatedConstant(m_possibleValues);
            Debug.Assert(negated == null, "m_possibleValues cannot contain negated constant");

            Debug.Assert(m_domain.IsSubsetOf(AllPossibleValuesInternal),
                         "All domain values must be contained in possibleValues");
        }
Esempio n. 6
0
        // requires: constants has at most one NegatedCellConstant
        // effects: Returns the NegatedCellConstant in this if any. Else
        // returns null
        private static NegatedConstant GetNegatedConstant(IEnumerable <Constant> constants)
        {
            NegatedConstant result = null;

            foreach (Constant constant in constants)
            {
                NegatedConstant negated = constant as NegatedConstant;
                if (negated != null)
                {
                    Debug.Assert(result == null, "Multiple negated cell constants?");
                    result = negated;
                }
            }
            return(result);
        }
Esempio n. 7
0
        // requires: this is complete
        // effects: Returns true iff this contains NOT(NULL OR ....)
        internal bool ContainsNotNull()
        {
            NegatedConstant negated = GetNegatedConstant(m_domain);

            return(negated != null && negated.Contains(Constant.Null));
        }
Esempio n. 8
0
 private void ExpandDomainsIfNeeded(Dictionary<MemberPath, CellConstantSet> domainMapForMembers)
 {
     // For the S-side, we always says that NOT(...) is
     // present. For example, if we are told "C", "P", we assume
     // that NOT(C, P) is possibly present in that column
     foreach (MemberPath path in domainMapForMembers.Keys)
     {
         CellConstantSet possibleValues = domainMapForMembers[path];
         if (path.IsScalarType() &&
             possibleValues.Any(c => c is NegatedConstant) == false)
         {
             if (MetadataHelper.HasDiscreteDomain(path.EdmType))
             {
                 // for a discrete domain, add all values that are not currently represented
                 // in the domain
                 Set<Constant> completeDomain = Domain.DeriveDomainFromMemberPath(path, m_edmItemCollection, true /* leaveDomainUnbounded */);
                 possibleValues.Unite(completeDomain);
             }
             else
             {
                 // for a non-discrete domain, add NOT("C", "P")
                 NegatedConstant negatedConstant = new NegatedConstant(possibleValues);
                 possibleValues.Add(negatedConstant);
             }
         }
     }
 }
Esempio n. 9
0
        private void AsCql(
            Action <NegatedConstant, IEnumerable <Constant> > negatedConstantAsCql,
            Action <Set <Constant> > varInDomain,
            Action varIsNotNull,
            Action varIsNull,
            bool skipIsNotNull)
        {
            Debug.Assert(this.RestrictedMemberSlot.MemberPath.IsScalarType(), "Expected scalar.");

            // If domain values contain a negated constant, delegate Cql generation into that constant.
            Debug.Assert(this.Domain.Values.Count(c => c is NegatedConstant) <= 1, "Multiple negated constants?");
            NegatedConstant negated = (NegatedConstant)this.Domain.Values.FirstOrDefault(c => c is NegatedConstant);

            if (negated != null)
            {
                negatedConstantAsCql(negated, this.Domain.Values);
            }
            else // We have only positive constants.
            {
                // 1. Generate "var in domain"
                // 2. If var is not nullable, append "... and var is not null".
                //    This is needed for boolean _from variables that must never evaluate to null because view generation assumes 2-valued boolean logic.
                // 3. If domain contains null, prepend "var is null or ...".
                //
                // A complete generation pattern:
                //     (var is null or    ( var in domain    and var is not null))
                //      ^^^^^^^^^^^^^^      ^^^^^^^^^^^^^    ^^^^^^^^^^^^^^^^^^^
                //      generated by #3    generated by #1     generated by #2

                // Copy the domain values for simplification changes.
                Set <Constant> domainValues = new Set <Constant>(this.Domain.Values, Constant.EqualityComparer);

                bool includeNull = false;
                if (domainValues.Contains(Constant.Null))
                {
                    includeNull = true;
                    domainValues.Remove(Constant.Null);
                }

                // Constraint counter-example could contain undefined cellconstant. E.g for booleans (for int its optimized out due to negated constants)
                // we want to treat undefined as nulls.
                if (domainValues.Contains(Constant.Undefined))
                {
                    includeNull = true;
                    domainValues.Remove(Constant.Undefined);
                }

                bool excludeNull = !skipIsNotNull && this.RestrictedMemberSlot.MemberPath.IsNullable;

                Debug.Assert(!includeNull || !excludeNull, "includeNull and excludeNull can't be true at the same time.");

                // #1: Generate "var in domain"
                if (domainValues.Count > 0)
                {
                    varInDomain(domainValues);
                }

                // #2: Append "... and var is not null".
                if (excludeNull)
                {
                    varIsNotNull();
                }

                // #3: Prepend "var is null or ...".
                if (includeNull)
                {
                    varIsNull();
                }
            }
        }
Esempio n. 10
0
        internal void ToUserString(bool invertOutput, StringBuilder builder, MetadataWorkspace workspace)
        {
            // If there is a negated cell constant, get the inversion of the domain
            NegatedConstant negatedConstant = null;

            foreach (Constant constant in Domain.Values)
            {
                negatedConstant = constant as NegatedConstant;
                if (negatedConstant != null)
                {
                    break;
                }
            }

            Set <Constant> constants;

            if (negatedConstant != null)
            {
                // Invert the domain and invert "invertOutput"
                invertOutput = !invertOutput;
                // Add all the values to negatedConstant's values to get the
                // final set of constants
                constants = new Set <Constant>(negatedConstant.Elements, Constant.EqualityComparer);
                foreach (Constant constant in Domain.Values)
                {
                    if (!(constant is NegatedConstant))
                    {
                        Debug.Assert(constants.Contains(constant), "Domain of negated constant does not have positive constant");
                        constants.Remove(constant);
                    }
                }
            }
            else
            {
                constants = new Set <Constant>(Domain.Values, Constant.EqualityComparer);
            }

            // Determine the resource to use
            Debug.Assert(constants.Count > 0, "one of const is false?");
            bool isNull         = constants.Count == 1 && constants.Single().IsNull();
            bool isTypeConstant = this is TypeRestriction;

            Func <object, string>         resourceName0 = null;
            Func <object, object, string> resourceName1 = null;

            if (invertOutput)
            {
                if (isNull)
                {
                    resourceName0 = isTypeConstant ? (Func <object, string>)Strings.ViewGen_OneOfConst_IsNonNullable : (Func <object, string>)Strings.ViewGen_OneOfConst_MustBeNonNullable;
                }
                else if (constants.Count == 1)
                {
                    resourceName1 = isTypeConstant ? (Func <object, object, string>)Strings.ViewGen_OneOfConst_IsNotEqualTo : (Func <object, object, string>)Strings.ViewGen_OneOfConst_MustNotBeEqualTo;
                }
                else
                {
                    resourceName1 = isTypeConstant ? (Func <object, object, string>)Strings.ViewGen_OneOfConst_IsNotOneOf : (Func <object, object, string>)Strings.ViewGen_OneOfConst_MustNotBeOneOf;
                }
            }
            else
            {
                if (isNull)
                {
                    resourceName0 = isTypeConstant ? (Func <object, string>)Strings.ViewGen_OneOfConst_MustBeNull : (Func <object, string>)Strings.ViewGen_OneOfConst_MustBeNull;
                }
                else if (constants.Count == 1)
                {
                    resourceName1 = isTypeConstant ? (Func <object, object, string>)Strings.ViewGen_OneOfConst_IsEqualTo : (Func <object, object, string>)Strings.ViewGen_OneOfConst_MustBeEqualTo;
                }
                else
                {
                    resourceName1 = isTypeConstant ? (Func <object, object, string>)Strings.ViewGen_OneOfConst_IsOneOf : (Func <object, object, string>)Strings.ViewGen_OneOfConst_MustBeOneOf;
                }
            }

            // Get the constants
            StringBuilder constantBuilder = new StringBuilder();

            Constant.ConstantsToUserString(constantBuilder, constants);

            Debug.Assert((resourceName0 == null) != (resourceName1 == null),
                         "Both resources must not have been set or be null");
            string variableName = m_restrictedMemberSlot.MemberPath.PathToString(false);

            if (isTypeConstant)
            {
                variableName = "TypeOf(" + variableName + ")";
            }

            if (resourceName0 != null)
            {
                builder.Append(resourceName0(variableName));
            }
            else
            {
                builder.Append(resourceName1(variableName, constantBuilder.ToString()));
            }

            if (invertOutput && isTypeConstant)
            {
                InvertOutputStringForTypeConstant(builder, constants, workspace);
            }
        }