public void Notify(int index, Quadstate before, Quadstate after)
            {
                var a = after == Quadstate.Yes || after == Quadstate.Contradiction;
                var b = before == Quadstate.Yes || before == Quadstate.Contradiction;

                if (a && !b)
                {
                    VisitNearby(index, false);
                }
                if (b && !a)
                {
                    // Must be backtracking.
                    // The main backtrack mechanism will handle undoing bans, and
                    // undos are always in order, so we just need to reverse VisitNearby
                    VisitNearby(index, true);
                }
            }
Exemplo n.º 2
0
            public void Notify(int index, Quadstate before, Quadstate after)
            {
                switch (before)
                {
                case Quadstate.No: NoCount--; break;

                case Quadstate.Maybe: MaybeCount--; break;

                case Quadstate.Yes: YesCount--; break;
                }
                switch (after)
                {
                case Quadstate.No: NoCount++; break;

                case Quadstate.Maybe: MaybeCount++; break;

                case Quadstate.Yes: YesCount++; break;
                }
            }
Exemplo n.º 3
0
 public static bool Possible(this Quadstate v) => (int)v >= 0;
Exemplo n.º 4
0
 public static bool IsContradiction(this Quadstate v) => v == Quadstate.Contradiction;
Exemplo n.º 5
0
 public static bool IsNo(this Quadstate v) => v == Quadstate.No;
Exemplo n.º 6
0
 public static bool IsMaybe(this Quadstate v) => v == Quadstate.Maybe;
Exemplo n.º 7
0
 public static bool IsYes(this Quadstate v) => v == Quadstate.Yes;
            public bool Next(int index, Quadstate selected)
            {
                switch (state)
                {
                case State.Initial:
                    if (selected.IsYes())
                    {
                        state         = State.InRun;
                        runCount      = 1;
                        runStartIndex = index;
                    }
                    return(false);

                case State.JustAfterRun:
                    if (selected.IsYes())
                    {
                        state         = State.InRun;
                        runCount      = 1;
                        runStartIndex = index;
                        goto checkCases;
                    }
                    else
                    {
                        state        = State.Initial;
                        prevRunCount = 0;
                        runCount     = 0;
                    }
                    return(false);

                case State.InRun:
                    if (selected.IsYes())
                    {
                        state     = State.InRun;
                        runCount += 1;
                        if (runCount > max)
                        {
                            // Immediate contradiction
                            return(true);
                        }
                        goto checkCases;
                    }
                    else
                    {
                        // Also case 1.
                        if (runCount == max)
                        {
                            if (selected.Possible())
                            {
                                banAt(index);
                            }
                        }
                        state        = State.JustAfterRun;
                        prevRunCount = runCount;
                        runCount     = 0;
                    }
                    return(false);
                }
                // Unreachable
                throw new Exception("Unreachable");
checkCases:
                // Have we entered case 1 or 2?
                if (prevRunCount + runCount == max)
                {
                    // Ban on the previous end of the run
                    if (runStartIndex == 0)
                    {
                        if (periodic)
                        {
                            banAt(indexCount - 1);
                        }
                    }
                    else
                    {
                        banAt(runStartIndex - 1);
                    }
                }
                return(false);
            }