Пример #1
0
        public void TryDropPossibility_WhenRejectedByParent_LeavesUnchanged()
        {
            var fakePossibilities = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
            };
            var childOptional = OptionalObjective.CreateWithPossibilities(
                Possibilities.CreatePossibilities(new(), 2), 1);
            var possibilities = fakePossibilities.Cast <IPossibility>().Append(childOptional).ToArray();
            var optional      = OptionalObjective.CreateWithPossibilities(possibilities, 3);
            var parent        = new FakeObjective(isRequired: true);

            parent.CanDropPossibilities = false;
            IPossibility possibility = optional;
            IObjective   objective   = optional;

            Link.CreateConnectedLink(possibility, parent);
            var childToDrop = fakePossibilities[0];

            Assert.False(objective.TryDropPossibility(childToDrop.AttachedObjectives.First()));

            Assert.Equal(NodeState.UNKNOWN, optional.State);
            Assert.Empty(parent.DroppedPossibilities);
            Assert.Empty(fakePossibilities[0].DroppedFromObjectives);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);
            Assert.Equal(NodeState.UNKNOWN, childOptional.State);
        }
Пример #2
0
        public void TryDropAndReturnPossibility_WhenOkWithParent_Succeeds()
        {
            var fakePossibilities = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
            };
            var          optional     = OptionalObjective.CreateWithPossibilities(fakePossibilities, 1);
            var          parent       = new FakeObjective(isRequired: true);
            IPossibility possibility  = optional;
            IObjective   objective    = optional;
            var          linkToParent = Link.CreateConnectedLink(possibility, parent);
            var          childToDrop  = fakePossibilities[0];

            Assert.True(objective.TryDropPossibility(childToDrop.AttachedObjectives.First()));
            Assert.Equal(NodeState.UNKNOWN, optional.State);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);
            Assert.Empty(parent.DroppedPossibilities);

            Assert.True(objective.TryDropPossibility(fakePossibilities[1].AttachedObjectives.First()));
            Assert.Equal(NodeState.DROPPED, optional.State);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);
            Assert.Single(parent.DroppedPossibilities, linkToParent);

            objective.ReturnPossibility(fakePossibilities[1].AttachedObjectives.First());
            Assert.Equal(NodeState.UNKNOWN, optional.State);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);
            Assert.Empty(parent.DroppedPossibilities);

            objective.ReturnPossibility(childToDrop.AttachedObjectives.First());
            Assert.Equal(NodeState.UNKNOWN, optional.State);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);
            Assert.Empty(parent.DroppedPossibilities);
        }
Пример #3
0
        public void TryDropAndReturnFromObjective_CascadesToOtherParents_DropsThenReturns()
        {
            var fakePossibilities = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
            };
            var childOptional = OptionalObjective.CreateWithPossibilities(
                Possibilities.CreatePossibilities(new(), 2), 1);
            var optional = OptionalObjective.CreateWithPossibilities(
                fakePossibilities.Cast <IPossibility>().Prepend(childOptional).ToArray(), 1);
            var parentToDropFrom = OptionalObjective.CreateWithPossibilities(
                new IPossibility[] {
                new FakePossibility(),
            }, 1);
            var linkToParent        = Link.CreateConnectedLink(optional, parentToDropFrom);
            var parentToCascadeDrop = OptionalObjective.CreateWithPossibilities(
                new IPossibility[] {
                new FakePossibility(),
                optional,
            }, 2);
            var required = new FakeObjective(isRequired: true);

            Link.CreateConnectedLink(parentToDropFrom, required);
            Link.CreateConnectedLink(parentToCascadeDrop, required);
            IPossibility possibility = optional;

            Assert.True(possibility.TryDropFromObjective(linkToParent));
            Assert.Equal(NodeState.DROPPED, optional.State);
            Assert.Equal(NodeState.DROPPED, parentToCascadeDrop.State);

            possibility.ReturnFromObjective(linkToParent);
            Assert.Equal(NodeState.UNKNOWN, optional.State);
            Assert.Equal(NodeState.UNKNOWN, parentToCascadeDrop.State);
        }
