Example #1
0
        /// <summary>
        /// Combine all the IConstraints in only one IConstraint.
        /// </summary>
        /// <param name="expression">The expression, in the form of a list
        /// of IConstraint in a postfix expression form</param>
        /// <returns></returns>
        public IConstraint ResolveExpression(IList <IConstraint> expression)
        {
            Stack <IConstraint> stack  = new Stack <IConstraint>();
            StringBuilder       errors = new StringBuilder();

            foreach (IConstraint IConstraint in expression)
            {
                if (IConstraint is BinaryConstraint)
                {
                    BinaryConstraint binop = IConstraint as BinaryConstraint;
                    IConstraint      right = stack.Pop();
                    IConstraint      left  = stack.Pop();
                    stack.Push(binop.SetConstraint(left, right));
                }
                else if (IConstraint is UnaryConstraint)
                {
                    Debug.Assert(stack.Count > 0, "trying to apply an unary IConstraint on a null object");
                    UnaryConstraint unop = IConstraint as UnaryConstraint;
                    stack.Push(unop.SetConstraint(stack.Pop()));
                }
                else
                {
                    stack.Push(IConstraint);
                }
            }
            return(stack.Pop());
        }
Example #2
0
        private Constraint GenerateBinaryNeighbor(int var1Id, int value1Id, int var2Id, int value2Id)
        {
            Constraint result = new BinaryConstraint <Permutation>()
            {
                Check = () => Variables[var1Id].Current == null || Variables[var2Id].Current == null ||
                        Math.Abs(Array.IndexOf(Variables[var1Id].Current.Values, value1Id) - Array.IndexOf(Variables[var2Id].Current.Values, value2Id)) == 1,
                VariableA = Variables[var1Id],
                VariableB = Variables[var2Id]
            };

            return(result);
        }
        public EinsteinCsp()
        {
            // setup variables
            var yellow = new EinsteinVariable(EinsteinValue.Yellow, this);
            var blue   = new EinsteinVariable(EinsteinValue.Blue, this);
            var red    = new EinsteinVariable(EinsteinValue.Red, this);
            var white  = new EinsteinVariable(EinsteinValue.White, this);
            var green  = new EinsteinVariable(EinsteinValue.Green, this);

            var norwegian = new EinsteinVariable(EinsteinValue.Norwegian, new List <House> {
                House.First
            }, this);
            var dane       = new EinsteinVariable(EinsteinValue.Dane, this);
            var englishman = new EinsteinVariable(EinsteinValue.Englishman, this);
            var german     = new EinsteinVariable(EinsteinValue.German, this);
            var swede      = new EinsteinVariable(EinsteinValue.Swede, this);

            var water = new EinsteinVariable(EinsteinValue.Water, this);
            var tea   = new EinsteinVariable(EinsteinValue.Tea, this);
            var milk  = new EinsteinVariable(EinsteinValue.Milk, new List <House> {
                House.Third
            }, this);
            var beer   = new EinsteinVariable(EinsteinValue.Beer, this);
            var coffee = new EinsteinVariable(EinsteinValue.Coffee, this);

            var cigar    = new EinsteinVariable(EinsteinValue.Cigar, this);
            var lights   = new EinsteinVariable(EinsteinValue.Lights, this);
            var noFilter = new EinsteinVariable(EinsteinValue.NoFilter, this);
            var pipe     = new EinsteinVariable(EinsteinValue.Pipe, this);
            var menthol  = new EinsteinVariable(EinsteinValue.Menthol, this);

            var cat   = new EinsteinVariable(EinsteinValue.Cat, this);
            var horse = new EinsteinVariable(EinsteinValue.Horse, this);
            var bird  = new EinsteinVariable(EinsteinValue.Bird, this);
            var dog   = new EinsteinVariable(EinsteinValue.Dog, this);
            var fish  = new EinsteinVariable(EinsteinValue.Fish, this);

            // setup riddle constraints
            _ = new BinaryConstraint <EinsteinValue, House>[]
            {
                // riddle hints
                new InTheSameHouse(englishman, red), //2nd
                new InTheSameHouse(red, englishman),

                new HouseOnTheLeft(white, green), //3rd
                new HouseOnTheRight(green, white),

                new InTheSameHouse(dane, tea), //4th
                new InTheSameHouse(tea, dane),

                new HouseNextTo(lights, cat), //5th
                new HouseNextTo(cat, lights),

                new InTheSameHouse(yellow, cigar), //6th
                new InTheSameHouse(cigar, yellow),

                new InTheSameHouse(german, pipe), //7th
                new InTheSameHouse(pipe, german),

                new HouseNextTo(lights, water), //9th
                new HouseNextTo(water, lights),

                new InTheSameHouse(noFilter, bird), //10th
                new InTheSameHouse(bird, noFilter),

                new InTheSameHouse(swede, dog), //11th
                new InTheSameHouse(dog, swede),

                new HouseNextTo(norwegian, blue), //12th
                new HouseNextTo(blue, norwegian),

                new HouseNextTo(horse, yellow), //13th
                new HouseNextTo(yellow, horse),

                new InTheSameHouse(menthol, beer), //14th
                new InTheSameHouse(beer, menthol),

                new InTheSameHouse(green, coffee), //15th
                new InTheSameHouse(coffee, green)
            };

            // unique house constraints
            var c = Constraints as List <BinaryConstraint <EinsteinValue, House> >;

            // colors
            foreach (var(bc1, bc2) in MathCsp.Combinations(yellow, blue, red, green, white)
                     .Select(pair =>
                             EinsteinBidirectionalConstraintFactory
                             .CreateBidirectionalConstraints(pair.Item1, pair.Item2, EinsteinConstraintType.UniqueHouse)))
            {
                c?.Add(bc1);
                c?.Add(bc2);
            }

            // nationalities
            foreach (var(bc1, bc2) in MathCsp.Combinations(german, norwegian, englishman, swede, dane)
                     .Select(pair =>
                             EinsteinBidirectionalConstraintFactory
                             .CreateBidirectionalConstraints(pair.Item1, pair.Item2, EinsteinConstraintType.UniqueHouse)))
            {
                c?.Add(bc1);
                c?.Add(bc2);
            }

            // drinks
            foreach (var(bc1, bc2) in MathCsp.Combinations(milk, water, beer, coffee, tea)
                     .Select(pair =>
                             EinsteinBidirectionalConstraintFactory
                             .CreateBidirectionalConstraints(pair.Item1, pair.Item2, EinsteinConstraintType.UniqueHouse)))
            {
                c?.Add(bc1);
                c?.Add(bc2);
            }

            // pets
            foreach (var(bc1, bc2) in MathCsp.Combinations(cat, dog, horse, fish, bird)
                     .Select(pair =>
                             EinsteinBidirectionalConstraintFactory
                             .CreateBidirectionalConstraints(pair.Item1, pair.Item2, EinsteinConstraintType.UniqueHouse)))
            {
                c?.Add(bc1);
                c?.Add(bc2);
            }

            // smokes
            foreach (var(bc1, bc2) in MathCsp.Combinations(noFilter, menthol, pipe, cigar, lights)
                     .Select(pair =>
                             EinsteinBidirectionalConstraintFactory
                             .CreateBidirectionalConstraints(pair.Item1, pair.Item2, EinsteinConstraintType.UniqueHouse)))
            {
                c?.Add(bc1);
                c?.Add(bc2);
            }
        }