Пример #4
0
        public void TrySelectPossibility_WhenRejectedByParent_LeavesUnchanged()
        {
            var fakePossibilities = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
            };
            var childOptional = OptionalObjective.CreateWithPossibilities(
                Possibilities.CreatePossibilities(new(), 2), 1);
            var optional            = OptionalObjective.CreateWithPossibilities(fakePossibilities, 1);
            var linkToChildOptional = Link.CreateConnectedLink(childOptional, optional);
            var parent = new FakeObjective(isRequired: true);

            parent.CanSelectPossibilities = false;
            var          linkToParent = Link.CreateConnectedLink(optional, parent);
            IPossibility possibility  = optional;
            IObjective   objective    = optional;

            Assert.False(objective.TrySelectPossibility(fakePossibilities[0].AttachedObjectives.First()));
            Assert.Equal(NodeState.UNKNOWN, optional.State);
            Assert.Equal(NodeState.UNKNOWN, childOptional.State);
            Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(),
                       p => Assert.Equal(NodeState.UNKNOWN, p.State));
            Assert.Empty(fakePossibilities[0].DroppedFromObjectives);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);
            Assert.Empty(parent.SelectedPossibilities);
        }
Пример #5
0
        internal static Link CreateConnectedLink(IPossibility possibility, IObjective objective)
        {
            var link = new Link(possibility, objective);

            possibility.AppendObjective(link);
            objective.AppendPossibility(link);
            return(link);
        }
Пример #6
0
        public void TrySelectAndDeselectPossibility_Succeeds()
        {
            var fakePossibilities = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
            };
            var childOptional = OptionalObjective.CreateWithPossibilities(
                Possibilities.CreatePossibilities(new(), 2), 1);
            var          optional            = OptionalObjective.CreateWithPossibilities(fakePossibilities, 2);
            var          linkToChildOptional = Link.CreateConnectedLink(childOptional, optional);
            var          parent       = new FakeObjective(isRequired: true);
            var          linkToParent = Link.CreateConnectedLink(optional, parent);
            IPossibility possibility  = optional;
            IObjective   objective    = optional;

            Assert.True(objective.TrySelectPossibility(fakePossibilities[0].AttachedObjectives.First()));
            Assert.Equal(NodeState.UNKNOWN, optional.State);
            Assert.Equal(NodeState.UNKNOWN, childOptional.State);
            Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(),
                       p => Assert.Equal(NodeState.UNKNOWN, p.State));
            Assert.Empty(fakePossibilities[0].DroppedFromObjectives);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);
            Assert.Empty(parent.SelectedPossibilities);

            Assert.True(objective.TrySelectPossibility(fakePossibilities[1].AttachedObjectives.First()));
            Assert.Equal(NodeState.SELECTED, optional.State);
            Assert.Equal(NodeState.UNKNOWN, childOptional.State);
            Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(),
                       p => Assert.Equal(NodeState.UNKNOWN, p.State));
            Assert.Single(parent.SelectedPossibilities, linkToParent);
            Assert.Empty(fakePossibilities[0].DroppedFromObjectives);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);

            objective.DeselectPossibility(fakePossibilities[1].AttachedObjectives.First());
            Assert.Equal(NodeState.UNKNOWN, optional.State);
            Assert.Equal(NodeState.UNKNOWN, childOptional.State);
            Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(),
                       p => Assert.Equal(NodeState.UNKNOWN, p.State));
            Assert.Empty(fakePossibilities[0].DroppedFromObjectives);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);
            Assert.Empty(parent.SelectedPossibilities);

            objective.DeselectPossibility(fakePossibilities[0].AttachedObjectives.First());
            Assert.Equal(NodeState.UNKNOWN, optional.State);
            Assert.Equal(NodeState.UNKNOWN, childOptional.State);
            Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(),
                       p => Assert.Equal(NodeState.UNKNOWN, p.State));
            Assert.Empty(fakePossibilities[0].DroppedFromObjectives);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);
            Assert.Empty(parent.SelectedPossibilities);
        }
Пример #7
0
        public void AllUnknownPossibilitiesAreConcrete_UpdatesWhenPossibilitiesChange()
        {
            var puzzle          = new Puzzle(4);
            var matrix          = ExactCoverGraph.Create(puzzle);
            var fakePossibility = new FakePossibility(isConcrete: false);
            var possibilities   = new IPossibility[] {
                new Possibility(new Coordinate(), 0),
                fakePossibility,
            };

            var objective = Objective.CreateFullyConnected(matrix, possibilities, 1);

            Assert.Single(fakePossibility.AttachedObjectives);
            Assert.False(objective.AllUnknownPossibilitiesAreConcrete);

            Assert.True(((IObjective)objective).TryDropPossibility(fakePossibility.AttachedObjectives.First()));
            Assert.True(objective.AllUnknownPossibilitiesAreConcrete);
        }
Пример #8
0
        public void TrySelectAndDeselect_WhenSharedByOpposingObjectives_Fails()
        {
            var puzzle = new Puzzle(4);
            var matrix = ExactCoverGraph.Create(puzzle);
            var concretePossibility = new Possibility(new(), 1);
            var possibilities       = new IPossibility[] { concretePossibility };
            var parentA             = OptionalObjective.CreateWithPossibilities(possibilities, 1);
            var parentB             = OptionalObjective.CreateWithPossibilities(possibilities.Append(new FakePossibility()).ToArray(), 1);
            var required            = Objective.CreateFullyConnected(
                matrix,
                new IPossibility[] { parentA, parentB },
                1);

            Assert.False(concretePossibility.TrySelect());
            Assert.Equal(NodeState.UNKNOWN, parentA.State);
            Assert.Equal(NodeState.UNKNOWN, parentB.State);
            Assert.NotEqual(NodeState.SELECTED, required.State);
        }
Пример #9
0
        public void TryDetachAndReattachObjective_IfRequiredObjective_DropsThenReturns()
        {
            var          concretePossibility = new Possibility(new(), 1);
            IPossibility possibility         = concretePossibility;
            var          objective           = new FakeObjective();
            var          objectiveToDetach   = new FakeObjective(isRequired: true);
            var          linkToDrop          = Link.CreateConnectedLink(possibility, objective);
            var          linkToDetach        = Link.CreateConnectedLink(possibility, objectiveToDetach);

            Assert.True(possibility.TryDropFromObjective(linkToDetach));
            Assert.Equal(NodeState.DROPPED, concretePossibility.State);
            Assert.Single(objective.DroppedPossibilities, linkToDrop);
            Assert.Empty(objectiveToDetach.DroppedPossibilities);

            possibility.ReturnFromObjective(linkToDetach);
            Assert.Equal(NodeState.UNKNOWN, concretePossibility.State);
            Assert.Empty(objective.DroppedPossibilities);
            Assert.Empty(objectiveToDetach.DroppedPossibilities);
        }
Пример #10
0
        public void TryDetach_CausingDrop_IfDropDisallowed_LeavesUnchanged()
        {
            var          concretePossibility = new Possibility(new(), 1);
            IPossibility possibility         = concretePossibility;
            var          objective           = new FakeObjective(isRequired: true);

            objective.CanDropPossibilities = false;
            var  objectiveToDetach = new FakeObjective(isRequired: true);
            Link linkToOther       = Link.CreateConnectedLink(possibility, objective);
            Link linkToDetach      = Link.CreateConnectedLink(possibility, objectiveToDetach);

            Assert.False(possibility.TryDropFromObjective(linkToDetach));
            Assert.Equal(NodeState.UNKNOWN, concretePossibility.State);
            Assert.Empty(objective.DroppedPossibilities);
            Assert.Empty(objectiveToDetach.DroppedPossibilities);

            // Verify the attempted-detached objective was still attached by dropping the
            // possibility from it.
            Assert.True(possibility.TryDropFromObjective(linkToOther));
            Assert.Equal(NodeState.DROPPED, concretePossibility.State);
            Assert.Single(objectiveToDetach.DroppedPossibilities, linkToDetach);
        }
Пример #11
0
        public void TryDropFromObjective_LeavesPossibilitiesUnchanged()
        {
            var fakePossibilities = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
            };
            var childOptional = OptionalObjective.CreateWithPossibilities(
                Possibilities.CreatePossibilities(new(), 2), 1);
            var optional = OptionalObjective.CreateWithPossibilities(
                fakePossibilities.Cast <IPossibility>().Prepend(childOptional).ToArray(), 1);
            var          parent       = new FakeObjective(isRequired: true);
            var          linkToParent = Link.CreateConnectedLink(optional, parent);
            IPossibility possibility  = optional;
            IObjective   objective    = optional;

            Assert.True(possibility.TryDropFromObjective(linkToParent));
            Assert.Equal(NodeState.DROPPED, optional.State);
            Assert.Equal(NodeState.UNKNOWN, childOptional.State);
            Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(),
                       p => Assert.Equal(NodeState.UNKNOWN, p.State));
            Assert.Empty(parent.SelectedPossibilities);
            Assert.Empty(fakePossibilities[0].DroppedFromObjectives);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);
        }
Пример #12
0
 private Link(IPossibility possibility, IObjective objective)
 {
     Possibility         = possibility;
     Objective           = objective;
     PreviousOnObjective = NextOnObjective = NextOnPossibility = PreviousOnPossibility = this;
 }